Enchance Mouxusheng (#235)

1. 谋徐盛增加大离间、复活,可以变更副将
2. 修改CardEffecting等时机的承载者
3. 修复changeHero
4. 给moveCardTo堆一个proposer
5. 修复一些标准版武将和装备
This commit is contained in:
Nyutanislavsky 2023-08-02 21:50:47 +08:00 committed by GitHub
parent cc0228dc03
commit 35477c0ea1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 123 additions and 81 deletions

View File

@ -337,9 +337,13 @@ GameEvent.functions[GameEvent.CardEffect] = function(self)
self.logic:breakEvent() self.logic:breakEvent()
end end
if event == fk.PreCardEffect then
if cardEffectEvent.from and self.logic:trigger(event, self:getPlayerById(cardEffectEvent.from), cardEffectEvent) then if cardEffectEvent.from and self.logic:trigger(event, self:getPlayerById(cardEffectEvent.from), cardEffectEvent) then
self.logic:breakEvent() self.logic:breakEvent()
end end
elseif cardEffectEvent.to and self.logic:trigger(event, self:getPlayerById(cardEffectEvent.to), cardEffectEvent) then
self.logic:breakEvent()
end
self:handleCardEffect(event, cardEffectEvent) self:handleCardEffect(event, cardEffectEvent)
end end

View File

@ -570,7 +570,7 @@ function Room:setDeputyGeneral(player, general)
end end
---@param player ServerPlayer @ 要换将的玩家 ---@param player ServerPlayer @ 要换将的玩家
---@param new_general string @ 要变更的武将,若不存在则变身为孙策,孙策也不存在则nil错 ---@param new_general string @ 要变更的武将,若不存在则变身为孙策,孙策不存在变身为士兵
---@param full boolean|nil @ 是否血量满状态变身 ---@param full boolean|nil @ 是否血量满状态变身
---@param isDeputy boolean|nil @ 是否变的是副将 ---@param isDeputy boolean|nil @ 是否变的是副将
---@param sendLog boolean|nil @ 是否发Log ---@param sendLog boolean|nil @ 是否发Log
@ -580,7 +580,7 @@ function Room:changeHero(player, new_general, full, isDeputy, sendLog)
orig = Fk.generals[orig] orig = Fk.generals[orig]
local orig_skills = orig and orig:getSkillNameList() or Util.DummyTable local orig_skills = orig and orig:getSkillNameList() or Util.DummyTable
local new = Fk.generals[new_general] or Fk.generals["sunce"] local new = Fk.generals[new_general] or Fk.generals["sunce"] or Fk.generals["blank_shibing"]
local new_skills = table.map(orig_skills, function(e) local new_skills = table.map(orig_skills, function(e)
return "-" .. e return "-" .. e
end) end)
@ -590,24 +590,16 @@ function Room:changeHero(player, new_general, full, isDeputy, sendLog)
self:handleAddLoseSkills(player, table.concat(new_skills, "|"), nil, false) self:handleAddLoseSkills(player, table.concat(new_skills, "|"), nil, false)
if isDeputy then if isDeputy then
player.deputyGeneral = new_general self:setPlayerProperty(player, "deputyGeneral", new_general)
self:broadcastProperty(player, "deputyGeneral")
else else
player.general = new_general self:setPlayerProperty(player, "general", new_general)
self:broadcastProperty(player, "general") self:setPlayerProperty(player, "gender", new.gender)
self:setPlayerProperty(player, "kingdom", new.kingdom)
end end
player.gender = new.gender self:setPlayerProperty(player, "maxHp", player:getGeneralMaxHp())
self:broadcastProperty(player, "gender")
player.kingdom = new.kingdom
self:broadcastProperty(player, "kingdom")
player.maxHp = player:getGeneralMaxHp()
self:broadcastProperty(player, "maxHp")
if full or player.hp > player.maxHp then if full or player.hp > player.maxHp then
player.hp = player.maxHp self:setPlayerProperty(player, "hp", player.maxHp)
self:broadcastProperty(player, "hp")
end end
end end
@ -1080,7 +1072,7 @@ Room.askForUseViewAsSkill = Room.askForUseActiveSkill
function Room:askForDiscard(player, minNum, maxNum, includeEquip, skillName, cancelable, pattern, prompt, skipDiscard, no_indicate) function Room:askForDiscard(player, minNum, maxNum, includeEquip, skillName, cancelable, pattern, prompt, skipDiscard, no_indicate)
cancelable = (cancelable == nil) and true or cancelable cancelable = (cancelable == nil) and true or cancelable
no_indicate = no_indicate or false no_indicate = no_indicate or false
pattern = pattern or "" pattern = pattern or "."
local canDiscards = table.filter( local canDiscards = table.filter(
player:getCardIds{ Player.Hand, includeEquip and Player.Equip or nil }, function(id) player:getCardIds{ Player.Hand, includeEquip and Player.Equip or nil }, function(id)
@ -1200,7 +1192,7 @@ function Room:askForCard(player, minNum, maxNum, includeEquip, skillName, cancel
end end
cancelable = (cancelable == nil) and true or cancelable cancelable = (cancelable == nil) and true or cancelable
no_indicate = no_indicate or false no_indicate = no_indicate or false
pattern = pattern or "" pattern = pattern or "."
local chosenCards = {} local chosenCards = {}
local data = { local data = {
@ -1305,7 +1297,7 @@ function Room:askForGeneral(player, generals, n)
end end
--- 询问玩家若为神将、双势力需选择一个势力。 --- 询问玩家若为神将、双势力需选择一个势力。
---@param player ServerPlayer[]|nil @ 询问目标 ---@param players ServerPlayer[]|nil @ 询问目标
function Room:askForChooseKingdom(players) function Room:askForChooseKingdom(players)
players = players or self.alive_players players = players or self.alive_players
local specialKingdomPlayers = table.filter(players, function(p) local specialKingdomPlayers = table.filter(players, function(p)
@ -2023,7 +2015,8 @@ function Room:askForMoveCardInBoard(player, targetOne, targetTwo, skillName, fla
fk.ReasonPut, fk.ReasonPut,
skillName, skillName,
nil, nil,
true true,
player.id
) )
return { card = cardToMove, from = from.id, to = to.id } return { card = cardToMove, from = from.id, to = to.id }
@ -2615,10 +2608,12 @@ end
---@param skill_name string|nil @ 技能名 ---@param skill_name string|nil @ 技能名
---@param special_name string|nil @ 私人牌堆名 ---@param special_name string|nil @ 私人牌堆名
---@param visible boolean|nil @ 是否明置 ---@param visible boolean|nil @ 是否明置
function Room:moveCardTo(card, to_place, target, reason, skill_name, special_name, visible) ---@param proposer integer
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 ""
special_name = special_name or "" special_name = special_name or ""
proposer = proposer or nil
local ids = Card:getIdList(card) local ids = Card:getIdList(card)
local to local to
@ -2637,6 +2632,7 @@ function Room:moveCardTo(card, to_place, target, reason, skill_name, special_nam
skillName = skill_name, skillName = skill_name,
specialName = special_name, specialName = special_name,
moveVisible = visible, moveVisible = visible,
proposer = proposer,
} }
end end

View File

@ -7,6 +7,10 @@ local discardSkill = fk.CreateActiveSkill{
return false return false
end end
if Fk:currentRoom():getCardArea(to_select) == Player.Special then
return false
end
local checkpoint = true local checkpoint = true
local card = Fk:getCardById(to_select) local card = Fk:getCardById(to_select)
@ -46,6 +50,10 @@ local chooseCardsSkill = fk.CreateActiveSkill{
return false return false
end end
if Fk:currentRoom():getCardArea(to_select) == Player.Special then
return false
end
local checkpoint = true local checkpoint = true
local card = Fk:getCardById(to_select) local card = Fk:getCardById(to_select)

View File

@ -12,13 +12,10 @@ local jianxiong = fk.CreateTriggerSkill{
can_trigger = function(self, event, target, player, data) can_trigger = function(self, event, target, player, data)
local room = target.room local room = target.room
return target == player and player:hasSkill(self.name) and data.card and return target == player and player:hasSkill(self.name) and data.card and
table.find(data.card:isVirtual() and data.card.subcards or {data.card.id}, function(id) return room:getCardArea(id) == Card.Processing end) table.every(data.card:isVirtual() and data.card.subcards or {data.card.id}, function(id) return room:getCardArea(id) == Card.Processing end)
end, end,
on_use = function(self, event, target, player, data) on_use = function(self, event, target, player, data)
local room = player.room player.room:obtainCard(player.id, data.card, true, fk.ReasonJustMove)
local dummy = Fk:cloneCard("jueying")
dummy:addSubcards(table.filter(data.card:isVirtual() and data.card.subcards or {data.card.id}, function(id) return room:getCardArea(id) == Card.Processing end))
room:obtainCard(player.id, dummy, false, fk.ReasonJustMove)
end, end,
} }
@ -386,7 +383,7 @@ local qingguo = fk.CreateViewAsSkill{
card_filter = function(self, to_select, selected) card_filter = function(self, to_select, selected)
if #selected == 1 then return false end if #selected == 1 then return false end
return Fk:getCardById(to_select).color == Card.Black return Fk:getCardById(to_select).color == Card.Black
and Fk:currentRoom():getCardArea(to_select) ~= Player.Equip and Fk:currentRoom():getCardArea(to_select) ~= Player.Hand
end, end,
view_as = function(self, cards) view_as = function(self, cards)
if #cards ~= 1 then if #cards ~= 1 then
@ -406,7 +403,7 @@ local rende = fk.CreateActiveSkill{
name = "rende", name = "rende",
anim_type = "support", anim_type = "support",
card_filter = function(self, to_select, selected) card_filter = function(self, to_select, selected)
return Fk:currentRoom():getCardArea(to_select) ~= Card.PlayerEquip return Fk:currentRoom():getCardArea(to_select) == Card.PlayerHand
end, end,
target_filter = function(self, to_select, selected) target_filter = function(self, to_select, selected)
return #selected == 0 and to_select ~= Self.id return #selected == 0 and to_select ~= Self.id
@ -418,9 +415,7 @@ local rende = fk.CreateActiveSkill{
local player = room:getPlayerById(effect.from) local player = room:getPlayerById(effect.from)
local cards = effect.cards local cards = effect.cards
local marks = player:getMark("_rende_cards-phase") local marks = player:getMark("_rende_cards-phase")
local dummy = Fk:cloneCard'slash' room:moveCardTo(cards, Player.Hand, target, fk.ReasonGive, self.name, nil, false, player.id)
dummy:addSubcards(cards)
room:obtainCard(target.id, dummy, false, fk.ReasonGive)
room:addPlayerMark(player, "_rende_cards-phase", #cards) room:addPlayerMark(player, "_rende_cards-phase", #cards)
if marks < 2 and marks + #cards >= 2 and player:isWounded() then if marks < 2 and marks + #cards >= 2 and player:isWounded() then
room:recover{ room:recover{
@ -877,20 +872,27 @@ local liuli = fk.CreateTriggerSkill{
local ret = target == player and player:hasSkill(self.name) and local ret = target == player and player:hasSkill(self.name) and
data.card.trueName == "slash" data.card.trueName == "slash"
if ret then if ret then
self.target_list = {}
local room = player.room local room = player.room
for _, p in ipairs(room:getOtherPlayers(player)) do local from = room:getPlayerById(data.from)
if p.id ~= data.from and player:inMyAttackRange(p) then for _, p in ipairs(room.alive_players) do
table.insert(self.target_list, p.id) if p ~= player and p.id ~= data.from and player:inMyAttackRange(p) and not from:isProhibited(p, data.card) then
return true
end end
end end
return #self.target_list > 0
end 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 prompt = "#liuli-target" local prompt = "#liuli-target"
local plist, cid = room:askForChooseCardAndPlayers(player, self.target_list, 1, 1, nil, prompt, self.name, true) local targets = {}
local from = room:getPlayerById(data.from)
for _, p in ipairs(room.alive_players) do
if p ~= player and p.id ~= data.from and player:inMyAttackRange(p) and not from:isProhibited(p, data.card) then
table.insert(targets, p.id)
end
end
if #targets == 0 then return false end
local plist, cid = room:askForChooseCardAndPlayers(player, targets, 1, 1, nil, prompt, self.name, true)
if #plist > 0 then if #plist > 0 then
self.cost_data = {plist[1], cid} self.cost_data = {plist[1], cid}
return true return true
@ -979,7 +981,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.Equip return #selected < 2 and Fk:currentRoom():getCardArea(to_select) == Player.Hand
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)
@ -1019,7 +1021,7 @@ local qingnang = 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, targets) card_filter = function(self, to_select, selected, targets)
return #selected == 0 and Fk:currentRoom():getCardArea(to_select) ~= Player.Equip return #selected == 0 and Fk:currentRoom():getCardArea(to_select) == Player.Hand
end, end,
target_filter = function(self, to_select, selected, cards) target_filter = function(self, to_select, selected, cards)
return #selected == 0 and Fk:currentRoom():getPlayerById(to_select):isWounded() return #selected == 0 and Fk:currentRoom():getPlayerById(to_select):isWounded()

View File

@ -936,19 +936,14 @@ extension:addCards({
local bladeSkill = fk.CreateTriggerSkill{ local bladeSkill = fk.CreateTriggerSkill{
name = "#blade_skill", name = "#blade_skill",
attached_equip = "blade", attached_equip = "blade",
events = {fk.CardUseFinished}, events = {fk.CardEffectCancelledOut},
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 return player:hasSkill(self.name) and data.from == player.id and data.card.trueName == "slash" and not player.room:getPlayerById(data.to).dead
local use = data ---@type CardUseStruct
if use.card.name == "jink" and use.toCard and use.toCard.trueName == "slash" then
local effect = use.responseToEvent
return effect.from == player.id
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 use = room:askForUseCard(player, "slash", nil, "#blade_slash:" .. target.id, local use = room:askForUseCard(player, "slash", nil, "#blade_slash:" .. data.to,
true, { must_targets = {target.id}, exclusive_targets = {target.id}, bypass_distances = true, bypass_times = true }) true, { must_targets = {data.to}, exclusive_targets = {data.to}, bypass_distances = true, bypass_times = true })
if use then if use then
use.extraUse = true use.extraUse = true
self.cost_data = use self.cost_data = use
@ -1008,7 +1003,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" return player:hasSkill(self.name) 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
@ -1060,11 +1055,13 @@ 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" if player:hasSkill(self.name) and skill.trueName == "slash_skill" then
and #player:getCardIds(Player.Hand) == 1 local cards = card:isVirtual() and card.subcards or {card.id}
and player:getCardIds(Player.Hand)[1] == card.id then local handcards = player:getCardIds(Player.Hand)
if #cards == #handcards and table.every(cards, function(id) return table.contains(handcards, id) end) then
return 2 return 2
end end
end
end, end,
} }
halberdSkill:addRelatedSkill(halberdAudio) halberdSkill:addRelatedSkill(halberdAudio)

View File

@ -10,15 +10,16 @@ local cheat = fk.CreateActiveSkill{
can_use = function(self, player) can_use = function(self, player)
return true return true
end, end,
card_filter = function(self, card)
return false
end,
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)
local cardTypeName = room:askForChoice(from, { 'BasicCard', 'TrickCard', 'Equip' }, "cheat") local cardType = { 'basic', 'trick', 'equip' }
local cardType = Card.TypeBasic local cardTypeName = room:askForChoice(from, cardType, "cheat")
if cardTypeName == 'TrickCard' then local card_types = {Card.TypeBasic, Card.TypeTrick, Card.TypeEquip}
cardType = Card.TypeTrick cardType = card_types[table.indexOf(cardType, cardTypeName)]
elseif cardTypeName == 'Equip' then
cardType = Card.TypeEquip
end
local allCardIds = Fk:getAllCardIds() local allCardIds = Fk:getAllCardIds()
local allCardMapper = {} local allCardMapper = {}
@ -176,6 +177,7 @@ local test_trig = fk.CreateTriggerSkill{
local damage_maker = fk.CreateActiveSkill{ local damage_maker = fk.CreateActiveSkill{
name = "damage_maker", name = "damage_maker",
anim_type = "offensive", anim_type = "offensive",
prompt = "#damage_maker",
can_use = function(self, player) can_use = function(self, player)
return true return true
end, end,
@ -183,40 +185,65 @@ local damage_maker = fk.CreateActiveSkill{
return false return false
end, end,
card_num = 0, card_num = 0,
target_filter = function(self) target_filter = function(self, to_select, selected)
return true if self.interaction.data == "revive" then return false end
return #selected < 2
end, end,
target_num = 1, min_target_num = function(self)
interaction = function()return UI.ComboBox { return self.interaction.data == "revive" and 0 or 1
choices = {"normal_damage", "thunder_damage", "fire_damage", "ice_damage", "lose_hp", "heal_hp", "lose_max_hp", "heal_max_hp"} end,
}end, max_target_num = function(self)
return self.interaction.data == "revive" and 0 or 2
end,
interaction = function() return UI.ComboBox {
choices = {"normal_damage", "thunder_damage", "fire_damage", "ice_damage", "lose_hp", "heal_hp", "lose_max_hp", "heal_max_hp", "revive"}
} 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)
local target = room:getPlayerById(effect.tos[1]) local victim = #effect.tos > 0 and room:getPlayerById(effect.tos[1])
local target = #effect.tos > 1 and room:getPlayerById(effect.tos[2])
local choice = self.interaction.data local choice = self.interaction.data
local number
if choice ~= "revive" then
local choices = {} local choices = {}
for i = 1, 99 do for i = 1, 99 do
table.insert(choices, tostring(i)) table.insert(choices, tostring(i))
end end
local number = tonumber(room:askForChoice(from, choices, self.name, nil)) number = tonumber(room:askForChoice(from, choices, self.name, nil))
end
if target then from = target end
if choice == "heal_hp" then if choice == "heal_hp" then
room:recover{ room:recover{
who = target, who = victim,
num = number, num = number,
recoverBy = from, recoverBy = from,
skillName = self.name skillName = self.name
} }
elseif choice == "heal_max_hp" then elseif choice == "heal_max_hp" then
room:changeMaxHp(target, number) room:changeMaxHp(victim, number)
elseif choice == "lose_max_hp" then elseif choice == "lose_max_hp" then
room:changeMaxHp(target, -number) room:changeMaxHp(victim, -number)
elseif choice == "lose_hp" then elseif choice == "lose_hp" then
room:loseHp(target, number, self.name) room:loseHp(victim, number, self.name)
elseif choice == "revive" then
local targets = table.map(table.filter(room.players, function(p) return p.dead end), function(p) return "seat#" .. tostring(p.seat) end)
if #targets > 0 then
targets = room:askForChoice(from, targets, self.name, "#revive-ask")
if targets then
target = tonumber(string.sub(targets, 6))
for _, p in ipairs(room.players) do
if p.seat == target then
room:revivePlayer(p, true)
break
end
end
end
end
else else
choices = {"normal_damage", "thunder_damage", "fire_damage", "ice_damage"} local choices = {"normal_damage", "thunder_damage", "fire_damage", "ice_damage"}
room:damage({ room:damage({
from = from, from = from,
to = target, to = victim,
damage = number, damage = number,
damageType = table.indexOf(choices, choice), damageType = table.indexOf(choices, choice),
skillName = self.name skillName = self.name
@ -237,15 +264,21 @@ local change_hero = fk.CreateActiveSkill{
return #selected < 1 return #selected < 1
end, end,
target_num = 1, target_num = 1,
interaction = function(self)
return UI.ComboBox {
choices = { "mainGeneral", "deputyGeneral"},
}
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)
local target = room:getPlayerById(effect.tos[1]) local target = room:getPlayerById(effect.tos[1])
local choice = self.interaction.data
local generals = table.map(Fk:getGeneralsRandomly(8, Fk:getAllGenerals()), function(p) return p.name end) local generals = table.map(Fk:getGeneralsRandomly(8, Fk:getAllGenerals()), function(p) return p.name end)
local general = room:askForGeneral(from, generals, 1) local general = room:askForGeneral(from, generals, 1)
if general == nil then if general == nil then
general = table.random(generals) general = table.random(generals)
end end
room:changeHero(target, general, false, false, true) room:changeHero(target, general, false, choice == "deputyGeneral", true)
end, end,
} }
local test_zhenggong = fk.CreateTriggerSkill{ local test_zhenggong = fk.CreateTriggerSkill{
@ -304,6 +337,8 @@ Fk:loadTranslationTable{
["damage_maker"] = "制伤", ["damage_maker"] = "制伤",
[":damage_maker"] = "出牌阶段,你可以进行一次伤害制造器。", [":damage_maker"] = "出牌阶段,你可以进行一次伤害制造器。",
["#damage_maker"] = "制伤:选择一名小白鼠,可选另一名角色做伤害来源(默认谋徐盛)",
["#revive-ask"] = "复活一名角色!",
["change_hero"] = "变更", ["change_hero"] = "变更",
[":change_hero"] = "出牌阶段,你可以变更一名角色武将牌。", [":change_hero"] = "出牌阶段,你可以变更一名角色武将牌。",