diff --git a/audio/die/mb_cuilingyi.mp3 b/audio/die/mb_cuilingyi.mp3 new file mode 100644 index 0000000000..46635694fb Binary files /dev/null and b/audio/die/mb_cuilingyi.mp3 differ diff --git a/audio/skill/mbcaiqiu1.mp3 b/audio/skill/mbcaiqiu1.mp3 new file mode 100644 index 0000000000..10ca6a7e99 Binary files /dev/null and b/audio/skill/mbcaiqiu1.mp3 differ diff --git a/audio/skill/mbcaiqiu2.mp3 b/audio/skill/mbcaiqiu2.mp3 new file mode 100644 index 0000000000..15e3032027 Binary files /dev/null and b/audio/skill/mbcaiqiu2.mp3 differ diff --git a/audio/skill/mbcaiqiu3.mp3 b/audio/skill/mbcaiqiu3.mp3 new file mode 100644 index 0000000000..c20ec6c56d Binary files /dev/null and b/audio/skill/mbcaiqiu3.mp3 differ diff --git a/audio/skill/mbcaiqiu4.mp3 b/audio/skill/mbcaiqiu4.mp3 new file mode 100644 index 0000000000..f5d85bc49c Binary files /dev/null and b/audio/skill/mbcaiqiu4.mp3 differ diff --git a/audio/skill/mbweizhuang_dongjiao1.mp3 b/audio/skill/mbweizhuang_dongjiao1.mp3 new file mode 100644 index 0000000000..e0a492e5e8 Binary files /dev/null and b/audio/skill/mbweizhuang_dongjiao1.mp3 differ diff --git a/audio/skill/mbweizhuang_dongjiao2.mp3 b/audio/skill/mbweizhuang_dongjiao2.mp3 new file mode 100644 index 0000000000..4ac62338b9 Binary files /dev/null and b/audio/skill/mbweizhuang_dongjiao2.mp3 differ diff --git a/audio/skill/mbweizhuang_dongjiao3.mp3 b/audio/skill/mbweizhuang_dongjiao3.mp3 new file mode 100644 index 0000000000..b6ffb67e81 Binary files /dev/null and b/audio/skill/mbweizhuang_dongjiao3.mp3 differ diff --git a/audio/skill/mbweizhuang_dongjiao4.mp3 b/audio/skill/mbweizhuang_dongjiao4.mp3 new file mode 100644 index 0000000000..6292dfd057 Binary files /dev/null and b/audio/skill/mbweizhuang_dongjiao4.mp3 differ diff --git a/audio/skill/mbweizhuang_dongjiao5.mp3 b/audio/skill/mbweizhuang_dongjiao5.mp3 new file mode 100644 index 0000000000..4728920f7d Binary files /dev/null and b/audio/skill/mbweizhuang_dongjiao5.mp3 differ diff --git a/audio/skill/mbweizhuang_dongjiao6.mp3 b/audio/skill/mbweizhuang_dongjiao6.mp3 new file mode 100644 index 0000000000..93739e6ed2 Binary files /dev/null and b/audio/skill/mbweizhuang_dongjiao6.mp3 differ diff --git a/audio/skill/mbweizhuang_guidian1.mp3 b/audio/skill/mbweizhuang_guidian1.mp3 new file mode 100644 index 0000000000..7ca3df5f0c Binary files /dev/null and b/audio/skill/mbweizhuang_guidian1.mp3 differ diff --git a/audio/skill/mbweizhuang_guidian2.mp3 b/audio/skill/mbweizhuang_guidian2.mp3 new file mode 100644 index 0000000000..6bfb0c8078 Binary files /dev/null and b/audio/skill/mbweizhuang_guidian2.mp3 differ diff --git a/audio/skill/mbweizhuang_guidian3.mp3 b/audio/skill/mbweizhuang_guidian3.mp3 new file mode 100644 index 0000000000..687dd34934 Binary files /dev/null and b/audio/skill/mbweizhuang_guidian3.mp3 differ diff --git a/audio/skill/mbweizhuang_guidian4.mp3 b/audio/skill/mbweizhuang_guidian4.mp3 new file mode 100644 index 0000000000..b0b9741d4c Binary files /dev/null and b/audio/skill/mbweizhuang_guidian4.mp3 differ diff --git a/audio/skill/mbweizhuang_xiuge1.mp3 b/audio/skill/mbweizhuang_xiuge1.mp3 new file mode 100644 index 0000000000..b30d8efec5 Binary files /dev/null and b/audio/skill/mbweizhuang_xiuge1.mp3 differ diff --git a/audio/skill/mbweizhuang_xiuge2.mp3 b/audio/skill/mbweizhuang_xiuge2.mp3 new file mode 100644 index 0000000000..08c424eb67 Binary files /dev/null and b/audio/skill/mbweizhuang_xiuge2.mp3 differ diff --git a/audio/skill/mbweizhuang_xiuge3.mp3 b/audio/skill/mbweizhuang_xiuge3.mp3 new file mode 100644 index 0000000000..8dfd7ae231 Binary files /dev/null and b/audio/skill/mbweizhuang_xiuge3.mp3 differ diff --git a/audio/skill/mbweizhuang_xiuge4.mp3 b/audio/skill/mbweizhuang_xiuge4.mp3 new file mode 100644 index 0000000000..78144a2a5e Binary files /dev/null and b/audio/skill/mbweizhuang_xiuge4.mp3 differ diff --git a/audio/skill/mbweizhuang_xiuge5.mp3 b/audio/skill/mbweizhuang_xiuge5.mp3 new file mode 100644 index 0000000000..928bb1c32a Binary files /dev/null and b/audio/skill/mbweizhuang_xiuge5.mp3 differ diff --git a/audio/skill/mbweizhuang_xiuge6.mp3 b/audio/skill/mbweizhuang_xiuge6.mp3 new file mode 100644 index 0000000000..1452ad2375 Binary files /dev/null and b/audio/skill/mbweizhuang_xiuge6.mp3 differ diff --git a/audio/skill/mbxishang1.mp3 b/audio/skill/mbxishang1.mp3 new file mode 100644 index 0000000000..12c7ba8449 Binary files /dev/null and b/audio/skill/mbxishang1.mp3 differ diff --git a/audio/skill/mbxishang2.mp3 b/audio/skill/mbxishang2.mp3 new file mode 100644 index 0000000000..166cfcc30e Binary files /dev/null and b/audio/skill/mbxishang2.mp3 differ diff --git a/audio/skill/mbxishang3.mp3 b/audio/skill/mbxishang3.mp3 new file mode 100644 index 0000000000..e0f53809cd Binary files /dev/null and b/audio/skill/mbxishang3.mp3 differ diff --git a/audio/skill/mbxishang4.mp3 b/audio/skill/mbxishang4.mp3 new file mode 100644 index 0000000000..645f185a31 Binary files /dev/null and b/audio/skill/mbxishang4.mp3 differ diff --git a/audio/skill/mbxishang5.mp3 b/audio/skill/mbxishang5.mp3 new file mode 100644 index 0000000000..d6af51075e Binary files /dev/null and b/audio/skill/mbxishang5.mp3 differ diff --git a/audio/skill/mbxishang6.mp3 b/audio/skill/mbxishang6.mp3 new file mode 100644 index 0000000000..40a1bc20c9 Binary files /dev/null and b/audio/skill/mbxishang6.mp3 differ diff --git a/audio/skill/mbxishang7.mp3 b/audio/skill/mbxishang7.mp3 new file mode 100644 index 0000000000..ecacddf24d Binary files /dev/null and b/audio/skill/mbxishang7.mp3 differ diff --git a/audio/skill/mbxishang8.mp3 b/audio/skill/mbxishang8.mp3 new file mode 100644 index 0000000000..cf865635ee Binary files /dev/null and b/audio/skill/mbxishang8.mp3 differ diff --git a/card/yingbian.js b/card/yingbian.js index 01f7704c39..ea1fcc583e 100644 --- a/card/yingbian.js +++ b/card/yingbian.js @@ -385,8 +385,37 @@ game.import("card", function () { }, skills: ["taigongyinfu_skill", "taigongyinfu_link"], }, + baipidao: { + audio: true, + fullskin: true, + type: "equip", + subtype: "equip1", + bingzhu: ["曹操"], + distance: { attackFrom: -1 }, + ai: { + basic: { + equipValue: 4, + }, + }, + skills: ["baipidao_skill"], + }, }, skill: { + baipidao_skill: { + audio: true, + equipSkill: true, + trigger: { + source: "damageSource", + }, + filter(event, player) { + return event.card?.name == "sha" && event.notLink() && event.player?.isIn() && event.player.countGainableCards(player, "h"); + }, + prompt2: "获得其一张手牌", + logTarget: "player", + async content(event, trigger, player) { + await player.gainPlayerCard(trigger.player, "h", true); + }, + }, suijiyingbian_skill: { mod: { cardname(card, player) { @@ -890,6 +919,9 @@ game.import("card", function () { tianjitu_info: "锁定技,当此牌进入你的装备区时,你弃置一张不为此【天机图】的牌。当此牌离开你的装备区时,你将手牌摸至五张。", taigongyinfu: "太公阴符", taigongyinfu_info: "出牌阶段开始时,你可以横置或重置一名角色。出牌阶段结束时,你可以重铸一张手牌。", + baipidao: "百辟刀", + baipidao_skill: "百辟刀", + baipidao_info: "当你使用【杀】对目标角色造成伤害后,可以获得其一张手牌。", taigongyinfu_skill: "太公阴符", taigongyinfu_link: "太公阴符", yingbian_zhuzhan_tag: "助战", diff --git a/character/extra/character.js b/character/extra/character.js index 17784c16d6..855f1fac06 100644 --- a/character/extra/character.js +++ b/character/extra/character.js @@ -1,4 +1,11 @@ const characters = { + dc_shen_sunquan: { + sex: "male", + group: "shen", + hp: 4, + skills: ["dccangming", "dcchouxi", "dcjichao"], + groupInGuozhan: "wu", + }, zc26_shen_huangyueying: { sex: "female", group: "shen", diff --git a/character/extra/characterTitle.js b/character/extra/characterTitle.js index 40207aa26a..ac69e2f9ee 100644 --- a/character/extra/characterTitle.js +++ b/character/extra/characterTitle.js @@ -1,4 +1,5 @@ export default { + //dc_shen_sunquan: "", shen_liubei: "誓守桃园义", shen_luxun: "红莲业火", shen_ganning: "江表之力牧", diff --git a/character/extra/skill.js b/character/extra/skill.js index 691b8a1a22..4eda6f67a4 100644 --- a/character/extra/skill.js +++ b/character/extra/skill.js @@ -2,6 +2,277 @@ import { lib, game, ui, get, ai, _status } from "../../noname.js"; /** @type { importCharacterConfig['skill'] } */ const skills = { + //新杀神孙权 + dccangming: { + audio: 2, + trigger: { + global: "gameDrawAfter", + }, + forced: true, + filter(event, player) { + return game.countPlayer(() => true) > 0; + }, + logTarget() { + return game.filterPlayer(() => true); + }, + async content(event, trigger, player) { + const { name } = event; + const func = async target => { + if (!target.countCards("h")) { + return; + } + const next = target.addToExpansion(target.getCards("h"), target, "giveAuto", false); + next.gaintag.add(name); + await next; + }; + await game.doAsyncInOrder(event.targets, func); + }, + marktext: "溟", + intro: { + markcount: "expansion", + mark(dialog, storage, player) { + const cards = player.getExpansions("dccangming"); + if (player.isUnderControl(true)) { + dialog.addAuto(cards); + } else { + return "共有" + get.cnNumber(cards.length) + "张牌"; + } + }, + }, + global: "dccangming_gain", + subSkill: { + gain: { + trigger: { + player: ["phaseBegin", "damageEnd"], + }, + filter(event, player) { + return player.countExpansions("dccangming") > 0; + }, + forced: true, + async content(event, trigger, player) { + await player.gain(player.getExpansions("dccangming"), "giveAuto"); + }, + }, + }, + }, + dcchouxi: { + audio: 2, + enable: "phaseUse", + onChooseToUse(event) { + if (game.online) { + return; + } + const list = []; + game.countPlayer(current => { + if (!current.countExpansions("dccangming")) { + return false; + } + for (const card of current.getExpansions("dccangming")) { + if (["basic", "trick"].includes(get.type(card, false))) { + list.add(get.name(card, false)); + } + } + return true; + }); + list.removeArray(event.player.getStorage("dcchouxi_used")); + event.set("dcchouxiList", list); + }, + filter(event, player) { + if (!event.dcchouxiList?.length || !player.countCards("hs")) { + return false; + } + return event.dcchouxiList.some(name => { + const card = get.autoViewAs({ name: name, storage: { dcchouxi: true } }, "unsure"); + return player.hasUseTarget(card); + }); + }, + chooseButton: { + dialog(event, player) { + const list = event.dcchouxiList.filter(name => { + const card = get.autoViewAs({ name: name, storage: { dcchouxi: true } }, "unsure"); + return player.hasUseTarget(card); + }); + const dialog = ui.create.dialog("筹汐", [list, "vcard"], "hidden"); + dialog.direct = true; + return dialog; + }, + check(button) { + const player = get.player(), + card = get.autoViewAs({ name: button.link[2], storage: { dcchouxi: true } }, "unsure"); + return player.getUseValue(card); + }, + backup(links, player) { + return { + audio: "dcchouxi", + popname: true, + viewAs: { + name: links[0][2], + storage: { + dcchouxi: true, + }, + }, + filterCard: true, + position: "hs", + check(card) { + return 5 - get.value(card); + }, + async precontent(event, trigger, player) { + player.addTempSkill("dcchouxi_used"); + player.markAuto("dcchouxi_used", event.result.card.name); + event.getParent().addCount = false; + }, + }; + }, + prompt(links, player) { + return `将一张手牌当作${get.translation(links[0][2])}使用`; + }, + }, + locked: false, + mod: { + cardUsable(card, player) { + if (card?.storage?.dcchouxi) { + return Infinity; + } + }, + targetInRange(card, player) { + if (card?.storage?.dcchouxi) { + return true; + } + }, + }, + ai: { + order: 8, + result: { + player: 1, + }, + }, + subSkill: { + backup: {}, + used: { + charlotte: true, + onremove: true, + }, + }, + }, + dcjichao: { + audio: 2, + enable: "phaseUse", + usable: 1, + filter(event, player) { + return game.hasPlayer(current => current != player && current.countCards("h") > 0); + }, + chooseButton: { + dialog(event, player) { + const choiceList = [ + ["one", "令一名其他角色将随机一半手牌(向上取整)置于武将牌上"], + ["all", "令所有其他角色将手牌置于武将牌上"], + ]; + const dialog = ui.create.dialog("激潮", [choiceList, "textbutton"], "hidden"); + dialog.direct = true; + return dialog; + }, + filter(button, player) { + return button.link == "one" || !player.hasSkill("dcjichao_blocker"); + }, + check(button) { + const player = get.player(); + if (button.link == "all") { + return 2; + } + return 1; + }, + backup(links, player) { + return { + choice: links[0], + manualConfirm: true, + filterTarget(card, player, target) { + return target != player && target.countCards("h") > 0; + }, + selectTarget() { + const { choice } = get.info("dcjichao_backup"); + if (choice == "all") { + return -1; + } + return 1; + }, + async contentBefore(event, trigger, player) { + const { choice } = get.info("dcjichao_backup"); + if (choice == "all") { + player.addTempSkill("dcjichao_blocker", { source: "die" }); + } + }, + async content(event, trigger, player) { + const { target, name } = event, + { choice } = get.info(name); + let cards = target.getCards("h"); + if (choice !== "all") { + let num = Math.ceil(cards.length / 2); + if (num > 0) { + cards = cards.randomGets(num); + } + } + if (!cards.length) { + return; + } + const next = target.addToExpansion(cards, target, "giveAuto"); + next.gaintag.add("dccangming"); + await next; + }, + ai1: () => 1, + ai2(target) { + const player = get.player(); + return -get.attitude(player, target); + }, + }; + }, + prompt(links, player) { + if (links[0] == "all") { + return "令所有其他角色将手牌置于武将牌上,称为“溟”"; + } + return "令一名其他角色将随机一半手牌(向上取整)置于武将牌上,称为“溟”"; + }, + }, + ai: { + order(item, player) { + player ??= get.player(); + if ( + game.hasPlayer(current => { + if (current == player || !current.countCards("h")) { + return false; + } + if (get.attitude(player, current) > 0) { + return false; + } + return player.countCards("hs", card => player.canUse(card, current) && get.effect(current, card, player, player) > 0) > 0; + }) + ) { + return 9; + } + return 1; + }, + result: { + player(player, target) { + if ( + game.hasPlayer(current => { + if (current == player || !current.countCards("h")) { + return false; + } + return get.attitude(player, current) < 0; + }) + ) { + return 1; + } + return 0; + }, + }, + }, + subSkill: { + blocker: { + charlotte: true, + }, + backup: {}, + }, + }, //26珍藏神黄月英 zc26_cangqiao: { trigger: { diff --git a/character/extra/sort.js b/character/extra/sort.js index 37936104ca..80f4cba751 100644 --- a/character/extra/sort.js +++ b/character/extra/sort.js @@ -5,7 +5,7 @@ const characterSort = { extra_shan: ["shen_zhaoyun", "shen_simayi"], extra_yin: ["shen_liubei", "shen_luxun"], extra_lei: ["shen_ganning", "shen_zhangliao"], - extra_decade: ["shen_zhonghui", "shen_huangzhong", "shen_jiangwei", "shen_machao", "shen_zhangfei", "shen_zhangjiao", "shen_dengai", "shen_xuzhu", "dc_shen_huatuo", "shen_pangtong"], + extra_decade: ["dc_shen_sunquan", "shen_zhonghui", "shen_huangzhong", "shen_jiangwei", "shen_machao", "shen_zhangfei", "shen_zhangjiao", "shen_dengai", "shen_xuzhu", "dc_shen_huatuo", "shen_pangtong"], extra_ol: ["shen_dianwei", "ol_zhangliao", "shen_caopi", "shen_zhenji", "shen_sunquan", "junk_zhangjiao"], extra_mobilezhi: ["shen_guojia", "shen_xunyu"], extra_mobilexin: ["shen_taishici", "shen_sunce"], diff --git a/character/extra/translate.js b/character/extra/translate.js index 946cdbac91..d681a073a2 100644 --- a/character/extra/translate.js +++ b/character/extra/translate.js @@ -551,6 +551,14 @@ const translates = { zc26_lingling_info: "准备阶段,你须对一名角色造成1点雷电伤害;每轮结束时,所有死亡角色同时秘密选择上家或下家,然后按顺序(死亡由前到后)依次移动此牌至选择的角色对应区域内。", zc26_lingling_skill: "軨軨", zc26_lingling_skill_info: "准备阶段,你须对一名角色造成1点雷电伤害;每轮结束时,所有死亡角色同时秘密选择上家或下家,然后按顺序(死亡由前到后)依次移动此牌至选择的角色对应区域内。", + dc_shen_sunquan: "新杀神孙权", + dc_shen_sunquan_prefix: "新杀|神", + dccangming: "沧溟", + dccangming_info: "锁定技,分发初始手牌后,你令所有角色将手牌置于武将牌上,称为“溟”。一名角色受到伤害后或回合开始时,获得其武将牌上的所有“溟”。", + dcchouxi: "筹汐", + dcchouxi_info: "出牌阶段,你可将一张手牌当作“溟”中的一张基本牌或普通锦囊牌使用(每种牌名每回合限一次),以此法使用牌无距离次数限制。", + dcjichao: "激潮", + dcjichao_info: "出牌阶段限一次,你可选择一项:1.令一名其他角色将随机一半数量的手牌(向上取整)置于武将牌上,称为“溟”;2.令所有其他角色将手牌置于武将牌上,称为“溟”,然后此选项失效直到你杀死一名角色。", }; export default translates; diff --git a/character/huicui/skill.js b/character/huicui/skill.js index 305109f839..af2911ddb7 100644 --- a/character/huicui/skill.js +++ b/character/huicui/skill.js @@ -11746,9 +11746,9 @@ const skills = { target.addSkill("dcyongbi_eff1"); } if (list.length >= 3) { - player.addMark("dcyongbi_eff2", 2, false); + player.addMark("dcyongbi_eff2", 1, false); player.addSkill("dcyongbi_eff2"); - target.addMark("dcyongbi_eff2", 2, false); + target.addMark("dcyongbi_eff2", 1, false); target.addSkill("dcyongbi_eff2"); } }, @@ -14295,7 +14295,7 @@ const skills = { usable: 1, content() { "step 0"; - player.draw(); + player.draw(2); "step 1"; if (player.countCards("h") > 0 && game.hasPlayer(current => current != player)) { var suits = lib.suit.slice(0), diff --git a/character/huicui/translate.js b/character/huicui/translate.js index 27d55dee59..01f7dbffc4 100644 --- a/character/huicui/translate.js +++ b/character/huicui/translate.js @@ -81,7 +81,7 @@ const translates = { xixiu_info: "锁定技。①当你成为其他角色使用牌的目标时,若你的装备区内有和此牌花色相同的牌,则你摸一张牌。②若你装备区内的牌数为1,则其他角色不能弃置你装备区内的牌。", zhangyao: "张媱", yuanyu: "怨语", - yuanyu_info: "出牌阶段限一次。你可以摸一张牌,然后选择一张手牌和一名其他角色。该角色获得如下效果直到你发动〖夕颜〗:{你与该角色的弃牌阶段开始时,或当该角色造成1点伤害后,其须将一张手牌作为“怨”置于你的武将牌上}。然后你将你选择的手牌作为“怨”置于你的武将牌上。", + yuanyu_info: "出牌阶段限一次。你可以摸两张牌,然后选择一张手牌和一名其他角色。该角色获得如下效果直到你发动〖夕颜〗:{你与该角色的弃牌阶段开始时,或当该角色造成1点伤害后,其须将一张手牌作为“怨”置于你的武将牌上}。然后你将你选择的手牌作为“怨”置于你的武将牌上。", xiyan: "夕颜", xiyan_info: "当有牌作为“怨”移动到你的武将牌上后,若“怨”中的花色数达到4种,则你可以获得所有“怨”。然后若当前回合角色:是你,你本回合手牌上限+4且使用牌无次数限制且重置你的〖怨语〗于此阶段的发动次数;不是你,你可令当前回合角色本回合手牌上限-4且不能使用基本牌。", xiahoulingnv: "夏侯令女", @@ -235,7 +235,7 @@ const translates = { dcyingyu: "媵予", dcyingyu_info: "准备阶段开始时,你可以展示两名角色的各一张手牌。若这两张牌的花色不同,则你可以令一名角色获得另一名角色的展示牌。", dcyongbi: "拥嬖", - dcyongbi_info: "限定技。出牌阶段,你可以将所有手牌交给一名其他男性角色。你将〖媵予〗的发动时机改为“准备阶段和结束阶段开始时”。然后若这些牌中包含的花色数:大于1,则你与其本局游戏的手牌上限+2;大于2,则当你或其于本局游戏内受到大于1的伤害时,此伤害-2。", + dcyongbi_info: "限定技。出牌阶段,你可以将所有手牌交给一名其他男性角色。你将〖媵予〗的发动时机改为“准备阶段和结束阶段开始时”。然后若这些牌中包含的花色数:大于1,则你与其本局游戏的手牌上限+2;大于2,则当你或其于本局游戏内受到大于1的伤害时,此伤害-1。", dc_huangquan: "黄权", dcquanjian: "劝谏", dcquanjian_info: "出牌阶段每项各限一次。你可以选择一项流程并选择一名其他角色A:⒈令A对其攻击范围内的另一名角色B造成1点伤害。⒉令A将手牌数调整至手牌上限(至多摸至五张),且其本回合内不能使用手牌。然后A选择一项:⒈执行此流程。⒉本回合下次受到的伤害+1。", diff --git a/character/jsrg/skill.js b/character/jsrg/skill.js index 1c05059612..fba5c7dd75 100644 --- a/character/jsrg/skill.js +++ b/character/jsrg/skill.js @@ -4920,14 +4920,35 @@ const skills = { async cost(event, trigger, player) { const cards = player.getExpansions("jsrgshacheng"); const targets = trigger.targets.filter(i => i.isIn() && i.hasHistory("lose", evt => evt.cards2.length)); + const map = new Map(); + trigger.targets.forEach(target => { + if (target.isIn()) { + const num = Math.min( + 5, + target + .getHistory("lose") + .map(evt => evt.cards2.length) + .reduce((p, c) => p + c, 0) + ); + if (num > 0) { + map.set(target, num); + } + } + }); const result = await player .chooseButtonTarget({ createDialog: [`###${get.prompt(event.skill)}###移去一张“城”,令一名目标角色摸X张牌(X为该角色本回合失去过的牌数且至多为5)`, cards], targets: targets, + drawMap: map, filterButton: true, filterTarget(card, player, target) { - return get.event().targets.includes(target); + const { targets, drawMap } = get.event(); + if (drawMap.has(target)) { + target.prompt(`${drawMap.get(target)}张`); + } + return targets.includes(target); }, + complexTarget: true, ai2(target) { return target == get.event("targetx") ? 1 : 0; }, diff --git a/character/mobile/character.js b/character/mobile/character.js index 0bef4ecded..a0214001c4 100644 --- a/character/mobile/character.js +++ b/character/mobile/character.js @@ -1,4 +1,11 @@ const characters = { + mb_cuilingyi: { + sex: "female", + group: "wei", + hp: 3, + skills: ["mbcaiqiu", "mbxishang"], + names: "崔|null", + }, mb_luyu: { sex: "male", group: "wei", diff --git a/character/mobile/characterTitle.js b/character/mobile/characterTitle.js index b12050f5ea..ba5f3d9b06 100644 --- a/character/mobile/characterTitle.js +++ b/character/mobile/characterTitle.js @@ -1,5 +1,6 @@ export default { //pot_dengai: "", + mb_luyu: "秉性贞固", mb_sunluyu: "舍身饲虎", mb_caohong: "福将", mb_guanyinping: "武姬", diff --git a/character/mobile/dynamicTranslate.js b/character/mobile/dynamicTranslate.js index 2f4ff0c0bb..cc6c5309fa 100644 --- a/character/mobile/dynamicTranslate.js +++ b/character/mobile/dynamicTranslate.js @@ -1,6 +1,20 @@ import { lib, game, ui, get, ai, _status } from "../../noname.js"; const dynamicTranslates = { + mbweizhuang(player, skill) { + if (!player) { + return lib.translate[`${skill}_info`]; + } + if (get.nameList(player).includes("mb_cuilingyi")) { + const skin = player.skin[player.name2 === "mb_cuilingyi" ? "name2" : "name"], + index = lib.characterSubstitute["mb_cuilingyi"].map(i =>i[0]).indexOf(skin); + if (index >= 0) { + const trueSkill = `${skill}_${skin.slice(13, -1)}x`; + return get.skillInfoTranslation(trueSkill, player, false); + } + } + return "这衣服,岂是你配穿的?"; + }, mbfozong(player) { const list = player.getStorage("mbfozong"); if (!list?.length) { diff --git a/character/mobile/index.js b/character/mobile/index.js index ac39be59ca..b85b234281 100644 --- a/character/mobile/index.js +++ b/character/mobile/index.js @@ -57,6 +57,17 @@ game.import("character", function () { ["mb_zerong_black", ["die:mb_zerong"]], ["mb_zerong_all", ["die:mb_zerong"]], ], + mb_cuilingyi: [ + ["mb_cuilingyi_guidian1", ["die:mb_cuilingyi"]], + ["mb_cuilingyi_guidian2", ["die:mb_cuilingyi"]], + ["mb_cuilingyi_guidian3", ["die:mb_cuilingyi"]], + ["mb_cuilingyi_dongjiao1", ["die:mb_cuilingyi"]], + ["mb_cuilingyi_dongjiao2", ["die:mb_cuilingyi"]], + ["mb_cuilingyi_dongjiao3", ["die:mb_cuilingyi"]], + ["mb_cuilingyi_xiuge1", ["die:mb_cuilingyi"]], + ["mb_cuilingyi_xiuge2", ["die:mb_cuilingyi"]], + ["mb_cuilingyi_xiuge3", ["die:mb_cuilingyi"]], + ], }, card: { ...cards }, skill: { ...skills }, diff --git a/character/mobile/skill.js b/character/mobile/skill.js index 492ab3e282..6f56f2ad16 100644 --- a/character/mobile/skill.js +++ b/character/mobile/skill.js @@ -2,6 +2,716 @@ import { lib, game, ui, get, ai, _status } from "../../noname.js"; /** @type { importCharacterConfig['skill'] } */ const skills = { + //手杀崔令仪 + mbcaiqiu: { + audio: 4, + logAudio(event, player) { + if (event.name == "useCard") { + return ["mbcaiqiu3.mp3", "mbcaiqiu4.mp3"]; + } + return 2; + }, + trigger: { + global: ["roundStart", "useCardAfter"], + }, + filter(event, player) { + if (event.name == "useCard") { + return ( + event.player != player && + player.getRoundHistory("gain", evt => { + if (evt.getParent().name != "mbcaiqiu") { + return false; + } + return evt.cards?.length && evt.cards.some(card => card.name == event.card.name); + }).length > 0 + ); + } + return game.countPlayer2(() => true, true) > 0; + }, + forced: true, + locked: false, + async content(event, trigger, player) { + if (trigger?.name == "useCard") { + await player.loseHp(); + return; + } + const cards = get.cards( + game.countPlayer2(() => true, true), + true + ); + const result = await player + .chooseButton(["裁裘:是否获得其中任意张牌?", cards], [1, Infinity], "allowChooseAll") + .set("ai", button => { + const player = get.player(); + //只要贪不死就往死里贪 + if (game.countPlayer(() => true) > player.hp && ["sha", "shan"].includes(button.link.name)) { + return 0; + } + return 1; + }) + .forResult(); + if (result?.bool && result.links?.length) { + await player.gain(result.links, "draw"); + } + }, + }, + mbxishang: { + audio: 8, + logAudio(event, player) { + if (!get.nameList(player).includes("mb_cuilingyi")) { + return 6; + } + const skin = player.skin[player.name2 === "mb_cuilingyi" ? "name2" : "name"]; + if (skin?.indexOf("guidian") !== -1) { + return 2; + } + if (skin?.indexOf("dongjiao") !== -1) { + return ["mbxishang3.mp3", "mbxishang4.mp3"]; + } + if (skin?.indexOf("xiuge") !== -1) { + return ["mbxishang5.mp3", "mbxishang6.mp3"]; + } + return 6; + }, + derivation: ["mbweizhuang", "mbweizhuang_guidianx", "mbweizhuang_dongjiaox", "mbweizhuang_xiugex"], + trigger: { + player: "enterGame", + global: "phaseBefore", + }, + filter(event, player) { + if (!get.nameList(player).includes("mb_cuilingyi")) { + return false; + } + return event.name != "phase" || game.phaseNumber == 0; + }, + locked: true, + async cost(event, trigger, player) { + const list = lib.characterSubstitute["mb_cuilingyi"]; + if (!list.length) { + return; + } + const createButton = (item, type, position, noclick, node) => { + const [name, info] = item, + skill = `mbweizhuang_${name.slice(13, -1)}x`; + let isTemp = false; + if (!lib.character[name]) { + isTemp = true; + lib.character[name] = get.convertedCharacter(["female", "", 0, [], info || []]); + } + lib.translate[name] ??= lib.translate[skill]; + node = ui.create.buttonPresets.character(name, type, position, noclick); + if (isTemp) { + delete lib.character[name]; + } + node._link = node.link = [null, null, name]; + node.skinSkill = skill; + node._customintro = [node => `形象:${lib.translate[node.skinSkill]}`, node => get.skillInfoTranslation(node.skinSkill, null, false)]; + return node; + }; + const result = await player.chooseButton(["袭裳:选择你本局的形象", [list.slice(0, 3), createButton], [list.slice(3, 6), createButton], [list.slice(6), createButton]], true).forResult(); + if (result?.bool && result.links?.length) { + player.changeSkin(event.skill, result.links[0][2]); + event.result = { + bool: true, + }; + } + }, + async content(event, trigger, player) { + player.addSkills("mbweizhuang"); + }, + mark: true, + marktext: "裳", + intro: { + markcount(storage, player) { + return player.countCards("h", card => card.hasGaintag("faceup_tag")); + }, + mark(dialog, content, player) { + const cards = player.getCards("h", card => card.hasGaintag("faceup_tag")); + if (cards.length) { + dialog.addAuto(cards); + } else { + return "无明置牌"; + } + }, + }, + group: "mbxishang_show", + subSkill: { + show: { + audio: "mbxishang", + logAudio() { + return ["mbxishang7.mp3", "mbxishang8.mp3"]; + }, + trigger: { + player: "gainAfter", + global: "loseAsyncAfter", + }, + filter(event, player) { + if (event.getParent().name == "draw") { + return false; + } + const cards = event.getg(player); + return cards?.length && player.getCards("h").containsSome(...cards); + }, + forced: true, + async content(event, trigger, player) { + const gains = trigger.getg(player); + const cards = player.getCards("h", card => gains.includes(card)); + if (!cards.length) { + return; + } + const next = game.createEvent("faceUpCard"); + next.player = player; + next.cards = cards; + next.skill = "mbxishang"; + next.setContent(async (event, trigger, player) => { + const { cards } = event; + game.log(player, "明置了", cards); + game.addCardKnower( + cards, + game.filterPlayer(() => true) + ); + game.broadcastAll(cards => { + cards.forEach(card => card.addGaintag("faceup_tag")); + }, cards); + }); + player.markSkill("mbxishang"); + }, + }, + }, + }, + mbweizhuang: { + // @ts-ignore audio的类型注释不够全 + audio: ["guidian", "dongjiao", "xiuge"].map(key => `mbweizhuang_${key}`), + getFaceupCards(player, judge = false) { + const cards = player.getCards("h", card => card.hasGaintag("faceup_tag")); + if (player.countCards("e")) { + cards.addArray(player.getCards("e")); + } + if (judge && player.countCards("j")) { + cards.addArray(player.getCards("j")); + } + return cards; + }, + derivation: ["mbweizhuang_guidianx", "mbweizhuang_dongjiaox", "mbweizhuang_xiugex"], + group: ["mbweizhuang_guidian", "mbweizhuang_dongjiao", "mbweizhuang_xiuge"], + subSkill: { + guidianx: { + audio: "mbweizhuang_guidian", + }, + dongjiaox: { + audio: "mbweizhuang_dongjiao", + }, + xiugex: { + audio: "mbweizhuang_xiuge", + }, + guidian: { + audio: 4, + logAudio(event, player) { + if (event.name == "faceUpCard") { + return ["mbweizhuang_guidian3.mp3", "mbweizhuang_guidian4.mp3"]; + } + return 2; + }, + trigger: { + global: ["faceUpCardAfter", "phaseJieshuBegin"], + player: "phaseDrawBegin2", + }, + filter(event, player) { + if (!get.nameList(player).includes("mb_cuilingyi")) { + return false; + } + const skin = player.skin[player.name2 === "mb_cuilingyi" ? "name2" : "name"]; + if (!skin || skin.indexOf("guidian") === -1) { + return false; + } + if (event.name == "phaseDraw") { + return !event.numFixed && player.getStorage("mbweizhuang_guidian", [0, 0, 0])[0] !== 0; + } + if (event.name == "phaseJieshu") { + if (!get.info("mbweizhuang").getFaceupCards(event.player).length) { + return false; + } + return true; + } + if (player.countMark("mbweizhuang_used") > game.countPlayer2(() => true, true)) { + return false; + } + let num = 0, + evts = game.getAllGlobalHistory("everything", evt => evt.name == "faceUpCard"); + for (let i = evts.indexOf(event); i >= 0; i--) { + const evt = evts[i]; + if (evt?.mbweizhuang_count) { + break; + } + if (evt.cards?.length) { + num += evt.cards.length; + } + } + return num > game.countPlayer2(() => true, true); + }, + intro: { + nocount: true, + content(storage, player, skill) { + const list = player.getStorage("mbweizhuang_guidian", [0, 0, 0]); + const getStr = num => { + if (num >= 0) { + return `+${num}`; + } + return num; + }; + return `摸牌阶段摸牌数${getStr(list[0])}
出杀次数${getStr(list[1])}
手牌上限${getStr(list[2])}`; + }, + }, + onremove: true, + locked: false, + mod: { + cardUsable(card, player, num) { + if (card.name == "sha") { + const list = player.getStorage("mbweizhuang_guidian", [0, 0, 0]); + return num + list[1]; + } + }, + maxHandcard(player, num) { + const list = player.getStorage("mbweizhuang_guidian", [0, 0, 0]); + return num + list[2]; + }, + }, + async cost(event, trigger, player) { + let record = player.getStorage(event.skill, [0, 0, 0]); + if (trigger.name == "phaseDraw") { + trigger.num = Math.max(0, trigger.num + record[0]); + return; + } + const list = [2 + record[0], player.getCardUsable("sha", true), player.getHandcardLimit(), player.getHp()]; + const prompt = trigger.name == "phaseJieshu" ? `是否令一项数值-1并发动一次${get.poptip("mbcaiqiu")}?` : `令一项数值+1`; + const choiceList = [ + ["draw", `摸牌阶段摸牌数(${list[0]})`], + ["sha", `出杀次数(${list[1]})`], + ["limit", `手牌上限(${list[2]})`], + ["hp", `体力值(${list[3]})`], + ]; + const next = player + .chooseButton([ + `褽装:${prompt}`, + [choiceList.slice(0, 2), "tdnodes"], + [choiceList.slice(2), "tdnodes"], + [ + dialog => { + dialog.buttons.forEach(i => { + i.style.setProperty("width", "200px", "important"); + i.style.setProperty("text-align", "left", "important"); + }); + }, + "handle", + ], + ]) + .set("numList", list); + if (trigger.name == "phaseJieshu") { + next.set("filterButton", button => { + const { player, numList } = get.event(), + index = ["draw", "sha", "limit", "hp"].indexOf(button.link); + return numList[index] > 0; + }); + next.set("ai", button => { + const { player, numList } = get.event(); + if (numList[1] > 1 && button.link == "sha") { + return 3; + } + if (numList[2] > 2 && button.link == "limit") { + return 2; + } + if (button.link == "draw") { + return 1; + } + return 0; + }); + } else { + next.set("filterButton", button => { + const { player, numList } = get.event(); + return button.link != "hp" || player.isDamaged(); + }); + next.set("ai", button => { + const { player, numList } = get.event(); + if (button.link == "hp") { + return 3; + } + if (numList[1] < 3 && button.link == "sha") { + return 2; + } + return Math.random(); + }); + next.set("forced", true); + } + const result = await next.forResult(); + if (result?.bool && result.links?.length) { + event.result = { + bool: true, + cost_data: result.links[0], + }; + } + }, + async content(event, trigger, player) { + const choice = event.cost_data, + index = ["draw", "sha", "limit", "hp"].indexOf(choice), + list = player.getStorage(event.name, [0, 0, 0]); + if (trigger.name != "phaseJieshu") { + trigger.set("mbweizhuang_count", true); + player.addSkill("mbweizhuang_used"); + player.addMark("mbweizhuang_used", 1, false); + } + if (index > 2) { + if (trigger.name == "phaseJieshu") { + await player.loseHp(); + } else { + await player.recover(); + } + } else { + if (trigger.name == "phaseJieshu") { + list[index]--; + } else { + list[index]++; + } + player.setStorage(event.name, list, true); + } + if (trigger.name == "phaseJieshu") { + await player.useResult({ skill: "mbcaiqiu" }, event); + } + }, + }, + used: { + charlotte: true, + onremove: true, + }, + dongjiao: { + audio: 6, + trigger: { + player: ["useCard", "useCardToPlayered", "useCardAfter"], + }, + logAudio(event, player, name) { + if (name == "useCardAfter") { + return ["mbweizhuang_dongjiao3.mp3", "mbweizhuang_dongjiao4.mp3"]; + } + if (name == "useCardToPlayered") { + return ["mbweizhuang_dongjiao5.mp3", "mbweizhuang_dongjiao6.mp3"]; + } + return 2; + }, + filter(event, player, name) { + if (!get.nameList(player).includes("mb_cuilingyi")) { + return false; + } + const skin = player.skin[player.name2 === "mb_cuilingyi" ? "name2" : "name"]; + if (!skin || skin.indexOf("dongjiao") === -1) { + return false; + } + const num = get + .info("mbweizhuang") + .getFaceupCards(player) + ?.map(card => get.type2(card)) + ?.toUniqued()?.length; + if (name == "useCard") { + return num >= 1 && get.type(event.card) == "basic"; + } + if (name == "useCardAfter") { + return ( + num >= 3 && + get.type(event.card) == "equip" && + game.hasPlayer(current => { + if (player.getStorage("mbweizhuang_block").includes(current)) { + return false; + } + return get.info("mbweizhuang").getFaceupCards(current).length; + }) + ); + } + return ( + event.isFirstTarget && + num >= 2 && + get.type2(event.card) == "trick" && + event.targets?.length && + event.targets.some(target => { + const pos = target == player ? "e" : "he"; + return target.countGainableCards(player, pos); + }) + ); + }, + async cost(event, trigger, player) { + switch (event.triggername) { + case "useCard": { + event.result = { + bool: true, + }; + return; + } + case "useCardAfter": { + const targets = game.filterPlayer(current => { + if (player.getStorage("mbweizhuang_block").includes(current)) { + return false; + } + return get.info("mbweizhuang").getFaceupCards(current).length; + }); + if (!targets?.length) { + return; + } + event.result = await player + .chooseTarget(`###是否发动【褽装】?###令一名有明置牌的角色摸两张牌`, (card, player, target) => { + return get.event("targetx").includes(target); + }) + .set("targetx", targets) + .set("ai", target => { + const player = get.player(); + return get.effect(target, { name: "draw" }, player, player); + }) + .forResult(); + return; + } + default: { + const targets = trigger.targets.filter(target => { + const pos = target == player ? "e" : "he"; + return target.countGainableCards(player, pos); + }); + if (!targets?.length) { + return; + } + event.result = await player + .chooseTarget(`###是否发动【褽装】?###获得一名目标角色一张牌`, (card, player, target) => { + return get.event("targetx").includes(target); + }) + .set("targetx", targets) + .set("ai", target => { + const player = get.player(); + return get.effect(target, { name: "shunshou_copy2" }, player, player); + }) + .forResult(); + return; + } + } + }, + async content(event, trigger, player) { + const { targets, triggername: name } = event; + switch (name) { + case "useCard": { + trigger.baseDamage ??= 1; + trigger.baseDamage++; + break; + } + case "useCardAfter": { + player.addTempSkill("mbweizhuang_block"); + player.markAuto("mbweizhuang_block", targets); + await game.doAsyncInOrder(targets, async target => await target.draw(2)); + break; + } + default: { + await game.doAsyncInOrder(targets, async target => { + const pos = target == player ? "e" : "he"; + if (target.countGainableCards(player, pos)) { + await player.gainPlayerCard(target, pos, true); + } + }); + } + } + }, + }, + block: { + charlotte: true, + onremove: true, + }, + xiuge: { + audio: 6, + logAudio(event, player) { + if (typeof event == "string") { + const index = ["sha", "jiu", "tao", "shan"].indexOf(event) + 3; + return `mbweizhuang_xiuge${index}.mp3`; + } + return 2; + }, + enable: "chooseToUse", + hiddenCard(player, name) { + if (!get.nameList(player).includes("mb_cuilingyi")) { + return false; + } + const skin = player.skin[player.name2 === "mb_cuilingyi" ? "name2" : "name"]; + if (!skin || skin.indexOf("xiuge") === -1) { + return false; + } + const list = ["sha", "shan", "tao", "jiu"]; + if (!list.includes(name) || player.getStorage("mbweizhuang_blocker").includes(name)) { + return false; + } + const subtype = `equip${list.indexOf(name) + 1}`, + count = get + .info("mbweizhuang") + .getFaceupCards(player) + ?.map(card => get.suit(card)) + ?.toUniqued()?.length; + return ( + player.countCards("he", card => { + if (get.subtype(card) != subtype) { + return false; + } + return count >= 4 || lib.filter.cardDiscardable(card, player, "mbweizhuang"); + }) > 0 + ); + }, + filter(event, player) { + if (!get.nameList(player).includes("mb_cuilingyi")) { + return false; + } + const skin = player.skin[player.name2 === "mb_cuilingyi" ? "name2" : "name"]; + if (!skin || skin.indexOf("xiuge") === -1) { + return false; + } + const list = ["sha", "shan", "tao", "jiu"], + count = get + .info("mbweizhuang") + .getFaceupCards(player) + ?.map(card => get.suit(card)) + ?.toUniqued()?.length; + return list.some(name => { + if (player.getStorage("mbweizhuang_blocker").includes(name)) { + return false; + } + const vcard = new lib.element.VCard({ name: name, isCard: true, storage: { wzxiuge: true } }); + if (!event.filterCard(vcard, player, event)) { + return false; + } + const subtype = `equip${list.indexOf(name) + 1}`; + return ( + player.countCards("he", card => { + if (get.subtype(card) != subtype) { + return false; + } + return count >= 4 || lib.filter.cardDiscardable(card, player, "mbweizhuang"); + }) > 0 + ); + }); + }, + viewAs(cards, player) { + if (cards.length) { + let name = false; + const subtype = get.subtype(cards[0], player); + if (typeof subtype == "string") { + name = ["sha", "shan", "tao", "jiu"][subtype.slice(5) - 1]; + } + if (name) { + return { + name: name, + isCard: true, + suit: "none", + number: null, + storage: { + wzxiuge: true, + }, + }; + } + } + return null; + }, + filterCard(card, player, event) { + event ??= _status.event; + const filter = event._backup.filterCard; + const list = ["sha", "shan", "tao", "jiu"], + count = get + .info("mbweizhuang") + .getFaceupCards(player) + ?.map(card => get.suit(card)) + ?.toUniqued()?.length; + if (count < 4 && !lib.filter.cardDiscardable(card, player, "mbweizhuang")) { + return false; + } + for (const name of list) { + if (player.getStorage("mbweizhuang_blocker").includes(name)) { + continue; + } + const vcard = new lib.element.VCard({ name: name, isCard: true, storage: { wzxiuge: true } }); + if (!filter(vcard, player, event)) { + continue; + } + const subtype = `equip${list.indexOf(name) + 1}`; + if (subtype == get.subtype(card, player)) { + return true; + } + } + return false; + }, + popname: true, + ignoreMod: true, + position: "he", + log: false, + check(card) { + const player = get.player(); + if (_status.event.type == "phase") { + const name = ["sha", "shan", "tao", "jiu"][get.subtype(card, player)?.slice(5) - 1]; + if (name) { + const vcard = new lib.element.VCard({ name: name, isCard: true, storage: { wzxiuge: true } }); + if (player.getUseValue(vcard) > 0) { + return 14 - get.value(card); + } + } + return 0; + } + return 1; + }, + prompt(event, player) { + return get.skillInfoTranslation("mbweizhuang_xiugex", player); + }, + async precontent(event, trigger, player) { + const name = event.result.card?.name, + cards = event.result.cards; + player.addTempSkill("mbweizhuang_blocker"); + player.markAuto("mbweizhuang_blocker", name); + //delete event.result.skill; + event.getParent().addCount = false; + player.logSkill("mbweizhuang_xiuge", null, null, null, [name]); + const count = get + .info("mbweizhuang") + .getFaceupCards(player) + ?.map(card => get.suit(card)) + ?.toUniqued()?.length; + if (count >= 4) { + await player.showCards(cards, `${get.translation(player)}发动了【褽装】`); + } else { + await player.modedDiscard(cards); + } + event.result.card = new lib.element.VCard({ name: name, isCard: true, storage: { wzxiuge: true } }); + event.result.cards = []; + player + .when("useCardAfter") + .filter(evt => evt.getParent() == event.getParent()) + .step(async (event, trigger, player) => { + player.logSkill("mbweizhuang_xiuge"); + const card = get.cardPile(card => get.suit(card) == get.suit(cards[0])); + if (card) { + await player.gain(card, "gain2"); + } + }); + }, + locked: false, + mod: { + cardUsable(card, player) { + if (card?.storage?.wzxiuge) { + return Infinity; + } + }, + }, + ai: { + order: 3, + result: { + player(player) { + if (_status.event.dying) { + return get.attitude(player, _status.event.dying); + } + return 1; + }, + }, + }, + }, + blocker: { + charlotte: true, + onremove: true, + }, + }, + }, //君子六艺 //礼·卢毓 mbbingfa: { @@ -2262,12 +2972,12 @@ const skills = { logAudio: () => 2, trigger: { player: "phaseJieshuBegin" }, filter(event, player) { - return game.hasPlayer(target => target.hp <= player.hp && target != player); // + return game.hasPlayer(target => target != player); //target.hp <= player.hp && }, async cost(event, trigger, player) { event.result = await player .chooseTarget(get.prompt2(event.skill), (card, player, target) => { - return target.hp <= player.hp && target != player; // + return target != player; //target.hp <= player.hp && }) .set("ai", target => { return get.attitude(get.player(), target); @@ -2316,7 +3026,7 @@ const skills = { }) .join("
") ); - await player.drawTo(player.maxHp); + await player.drawTo(4); }, }, clear: { @@ -2423,7 +3133,7 @@ const skills = { if (!selected.length) { return true; } - return Math.abs(target.countCards("h") - selected[0].countCards("h")) <= player.getDamagedHp(); + return Math.abs(target.countCards("h") - selected[0].countCards("h")) <= 3; }, complexTarget: true, selectTarget: 2, @@ -2433,12 +3143,31 @@ const skills = { const { targets } = event, num = player.getDamagedHp(); await targets[0].swapHandcards(targets[1]); - if (targets[0].countCards("h") == targets[1].countCards("h") || num == 0) { + if (num == 0) { + return; + } + const discard = Math.min(num, player.countDiscardableCards(player, "he")), + count = targets[0].countCards("h") - targets[1].countCards("h"); + if (discard == 0 && count == 0) { + return; + } + if (count == 0) { + await player.chooseToDiscard(`缔盟:是否弃置${get.cnNumber(discard)}张牌?`, discard, "he"); return; } const target = targets.sort((a, b) => a.countCards("h") - b.countCards("h"))[0]; + if (discard == 0) { + const result = await player + .chooseBool(`缔盟:是否令${get.translation(target)}摸${get.cnNumber(num)}张牌?`) + .set("choice", get.effect(target, { name: "draw" }, player, player) > 0) + .forResult(); + if (result?.bool) { + await target.draw(num); + } + return; + } const result = await player - .chooseToDiscard(`缔盟:弃置${num}张牌或令${get.translation(target)}摸${num}张牌`, num) + .chooseToDiscard(`缔盟:弃置${get.cnNumber(discard)}张牌或令${get.translation(target)}摸${get.cnNumber(num)}张牌`, discard, "he") .set("targetx", target) .set("ai", card => { const player = get.player(), @@ -2451,7 +3180,7 @@ const skills = { }) .forResult(); if (!result?.cards?.length) { - await target.draw(player.getDamagedHp()); + await target.draw(num); } }, ai: { diff --git a/character/mobile/sort.js b/character/mobile/sort.js index a42dd5d709..1782292a2b 100644 --- a/character/mobile/sort.js +++ b/character/mobile/sort.js @@ -16,7 +16,7 @@ const characterSort = { mobile_xlqk2: ["pangdegong", "miheng"], mobile_xlqk3: ["majun", "zhengxuan", "simashi"], mobile_xlqk4: ["nanhualaoxian", "shichangshi", "sunhanhua"], - mobile_xlqk5: ["mb_zhangfen", "mb_zerong"], + mobile_xlqk5: ["mb_zhangfen", "mb_zerong", "mb_cuilingyi"], mobile_xlqk6: ["mb_luyu"], mobile_longxue: ["mb_simazhao", "mb_simafu", "mb_wenqin", "mb_simazhou", "mb_sp_guanqiujian", "mb_caomao", "chengji", "lizhaojiaobo", "mb_jiachong"], mobile_bingshiPack: ["pot_xinxianying", "mb_chenzhi", "mb_sunjun", "pot_lusu", "pot_weiyan", "guoyuan", "mb_huangzu", "mb_tianfeng", "mb_luyusheng", "pot_taishici", "pot_dongzhao", "pot_lougui", "pot_yuji", "mb_xiahoushang", "pangxi", "sunsháo", "mb_yanghong", "pot_chendao", "mb_zhangyan", "pot_huanjie", "pot_dengai"], //potential--潜在, 潜力, 可能, 电位, 潜能, 势 diff --git a/character/mobile/translate.js b/character/mobile/translate.js index 20f8a7af74..87a3fd11fc 100644 --- a/character/mobile/translate.js +++ b/character/mobile/translate.js @@ -1119,9 +1119,9 @@ const translates = { pot_lusu: "势鲁肃", pot_lusu_prefix: "势", pothaoshi: "好施", - pothaoshi_info: "结束阶段,你可以选择一名体力值小于等于你的其他角色:直到你的下个回合开始,其可以如手牌般使用或打出你的手牌,且其前两次因此令你失去最后的手牌时,你将手牌数摸至体力上限。", + pothaoshi_info: "结束阶段,你可以选择一名其他角色:直到你的下个回合开始,其可以如手牌般使用或打出你的手牌,且其前两次因此令你失去最后的手牌时,你将手牌摸至四张。", potdimeng: "缔盟", - potdimeng_info: "出牌阶段限一次,你可以选择两名手牌数之差小于等于X的角色(X为你已损失的体力值),令他们交换手牌。然后你选择一项:弃置X张牌(不足则全弃):交换后手牌较少的角色摸X张牌。", + potdimeng_info: "出牌阶段限一次,你可以选择两名手牌数之差小于等于3的角色,令他们交换手牌。然后你选择一项:1.弃置X张牌(不足则全弃);2.交换后手牌较少的角色摸X张牌(X为你已损失的体力值)。", mb_sunjun: "势孙峻", mb_sunjun_prefix: "势", mbxiongtu: "凶图", @@ -1195,6 +1195,22 @@ const translates = { })}并令其他角色投票,得票最多的${get.poptip("bingfa_lvfa")}于本轮结束时执行。`, mbshuxing: "束刑", mbshuxing_info: "每回合限一次,一名角色成为【杀】的目标时,你可令此【杀】无效并展示手牌,若其中有【闪】,你令使用者选择一项:1.失去1点体力;2.交给你其手牌中【闪】和〖秉法〗的投票权。", + mb_cuilingyi: "手杀崔令仪", + mb_cuilingyi_ab: "手杀崔芙", + mb_cuilingyi_prefix: "手杀", + mbcaiqiu: "裁裘", + mbcaiqiu_info: "①每轮开始时,你观看牌堆顶X张牌(X为游戏人数),然后可以获得其中任意张牌。②其他角色使用牌结算结束后,若你本轮因〖裁裘〗获得过同名牌,你失去1点体力。", + mbxishang: "袭裳", + mbxishang_info: `锁定技,①游戏开始时,你选择本局形象并获得${get.poptip("mbweizhuang")}。②你不因摸牌而获得牌时,明置之。`, + faceup_tag: "明置牌", + mbweizhuang: "褽装", + mbweizhuang_info: `此技能效果根据你的形象发生变化:${get.poptip("mbweizhuang_guidianx")}${get.poptip("mbweizhuang_dongjiaox")}${get.poptip("mbweizhuang_xiugex")}。`, + mbweizhuang_guidianx: "桂殿", + mbweizhuang_guidianx_info: `①有明置牌的角色的结束阶段,你可令以下一个数值-1并发动${get.poptip("mbcaiqiu")}:1.摸牌阶段摸牌数;2.出【杀】次数;3.手牌上限;4.体力值。②每局游戏限X+1次,每X+1张牌被明置后,你令以上一项数值+1(X为游戏人数)。`, + mbweizhuang_dongjiaox: "东郊", + mbweizhuang_dongjiaox_info: `若你的明置牌包含类型数不小于:1,你使用基本牌数值+1;2,你使用锦囊牌指定目标后,可以获得其中一个目标一张牌;3,每回合每名角色限一次,你使用装备牌结算结束后,可以令一名有明置牌的角色摸两张牌。`, + mbweizhuang_xiugex: "绣阁", + mbweizhuang_xiugex_info: `①每回合每项各限一次,你可以弃置一张指定副类别的牌并视为使用一张无次数限制的对应牌,此牌结算结束后获得一张与弃置牌花色相同的牌:1.武器牌,【杀】;2.防具牌,【闪】;3.防御坐骑牌,【桃】;4.进攻坐骑牌,【酒】。②若你的明置牌包含四种花色,将此技能的“弃置”改为“展示”。`, }; export default translates; diff --git a/character/mobile/voices.js b/character/mobile/voices.js index f19d3cc53b..d6e8833c8c 100644 --- a/character/mobile/voices.js +++ b/character/mobile/voices.js @@ -1,4 +1,33 @@ export default { + "#mbcaiqiu1": "衣为礼之大者,岂可草草而决?", + "#mbcaiqiu2": "事关颜面,自是要百里挑一。", + "#mbcaiqiu3": "贱婢好不知耻,竟敢效我衣着。", + "#mbcaiqiu4": "想是夫君宠汝太甚,竟不知尊卑之礼。", + "#mbxishang1": "此次观礼,我定可艳压群芳。", + "#mbxishang2": "妾身天生丽质,岂可对镜独赏?", + "#mbxishang3": "此等霓裳,方配此山野之趣。", + "#mbxishang4": "既未逾礼,此衣何不可服?", + "#mbxishang5": "虽身处闺阁,一不可自屈。", + "#mbxishang6": "炫服靓妆,不过聊以自娱。", + "#mbxishang7": "宝衣自当示人,然非等闲可观。", + "#mbxishang8": "珠以蚌蔽之,衣以箧藏之。", + "#mbweizhuang_guidian1": "出门难得,唯以自妆为乐。", + "#mbweizhuang_guidian2": "当择一华服,以尽显妾身之美。", + "#mbweizhuang_guidian3": "嘉宴在即,自要盛装以待。", + "#mbweizhuang_guidian4": "衣饰岂可复着,当更新衣以庆。", + "#mbweizhuang_dongjiao1": "貌美非吾本意,奈何难拒天恩。", + "#mbweizhuang_dongjiao2": "沉鱼落雁难参比,质本天然第一流。", + "#mbweizhuang_dongjiao3": "固为妾之所得,何来赏赐直说?", + "#mbweizhuang_dongjiao4": "此衣妃者所服,贱婢岂敢逾制。", + "#mbweizhuang_dongjiao5": "此婢不尊主母,该当何罪?", + "#mbweizhuang_dongjiao6": "妾身受屈良久,夫君何以为谢?", + "#mbweizhuang_xiuge1": "妾身之美,可入夫君眸中?", + "#mbweizhuang_xiuge2": "夫君所选,自是雍容非凡。", + "#mbweizhuang_xiuge3": "哼,尔等婢妾,岂配与我相较。", + "#mbweizhuang_xiuge4": "景好使人悦,该当小酌一杯。", + "#mbweizhuang_xiuge5": "面若春桃,亦需华服来饰。", + "#mbweizhuang_xiuge6": "纵我舍得,夫君可否舍得?", + "#mb_cuilingyi:die": "铅华难驻容千载,贵贱同归土一丘。", "#potjiejie1": "职守,人之大义也,安可不出?", "#potjiejie2": "为人执鞭而弃其事,不祥,不可也!", "#potqingshi1": "军旅之间可以济者,唯仁与恕。", diff --git a/character/newjiang/characterTitle.js b/character/newjiang/characterTitle.js index 2f1335c861..2522e0c8f8 100644 --- a/character/newjiang/characterTitle.js +++ b/character/newjiang/characterTitle.js @@ -1,6 +1,9 @@ export default { //yj_puyuan: "", //yao_yuanshu: "", + //yj_fazheng: "", + //yj_hanbing: "", + //yj_tengjia: "", yj_zhanghe: "宁国中郎将", yj_zhangliao: "蹈锋饮血", yj_xuhuang: "沉详性严", diff --git a/character/newjiang/skill.js b/character/newjiang/skill.js index 865e2e003d..fd79f644e8 100644 --- a/character/newjiang/skill.js +++ b/character/newjiang/skill.js @@ -106,7 +106,7 @@ const skills = { event.result = await player .chooseCardTarget({ prompt: get.prompt("ciren"), - prompt2: `将一张牌交给${targets}${targets.length > 1 ? "中的一人" : ""},令其交给你另一张同花色牌,或你摸一张牌`, + prompt2: `将一张牌交给${get.translation(targets)}${targets.length > 1 ? "中的一人" : ""},令其交给你另一张同花色牌,或你摸一张牌`, position: "he", filterCard: true, filterTarget(card, player, target) { diff --git a/character/offline/character.js b/character/offline/character.js index 9144102514..0276fdc934 100644 --- a/character/offline/character.js +++ b/character/offline/character.js @@ -1,4 +1,11 @@ const characters = { + wxdl_caocao: { + sex: "male", + group: "wei", + hp: 4, + skills: ["wxdl_kejie", "wxdl_hongqi"], + isZhugong: true, + }, shinin_zhenji: { sex: "female", group: "wei", diff --git a/character/offline/characterTitle.js b/character/offline/characterTitle.js index 0491f0840b..1a129249d3 100644 --- a/character/offline/characterTitle.js +++ b/character/offline/characterTitle.js @@ -2,6 +2,7 @@ export default { //pe_guozhao: "", //scl_lvbu: "", //jun_lvbu: "", + wxdl_caocao: "东临碣石", shinin_zhenji: "薄幸的美人", awaken_shinin_zhenji: "闪耀战姬", shinin_wuguotai: "武烈皇后", diff --git a/character/offline/skill.js b/character/offline/skill.js index 8ae00a36a0..c079d5b33b 100644 --- a/character/offline/skill.js +++ b/character/offline/skill.js @@ -2,6 +2,180 @@ import { lib, game, ui, get, ai, _status } from "../../noname.js"; /** @type { importCharacterConfig['skill'] } */ const skills = { + //文心雕龙 + wxdl_kejie: { + audio: 2, + trigger: { + player: "phaseDrawEnd", + }, + filter(event, player) { + if (player.countCards("h") >= 5) { + return false; + } + return game.hasPlayer(current => current != player && current.isDamaged()); + }, + async cost(event, trigger, player) { + const targets = game.filterPlayer(current => current != player && current.isDamaged()); + let answer_ok = undefined; + let humans = targets.filter(current => current === game.me || current.isOnline()); + let locals = targets.slice(0).randomSort(); + locals.removeArray(humans); + const eventId = get.id(); + const send = (current, player, eventId) => { + lib.skill.wxdl_kejie.chooseBool(current, player, eventId); + game.resume(); + }; + event._global_waiting = true; + let time = 10000; + if (lib.configOL && lib.configOL.choose_timeout) { + time = parseInt(lib.configOL.choose_timeout) * 1000; + } + targets.forEach(current => current.showTimer(time)); + if (humans.length > 0) { + const solve = function (resolve, reject) { + return function (result, player) { + if (result?.bool && !answer_ok) { + answer_ok = player; + resolve(); + } else { + reject(); + } + }; + }; + await Promise.any( + humans.map(current => { + return new Promise((resolve, reject) => { + if (current.isOnline()) { + current.send(send, current, player, eventId); + current.wait(solve(resolve, reject)); + } else { + const next = lib.skill.wxdl_kejie.chooseBool(current, player, eventId); + const solver = solve(resolve, reject); + if (_status.connectMode) { + game.me.wait(solver); + } + return next.forResult().then(result => { + if (_status.connectMode && !answer_ok) { + game.me.unwait(result, current); + } else { + solver(result, current); + } + }); + } + }); + }) + ).catch(() => {}); + game.broadcastAll("cancel", eventId); + } + if (!answer_ok && locals.length > 0) { + for (const current of locals) { + const result = await lib.skill.wxdl_kejie.chooseBool(current, player).forResult(); + if (result?.bool) { + answer_ok = current; + break; + } + } + } + delete event._global_waiting; + for (const i of targets) { + i.hideTimer(); + } + if (answer_ok && get.itemtype(answer_ok) == "player") { + event.result = { + bool: true, + targets: [answer_ok], + }; + } + }, + async content(event, trigger, player) { + const target = event.targets[0]; + const result = { + skill: "xiantu", + targets: [player], + }; + await target.useResult(result, event); + const result2 = await player + .chooseCard( + "克捷:是否重铸任意张【闪】?", + [1, Infinity], + function (card) { + if (get.name(card) != "shan") { + return false; + } + return lib.filter.cardRecastable.apply(this, arguments); + }, + "he", + "allowChooseAll" + ) + .set("ai", card => { + return 6 - get.value(card); + }) + .forResult(); + if (result2?.bool) { + await player.recast(result2.cards); + player.addTempSkill("wxdl_kejie_sha"); + player.addMark("wxdl_kejie_sha", result2.cards.length, false); + } + }, + chooseBool(player, source, eventId) { + const next = player.chooseBool(`###克捷###
是否对${get.translation(source)}发动${get.poptip("xiantu")}?
`); + next.set("id", eventId); + next.set("_global_waiting", true); + next.set("choice", get.attitude(player, source) > 0); + return next; + }, + subSkill: { + sha: { + charlotte: true, + onremove: true, + intro: { + content: "出杀次数+#", + }, + mod: { + cardUsable(card, player, num) { + if (card?.name == "sha") { + return num + player.countMark("wxdl_kejie_sha"); + } + }, + }, + }, + }, + derivation: "xiantu", + }, + wxdl_hongqi: { + audio: 2, + trigger: { + player: "phaseZhunbeiBegin", + }, + limited: true, + zhuSkill: true, + skillAnimation: true, + animationColor: "water", + filter(event, player) { + const card = new lib.element.VCard({ name: "wanjian", isCard: true }); + return player.hasUseTarget(card); + }, + async content(event, trigger, player) { + player.awakenSkill(event.name); + const card = new lib.element.VCard({ name: "wanjian", isCard: true }); + await player.chooseUseTarget(card, true); + const func = async target => { + if (!target?.isIn() || target.group !== "wei" || target == player) { + return; + } + await target.chooseToUse(function (card, player, event) { + if (get.name(card) != "sha") { + return false; + } + return lib.filter.filterCard.apply(this, arguments); + }, "洪起:是否使用一张杀?"); + }; + await game.doAsyncInOrder( + game.filterPlayer(() => true), + func + ); + }, + }, zj_juxian: { trigger: { player: ["damageBegin3", "loseBefore"], @@ -29,9 +203,11 @@ const skills = { return event.cards.filterInD("he").reduce((sum, card) => sum + player.getUseValue(card), -10) > 0; }, async content(event, trigger, player) { - if (trigger.name !== "damage") { - await player.loseHp(); + if (trigger.name == "damage") { + trigger.cancel(); + return; } + await player.loseHp(); if (trigger.cards.everyInD("he")) { trigger.cancel(); } else { @@ -9164,6 +9340,8 @@ const skills = { if (trigger.name == "phase" && !trigger._finished) { let first = game.findPlayer(current => current.getSeatNum() == 1) || trigger.player; trigger.finish(); + trigger._finished = true; + trigger.untrigger(true); trigger._triggered = 5; const evtx = first.insertPhase(); delete evtx.skill; @@ -9352,6 +9530,8 @@ const skills = { let newzhu = game.findPlayer(i => i.getSeatNum() == 1); if (trigger.name === "phase" && newzhu != zhu && !trigger._finished) { trigger.finish(); + trigger._finished = true; + trigger.untrigger(true); trigger._triggered = 5; const evt = newzhu.insertPhase(); delete evt.skill; @@ -22753,17 +22933,17 @@ const skills = { const result2 = await player .chooseButton([`是否将${get.translation(result)}当作其中一张使用?`, [list, "vcard"]]) .set("filterButton", button => { - let card = get.autoViewAs({ name: button.link[2], natrue: button.link[3] }, get.event("resultCard")); + let card = get.autoViewAs({ name: button.link[2], nature: button.link[3] }, get.event("resultCard")); return get.player().hasUseTarget(card); }) .set("resultCard", [card]) .set("ai", button => { - let card = get.autoViewAs({ name: button.link[2], natrue: button.link[3] }, get.event("resultCard")); + let card = get.autoViewAs({ name: button.link[2], nature: button.link[3] }, get.event("resultCard")); return get.player().getUseValue(card); }) .forResult(); if (result2.bool && player.getCards("h").includes(card)) { - const cardx = { name: result2.links[0][2], natrue: result2.links[0][3] }; + const cardx = { name: result2.links[0][2], nature: result2.links[0][3] }; game.broadcastAll(function (card) { lib.skill.tyqingkou_backup.viewAs = card; lib.skill.tyqingkou_backup.prompt = `是否将此牌当作${get.translation(card)}使用?`; @@ -22823,17 +23003,17 @@ const skills = { const result2 = await player .chooseButton([`是否将${get.translation(result)}当作其中一张使用?`, [list, "vcard"]]) .set("filterButton", button => { - let card = get.autoViewAs({ name: button.link[2], natrue: button.link[3] }, get.event("resultCard")); + let card = get.autoViewAs({ name: button.link[2], nature: button.link[3] }, get.event("resultCard")); return get.player().hasUseTarget(card); }) .set("resultCard", [card]) .set("ai", button => { - let card = get.autoViewAs({ name: button.link[2], natrue: button.link[3] }, get.event("resultCard")); + let card = get.autoViewAs({ name: button.link[2], nature: button.link[3] }, get.event("resultCard")); return get.player().getUseValue(card); }) .forResult(); if (result2.bool && result2?.links?.length && player.getCards("h").includes(card)) { - const cardx = { name: result2.links[0][2], natrue: result2.links[0][3] }; + const cardx = { name: result2.links[0][2], nature: result2.links[0][3] }; game.broadcastAll(function (card) { lib.skill.tyfenwu_backup.viewAs = card; lib.skill.tyfenwu_backup.prompt = `是否将此牌当作${get.translation(card)}使用?`; diff --git a/character/offline/sort.js b/character/offline/sort.js index cc881ada7e..847c49a853 100644 --- a/character/offline/sort.js +++ b/character/offline/sort.js @@ -30,6 +30,7 @@ const characterSort = { offline_fengyun: ["ps_caocao", "ps_liubei", "ps_sunquan"], offline_xy: ["xy_caocao", "xy_chengyu", "xy_xunyu", "xy_chengong", "xy_zhangkai", "xy_lvbu", "xy_zhangmiao", "xy_caosong"], offline_zc26: ["zc26_lusu", "zc26_jiaxu", "zc26_zhanghe", "zc26_taishici"], + offline_wenxindiaolong: ["wxdl_caocao"], offline_shiningGrils: ["shinin_zhenji", "shinin_wuguotai", "shinin_ruiji", "shinin_lvlingqi", "shinin_dongwan", "goblin", "lord_goblin"], //offline_others: [], }; @@ -69,6 +70,7 @@ const characterSortTranslate = { offline_Europe: "风云志·欧陆风云", offline_xy: "徐兖纵横", offline_zc26: "26珍藏", + offline_wenxindiaolong: "星汉灿烂·文心雕龙", offline_shiningGrils: "闪耀战姬", }; diff --git a/character/offline/translate.js b/character/offline/translate.js index d991a7a3c9..1a5faf2f4c 100644 --- a/character/offline/translate.js +++ b/character/offline/translate.js @@ -1820,6 +1820,12 @@ const translates = { wn_zhuling_prefix: "渭南", wn_zhanyi: "战意", wn_zhanyi_info: "出牌阶段限一次,你可以失去1点体力并弃置一张基本或锦囊牌,令你本回合使用此类型的牌额外结算一次。", + wxdl_caocao: "文心雕龙曹操", + wxdl_caocao_prefix: "文心雕龙", + wxdl_kejie: "克捷", + wxdl_kejie_info: `每当你的摸牌阶段结束,若手牌数小于5,其他受伤角色可以对你发动一次${get.poptip("xiantu")},然后你可将任意张【闪】重铸,令你本回合增加等量出杀次数。`, + wxdl_hongqi: "洪起", + wxdl_hongqi_info: "主公技,限定技,准备阶段,你可以视为使用一张【万箭齐发】,然后其他魏势力角色可以使用一张【杀】。", }; export default translates; diff --git a/character/old/characterTitle.js b/character/old/characterTitle.js index b01fdf7b9d..8102371dc7 100644 --- a/character/old/characterTitle.js +++ b/character/old/characterTitle.js @@ -1,4 +1,6 @@ -export default { +export default { + //two_yj_hanbing: "", + //two_yj_tengjia: "", old_zhangxingcai: "将门红妆", old_xusheng: "奋身御前", old_lingtong: "豪情烈胆", diff --git a/character/old/skill.js b/character/old/skill.js index f77acb1638..c48a87b5e7 100644 --- a/character/old/skill.js +++ b/character/old/skill.js @@ -162,7 +162,7 @@ const skills = { }, async cost(event, trigger, player) { event.result = await player - .chooseToDiscard(get.prompt2(event.skill), 2) + .chooseToDiscard(get.prompt2(event.skill), 2, "he") .set("eff", get.damageEffect(player, trigger.source ?? player, player)) .set("ai", card => { const { player, eff } = get.event(); diff --git a/character/onlyOL/character.js b/character/onlyOL/character.js index bc15d321a2..06548dbdad 100644 --- a/character/onlyOL/character.js +++ b/character/onlyOL/character.js @@ -1,4 +1,10 @@ const characters = { + dm_caocao: { + sex: "male", + group: "wei", + hp: 4, + skills: ["olbachao", "olfuzai"], + }, ol_sb_xizhicai: { sex: "male", group: "wei", diff --git a/character/onlyOL/characterTitle.js b/character/onlyOL/characterTitle.js index aa3bee049b..51f999870b 100644 --- a/character/onlyOL/characterTitle.js +++ b/character/onlyOL/characterTitle.js @@ -1,11 +1,12 @@ export default { - //dm_sunquan: "", //ol_sb_yl_luzhi: "国之桢干", //暂无称号,先取别的称号顶替一下 //ol_sunxiu: "弥殇的景君", //暂无称号,先取别的称号顶替一下 //ol_sb_zhaoyun: "七进七出", //暂无称号,先取别的称号顶替一下 //ol_sb_zhangfei: "义付桃园", //暂无称号,先取别的称号顶替一下 //ol_sb_jushou: "忠不逢时", //暂无称号,先取别的称号顶替一下 //ol_re_yujin: "", + //dm_sunquan: "", + //dm_caocao: "", ol_jsrg_zhujun: "征无遗虑", ol_jsrg_sunjian: "拔定烈志", ol_sb_xizhicai: "薪火相传", diff --git a/character/onlyOL/skill.js b/character/onlyOL/skill.js index 3f95a5d369..ce5316c97d 100644 --- a/character/onlyOL/skill.js +++ b/character/onlyOL/skill.js @@ -2,6 +2,367 @@ import { lib, game, ui, get, ai, _status } from "../../noname.js"; /** @type { importCharacterConfig['skill'] } */ const skills = { + //魔曹操 + olbachao: { + audio: 2, + trigger: { + player: "phaseUseBegin", + }, + filter(event, player) { + return game.hasPlayer(current => current != player); + }, + logTarget(event, player) { + return game.filterPlayer(current => current != player); + }, + check(event, player) { + if (player.hp > 1) { + return true; + } + return game.countPlayer(current => current != player) > 1; + }, + chooseToGive(target, player) { + const next = target.chooseCard(`霸朝:是否交给${get.translation(player)}一张非基本牌`, "he"); + next.set("filterCard", card => { + return get.type(card) != "basic"; + }); + next.set("sourcex", player); + next.set("att", get.attitude(target, player)); + next.set("ai", card => { + const { player, att, sourcex } = get.event(); + if (att > 0) { + return 15 - get.value(card); + } + if (game.countPlayer(current => current != sourcex) <= 3) { + return 10 - get.value(card); + } + return 0; + }); + return next; + }, + async content(event, trigger, player) { + const map = await game.chooseAnyOL(event.targets, get.info(event.name).chooseToGive, [player]).forResult(); + if (!map.size) { + return; + } + const cards = []; + for (const target of Array.from(map.keys())) { + const result = map.get(target); + if (result?.bool && result.cards?.length) { + cards.addArray(result.cards); + } + } + let next; + if (cards.length) { + next = player.gain(cards, "giveAuto"); + await next; + } + const targets = game.filterPlayer(current => { + return !current.hasHistory("lose", evt => evt.getParent() == next); + }); + if (!targets.length) { + return; + } + const result = + targets.length > 1 + ? await player + .chooseTarget("霸朝:对一名未交给你牌的角色造成1点伤害", true, (card, player, target) => { + return get.event("targetx").includes(target); + }) + .set("targetx", targets) + .set("ai", target => { + const player = get.player(); + return get.damageEffect(target, player, player); + }) + .forResult() + : { + bool: true, + targets: targets, + }; + if (result?.bool && result.targets?.length) { + const target = result.targets[0]; + player.line(target, "green"); + await target.damage(player); + if (target == player) { + player.addTempSkill("olbachao_effect", { global: "phaseAnyAfter" }); + player.addGaintag(player.getCards("h"), "olbachao_effect"); + if (!player.hasSkill("olrumo", null, null, false)) { + player.addSkill("olrumo"); + } + } + } + }, + subSkill: { + effect: { + onremove(player, skill) { + player.removeGaintag(skill); + }, + trigger: { + player: "useCard1", + }, + firstDo: true, + charlotte: true, + filter(event, player) { + if (event.addCount === false) { + return false; + } + return player.hasHistory("lose", evt => { + const evtx = evt.relatedEvent || evt.getParent(); + if (evtx != event) { + return false; + } + return Object.values(evt.gaintag_map)?.flat()?.includes("olbachao_effect"); + }); + }, + async cost(event, trigger, player) { + trigger.addCount = false; + const stat = player.getStat("card"), + name = trigger.card.name; + if (typeof stat[name] == "number" && stat[name] > 0) { + stat[name]--; + } + }, + mod: { + targetInRange(card, player) { + if (get.number(card) === "unsure" || card.cards?.some(card => card.hasGaintag("olbachao_effect"))) { + return true; + } + }, + cardUsable(card, player) { + if (get.number(card) === "unsure" || card.cards?.some(card => card.hasGaintag("olbachao_effect"))) { + return Infinity; + } + }, + }, + }, + }, + }, + olfuzai: { + audio: 2, + enable: "chooseToUse", + locked: true, + filter(event, player) { + const hs = player.getCards("he", card => get.type(card) == "equip"); + if (!hs.length) { + return false; + } + return ["jiedao", "wuzhong"].some(name => { + return hs.some(card => { + const vcard = get.autoViewAs({ name: name }, [card]); + return event.filterCard(vcard, player, event) && player.hasUseTarget(vcard); + }); + }); + }, + chooseButton: { + dialog(event, player) { + const hs = player.getCards("he", card => get.type(card) == "equip"); + const list = ["jiedao", "wuzhong"].filter(name => { + return hs.some(card => { + const vcard = get.autoViewAs({ name: name }, [card]); + return event.filterCard(vcard, player, event) && player.hasUseTarget(vcard); + }); + }); + const dialog = ui.create.dialog("覆载", [list, "vcard"], "hidden"); + dialog.direct = true; + return dialog; + }, + check(button) { + const player = get.player(), + card = get.autoViewAs({ name: button.link[2] }, "unsure"); + return player.getUseValue(card); + }, + backup(links, player) { + return { + viewAs: { + name: links[0][2], + }, + position: "he", + filterCard(card, player) { + return get.type(card) == "equip"; + }, + async precontent(event, trigger, player) { + event.result.skill = "olfuzai"; + }, + }; + }, + prompt(links, player) { + return "将一张装备牌当做" + (get.translation(links[0][3]) || "") + get.translation(links[0][2]) + "使用"; + }, + }, + hiddenCard(player, name) { + if (!["jiedao", "wuzhong"].includes(name)) { + return false; + } + return player.countCards("he", card => get.type(card) == "equip") > 0; + }, + mod: { + cardEnabled(card, player) { + if (["jiedao", "wuzhong"].includes(get.name(card))) { + return; + } + const hs = player.getCards("he", card => get.type(card) == "equip"); + if ("cards" in card && Array.isArray(card.cards) && card.cards.containsSome(...hs)) { + return false; + } + }, + cardSavable(card, player) { + if (["jiedao", "wuzhong"].includes(get.name(card))) { + return; + } + const hs = player.getCards("he", card => get.type(card) == "equip"); + if ("cards" in card && Array.isArray(card.cards) && card.cards.containsSome(...hs)) { + return false; + } + }, + }, + ai: { + order: 8, + result: { + player: 1, + }, + }, + intro: { + content: "视为装备着:$", + }, + onremove(player, skill) { + player.removeTip(skill); + player.removeAdditionalSkill(skill); + player.setStorage(skill, null, true); + }, + group: "olfuzai_equip", + subSkill: { + equip: { + trigger: { + global: ["phaseBefore", "loseAfter", "loseAsyncAfter", "equipAfter", "addToExpansionAfter", "addJudgeAfter", "gainAfter"], + player: ["enterGame", "expandEquipAfter", "disableEquipAfter", "enableEquipAfter", "changeHpAfter", "changeSkillsAfter"], + }, + filter(event, player) { + if (player.countCards("e")) { + return player.getStorage("olfuzai").length; + } + if (event.name == "phase" && game.phaseNumber !== 0) { + return false; + } + if (event.name == "changeSkills" && !event.addSkill?.includes("olfuzai")) { + return false; + } + if (event.name.indexOf("Equip") > 0) { + if (event.name == "disableEquip") { + return player.getStorage("olfuzai").some(name => { + const slot = get.subtype(name); + return event.slots.includes(slot) && !player.hasEmptySlot(slot); + }); + } + return ["equip1", "equip2"].some(slot => { + if (!event.slots.includes(slot) || !player.hasEmptySlot(slot)) { + return false; + } + return !player.getStorage("olfuzai").some(name => get.subtype(name) == slot); + }); + } + if (event.name != "changeHp" && player.getStorage("olfuzai").length) { + return false; + } + return player.hasEmptySlot(1) || player.hasEmptySlot(2); + }, + forced: true, + async content(event, trigger, player) { + if (player.getStorage("olfuzai").length) { + let list = []; + if (trigger.name == "disableEquip") { + list = player.getStorage("olfuzai").filter(name => { + return player.hasEmptySlot(get.subtype(name)); + }); + } + if (list.length) { + player.setStorage("olfuzai", list, true); + const skills = []; + for (const name of list) { + const info = lib.card[name]; + if (info?.skills && Array.isArray(info.skills)) { + skills.addArray(info.skills); + } + } + if (skills.length) { + player.addAdditionalSkill("olfuzai", skills); + } + player.addTip("olfuzai", list.map(name => `覆载 ${get.translation(name)}`).join("\n")); + } else { + player.setStorage("olfuzai", [], true); + player.removeAdditionalSkill("olfuzai"); + player.removeTip("olfuzai"); + } + } + if (player.countCards("e")) { + return; + } + const cards = []; + const check = slot => { + if (!player.hasEmptySlot(slot)) { + return false; + } + return player.getStorage("olfuzai").every(name => get.subtype(name) != slot); + }; + if (check("equip1")) { + const equip1 = lib.inpile + .filter(name => get.subtype(name) == "equip1") + .concat(["qibaodao", "baipidao"]) + .randomSort(); + let card = equip1.find(name => { + const info = lib.card[name]; + let range = 1; + if (info?.distance?.attackFrom) { + range -= info.distance.attackFrom; + } + return range == player.getHp(); + }); + if (!card) { + card = equip1.randomGet(); + } + cards.push(card); + } + if (check("equip2")) { + const equip2 = lib.inpile.filter(name => get.subtype(name) == "equip2").randomSort(); + let card = equip2.find(name => { + const num = get.cardNameLength(name); + return num == player.getHp(); + }); + if (!card) { + card = equip2.randomGet(); + } + cards.push(card); + } + if (!cards.length) { + return; + } + const skills = []; + for (const name of cards) { + const info = lib.card[name]; + if (info?.skills && Array.isArray(info.skills)) { + skills.addArray(info.skills); + } + } + if (skills.length) { + player.addAdditionalSkill("olfuzai", skills); + } + player.setStorage("olfuzai", cards, true); + player.addTip("olfuzai", cards.map(name => `覆载 ${get.translation(name)}`).join("\n")); + }, + mod: { + attackRange(player, num) { + const equips = player.getStorage("olfuzai"); + let range = 0; + for (const card of equips) { + const info = lib.card[card]; + if (info?.distance?.attackFrom) { + range -= info.distance.attackFrom; + } + } + return num + range; + }, + }, + }, + }, + }, //谋戏子 olsbxinchuan: { audio: 2, @@ -609,7 +970,7 @@ const skills = { olquanyu: { audio: 2, map: { - olquanyu_baihong: "白虹:基础伤害改为2", + olquanyu_baihong: "白虹:伤害+1", olquanyu_qingmin: "青冥:多指定一个目标", olquanyu_bixie: "辟邪:无视防具", olquanyu_zidian: "紫电:不可响应", @@ -672,6 +1033,14 @@ const skills = { const map = get.info(event.name).map; const list = Object.keys(map); const result = await game.chooseAnyOL(targets.filter(target => target.getStorage(name).length < 6).sortBySeat(), get.info(event.name).chooseButton, [list, map]).forResult(); + let num = 0, + me; + if (result.has(player)) { + const resultx = result.get(player); + if (resultx?.links?.length) { + me = resultx.links[0]; + } + } for (const [target, resultx] of result.entries()) { if (resultx?.links?.length) { const { @@ -681,6 +1050,9 @@ const skills = { target.setStorage(event.name, link); target.markSkill(event.name); target.popup(map[link].slice(0, 2)); + if (link == me) { + num++; + } target .when("roundStart") .filter(evt => evt != trigger) @@ -690,21 +1062,25 @@ const skills = { }); } } + if (num > 0) { + await player.draw(num); + } }, group: "olquanyu_effect", subSkill: { effect: { - trigger: { player: "useCard" }, + trigger: { player: "useCardToPlayer" }, filter(event, player) { - if (event.card.name != "sha") { + if (event.card.name != "sha" || event.targets?.length != 1) { return false; } return player.storage.olquanyu?.length; }, actionMap: { olquanyu_baihong: async (trigger, player) => { - trigger.baseDamage = 2; - game.log(trigger.card, "基础伤害改为2"); + trigger.baseDamage ??= 1; + trigger.baseDamage++; + game.log(trigger.card, "基础伤害+1"); }, olquanyu_qingmin: async (trigger, player) => { const check = (card, player, target) => !trigger.targets.includes(target) && lib.filter.targetEnabled2(card, player, target) && lib.filter.targetInRange(card, player, target); @@ -749,7 +1125,7 @@ const skills = { forced: true, async content(event, trigger, player) { const map = get.info(event.name).actionMap; - await map[player.storage.olquanyu](trigger, player); + await map[player.storage.olquanyu](trigger.getParent(), player); }, mod: { cardUsable(card, player, num) { @@ -791,22 +1167,39 @@ const skills = { player.markAuto(`${event.name}_used`, bool); if (!bool) { await target.randomDiscard().set("discarder", player); - player.logSkill("olquanyu", target); - const next = game.createEvent("olquanyu"); - next.set("player", player); - next.set("targets", [target]); - next.setContent(get.info("olquanyu").content); - await next; + const result = { + skill: "olquanyu", + targets: [target], + }; + await player.useResult(result, event); } else { const card = get.cardPile2("sha"); if (card) { - await player.gain(card, "gain2"); + player.addSkill("oltianen_effect"); + const next = player.gain(card, "gain2"); + next.gaintag.add("oltianen"); + await next; } else { player.chat("我的王之力啊!"); } } }, subSkill: { + effect: { + charlotte: true, + mod: { + ignoredHandcard(card, player) { + if (card.hasGaintag("oltianen")) { + return true; + } + }, + cardDiscardable(card, player, name) { + if (name == "phaseDiscard" && card.hasGaintag("oltianen")) { + return false; + } + }, + }, + }, used: { charlotte: true, onremove: true, @@ -841,7 +1234,7 @@ const skills = { const choices = trigger.targets[0].getStorage("olquanyu_record"); const map = get.info("olquanyu").map; const list = Object.keys(map); - const result = await player + /*const result = await player .chooseButton( [ `乾纲:请选择要额外执行的“权御”效果`, @@ -884,10 +1277,8 @@ const skills = { } return 1; }) - .forResult(); - if (result?.links?.length) { - event.result = { bool: true, cost_data: result.links }; - } + .forResult();*/ + event.result = { bool: true, cost_data: choices }; }, async content(event, trigger, player) { const { cost_data: list } = event; @@ -2472,6 +2863,7 @@ const skills = { .assign({ firstDo: true }); if (!trigger._finished) { trigger.finish(); + trigger._finished = true; trigger.untrigger(true); trigger._triggered = 5; if (!lib.onround.includes(get.info("olduoqi").onRound)) { @@ -6783,7 +7175,7 @@ const skills = { } const evtx = event.getParent(); if (evtx.name !== "orderingDiscard") { - return true; + return false; } const evt2 = evtx.relatedEvent || evtx.getParent(); return evt2.name == "useCard" && evt2.player != event.getParent("phaseUse")?.player; @@ -6966,7 +7358,7 @@ const skills = { if (card?.storage?.olsbjiewan) { return 1 - Math.max(1, player.countExpansions("olsbjigu")); } - } + }, }, subSkill: { backup: { diff --git a/character/onlyOL/sort.js b/character/onlyOL/sort.js index c1277c25d5..a9d9bd248b 100644 --- a/character/onlyOL/sort.js +++ b/character/onlyOL/sort.js @@ -13,7 +13,7 @@ const characterSort = { onlyOL_sb_daquan: ["ol_sb_xuyou", "ol_sb_jushou", "ol_sb_yuanshu", "ol_sb_zhangrang"], onlyOL_sb_jichu: ["ol_sb_huangyueying", "ol_sb_xizhicai"], onlyOL_sb_huahao: ["ol_sb_xiaoqiao"], - onlyOL_demonized: ["dm_simayi", "dm_diaochan", "dm_lvbu", "dm_sunquan"], + onlyOL_demonized: ["dm_simayi", "dm_diaochan", "dm_lvbu", "dm_sunquan", "dm_caocao"], onlyOL_waitingforsort: [], }; diff --git a/character/onlyOL/translate.js b/character/onlyOL/translate.js index 804acf7a7a..377f995199 100644 --- a/character/onlyOL/translate.js +++ b/character/onlyOL/translate.js @@ -1,3 +1,5 @@ +import { lib, game, ui, get, ai, _status } from "@noname"; + const translates = { ol_sb_xizhicai: "OL谋戏志才", ol_sb_xizhicai_prefix: "OL谋", @@ -20,15 +22,20 @@ const translates = { dm_sunquan: "魔孙权", dm_sunquan_prefix: "魔", olquanyu: "权御", - olquanyu_info: "锁定技,每轮开始时,你令所有角色同时选择一项其本局未选择过的“权御”效果:白虹:基础伤害改为2;青冥:额外指定一个目标;辟邪:无视防具;紫电:不可响应;百里:额外结算一次;流星:无次数限制。然后你使用的【杀】附带你本轮所选的“权御”效果。", + olquanyu_info: `锁定技,每轮开始时,你令所有角色同时选择一项其本局未选择过的“${get.poptip({ + id: "quanyu_effect", + name: "权御", + type: "character", + info: "
  • 白虹:伤害+1
  • 青冥:额外指定一个目标
  • 辟邪:无视防具
  • 紫电:不可响应
  • 百里:额外结算一次
  • 流星:无次数限制", + })}”效果,然后你摸X张牌(X为与你选择效果相同的角色数)。你使用的指定唯一目标的【杀】附带你本轮所选的“权御”效果。`, oltianen: "天恩", - oltianen_info: "锁定技,每回合各限一次,你使用牌指定唯一目标后:若本轮你与其选择的“权御”效果不同,你随机弃置其一张牌,对其发动一次〖权御〗;若与你相同,你从牌堆获得一张【杀】。", + oltianen_info: `锁定技,每回合各限一次,你使用牌指定唯一目标后:若本轮你与其选择的“权御”效果不同,你随机弃置其一张牌,对其发动一次${get.poptip("olquanyu")};若与你相同,你从牌堆获得一张不计入手牌上限的【杀】。`, olqiangang: "乾纲", - olqiangang_info: "出牌阶段,你可入魔,失去〖天恩〗,然后本局你使用指定唯一目标的【杀】均额外执行目标所选择过的任意项“权御”效果。", + olqiangang_info: `出牌阶段,你可${get.poptip("rule_rumo")},失去〖天恩〗,然后本局你使用指定唯一目标的【杀】均执行目标所选择过的所有“权御”效果。`, ol_sb_guojia: "OL谋郭嘉", ol_sb_guojia_prefix: "OL谋", olsbdinglun: "定论", - olsbdinglun_info: "出牌阶段限一次,你可选择至多半数角色(向上取整),若这些角色的手牌数之和大于其他角色的手牌数之和,这些角色获得〖趋袭〗至你下个准备阶段并摸一张牌。", + olsbdinglun_info: `出牌阶段限一次,你可选择至多半数角色(向上取整),若这些角色的手牌数之和大于其他角色的手牌数之和,这些角色获得${get.poptip("olsbquxi")}至你下个准备阶段并摸一张牌。`, olsbquxi: "趋袭", olsbquxi_info: "出牌阶段各限一次,你的【闪】/【桃】可以当做【过河拆桥】/【顺手牵羊】使用。", olsbjieli: "解罹", @@ -44,7 +51,7 @@ const translates = { olsbqianfu: "迁附", olsbqianfu_info: "转换技,出牌阶段,阳:你可以将一张黑色牌当【过河拆桥】使用:阴:你可以将一张红色牌当【火攻】使用。结算后,你可将因此弃置的牌置于牌堆顶。", olsbyushi: "驭势", - olsbyushi_info: "你造成或受到伤害后,你可令一名:有转换技的角色切换其一个转换技的状态:无转换技的角色获得出牌阶段各限一次的〖迁附〗,直到其失去最后的手牌。每轮前X次,有转换技切换状态后,你摸一张牌(X为你的体力上限)。", + olsbyushi_info: `你造成或受到伤害后,你可令一名:有转换技的角色切换其一个转换技的状态:无转换技的角色获得出牌阶段各限一次的${get.poptip("olsbqianfu")},直到其失去最后的手牌。每轮前X次,有转换技切换状态后,你摸一张牌(X为你的体力上限)。`, olsbfenchao: "焚巢", olsbfenchao_info: "限定技,结束阶段,你可以令一名角色获得弃牌堆中的伤害牌(不超过存活人数)且令这些牌造成伤害时改为火焰伤害。", ol_sb_lusu: "OL谋鲁肃", @@ -88,7 +95,7 @@ const translates = { ol_guanzhang: "OL界关兴张苞", ol_guanzhang_prefix: "OL界", olfuhun: "父魂", - olfuhun_info: "你可将两张牌当【杀】使用或打出。你使用的转化【杀】目标角色只能使用颜色相同的手牌响应;你于出牌阶段使用【杀】造成伤害后,你本回合获得〖武圣〗和〖咆哮〗。", + olfuhun_info: `你可将两张牌当【杀】使用或打出。你使用的转化【杀】目标角色只能使用颜色相同的手牌响应;你于出牌阶段使用【杀】造成伤害后,你本回合获得${get.poptip("new_rewusheng")}和${get.poptip("olpaoxiao")}。`, ol_sunxiu: "OL界孙休", ol_sunxiu_prefix: "OL界", ol_sb_zhangxiu: "OL谋张绣", @@ -146,7 +153,7 @@ const translates = { olsbzhuri: "逐日", olsbzhuri_info: "你的阶段结束时,若你本阶段失去过手牌或得到过牌,则你可以与一名角色拼点。若你赢,你可以使用其中一张拼点牌;若你没赢,你失去1点体力或令此技能于本回合无效。", olsbranji: "燃己", - olsbranji_info: "限定技,结束阶段。若你本回合使用过牌的阶段数大于等于/小于等于体力值,你可以获得技能〖困奋〗/〖诈降〗(同时满足则都获得,以此法获得的〖困奋〗直接修改为非锁定技)。若如此做,你将手牌数调整至手牌上限或将体力值回复至体力上限,然后你不能回复体力直到你杀死角色。", + olsbranji_info: `限定技,结束阶段。若你本回合使用过牌的阶段数大于等于/小于等于体力值,你可以获得技能${get.poptip("kunfenx")}/${get.poptip("zhaxiang")}(同时满足则都获得,以此法获得的〖困奋〗直接修改为非锁定技)。若如此做,你将手牌数调整至手牌上限或将体力值回复至体力上限,然后你不能回复体力直到你杀死角色。`, kunfenx: "困奋", kunfenx_info: "结束阶段开始时,你可以失去1点体力,然后摸两张牌。", ol_sb_guanyu: "OL谋关羽", @@ -177,14 +184,14 @@ const translates = { olsbshenli_info: "出牌阶段限一次,当你使用【杀】指定目标后,你可以令所有可成为此牌目标的其他角色均成为此牌目标,此牌结算完毕后,若你因此牌造成的伤害值X:大于你的手牌数,你摸X张牌(至多摸五张);大于你的体力值,你再次对所有目标角色中可以成为此牌目标的角色使用此牌。", olsbyufeng: "玉锋", olsbyufeng_block: "思召剑", - olsbyufeng_info: "游戏开始时,你将【思召剑】置入装备区。", + olsbyufeng_info: `游戏开始时,你将${get.poptip("sizhaojian")}置入装备区。`, sizhaojian: "思召剑", sizhaojian_info: "当你使用有点数的【杀】指定目标后,你令目标角色只能使用无点数或点数大于等于此【杀】的【闪】响应此牌。", sizhaojian_append: '【思召剑】于闪闪节(3月2日-3月15日)外离开装备区后,销毁此牌', sizhaojian_skill: "思召剑", sizhaojian_skill_info: "当你使用有点数的【杀】指定目标后,你令目标角色只能使用无点数或点数大于等于此【杀】的【闪】响应此牌。", olsbshishou: "士首", - olsbshishou_info: "主公技,其他群势力角色失去装备区的牌后,若你的装备区中没有武器牌,其可将【思召剑】置入你的装备区。", + olsbshishou_info: `主公技,其他群势力角色失去装备区的牌后,若你的装备区中没有武器牌,其可将${get.poptip("sizhaojian")}置入你的装备区。`, ol_yufan: "OL界虞翻", ol_yufan_prefix: "OL界", olzongxuan: "纵玄", @@ -200,14 +207,14 @@ const translates = { ol_wangyi: "OL界王异", ol_wangyi_prefix: "OL界", olzhenlie: "贞烈", - olzhenlie_info: "当你成为其他角色使用【杀】或普通锦囊牌的目标后,你可以失去1点体力并令此牌对你无效,然后你选择一项:①获得使用者的一张牌;②于本回合的结束阶段发动一次〖秘计〗。", + olzhenlie_info: `当你成为其他角色使用【杀】或普通锦囊牌的目标后,你可以失去1点体力并令此牌对你无效,然后你选择一项:①获得使用者的一张牌;②于本回合的结束阶段发动一次${get.poptip("olmiji")}。`, olzhenlie_effect: "秘计", olmiji: "秘计", olmiji_info: "结束阶段,若你已受伤,则你可以摸X张牌,然后你可以将至多X张牌任意分配给其他角色(X为你已损失的体力值)。", ol_sb_pangtong: "OL谋庞统", ol_sb_pangtong_prefix: "OL谋", olsbhongtu: "鸿图", - olsbhongtu_info: "一名角色的阶段结束时,若你于此阶段得到过至少两张牌,你可以摸三张牌,展示三张手牌,令一名其他角色选择是否使用其中一张牌并令你随机弃置其中另一张牌。若使用牌的点数于三张牌中满足以下条件,其获得如下技能或效果直到其下一个回合的回合结束:唯一最大,其获得〖飞军〗;不为最大且不为最小,其获得〖潜袭〗;唯一最小,其手牌上限+2。若其未以此法使用牌,你对其与你各造成1点火焰伤害。", + olsbhongtu_info: `一名角色的阶段结束时,若你于此阶段得到过至少两张牌,你可以摸三张牌,展示三张手牌,令一名其他角色选择是否使用其中一张牌并令你随机弃置其中另一张牌。若使用牌的点数于三张牌中满足以下条件,其获得如下技能或效果直到其下一个回合的回合结束:唯一最大,其获得${get.poptip("nzry_feijun")};不为最大且不为最小,其获得${get.poptip("qianxi")};唯一最小,其手牌上限+2。若其未以此法使用牌,你对其与你各造成1点火焰伤害。`, olsbqiwu: "栖梧", olsbqiwu_info: "当你每回合首次受到伤害时,若伤害来源为你或在你的攻击范围内,你可以弃置一张红色牌,防止此伤害。", ol_fazheng: "OL界法正", @@ -292,7 +299,7 @@ const translates = { olfengshang: "封赏", olfengshang_info: "出牌阶段限一次或有角色进入濒死状态时(每回合限一次),你可以将两张本回合进入弃牌堆中的本轮未以此法选择过的相同花色的牌分配给等量角色。若你未以此法获得牌,你视为使用一张不计入次数的【酒】。", olzhibin: "执柄", - olzhibin_info: "主公技,锁定技。准备阶段,若其他群势力角色累计使用黑色牌的次数达到:三张,你增加1点体力上限并回复1点体力;六张,你获得〖焚城〗;九张:你获得〖崩坏〗。", + olzhibin_info: `主公技,锁定技。准备阶段,若其他群势力角色累计使用黑色牌的次数达到:三张,你增加1点体力上限并回复1点体力;六张,你获得${get.poptip("dcfencheng")};九张:你获得${get.poptip("benghuai")}。`, ol_sb_dengai: "OL谋邓艾", ol_sb_dengai_prefix: "OL谋", olsbjigu: "积谷", @@ -344,7 +351,7 @@ const translates = { olchaozheng: "朝争", olchaozheng_info: "①准备阶段,你可以与所有其他角色议事。若结果为:红色,意见为红色的角色各回复1点体力;黑色,意见为红色的其他角色各失去1点体力。然后你摸X张牌(X为此次议事意见与你相同的角色数且至多为2)。②当你参与的议事展示意见时,你的意见权重+1。", olshenchong: "甚宠", - olshenchong_info: "限定技。准备阶段,你可以令一名其他角色获得〖飞扬〗、〖跋扈〗。若如此做,当你死亡时,杀死你的角色弃置所有手牌,其失去所有技能。", + olshenchong_info: `限定技。准备阶段,你可以令一名其他角色获得${get.poptip("olrefeiyang")}${get.poptip("jsrgbahu")}。若如此做,当你死亡时,杀死你的角色弃置所有手牌,其失去所有技能。`, oljulian: "聚敛", oljulian_info: "主公技。①其他群势力角色每回合限一次。当其不于摸牌阶段且不因〖聚敛〗摸牌后,其可以摸一张牌。②结束阶段,你可以获得所有其他群势力角色各一张牌。", olrefeiyang: "飞扬", @@ -354,8 +361,8 @@ const translates = { olguifu: "诡伏", olguifu_info: "①每轮开始时或你受到伤害、失去体力、回复体力后,你可以随机从牌堆或弃牌堆获得一张不计入手牌上限的【闪】。②本局游戏中牌或技能直接造成伤害后,你记录此牌名或技能。③每回合每种牌名限一次,你可以将因此技能获得的【闪】当做不计入次数限制的〖诡伏②〗记录过的牌名使用。", olmoubian: "谋变", - olmoubian_info: "准备阶段,若你记录的牌名和技能之和大于等于3,你可以“入魔”,获得记录的全部技能,然后获得〖骤袭〗。", - olmoubian_append: `
  • 入魔:每局游戏限一次,当你满足条件后,可入魔。入魔后,每轮结束时,若本轮你未造成过伤害,你失去1点体力。`, + olmoubian_info: `准备阶段,若你记录的牌名和技能之和大于等于3,你可以${get.poptip("rule_rumo")},获得记录的全部技能,然后获得${get.poptip("olzhouxi")}。`, + //olmoubian_append: `
  • 入魔:每局游戏限一次,当你满足条件后,可入魔。入魔后,每轮结束时,若本轮你未造成过伤害,你失去1点体力。`, olzhouxi: "骤袭", olzhouxi_info: "①准备阶段,你从三个可造成伤害的技能中选择一个获得直到你的下回合开始。②本轮受到你伤害的角色于本轮结束时视为对你使用一张【杀】。", olrumo: "入魔", @@ -387,20 +394,26 @@ const translates = { olhuanhuo: "幻惑", olhuanhuo_info: "每轮开始时,你摸两张牌,然后弃置至多两张牌并选择等量其他角色。其下回合出牌阶段需要使用牌时强制选中一张可用的手牌(不能使用主动技能),且每使用一张牌后随机弃一张牌,直到其使用了两张牌后。", olqingshi: "倾世", - olqingshi_info: "准备阶段,你可入魔,令所有角色获得一张单目标伤害牌。其他角色使用此牌指定唯一目标时,你可弃置一张牌,重新指定牌的目标(无距离限制)。这些牌:造成伤害后,你摸一张牌;未因使用进入弃牌堆后,你获得之。(准备阶段,若这些牌均离开其手牌区,你再令所有角色获得牌。)入魔后,每轮结束时,若本轮你未造成过伤害,你失去1点体力。", + olqingshi_info: `准备阶段,你可${get.poptip("rule_rumo")},令所有角色获得一张单目标伤害牌。其他角色使用此牌指定唯一目标时,你可弃置一张牌,重新指定牌的目标(无距离限制)。这些牌:造成伤害后,你摸一张牌;未因使用进入弃牌堆后,你获得之。(准备阶段,若这些牌均离开其手牌区,你再令所有角色获得牌。)`, dm_lvbu: "魔吕布", dm_lvbu_prefix: "魔", olduoqi: "夺炁", olduoqi_info: "锁定技。①所有角色的初始手牌称为“炁”。②一号位首个回合开始前,你执行一个不能使用延时锦囊牌的出牌阶段。③你每回合对一名角色首次造成伤害后,你从弃牌堆、牌堆、场上角色的区域内中获得其一张“炁”。", olduoqi_tag: "炁", olkuangmo: "狂魔", - olkuangmo_info: "出牌阶段,你可以入魔并选择一名其他角色,你与其成为“狂”角色,每回合对彼此首次造成的伤害+1;杀死对方后,获得对方所有“炁”。“狂”角色死亡后,你重新指定。入魔后,每轮结束时,若本轮你未造成过伤害,你失去1点体力。", + olkuangmo_info: `出牌阶段,你可以${get.poptip("rule_rumo")}并选择一名其他角色,你与其成为“狂”角色,每回合对彼此首次造成的伤害+1;杀死对方后,获得对方所有“炁”。“狂”角色死亡后,你重新指定。`, olgangquan: "罡拳", olgangquan_info: "若你使用的上一张牌为“炁”,你可以将一张装备牌当指定相邻角色为目标的火【杀】使用;否则,你可以将一张锦囊牌当【决斗】使用。", ol_jsrg_zhangliao: "闪张辽", ol_jsrg_zhangliao_prefix: "闪", olzhengbing: "整兵", olzhengbing_info: "群势力技。出牌阶段限三次。你可以重铸一张牌,若此牌为:【杀】,你的手牌上限+1;【闪】,你摸一张牌;【桃】/【酒】,你于此回合结束时执行一个出牌阶段。然后若你以此法触发过所有选项,变更势力为魏。", + dm_caocao: "OL魔曹操", + dm_caocao_prefix: "OL|魔", + olbachao: "霸朝", + olbachao_info: `出牌阶段开始时,你可以令所有其他角色同时选择是否交给你一张非基本牌,然后你对一名未以此法交给你牌的角色造成1点伤害;若该角色为你,本阶段你使用当前手牌无距离次数限制并${get.poptip("rule_rumo")}。`, + olfuzai: "覆载", + olfuzai_info: "锁定技,①你的装备牌只能当【借刀杀人】或【无中生有】使用。②若你的装备区没有牌,你视为装备着随机武器和防具各一件(优先装备攻击距离/牌名字数与你的体力值相同的武器/防具)。", }; export default translates; diff --git a/character/rank.js b/character/rank.js index 72a56c31a3..04eb4d5370 100644 --- a/character/rank.js +++ b/character/rank.js @@ -2,6 +2,8 @@ window.noname_character_rank = { s: ["v_sunshangxiang", "two_yj_puyuan", "x_yao_yuanshu", "lord_goblin", "pe_guozhao", "xia_caopi", "pe_jun_caopi", "wn_shen_machao", "pe_que", "hm_shen_huangfusong", "tw_jsrg_huangfusong", "key_shiki", "sp_xiahoushi", "ns_zhangwei", "key_mio", "key_midori", "key_yuri", "key_yui", "key_lucia", "db_key_hina", "sp_key_kanade", "key_shizuru", "key_sakuya", "boss_zhaoyun", "noname", "ns_shijian", "key_iriya", "ol_nanhualaoxian", "huzun", "dc_xujing", "ty_shen_zhangfei", "vtb_xiaole", "yj_zhonghui", "duosidawang", "re_sp_zhugeliang", "re_pangtong", "tw_wujing", "dengzhi", "xin_chengpu", "tw_dongzhao", "sunwukong", "ps_shen_machao", "pk_sp_duyu", "std_pengyang", "diy_liaohua", "drag_xusheng"], ap: [ "dc_sb_zhuran", + "mb_cuilingyi", + "dc_shen_sunquan", "tw_jsrg_sunjian", "shinin_zhenji", "shinin_wuguotai", @@ -186,6 +188,7 @@ window.noname_character_rank = { "shen_lusu", "jin_jsrg_simazhao", "drag_caoren", + "dm_caocao", "dc_huangwudie", "ol_sb_pangtong", "ol_sb_yuanshu", @@ -296,6 +299,7 @@ window.noname_character_rank = { "zj_liuyin", "zj_huoyi", "mb_luyu", + "wxdl_caocao", "yj_fazheng", "ol_sb_lusu", "ol_sb_zhugeliang", @@ -2204,9 +2208,13 @@ window.noname_character_rank = { legend: [ "v_sunshangxiang", "zc26_shen_huangyueying", + "dc_shen_sunquan", "lord_goblin", "scl_jiaxu", + "mb_cuilingyi", "x_yao_yuanshu", + "dm_caocao", + "dm_sunquan", "zj_liuyuan", "zj_zhonghui", "xia_caopi", @@ -2512,6 +2520,7 @@ window.noname_character_rank = { epic: [ "dc_sb_zhuran", "mb_luyu", + "wxdl_caocao", "yj_fazheng", "zc26_lusu", "zc26_zhanghe", diff --git a/character/replace.js b/character/replace.js index 50eaa0f7a3..037a7ccc4a 100644 --- a/character/replace.js +++ b/character/replace.js @@ -10,7 +10,7 @@ window.noname_character_replace = { shen_lvmeng: ["shen_lvmeng", "tw_shen_lvmeng"], shen_machao: ["shen_machao", "ps_shen_machao", "wn_shen_machao", "mark_shen_machao"], shen_simayi: ["shen_simayi", "xin_simayi", "new_simayi"], - shen_sunquan: ["shen_sunquan", "junk_sunquan"], + shen_sunquan: ["shen_sunquan", "junk_sunquan", "dc_shen_sunquan"], shen_xuzhu: ["shen_xuzhu", "wn_shen_xuzhu"], shen_zhangfei: ["shen_zhangfei", "ty_shen_zhangfei"], shen_zhangliao: ["ol_zhangliao", "shen_zhangliao"], @@ -28,7 +28,7 @@ window.noname_character_replace = { caizhenji: ["caizhenji", "ol_caizhenji"], caoang: ["caoang", "dc_sb_caoang", "tw_caoang", "huan_caoang", "yj_caoang"], caoanmin: ["caoanmin", "ns_caoanmin"], - caocao: ["caocao", "re_caocao", "sp_ol_caocao", "ol_jsrg_caocao", "dc_caocao", "sb_caocao", "mb_caocao", "tw_jsrg_caocao", "jsrg_caocao", "jd_sb_caocao", "yj_caocao", "ns_caocao", "ns_caocaosp", "jy_caocao", "ps_caocao", "sxrm_caocao", "wn_caocao", "pe_jun_caocao", "xy_caocao", "v_caocao"], + caocao: ["caocao", "re_caocao", "sp_ol_caocao", "ol_jsrg_caocao", "dc_caocao", "sb_caocao", "mb_caocao", "tw_jsrg_caocao", "jsrg_caocao", "jd_sb_caocao", "yj_caocao", "ns_caocao", "ns_caocaosp", "jy_caocao", "ps_caocao", "sxrm_caocao", "wn_caocao", "pe_jun_caocao", "xy_caocao", "v_caocao", "wxdl_caocao", "dm_caocao"], caochong: ["caochong", "ol_caochong", "re_caochong", "huan_caochong", "old_caochong", "strong_caochong"], caochun: ["caochun", "dc_caochun", "old_caochun"], caofang: ["caofang", "jsrg_caofang"], @@ -56,6 +56,7 @@ window.noname_character_replace = { chenlin: ["chenlin", "dc_sb_chenlin"], chenqun: ["chenqun", "dc_chenqun", "re_chenqun", "old_chenqun"], chenshi: ["chenshi", "ty_chenshi"], + cuilingyi: ["cuilingyi", "mb_cuilingyi"], cuiyan: ["cuiyan", "sp_cuiyan"], chunyuqiong: ["chunyuqiong", "re_chunyuqiong", "jsrg_chunyuqiong"], daqiao: ["daqiao", "re_daqiao", "yue_daqiao", "sb_daqiao", "jd_sb_daqiao", "sp_daqiao"], diff --git a/character/sb/skill.js b/character/sb/skill.js index 8713c436ca..300b5dc328 100644 --- a/character/sb/skill.js +++ b/character/sb/skill.js @@ -7285,7 +7285,9 @@ const skills = { } } } - return ui.create.dialog("龙胆", [list, "vcard"], "hidden"); + const dialog = ui.create.dialog("龙胆", [list, "vcard"], "hidden"); + dialog.direct = true; + return dialog; }, check(button) { if (_status.event.getParent().type != "phase") { diff --git a/character/sp/character.js b/character/sp/character.js index 270a884918..6b2e254ab2 100644 --- a/character/sp/character.js +++ b/character/sp/character.js @@ -2,7 +2,7 @@ const characters = { ol_lvlingqi: { sex: "female", group: "qun", - hp: 3, + hp: 4, skills: ["olqiwu", "olzhuangrong"], }, huanshujun: { diff --git a/character/sp/dynamicTranslate.js b/character/sp/dynamicTranslate.js index 159d803ff7..450f012c14 100644 --- a/character/sp/dynamicTranslate.js +++ b/character/sp/dynamicTranslate.js @@ -1,12 +1,6 @@ import { lib, game, ui, get, ai, _status } from "../../noname.js"; const dynamicTranslates = { - olqiwu(player) { - if (player?.hasSkill("olzhuangrong_awaken")) { - return lib.translate["olqiwu_rewrite_info"]; - } - return lib.translate["olqiwu_info"]; - }, olwenyi(player) { let info = lib.translate["olwenyi_info"], limit = 1 + player.countMark("olwenyi_limit"); diff --git a/character/sp/skill.js b/character/sp/skill.js index 4a5270aabd..d5ffbaa1ef 100644 --- a/character/sp/skill.js +++ b/character/sp/skill.js @@ -18,7 +18,7 @@ const skills = { viewAs: { name: "sha", storage: { - olquwu: true, + olqiwu: true, }, suit: "none", number: null, @@ -28,11 +28,11 @@ const skills = { if (!lib.filter.cardDiscardable(card, player, "olqiwu")) { return false; } - return player.hasSkill("olzhuangrong_awaken") || !get.tag(card, "damage"); + return true; //player.hasSkill("olzhuangrong_awaken") || !get.tag(card, "damage"); }, selectCard: [1, Infinity], check(card) { - if (ui.selected.cards.every(cardx => get.type2(card) != get.type2(cardx))) { + if (ui.selected.cards.every(cardx => get.suit(card) != get.suit(cardx))) { return 6 - get.value(card); } return 0; @@ -46,6 +46,11 @@ const skills = { return true; } }, + cardUsable(card, player) { + if (card?.storage?.olqiwu) { + return Infinity; + } + }, }, async precontent(event, trigger, player) { const cards = event.result.cards; @@ -53,11 +58,12 @@ const skills = { await player.modedDiscard(cards); event.result.card = get.autoViewAs({ name: "sha", storage: { olqiwu: true }, isCard: true }); event.result.cards = []; + event.getParent().addCount = false; player .when("useCard1") .filter(evt => evt.getParent() == event.getParent()) .step(async (event, trigger, player) => { - const num = cards?.map(card => get.type2(card)).toUniqued().length; + const num = cards?.map(card => get.suit(card)).toUniqued().length; const func = async target => { const numx = Math.min(num, target.countDiscardableCards(target, "he")); let allCards = cards; @@ -71,19 +77,12 @@ const skills = { allCards = [...allCards, ...result.cards]; } if (allCards?.some(card => card.name == "shan")) { - if (player.hasSkill("olzhuangrong_awaken")) { - const gains = result?.cards?.filterInD("od"); - if (gains?.length) { - await player.gain(gains, "gain2"); - } - } else { - player.addTempSkill("olqiwu_effect"); - const gains = allCards.filter(card => card.name == "shan" && get.position(card) == "d"); - if (gains.length) { - const next = player.gain(gains, "gain2"); - next.gaintag.add("olqiwu"); - await next; - } + player.addTempSkill("olqiwu_effect"); + const gains = allCards.filter(card => card.name == "shan" && get.position(card) == "d"); + if (gains.length) { + const next = player.gain(gains, "gain2"); + next.gaintag.add("olqiwu"); + await next; } } else { trigger.directHit.addArray(game.players); @@ -131,7 +130,7 @@ const skills = { const map = `${skill}_map`; _status[map] ??= new Map(); if (!_status[map].has(player)) { - _status[map].set(player, get.info(skill).getNames); + _status[map].set(player, get.info(skill).getNames.slice(0)); } game.broadcastAll( (map, list) => { @@ -166,8 +165,29 @@ const skills = { } } }, - group: "olzhuangrong_awake", + group: "olzhuangrong_count", subSkill: { + count: { + trigger: { + global: "phaseEnd", + }, + filter(event, player) { + if (player.hasSkill("olzhuangrong_awaken")) { + return false; + } + const evts = player.getAllHistory("useSkill", evt => { + const skill = evt.skill.slice(0, -6); + return get.info("olzhuangrong").getNames.includes(skill); + }); + return evts.length > 1; + }, + forced: true, + async content(event, trigger, player) { + player.addSkill("olzhuangrong_awaken"); + await player.gainMaxHp(); + await player.recover(); + }, + }, awake: { trigger: { player: ["loseAfter"], @@ -330,18 +350,14 @@ const skills = { global: ["changeHpAfter"], }, filter(event, player) { + if (player.countMark("olwenyi_used") > player.countMark("olwenyi_limit")) { + return false; + } if (event.player.hp != 1 || event.num == 0) { return false; } return player.hasUsableCard("tao", "use") || player.countCards("he", card => _status.connectMode || get.type(card) == "equip"); }, - usable(skill, player) { - let count = Math.max(0, 1 + player.countMark("olwenyi_limit") - player.countMark("olwenyi_used")); - if (skill !== false) { - count += player.getStat("triggerSkill")[skill] || 0; - } - return count; - }, init(player, skill) { player.markSkill("olwenyi_limit"); }, @@ -450,12 +466,17 @@ const skills = { limit: { intro: { markcount(storage, player) { - let limit = get.info("olwenyi").usable(false, player); - return limit; + const used = player.countMark("olwenyi_used"), + max = player.countMark("olwenyi_limit") + 1; + if (max > used) { + return max - used; + } + return null; }, content(storage, player) { - let limit = get.info("olwenyi").usable(false, player); - return `剩余可发动次数:${get.cnNumber(limit)}次`; + const used = player.countMark("olwenyi_used"), + max = player.countMark("olwenyi_limit") + 1; + return `剩余可发动次数:${max - used}`; }, }, }, @@ -471,10 +492,12 @@ const skills = { return event.num ?? 0; }, async content(event, trigger, player) { - if (player.hasSkill("olwenyi", null, null, false)) { + const count = player.countMark("olwenyi_limit") + 1 - player.countMark("olwenyi_used"); + if (player.hasSkill("olwenyi", null, null, false) && count === 0) { player.addMark("olwenyi_limit", 1, false); - } - if (!player.getRoundHistory("useSkill", evt => evt.skill == "olwenyi").length) { + game.log(player, "的", "#g【温宜】", "可发动次数+1"); + await player.draw(); + } else { await player.draw(2); } }, @@ -38672,6 +38695,7 @@ const skills = { } else { delete evt.result.used; evt.result.card = get.autoViewAs(card); + evt.result._apply_args = { addSkillCount: false }; if (aozhan) { evt.result.card.name = name; } diff --git a/character/sp/translate.js b/character/sp/translate.js index f83f55a8e1..b37a4d3136 100644 --- a/character/sp/translate.js +++ b/character/sp/translate.js @@ -1563,15 +1563,13 @@ const translates = { olwenyi: "温宜", olwenyi_info: "每局游戏限一次,一名角色体力值变为1后,你可对其使用一张【桃】或交给其一张装备牌令其使用之,然后其复原武将牌。", olmiaoxin: "妙心", - olmiaoxin_info: "锁定技,你受到1点伤害后,令〖温宜〗发动次数+1,然后若本轮你未发动过〖温宜〗,你摸两张牌,", + olmiaoxin_info: "锁定技,你受到1点伤害后,摸两张牌;若〖温宜〗剩余发动次数为0,改为摸一张牌并令〖温宜〗剩余发动次数+1。", ol_lvlingqi: "OL吕玲绮", ol_lvlingqi_prefix: "OL", olqiwu: "绮舞", - olqiwu_info: "出牌阶段限一次,你可以弃置任意张非伤害牌,视为使用一张无距离限制的【杀】并令目标角色弃置X张牌(X为你弃置牌包含的类型数)。若你与其因此弃置的牌:包含【闪】,你获得其中的【闪】且这些牌本回合不计入手牌上限;不包含【闪】,此【杀】不可被响应。", - olqiwu_rewrite: "绮舞·改", - olqiwu_rewrite_info: "出牌阶段限一次,你可以弃置任意张牌,视为使用一张无距离限制的【杀】并令目标角色弃置X张牌(X为你弃置牌包含的类型数)。若你与其因此弃置的牌:包含【闪】,你获得其弃置的牌;不包含【闪】,此【杀】不可被响应。", + olqiwu_info: "出牌阶段限一次,你可以弃置任意张牌,视为使用一张无距离次数限制的【杀】并令目标角色弃置X张牌(X为你弃置牌包含的花色数)。若你与其因此弃置的牌:包含【闪】,你获得其中的【闪】且这些牌本回合不计入手牌上限;不包含【闪】,此【杀】不可被响应。", olzhuangrong: "妆戎", - olzhuangrong_info: `锁定技,回合开始时,将${get.poptip("shufazijinguan")}${get.poptip("linglongshimandai")}${get.poptip("hongmianbaihuapao")}${get.poptip("wushuangfangtianji")}中的随机一件装备从游戏外置入你的对应空置装备栏。你以此法装备过这些牌后,或你第二次失去以此法装备的牌后,你失去此技能并修改〖绮舞〗,然后增加1点体力上限并回复1点体力。`, + olzhuangrong_info: `①锁定技,回合开始时,将${get.poptip("shufazijinguan")}${get.poptip("linglongshimandai")}${get.poptip("hongmianbaihuapao")}${get.poptip("wushuangfangtianji")}中的随机一件装备从游戏外置入你的对应空置装备栏。②每局游戏限一次,每回合结束时,若你发动过至少两次这些装备的效果,你增加1点体力上限并回复1点体力。`, }; export default translates; diff --git a/character/sp2/skill.js b/character/sp2/skill.js index 3037dbf119..c35b157139 100644 --- a/character/sp2/skill.js +++ b/character/sp2/skill.js @@ -11,7 +11,7 @@ const skills = { async content(event, trigger, player) { const { target, name } = event; const result = await target - .chooseControl("一张", "两张", "三张") + .chooseControl("两张", "三张", "四张") .set("prompt", "声明一个数字") .set("ai", () => { return get.event("resultx"); @@ -19,34 +19,31 @@ const skills = { .set( "resultx", (() => { - if (get.attitude(target, player) > 0 && player.getHp() > 1) { - return "三张"; + if (get.attitude(target, player) > 0 && player.getDamagedHp() < 2) { + return "四张"; } - return "一张"; + return "两张"; })() ) .forResult(); target.popup(result.control, "wood"); - game.log(target, "声明的数字为", `#y${result.index + 1}`); + const num = result.index + 2; + game.log(target, "声明的数字为", `#y${num}`); const result2 = await player - .chooseToGive(target, "he", [1, Infinity], true, `交给${get.translation(target)}任意张牌`) + .chooseToGive(target, "he", num, `交给${get.translation(target)}${get.cnNumber(num)}张牌,否则你摸${get.cnNumber(num)}张牌`) .set("ai", card => { - const { getNum, player } = get.event(); - if (ui.selected.cards.length >= getNum && player.getHp() > 1) { + const { player } = get.event(); + if (player.getDamagedHp() < 2) { return 0; } return 7 - get.value(card); }) - .set("getNum", result.index) .forResult(); if (result2?.bool && result2.cards?.length) { - if (result2.cards.length > result.index) { - player.addSkill(`${name}_effect`); - player.addMark(`${name}_effect`, 1, false); - } else { - await player.damage(target); - await player.draw(result.index + 1); - } + player.addTempSkill(`${name}_effect`, { player: "phaseBegin" }); + player.addMark(`${name}_effect`, num, false); + } else { + await player.draw(num); } }, subSkill: { @@ -55,26 +52,46 @@ const skills = { onremove: true, locked: false, intro: { - content: "你的攻击范围和拼点点数+#", + content: "其他角色计算与你的距离和你的拼点点数+#", }, trigger: { player: "compare", target: "compare", + global: ["chooseToCompareAfter","compareMultipleAfter"], }, - filter(event, player) { - if (player != event.target && event.iwhile) { + filter(event, player, name) { + if (name == "compare") { + if (player != event.target && event.iwhile) { + return false; + } + return player.countMark("dczijue_effect"); + } + if (event.compareMultiple) { return false; } - return player.countMark("dczijue_effect"); + if (event.compareMeanwhile || [event.player, event.target].includes(player)) { + const winner = event.winner || event.result.winner; + return winner == player; + } + return false; }, async cost(event, trigger, player) { - const key = player == trigger.player ? "num1" : "num2"; - trigger[key] = Math.min(13, trigger[key] + player.countMark(event.skill)); - game.log(player, "的拼点牌点数+", player.countMark(event.skill)); + if (event.triggername == "compare") { + const key = player == trigger.player ? "num1" : "num2"; + trigger[key] = Math.min(13, trigger[key] + player.countMark(event.skill)); + game.log(player, "的拼点牌点数+", player.countMark(event.skill)); + return; + } + event.result = { + bool: true, + } + }, + async content(event, trigger, player) { + await player.draw(); }, mod: { - attackRange(player, num) { - return num + player.countMark("dczijue_effect"); + globalTo(from, to, num) { + return num + to.countMark("dczijue_effect"); }, }, }, diff --git a/character/sp2/translate.js b/character/sp2/translate.js index aa13766c87..b62b608e15 100644 --- a/character/sp2/translate.js +++ b/character/sp2/translate.js @@ -651,7 +651,7 @@ const translates = { starchiguo_info: "出牌阶段开始时,你可以观看牌堆底三张牌,本阶段你使用一张牌时,亮出牌堆底一张牌,若两张牌花色相同,你为你使用的牌增加或减少一个目标(目标数至少为1),然后将此牌置入弃牌堆;否则你将亮出牌交给一名目标角色。", cuilie: "崔烈", dczijue: "赀爵", - dczijue_info: "出牌阶段限一次,你可令一名其他角色声明1-3中的一个数字,然后你交给其任意张牌,若你交给其的牌数不小于其声明的数字,你的攻击范围和拼点牌点数+1;否则你受到其造成的1点伤害,然后你摸其声明数字张牌。", + dczijue_info: "出牌阶段限一次,你可令一名其他角色声明2-4中的一个数字,你可交给其X张牌并回复1点体力,然后其他角色计算与你的距离和你的拼点牌点数+X直到你的下回合开始且你拼点赢时摸一张牌;否则你摸X张牌(X为其声明的数字)。", dcchibi: "斥避", dcchibi_info: "每回合限一次,其他角色使用牌指定其攻击范围外的另一名角色为唯一目标时,你可与其拼点:若你赢,你令此牌无效并获得此牌;若你没赢,你成为此牌的额外目标。", }; diff --git a/character/standard/skill.js b/character/standard/skill.js index 582f72d841..e3c9d083cc 100644 --- a/character/standard/skill.js +++ b/character/standard/skill.js @@ -2173,7 +2173,7 @@ const skills = { trigger: { player: "damageBegin3" }, audio: 2, filter(event, player) { - return event.card?.name == "sha" && event.source?.isIn(); + return event.card?.name == "sha" && get.color(event.card) == "red" && event.source?.isIn(); }, forced: true, check() { diff --git a/character/sxrm/skill.js b/character/sxrm/skill.js index 60d1da3453..9d35437bd4 100644 --- a/character/sxrm/skill.js +++ b/character/sxrm/skill.js @@ -1039,7 +1039,10 @@ const skills = { const bool = player.getStorage(event.name, false); player.changeZhuanhuanji(event.name); if (bool) { - await player.discardPlayerCard(trigger.player, "he", 2, true); + const num = Math.min(2, trigger.player.countDiscardableCards(player, "he")); + if (num > 0) { + await player.discardPlayerCard(trigger.player, "he", num, true); + } } else { await game.asyncDraw([player, trigger.player]); } diff --git a/character/tw/character.js b/character/tw/character.js index ddebb9a13d..e8e0e8769d 100644 --- a/character/tw/character.js +++ b/character/tw/character.js @@ -91,7 +91,7 @@ const characters = { sex: "male", group: "wei", hp: 3, - skills: ["twxingshang", "twfangzhu", "twsongwei"], + skills: ["twsbxingshang", "twsbfangzhu", "twsbsongwei"], isZhugong: true, dieAudios: ["sb_caopi"], }, diff --git a/character/tw/skill.js b/character/tw/skill.js index 643db0f038..ba03b279ed 100644 --- a/character/tw/skill.js +++ b/character/tw/skill.js @@ -1891,7 +1891,434 @@ const skills = { }, }, //外服谋曹丕 + twsbxingshang: { + audio: "sbxingshang", + trigger: { + global: "die", + player: "phaseUseEnd", + }, + filter(event, player) { + if (event.name == "die") { + return event.player.countCards("hej") > 0; + } + return game.hasPlayer(current => { + return current.countCards("hej") > current.getHp(); + }); + }, + async cost(event, trigger, player) { + if (trigger.name != "die") { + event.result = await player + .chooseTarget(`###${get.prompt(event.skill)}###将一名角色区域里的牌数弃置至与其体力值相同`, (card, player, target) => { + return target.countCards("hej") > target.getHp(); + }) + .set("ai", target => { + const num = target.countCards("hej") - target.getHp(), + player = get.player(); + return num * get.effect(target, { name: "guohe" }, player, player); + }) + .forResult(); + return; + } + const cards = trigger.player.getCards("hej").slice(0), + give_map = new Map(); + if (_status.connectMode) { + game.broadcastAll(function () { + _status.noclearcountdown = true; + }); + } + do { + const prompt1 = give_map.size > 0 ? "行殇:继续分配剩余牌" : "行殇:是否分配本次弃置的牌?", + prompt2 = give_map.size > 0 ? `行殇:将${get.translation(cards)}分配给一名角色` : `行殇:是否令一名角色获得${get.translation(cards)}?`; + const { result } = + cards.length > 1 + ? await player + .chooseButtonTarget({ + createDialog: [prompt1, cards], + selectButton: [1, Infinity], + cardsx: cards, + forced: give_map.size > 0, + source: trigger.player, + filterTarget(card, player, target) { + return target != get.event("source"); + }, + ai1(button) { + return get.value(button.link); + }, + canHidden: true, + ai2(target) { + const player = get.player(); + const card = ui.selected.buttons[0].link; + if (card) { + return get.value(card, target) * get.attitude(player, target); + } + return 1; + }, + }) + .set("allowChooseAll", true) + : await player + .chooseTarget(prompt2, (card, player, target) => { + return target != get.event("source"); + }) + .set("forced", give_map.size > 0) + .set("ai", target => { + const att = get.attitude(_status.event.player, target); + if (_status.event.enemy) { + return -att; + } else if (att > 0) { + return att / (1 + target.countCards("h")); + } else { + return att / 100; + } + }) + .set("source", trigger.player) + .set("enemy", get.value(cards[0], player, "raw") < 0); + if (result?.bool) { + if (!result.links?.length) { + result.links = cards.slice(0); + } + cards.removeArray(result.links); + const target = result.targets[0], + list = give_map.has(target) ? give_map.get(target) : []; + give_map.set(target, [...list, ...result.links]); + } else { + break; + } + } while (cards.length > 0); + if (_status.connectMode) { + game.broadcastAll(function () { + delete _status.noclearcountdown; + game.stopCountChoose(); + }); + } + const targets = Array.from(give_map.keys()), + lose_list = []; + for (let i of targets) { + lose_list.add([i, give_map.get(i)]); + } + event.result = { + bool: targets.length > 0, + targets: targets?.sortBySeat(), + cost_data: lose_list, + }; + }, + async content(event, trigger, player) { + if (trigger.name != "die") { + const target = event.targets[0]; + const discards = target.getDiscardableCards(player, "hej"), + num = target.countCards("hej") - target.getHp(); + const result = discards.length > num ? await player + .discardPlayerCard(target, num, "hej", true) + .forResult() : { + bool: true, + links: discards, + }; + if (result?.bool && result.links?.length && target.getHp() > 0) { + const cards = [], + num = target.getHp(); + while (cards.length < num) { + const canUse = result.links.filter(card => { + return get.position(card) == "d" && !cards.includes(card) && player.hasUseTarget(card); + }); + if (!canUse?.length) { + break; + } + const result2 = await player + .chooseButton(["行殇:是否使用其中一张牌?", canUse]) + .set("ai", button => { + const player = get.player(); + return player.getUseValue(button.link); + }) + .forResult(); + if (result2?.bool) { + cards.addArray(result2.links); + const card = result2.links[0]; + if (player.hasUseTarget(card)) { + await player.chooseUseTarget(card, true, false); + } + } else { + break; + } + } + } + return; + } + await game + .loseAsync({ + gain_list: event.cost_data, + giver: trigger.player, + animate: "gain2", + }) + .setContent("gaincardMultiple"); + }, + }, + twsbfangzhu: { + audio: "sbfangzhu", + trigger: { + player: "damageEnd", + }, + filter(event, player) { + return event.source?.isIn() && event.source.getRoundHistory("sourceDamage", evt => { + return evt.player == player; + }).indexOf(event) == 0; + }, + async cost(event, trigger, player) { + const result = await player + .chooseButton([ + get.prompt(event.skill, trigger.source), + [ + [ + ["fengyin", `令其非锁定技失效并获得${get.poptip("twyuanbu")}直到其下个回合结束`], + ["gongsun", "令其不能使用或打出当前手牌直到其下个回合结束"], + ], + "textbutton", + ] + ]) + .set("att", get.attitude(player, trigger.source)) + .set("ai", button => { + if (get.event("att") > 0) { + return 0; + } + return Math.random(); + }) + .forResult(); + if (result?.bool && result.links?.length) { + event.result = { + bool: true, + cost_data: result.links[0], + } + } + }, + logTarget: "source", + async content(event, trigger, player) { + const { targets: [target], cost_data, name } = event, + skill = `${name}_${cost_data}`, + phase = trigger.getParent("phase"); + target.addSkill(skill); + if (cost_data == "fengyin") { + target.addAdditionalSkills(skill, "twyuanbu"); + target.markAuto(skill, [phase]); + } else { + target.markAuto(skill, [[phase, target.getCards("h")]]); + target.addGaintag(target.getCards("h"), "twsbfangzhu"); + } + }, + group: "twsbfangzhu_liufang", + subSkill: { + liufang: { + trigger: { + global: "phaseBegin", + }, + filter(event, player) { + if (player.hasSkill("twsbfangzhu_used")) { + return false; + } + return game.countPlayer(() => true) >= 4; + }, + async cost(event, trigger, player) { + event.result = await player + .chooseTarget(get.prompt(event.skill), "每轮限一次,你可令一名角色与其下家交换座次(不能包含当前回合角色)", (card, player, target) => { + if (!_status.currentPhase) { + return true; + } + const cannot = _status.currentPhase; + return target != cannot && target != cannot.getPrevious(); + }) + .set("ai", target => { + const player = get.player(), + targetx = target.getNext(); + let eff = -get.attitude(player, target); + if (targetx?.isIn()) { + eff += get.attitude(player, targetx); + } + return eff; + }) + .forResult(); + }, + async content(event, trigger, player) { + const target = event.targets[0], + targetx = target.getNext();; + player.addTempSkill("twsbfangzhu_used", { global: "roundStart" }); + game.broadcastAll( + function (target1, target2) { + game.swapSeat(target1, target2); + }, + target, + targetx + ); + }, + }, + used: { + charlotte: true, + }, + fengyin: { + init: function (player, skill) { + player.addSkillBlocker(skill); + player.addTip(skill, "放逐 远步"); + }, + onremove: function (player, skill) { + player.removeSkillBlocker(skill); + player.removeTip(skill); + player.setStorage(skill, []); + }, + trigger: { + player: "phaseEnd", + }, + async cost(event, trigger, player) { + const list = player.getStorage(event.skill); + if (list.length && list.some(phase => phase == trigger)) { + player.setStorage(event.skill, list.filter(phase => phase == trigger)); + } else { + player.removeSkill(event.skill); + } + }, + charlotte: true, + skillBlocker: function (skill, player) { + return !lib.skill[skill].persevereSkill && !lib.skill[skill].charlotte && !get.is.locked(skill, player); + }, + mark: true, + intro: { + markcount: () => null, + content: function (storage, player, skill) { + var list = player.getSkills(null, false, false).filter(function (i) { + return lib.skill.fengyin.skillBlocker(i, player); + }); + if (list.length) { + return "失效技能:" + get.translation(list); + } + return "无失效技能"; + }, + }, + }, + gongsun: { + init: function (player, skill) { + player.addTip(skill, "放逐 限牌"); + }, + onremove: function (player, skill) { + player.removeTip(skill); + player.setStorage(skill, []); + player.removeGaintag("twsbfangzhu"); + }, + trigger: { + player: "phaseEnd", + }, + async cost(event, trigger, player) { + const list = player.getStorage(event.skill); + if (list.length && list.some(list => list[0] == trigger)) { + player.setStorage(event.skill, list.filter(list => list[0] == trigger)); + player.removeGaintag("twsbfangzhu"); + const cards = []; + for (let i of list) { + if (i[0] !== trigger) { + continue; + } + cards.addArray(i[1]); + } + player.addGaintag(cards, "twsbfangzhu"); + } else { + player.removeSkill(event.skill); + } + }, + charlotte: true, + mod: { + cardEnabled(card, player) { + const cards = [card]; + if (Array.isArray(card.cards)) { + cards.addArray(card.cards); + } + const blocks = [], + list = player.getStorage("twsbfangzhu_gongsun"); + for (let i of list) { + if (Array.isArray(i) && Array.isArray(i[1])) { + blocks.addArray(i[1]); + } + } + if (cards.containsSome(...blocks)) { + return false; + } + }, + cardSavable(card, player) { + const cards = [card]; + if (Array.isArray(card.cards)) { + cards.addArray(card.cards); + } + const blocks = [], + list = player.getStorage("twsbfangzhu_gongsun"); + for (let i of list) { + if (Array.isArray(i) && Array.isArray(i[1])) { + blocks.addArray(i[1]); + } + } + if (cards.containsSome(...blocks)) { + return false; + } + }, + cardRespondable(card, player) { + const cards = [card]; + if (Array.isArray(card.cards)) { + cards.addArray(card.cards); + } + const blocks = [], + list = player.getStorage("twsbfangzhu_gongsun"); + for (let i of list) { + if (Array.isArray(i) && Array.isArray(i[1])) { + blocks.addArray(i[1]); + } + } + if (cards.containsSome(...blocks)) { + return false; + } + }, + }, + }, + }, + derivation: "twyuanbu", + }, + twyuanbu: { + audio: 2, + mod: { + maxHandcard(player, num) { + return num + Math.min(4, game.countPlayer(current => current != player)); + }, + globalFrom(from, to, num) { + return num + Math.min(4, game.countPlayer(current => current != from)); + }, + globalTo(from, to, num) { + return num + Math.min(4, game.countPlayer(current => current != to)); + }, + }, + }, + twsbsongwei: { + audio: "sbsongwei", + trigger: { + global: "phaseBegin", + }, + forced: true, + zhuSkill: true, + getPhases() { + let evts = game.getAllGlobalHistory("everything", evt => evt.name == "phase"); + const evt = evts.slice(0).reverse().find(evt => evt._roundStart); + if (evt) { + evts = evts.slice(evts.indexOf(evt)); + } + return evts.filter(evt => !evt._cancelled && !evt._finished); + }, + filter(event, player) { + if (event.player == player || event.player.group != "wei") { + return false; + } + const evts = get.info("twsbsongwei").getPhases(); + return game.countPlayer(current => { + return evts.every(evt => evt.player != current); + }) > 0; + }, + async content(event, trigger, player) { + const evts = get.info(event.name).getPhases(); + const num = Math.min(3, game.countPlayer(current => evts.every(evt => evt.player != current))); + await player.draw(num); + }, + }, //不想你,出生牢丕 + //想你了,牢丕😭 twxingshang: { getLimit: 9, getList: [ diff --git a/character/tw/translate.js b/character/tw/translate.js index b95622f256..65e6c49be2 100644 --- a/character/tw/translate.js +++ b/character/tw/translate.js @@ -831,6 +831,14 @@ const translates = { twfangzhu_info_doudizhu: "出牌阶段限一次,你可以:" + ["移去2个“颂”标记,令一名其他角色于手牌中只能使用锦囊牌直到其回合结束", "移去2个“颂”标记,令一名其他角色不能响应另一名角色使用的牌直到其回合结束", "移去3个“颂”标记,令一名其他角色将武将牌翻面"].map((str, index) => `${index + 1}.${str}`).join(";") + "。", twsongwei: "颂威", twsongwei_info: "主公技。①出牌阶段开始时,你获得Y个“颂”标记(Y为场上其他魏势力角色数的两倍)。②每局游戏限一次,你可以令一名其他魏势力角色失去武将牌上的所有技能。", + twsbxingshang: "行殇", + twsbxingshang_info: "一名角色死亡时,你可以分配其区域里的牌。出牌阶段结束时,你可将一名角色区域里的牌数弃置至与其体力值相等,然后你可使用至多X张其以此法弃置的牌(X为其体力值)。", + twsbfangzhu: "放逐", + twsbfangzhu_info: `①你受到伤害后,若为伤害来源本轮首次对你造成伤害,你可选择一项:1.令其非锁定技失效并获得${get.poptip("twyuanbu")}直到其下个回合结束;2.令其不能使用或打出当前手牌直到其下个回合结束。②每轮限一次,一名角色的回合开始时,你可令一名角色与其下家交换座次(不能包含当前回合角色)。`, + twyuanbu: "远步", + twyuanbu_info: "锁定技,你的手牌上限、计算与其他角色的距离、其他角色计算与你的距离+X(X为其他存活角色数且至多为4)。", + twsbsongwei: "颂威", + twsbsongwei_info: "主公技,锁定技,其他魏势力角色回合开始时,你摸X张牌(X为本轮未执行过回合的角色且至多为3)。", tw_simashi: "TW司马师", tw_simashi_prefix: "TW", twjinglve: "景略", diff --git a/character/xianding/character.js b/character/xianding/character.js index 2cfafaa7c2..b16d240548 100644 --- a/character/xianding/character.js +++ b/character/xianding/character.js @@ -39,7 +39,7 @@ const characters = { sex: "male", group: "wu", hp: 4, - skills: ["dcsbqinqiang"], + skills: ["dcsbqinqiang", "dcsbyizhen"], }, suyue: { sex: "male", @@ -132,6 +132,7 @@ const characters = { group: "wei", hp: 3, skills: ["dchuashang", "dcyuzhi"], + names: "崔|null", }, dc_wuzhi: { sex: "male", diff --git a/character/xianding/dynamicTranslate.js b/character/xianding/dynamicTranslate.js index b4321333c8..0470163ffd 100644 --- a/character/xianding/dynamicTranslate.js +++ b/character/xianding/dynamicTranslate.js @@ -4,7 +4,7 @@ const dynamicTranslates = { dcsbjunmou(player) { const bool = player.storage.dcsbjunmou; let yang = "此牌视为无距离次数限制的火【杀】并摸一张牌(你可额外摸一张牌并令此技能本阶段失效)", - yin = "此颜色的牌不计入手牌上限并横置一名角色(你可额外横置一名角色并令此技能本阶段失效)"; + yin = "令你此颜色的当前手牌不计入手牌上限并可横置一名角色(你可额外横置一名角色并令此技能本阶段失效)"; if (bool) { yin = `${yin}`; } else { diff --git a/character/xianding/skill.js b/character/xianding/skill.js index c415e10e22..6bc29a603f 100644 --- a/character/xianding/skill.js +++ b/character/xianding/skill.js @@ -1431,59 +1431,59 @@ const skills = { }) .forResult(); }, - popup: false, async content(event, trigger, player) { - player.addTempSkill("dcsbqinqiang_effect", { player: "phaseBegin" }); - const next = player.draw(event.cards.length * 2); - next.gaintag.add("dcsbqinqiang_effect"); - await next; + await player.draw(event.cards.length * 2); }, - subSkill: { + }, + dcsbyizhen: { + audio: 2, + trigger: { target: "useCardToTargeted" }, + filter(event, player) { + if (player == event.player) { + return false; + } + const suit = get.suit(event.card), + suits = lib.suit.slice(0), + map = {}; + suits.add(suit); + for (const suitx of suits) { + map[suitx] = player.countCards("h", { suit: suitx }); + } + if (suits.every(suitx => suitx == suit || map[suitx] < map[suit])) { + return player.countDiscardableCards(player, "h", card => get.suit(card) == suit) > 0; + } + return suits.every(suitx => map[suitx] >= map[suit]); + }, + forced: true, + async content(event, trigger, player) { + const suit = get.suit(trigger.card), + suits = lib.suit.slice(0), + map = {}; + suits.add(suit); + for (const suitx of suits) { + map[suitx] = player.countCards("h", { suit: suitx }); + } + if (suits.every(suitx => suitx == suit || map[suitx] < map[suit])) { + await player.chooseToDiscard("h", card => get.suit(card) == suit, true); + } + if (suits.every(suitx => map[suitx] >= map[suit])) { + player + .when({ global: "useCardAfter" }) + .filter((evt, player) => evt == trigger.getParent() && evt.cards?.someInD("od")) + .step(async (event, trigger, player) => { + await player.gain(trigger.cards.filterInD("od"), "gain2"); + }); + } + }, + ai: { effect: { - charlotte: true, - onremove(player, skill) { - player.removeGaintag(skill); - }, - audio: "dcsbqinqiang", - trigger: { target: "useCardToTargeted" }, - filter(event, player) { - const suit = get.suit(event.card); - if (!player.hasCard({ suit: suit }, "h") && event.cards?.someInD("od")) { - return true; - } - const suits = player.getCards("h").map(card => get.suit(card)), - num = Math.max(...suits.map(suitx => get.numOf(suits, suitx))); - return get.numOf(suits, suit) === num && player.hasCard(card => card.hasGaintag("dcsbqinqiang_effect") && lib.filter.cardDiscardable(card, player), "h"); - }, - forced: true, - async content(event, trigger, player) { - const suit = get.suit(trigger.card), - has = !player.hasCard({ suit: suit }, "h"), - suits = player.getCards("h").map(card => get.suit(card)), - num = Math.max(...[...lib.suit, "none"].map(suitx => get.numOf(suits, suitx))); - if (get.numOf(suits, suit) === num && player.hasCard(card => card.hasGaintag("dcsbqinqiang_effect") && lib.filter.cardDiscardable(card, player), "h")) { - await player.chooseToDiscard("h", true, card => card.hasGaintag("dcsbqinqiang_effect")); - } - if (!has) { - player - .when({ global: "useCardAfter" }) - .filter((evt, player) => evt.card === trigger.card && evt.cards?.someInD("od")) - .step(async (event, trigger, player) => { - await player.gain(trigger.cards.filterInD("od"), "gain2"); - }); + target(card, player, target) { + const suit = get.suit(card), + suits = target.getKnownCards(player).map(card => get.suit(card)); + if (suits.length && target.countCards("h") - suits.length < 2 && !suits.includes(suit)) { + return [1, 1]; } - }, - ai: { - effect: { - target(card, player, target) { - const suit = get.suit(card), - suits = target.getKnownCards(player).map(card => get.suit(card)); - if (suits.length && target.countCards("h") - suits.length < 2 && !suits.includes(suit)) { - return [1, 1]; - } - return [1, 0]; - }, - }, + return [1, 0]; }, }, }, @@ -3003,7 +3003,7 @@ const skills = { if (!storage) { return `一张牌结算结束后,若此牌的目标包括你,你可以选择一张手牌,此牌视为无距离次数限制的火【杀】并摸一张牌(你可额外摸一张牌并令此技能本阶段失效)。`; } - return `一张牌结算结束后,若此牌的目标包括你,你可以选择一张手牌,此颜色的牌不计入手牌上限并横置一名角色(你可额外横置一名角色并令此技能本阶段失效)。`; + return `一张牌结算结束后,若此牌的目标包括你,你可以选择一张手牌,令你此颜色的当前手牌不计入手牌上限并可横置一名角色(你可额外横置一名角色并令此技能本阶段失效)。`; }, }, trigger: { @@ -3015,7 +3015,7 @@ const skills = { async cost(event, trigger, player) { let prompt2; if (player.getStorage(event.skill, false)) { - prompt2 = "你可选择一张手牌,令此颜色牌不计入手牌上限并横置一名角色"; + prompt2 = "你可选择一张手牌,令你此颜色的当前手牌不计入手牌上限并可横置一名角色"; } else { prompt2 = "你可选择一张手牌,令此牌视为无距离次数限制的火【杀】并摸一张牌"; } @@ -3039,40 +3039,40 @@ const skills = { if (result?.control) { await player.draw(result.index + 1); if (result.index) { - player.tempBanSkill(name, { global: "phaseAnyAfter"}); + player.tempBanSkill(name, { global: "phaseAnyAfter" }); } } } else { const skill = `${name}_limit`; player.addSkill(skill); - player.markAuto(skill, get.color(cards[0])); + const cards2 = player.getCards("h", card => get.color(card) == get.color(cards[0]) && !card.hasGaintag(skill)); + if (cards2.length) { + player.addGaintag(cards2, skill); + } const targets = game.filterPlayer(current => !current.isLinked()); if (!targets?.length) { return; } - const result = targets.length > 1 ? await player - .chooseTarget("###隽谋:横置一名角色###你可横置两名角色并令此技能本阶段失效", (card, player, target) => { + const result = await player + .chooseTarget("###隽谋:是否横置一名角色?###你可横置两名角色并令此技能本阶段失效", (card, player, target) => { if (ui.selected.targets.length) { return 0; } return get.event("isLinked").includes(target); - }, [1, 2], true) + }, [1, 2]) .set("ai", target => { return get.effect(target, { name: "tiesuo" }, get.player(), get.player()); }) .set("isLinked", targets) - .forResult() : { - bool: true, - targets: targets, - } - if (result?.targets?.length) { + .forResult(); + if (result?.bool && result?.targets?.length) { player.line(result.targets, "yellow"); const func = async target => { await target.link(true); }; await game.doAsyncInOrder(result.targets, func); if (result.targets.length > 1) { - player.tempBanSkill(name, { global: "phaseAnyAfter"}); + player.tempBanSkill(name, { global: "phaseAnyAfter" }); } } } @@ -3107,8 +3107,6 @@ const skills = { } }, }, - forced: true, - popup: false, charlotte: true, firstDo: true, trigger: { @@ -3127,7 +3125,7 @@ const skills = { }) ); }, - async content(event, trigger, player) { + async cost(event, trigger, player) { trigger.addCount = false; const stat = player.getStat().card, name = trigger.card.name; @@ -3138,18 +3136,17 @@ const skills = { }, }, limit: { + name: "隽谋", onremove: true, charlotte: true, mod: { ignoredHandcard(card, player) { - const colors = player.getStorage("dcsbjunmou_limit"); - if (colors.includes(get.color(card))) { + if (card.hasGaintag("dcsbjunmou_limit")) { return true; } }, cardDiscardable(card, player, name) { - const colors = player.getStorage("dcsbjunmou_limit"); - if (name === "phaseDiscard" && colors.includes(get.color(card))) { + if (name === "phaseDiscard" && card.hasGaintag("dcsbjunmou_limit")) { return false; } }, @@ -3197,7 +3194,7 @@ const skills = { let { targets } = event; await player.recover(targets.length); while (true) { - targets = targets.filter(target => target.isIn() && target.countCards("h")); + targets = event.targets.filter(target => target.isIn() && target.countCards("h")); if (!targets.length) { break; } @@ -22899,6 +22896,7 @@ const skills = { target.storage["dcwumei_wake"][2].add(next); if (!trigger._finished) { trigger.finish(); + trigger._finished = true; trigger.untrigger(true); trigger._triggered = 5; if (!lib.onround.includes(lib.skill.dcwumei.onRound)) { diff --git a/character/xianding/translate.js b/character/xianding/translate.js index ec11d4a2f8..03ec1147ff 100644 --- a/character/xianding/translate.js +++ b/character/xianding/translate.js @@ -933,7 +933,7 @@ const translates = { dc_sb_luxun: "新杀谋陆逊", dc_sb_luxun_prefix: "新杀谋", dcsbjunmou: "隽谋", - dcsbjunmou_info: "转换技。①游戏开始时,你可以转换此技能状态;②一张牌结算结束后,若此牌的目标包括你,你可以选择一张手牌,阳:此牌视为无距离次数限制的火【杀】并摸一张牌(你可额外摸一张牌并令此技能本阶段失效);阴:此颜色的牌不计入手牌上限并横置一名角色(你可额外横置一名角色并令此技能本阶段失效)。", + dcsbjunmou_info: "转换技。①游戏开始时,你可以转换此技能状态;②一张牌结算结束后,若此牌的目标包括你,你可以选择一张手牌,阳:此牌视为无距离次数限制的火【杀】并摸一张牌(你可额外摸一张牌并令此技能本阶段失效);阴:令你此颜色的当前手牌不计入手牌上限并可横置一名角色(你可额外横置一名角色并令此技能本阶段失效)。", dcsbzhanyan: "绽炎", dcsbzhanyan_info: "限定技,出牌阶段,你可选择任意名横置的其他角色并回复等量体力,然后这些角色同时展示一张手牌,你可弃置相同花色牌并对展示对应花色的角色各造成1点火焰伤害,若这些角色均受到伤害则重复此流程, 且此技能结算期间你每失去一张牌则摸一张牌。", dongxu: "董絮", @@ -976,7 +976,9 @@ const translates = { dc_sb_xusheng_prefix: "新杀谋", dc_sb_xusheng: "新杀谋徐盛", dcsbqinqiang: "勤强", - dcsbqinqiang_info: "结束阶段,你可以弃置至多四张手牌,然后摸两倍数量的牌。若如此做,直到你的下回合开始,其他角色使用牌指定你为目标后,若此牌花色是你手牌中最多的花色,你弃置其中一张牌;若你手中没有此花色的牌,此牌结算后你获得之。", + dcsbqinqiang_info: "结束阶段,你可以弃置至多四张手牌,然后摸两倍数量的牌。", + dcsbyizhen: "疑阵", + dcsbyizhen_info: "其他角色使用牌指定你为目标后,若此牌花色在你手牌中:唯一最多,你弃置此花色的一张牌;最少,此牌结算后你获得之。", xuwen: "徐妏", dcfuhui: "赋绘", dcfuhui_info: "每种牌名每回合限一次,你可将两张不同花色的手牌当作任意一张基本牌或普通锦囊牌使用。若这两张手牌的花色组合为本回合首次使用,你摸一张牌。", diff --git a/character/yijiang/skill.js b/character/yijiang/skill.js index a681fa45a2..1a4c34f391 100644 --- a/character/yijiang/skill.js +++ b/character/yijiang/skill.js @@ -10603,12 +10603,13 @@ const skills = { }, xiantu: { audio: 2, - group: ["xiantu1", "xiantu2"], - }, - xiantu1: { - audio: true, + logAudio(event) { + if (typeof event == "string") { + return "xiantu2.mp3"; + } + return 1; + }, trigger: { global: "phaseUseBegin" }, - sourceSkill: "xiantu", filter(event, player) { return event.player != player; }, @@ -10632,69 +10633,52 @@ const skills = { } return true; }, - content() { - "step 0"; + async content(event, trigger, player) { + const target = event.targets[0]; if (get.mode() !== "identity" || player.identity !== "nei") { player.addExpose(0.2); } - player.draw(2); - "step 1"; - player.chooseCard(2, "he", true, "交给" + get.translation(trigger.player) + "两张牌").set("ai", function (card) { - if (ui.selected.cards.length && card.name == ui.selected.cards[0].name) { - return -1; - } - if (get.tag(card, "damage")) { - return 1; - } - if (get.type(card) == "equip") { - return 1; - } - return 0; - }); - "step 2"; - player.give(result.cards, trigger.player); - trigger.player.addSkill("xiantu4"); - trigger.player.storage.xiantu4.push(player); + await player.draw(2); + const result = await player + .chooseCard(2, "he", true, `交给${get.translation(target)}两张牌`) + .set("ai", card => { + if (ui.selected.cards.length && card.name == ui.selected.cards[0].name) { + return -1; + } + if (get.tag(card, "damage")) { + return 1; + } + if (get.type(card) == "equip") { + return 1; + } + return 0; + }) + .forResult(); + if (result?.bool && result.cards?.length) { + player.give(result.cards, target); + player + .when({ + global: "phaseAnyEnd", + }) + .filter(evt => evt == event.getParent(evt.name, true, true)) + .step(async (event, trigger, player) => { + if (game.hasGlobalHistory("everything", evt => { + if (evt.name != "die" || evt.source != target) { + return false; + } + return evt.getParent(trigger.name, true) == trigger; + })) { + return; + } + player.logSkill("xiantu", null, null, null, ["loseHp"]); + await player.loseHp(); + }); + } }, ai: { threaten: 1.1, }, }, - xiantu2: { audio: true }, - xiantu4: { - trigger: { player: "phaseUseEnd" }, - forced: true, - audio: false, - onremove: true, - sourceSkill: "xiantu", - init(player, skill) { - if (!player.storage[skill]) { - player.storage[skill] = []; - } - }, - charlotte: true, - content() { - while (player.storage.xiantu4.length) { - var current = player.storage.xiantu4.shift(); - if (current.isDead()) { - continue; - } - current.logSkill("xiantu2"); - current.loseHp(); - } - player.removeSkill("xiantu4"); - }, - group: "xiantu3", - }, - xiantu3: { - trigger: { source: "dieAfter" }, - forced: true, - audio: false, - sourceSkill: "xiantu", - content() { - player.removeSkill("xiantu4"); - }, - }, qiangzhi: { audio: 2, audioname: ["re_zhangsong"], diff --git a/character/yijiang/translate.js b/character/yijiang/translate.js index b82cc1d877..e25cf68c34 100644 --- a/character/yijiang/translate.js +++ b/character/yijiang/translate.js @@ -380,9 +380,6 @@ const translates = { qiangzhi_draw: "强识", qiangzhi_info: "出牌阶段开始时,你可以展示一名其他角色的一张手牌。若如此做,当你于此阶段内使用与此牌类别相同的牌时,你可以摸一张牌。", xiantu: "献图", - xiantu1: "献图", - xiantu2: "献图", - xiantu3: "献图", xiantu_info: "一名其他角色的出牌阶段开始时,你可以摸两张牌,然后交给其两张牌。若如此做,此阶段结束时,若该角色未于此阶段内杀死过角色,则你失去1点体力。", dingpin: "定品", dingpin_info: "出牌阶段,你可以弃置一张手牌,然后令一名已受伤的角色判定,若结果为黑色,该角色摸X张牌(X为该角色已损失的体力值),然后你本回合不能再对其发动〖定品〗;若结果为红色,你翻面(你不能弃置本回合已弃置或使用过的类型的牌)。", diff --git a/image/card/baipidao.png b/image/card/baipidao.png new file mode 100644 index 0000000000..ae9a40b95f Binary files /dev/null and b/image/card/baipidao.png differ diff --git a/image/character/wxdl_caocao.jpg b/image/character/wxdl_caocao.jpg new file mode 100644 index 0000000000..e44824f268 Binary files /dev/null and b/image/character/wxdl_caocao.jpg differ diff --git a/image/character/xia_caopi.jpg b/image/character/xia_caopi.jpg new file mode 100644 index 0000000000..8a20694ce2 Binary files /dev/null and b/image/character/xia_caopi.jpg differ diff --git a/mode/chess.js b/mode/chess.js index 7a0e150404..5a29c28f2c 100644 --- a/mode/chess.js +++ b/mode/chess.js @@ -5482,7 +5482,7 @@ export default () => { }, }, }, - zhiming: { + zhimingx: { trigger: { source: "damageBegin1" }, filter: function (event, player) { return get.distance(event.player, player, "attack") > 1 && event.card && event.card.name == "sha"; @@ -6072,8 +6072,8 @@ export default () => { lingdong_info: "结束阶段,你可以移动至多X格(X为你本回合内使用【杀】的次数)。", lianshe: "箭舞", lianshe_info: "当你于一回合内首次使用【杀】时,你可以摸一张牌;你的回合内,当你使用一张不为【杀】的牌时,你令本回合内使用【杀】的次数上限+1。", - zhiming: "穿杨", - zhiming_info: "锁定技,当你使用【杀】造成伤害时,若你不在目标角色的攻击范围内,此伤害+1。", + zhimingx: "穿杨", + zhimingx_info: "锁定技,当你使用【杀】造成伤害时,若你不在目标角色的攻击范围内,此伤害+1。", sanjiansheji: "散箭", sanjiansheji_info: "你可以将两张【杀】当做【杀】使用,你以此法使用的【杀】可以指定距离5格内的角色为目标。", guanchuan: "强弩", @@ -6515,7 +6515,7 @@ export default () => { sex: "male", group: "wei", hp: 4, - skills: ["gongji", "zhiming"], + skills: ["gongji", "zhimingx"], }, chess_huangzhong: { sex: "male", diff --git a/noname/game/index.js b/noname/game/index.js index 8dba37c178..13880e7837 100644 --- a/noname/game/index.js +++ b/noname/game/index.js @@ -10549,7 +10549,7 @@ export class Game extends GameCompatible { * * @param { Player[] } targets 需要执行async方法的目标 * @param { (player: Player, i: number) => Promise } asyncFunc 需要执行的async方法 - * @param { (a: Player, b: Player) => number } sort 排序器,默认为lib.sort.seat + * @param { (a: Player, b: Player) => number } [sort] 排序器,默认为lib.sort.seat */ async doAsyncInOrder(targets, asyncFunc, sort) { if (!sort) { @@ -10572,6 +10572,7 @@ export class Game extends GameCompatible { chooseAnyOL(targets, func, args) { const next = game.createEvent("chooseAnyOL"); next.targets = targets; + next.player = _status.event.player; next.func = func; next.args = args; next.setContent("chooseAnyOL"); diff --git a/noname/get/index.js b/noname/get/index.js index 8d4293e43b..ac39b62396 100644 --- a/noname/get/index.js +++ b/noname/get/index.js @@ -4969,6 +4969,30 @@ else if (entry[1] !== void 0) stringifying[key] = JSON.stringify(entry[1]);*/ uiintro.addText(get.colorspan(lib.characterAppend[node.name])); } + if (lib.config.show_sortPack) { + for (let packname in lib.characterPack) { + if (node.name in lib.characterPack[packname]) { + let pack = lib.translate[packname + '_character_config'], + sort; + if (lib.characterSort[packname]) { + let sorted = lib.characterSort[packname]; + for (let sortname in sorted) { + if (sorted[sortname].includes(node.name)) { + sort = `${lib.translate[sortname]}`; + break; + } + } + } + const sortPack = document.createElement("div"); + sortPack.innerHTML = `${pack}${sort ? `
    [${sort}]` : ""}`; + sortPack.appendChild(document.createElement("hr")); + sortPack.insertBefore(document.createElement("hr"), sortPack.firstChild); + uiintro.add(sortPack); + break; + } + } + } + if (get.characterInitFilter(node.name)) { const initFilters = get.characterInitFilter(node.name).filter(tag => { if (!lib.characterInitFilter[node.name]) { @@ -5333,6 +5357,7 @@ else if (entry[1] !== void 0) stringifying[key] = JSON.stringify(entry[1]);*/ if (lib.config.show_favourite && lib.character[node.name] && game.players.includes(node) && (!modepack || !modepack[node.name]) && (!simple || get.is.phoneLayout())) { var addFavourite = ui.create.div(".text.center.pointerdiv"); addFavourite.link = node.name; + addFavourite.style.marginRight = "15px"; if (lib.config.favouriteCharacter.includes(node.name)) { addFavourite.innerHTML = "移除收藏"; } else { @@ -5341,6 +5366,17 @@ else if (entry[1] !== void 0) stringifying[key] = JSON.stringify(entry[1]);*/ addFavourite.listen(ui.click.favouriteCharacter); uiintro.add(addFavourite); } + if (!simple || get.is.phoneLayout()) { + let viewInfo = ui.create.div(".text.center.pointerdiv"); + viewInfo.link = node; + viewInfo.innerHTML = "查看资料"; + viewInfo.listen(function() { + let player = this.link; + let audioName = player.skin.name || player.name1 || player.name; + ui.click.charactercard(player.name1 || player.name, null, null, true, player.node, audioName); + }); + uiintro.add(viewInfo); + } if (!simple || get.is.phoneLayout()) { if ((lib.config.change_skin || lib.skin) && !node.isUnseen()) { var num = 1; @@ -5776,6 +5812,30 @@ else if (entry[1] !== void 0) stringifying[key] = JSON.stringify(entry[1]);*/ uiintro.addText(get.colorspan(lib.characterAppend[node.link])); } + if (lib.config.show_sortPack) { + for (let packname in lib.characterPack) { + if (node.link in lib.characterPack[packname]) { + let pack = lib.translate[packname + '_character_config'], + sort; + if (lib.characterSort[packname]) { + let sorted = lib.characterSort[packname]; + for (let sortname in sorted) { + if (sorted[sortname].includes(node.link)) { + sort = `[${lib.translate[sortname]}]`; + break; + } + } + } + const sortPack = document.createElement("div"); + sortPack.innerHTML = `${pack}${sort ? `
    ${sort}` : ""}`; + sortPack.appendChild(document.createElement("hr")); + sortPack.insertBefore(document.createElement("hr"), sortPack.firstChild); + uiintro.add(sortPack); + break; + } + } + } + if (get.characterInitFilter(node.link)) { const initFilters = get.characterInitFilter(node.link).filter(tag => { if (!lib.characterInitFilter[node.link]) { @@ -5905,6 +5965,7 @@ else if (entry[1] !== void 0) stringifying[key] = JSON.stringify(entry[1]);*/ var addFavourite = ui.create.div(".text.center.pointerdiv"); addFavourite.link = node.link; addFavourite.style.marginBottom = "15px"; + addFavourite.style.marginRight = "15px"; if (lib.config.favouriteCharacter.includes(node.link)) { addFavourite.innerHTML = "移除收藏"; } else { @@ -5915,6 +5976,16 @@ else if (entry[1] !== void 0) stringifying[key] = JSON.stringify(entry[1]);*/ } else { uiintro.add(ui.create.div(".placeholder.slim")); } + if (!simple || get.is.phoneLayout()) { + let viewInfo = ui.create.div(".text.center.pointerdiv"); + viewInfo.link = node.link; + viewInfo.innerHTML = "查看资料"; + viewInfo.style.marginBottom = "15px"; + viewInfo.listen(function() { + return ui.click.charactercard(this.link, this); + }); + uiintro.add(viewInfo); + } var addskin = false; if (node.parentNode.classList.contains("menu-buttons")) { addskin = !lib.config.show_charactercard; diff --git a/noname/library/element/content.js b/noname/library/element/content.js index d3358d2ad5..afd3466e64 100644 --- a/noname/library/element/content.js +++ b/noname/library/element/content.js @@ -3763,7 +3763,7 @@ player.removeVirtualEquip(card); if ( !card?.cards.some(card => { return get.position(card, true) !== "o"; - }) + }) && target.canAddJudge(card) ) { target.addJudge(card, cards); } diff --git a/noname/library/element/gameEvent.js b/noname/library/element/gameEvent.js index 1946a1a2f2..51b865e043 100644 --- a/noname/library/element/gameEvent.js +++ b/noname/library/element/gameEvent.js @@ -980,7 +980,9 @@ export class GameEvent { doneList: [], }; const doingList = []; - const roles = ["player", "source", "target", "global"]; + const roles = ["player", "source", "target", "global"], + map = lib.relatedTrigger, + names = Object.keys(map); const playerMap = game.players.concat(game.dead).sortBySeat(start); let player = start; let allbool = false; @@ -1061,10 +1063,22 @@ export class GameEvent { if (role !== "global" && player !== event[role]) { return false; } + const checkTrigger = trigger => { + if (trigger == name) { + return true; + } + const evt = names.find(evt => trigger?.startsWith(evt)); + if (!evt) { + return false; + } + return map[evt].some(rawTrigger => { + return `${rawTrigger}${trigger.slice(evt.length)}` == name; + }); + } if (Array.isArray(expire[role])) { - return expire[role].includes(name); + return expire[role].length && expire[role].some(checkTrigger); } - return expire[role] === name; + return checkTrigger(expire[role]); }); } }) diff --git a/noname/library/element/player.js b/noname/library/element/player.js index 1493339af1..359202e2a4 100644 --- a/noname/library/element/player.js +++ b/noname/library/element/player.js @@ -10836,7 +10836,8 @@ export class Player extends HTMLDivElement { expire = { global: expire }; } this.tempSkills[skill] = expire; - + const map = lib.relatedTrigger, + names = Object.keys(map); if (get.objtype(expire) == "object") { const roles = ["player", "source", "target", "global"]; for (const i of roles) { @@ -10844,7 +10845,15 @@ export class Player extends HTMLDivElement { if (!Array.isArray(triggers)) { triggers = [triggers]; } - triggers.forEach(trigger => (lib.hookmap[trigger] = true)); + triggers.forEach(trigger => { + lib.hookmap[trigger] = true; + const key = names.find(name => trigger?.startsWith(name)); + if (key) { + map[key].forEach(rawTrigger => { + lib.hookmap[`${rawTrigger}${trigger.slice(key.length)}`] = true; + }); + } + }); } } game.broadcast( diff --git a/noname/library/index.js b/noname/library/index.js index 941868dde3..9c675ea95d 100644 --- a/noname/library/index.js +++ b/noname/library/index.js @@ -4714,6 +4714,15 @@ export class Library { document.documentElement.style.setProperty("--tip-display", bool ? "flex" : "none"); }, }, + show_sortPack: { + name: "显示武将分包", + intro: "开启后,长按/右键查看武将信息时将显示武将所在分包", + init: false, + unfrequent: true, + onclick(bool) { + game.saveConfig("show_sortPack", bool); + }, + }, show_deckMonitor: { name: "显示记牌器", init: true, @@ -11630,6 +11639,9 @@ export class Library { if (typeof event != "string") { event = event.getParent().name; } + if (player == target && !lib.filter.cardDiscardable(card, player, event)) { + return false; + } var mod = game.checkMod(card, player, target, event, "unchanged", "canBeDiscarded", target); if (mod != "unchanged") { return mod; @@ -14656,6 +14668,14 @@ export class Library { nature: "firemm", }, ], + [ + "文心雕龙", + { + showName: "文", + color: "#ffffff", + nature: "firemm", + }, + ], [ "26", { diff --git a/noname/library/poptip.js b/noname/library/poptip.js index ea2d4f9997..104ca9942d 100644 --- a/noname/library/poptip.js +++ b/noname/library/poptip.js @@ -15,6 +15,7 @@ const _poptipMap = new Map([ ["rule_beishui", { name: "背水", info: "背水是一种特殊的选项。发动技能时,若无法执行背水的后果,则无法选择背水。选择背水时,可将该技能的其余选项依次执行,再执行背水的后果。" }], ["rule_zhengsu", { name: "整肃", info: "技能发动者从擂进、变阵、鸣止中选择一项令目标执行,若其于其回合弃牌阶段结束后未整肃失败,则获得“整肃奖励”。
  • 整肃奖励:选择一项:1. 摸两张牌;2.回复1点体力。
  • 擂进:出牌阶段内,使用过至少三张牌,且这些牌的点数均严格递增。
  • 变阵:出牌阶段内,使用过至少两张牌,且这些牌的花色均相同。
  • 鸣止:弃牌阶段内,弃置过至少两张牌,且这些牌的花色均不相同。" }], ["rule_xieli", { name: "协力", info: "技能发动者从同仇、并进、疏财、勠力中选择一项,然后直到技能时机结束,若你与选择的角色均完成了“协力”,根据技能执行协力奖励。
  • 同仇:你与其造成的伤害值之和不小于4。
  • 并进:你与其总计摸过至少8张牌。
  • 疏财:你与其弃置的牌中包含4种花色。
  • 勠力:你与其使用或打出的牌中包含4种花色。" }], + ["rule_rumo", { name: "入魔", info: "每局游戏限一次,当你满足条件后,可入魔。入魔后,每轮结束时,若本轮你未造成过伤害,你失去1点体力。" }], ["rule_bianshenji", { name: "变身技", info: `当你满足技能描述的条件时,你获得对应指示物。当该指示物达到上限时,你可以在对应的时间点进入变身状态;当该指示物消耗至0时,你退出变身状态。` }], ["rule_bianshen", { name: "变身", info: "进入变身状态时,弃置判定区里的所有牌。变身状态下替换武将牌,两张武将牌血量单独计算" }], ["rule_shifa", { name: "施法", info: "若技能的拥有者未拥有等待执行的同名“施法”效果,则其可以发动“施法”技能。其须选择声明一个数字X(X∈[1, 3]),在此之后的第X个回合结束时,其执行“施法”效果,且效果中的数字X视为与技能发动者声明的X相同。" }], diff --git a/noname/ui/click/index.js b/noname/ui/click/index.js index e15250451c..5708fbe6e0 100644 --- a/noname/ui/click/index.js +++ b/noname/ui/click/index.js @@ -4042,7 +4042,7 @@ export class Click { var initskill = false; let deri = []; for (var i = 0; i < list.length; i++) { - if (!get.info(list[i]) || get.info(list[i]).nopop) { + if (get.info(list[i])?.nopop) { continue; } if (!lib.translate[list[i]] || !lib.translate[list[i] + "_info"]) { @@ -4074,7 +4074,7 @@ export class Click { continue; } let info = get.info(skill); - if (!Object.keys(info)?.length || info.nopop) { + if (info?.nopop) { continue; } if (!lib.translate[skill] || !lib.translate[skill + "_info"]) {