import { lib, game, ui, get, ai, _status } from "../../noname.js"; /** @type { importCharacterConfig['skill'] } */ const skills = { //李昭焦伯 mbzuoyou: { audio: 2, enable: "phaseUse", usable: 1, zhuanhuanji: true, filterTarget(card, player, target) { if (player.storage.mbzuoyou) return target.countCards("h") >= 2; return true; }, async content(event, trigger, player) { const storage = player.storage.mbzuoyou, target = event.target; if (event.name === "mbzuoyou") player.changeZhuanhuanji("mbzuoyou"); if (!storage) { await target.draw(2); await target.chooseToDiscard(1, true, "h"); } else { await target.chooseToDiscard(target === player ? "佐佑" : `${get.translation(player)}对你发动了【佐佑】`, "请弃置两张手牌,然后获得1点护甲", 2, true); await target.changeHujia(1, null, true); } }, mark: true, marktext: "☯", intro: { content(storage, player) { if (!storage) return "转换技。出牌阶段限一次,你可以令一名角色摸两张牌,然后其弃置一张手牌。"; return "转换技。出牌阶段限一次,你可以令一名手牌数不少于二的角色弃置两张手牌,然后其获得1点护甲。"; }, }, ai: { order(item, player) { if ( player.storage.mbzuoyou && game.hasPlayer(current => { return current !== player && get.effect(current, "mbzuoyou", player, player) > 0; }) ) return get.order({ name: "zengbin" }) + 0.1; return 2; }, result: { target(player, target) { let eff = 0; if (player.storage.mbzuoyou) eff = target.hujia < 5 ? 1 : 0; else eff = 1; if (target === player && player.hasSkill("mbshishou")) eff /= 10; return eff; }, }, }, }, mbshishou: { audio: 2, trigger: { player: "useSkillAfter" }, filter(event, player) { return event.skill === "mbzuoyou" && !event.targets.includes(player); }, forced: true, async content(event, trigger, player) { await lib.skill.mbzuoyou.content( { target: player, }, {}, player ); }, ai: { combo: "mbzuoyou", }, }, //成济 mbkuangli: { audio: 2, trigger: { player: "phaseUseBegin" }, filter(event, player) { return game.hasPlayer(current => current !== player); }, forced: true, group: ["mbkuangli_target", "mbkuangli_remove"], async content(event, trigger, player) { let targets = game.filterPlayer(current => current !== player).randomSort(); targets = targets.slice(0, Math.ceil(Math.random() * targets.length)); targets.sortBySeat(); player.line(targets, "thunder"); targets.forEach(current => { current.addSkill("mbkuangli_mark"); }); await game.asyncDelayx(); }, subSkill: { target: { audio: "mbkuangli", trigger: { player: "useCardToPlayered" }, filter(event, player) { return event.target.hasSkill("mbkuangli_mark") && [player, event.target].some(current => current.countCards("he")); }, forced: true, logTarget: "target", usable: 2, async content(event, trigger, player) { const target = trigger.target; const playerCards = player.getCards("he", card => { return lib.filter.cardDiscardable(card, player, "mbkuangli"); }); if (playerCards.length > 0) await player.discard(playerCards.randomGet()); const targetCards = target.getCards("he", card => { return lib.filter.cardDiscardable(card, target, "mbkuangli"); }); if (targetCards.length > 0) await target.discard(targetCards.randomGet()); await game.asyncDelayx(); await player.draw(); await game.asyncDelayx(); }, ai: { effect: { player_use(card, player, target, current) { if (!target) return; const counttrigger = player.storage.counttrigger; if (counttrigger && counttrigger.mbkuangli_target && counttrigger.mbkuangli_target >= lib.skill.mbkuangli_target.usable) return; if (target.hasSkill("mbkuangli_mark")) { if (get.attitude(player, target) > 0) return 0.75; return 1.25; } }, }, }, }, remove: { audio: "mbkuangli", trigger: { player: "phaseEnd" }, filter(event, player) { return game.hasPlayer(current => current.hasSkill("mbkuangli_mark")); }, forced: true, async content(event, trigger, player) { game.countPlayer(current => { if (current.hasSkill("mbkuangli_mark")) { player.line(current); current.removeSkill("mbkuangli_mark"); } }); }, }, mark: { mark: true, marktext: "戾", charlotte: true, intro: { name: "狂戾", name2: "狂戾", content: "已拥有“狂戾”标记", }, }, }, }, mbxiongsi: { audio: 2, enable: "phaseUse", filter(event, player) { return player.countCards("h") >= 3; }, limited: true, skillAnimation: true, animationColor: "fire", filterCard: true, selectCard: [-1, -2], async content(event, trigger, player) { player.awakenSkill("mbxiongsi"); const targets = game.filterPlayer(current => current !== player); for (const target of targets) { player.line(target, "thunder"); await target.loseHp(); } }, ai: { order(item, player) { if (get.effect(player, "mbxiongsi", player) <= 0) return 1; if ( player.countCards("h") > 3 && player.countCards("h", card => { return player.hasValueTarget(card); }) > 0 ) return 0.1; return 8; }, result: { player(player) { let eff = 0; game.countPlayer(current => { let effx = get.effect(current, { name: "losehp" }, player, player); if (get.attitude(player, current) < -6 && current.getHp() <= 1) effx *= 1.3; eff += effx; }); eff *= player.getHp() + player.countCards("hs", card => player.canSaveCard(card, player)) <= 2 ? 1.5 : 0.35; eff -= player .getCards("h") .map(card => { if (lib.filter.cardDiscardable(card, player, "mbxiongsi")) return get.value(card); return 0; }) .reduce((p, c) => p + c, 0); if (eff > 0) return 2; return -1; }, }, }, }, //SP母兵脸 mbcuizhen: { trigger: { global: "phaseBefore", player: "enterGame", }, filter(event, player) { return ( (event.name != "phase" || game.phaseNumber == 0) && game.hasPlayer(current => { return current !== player && current.hasEnabledSlot(1); }) && get.mode() == "identity" ); }, async cost(event, trigger, player) { event.result = await player .chooseTarget(get.prompt("mbcuizhen"), "废除至多两名其他角色的武器栏", [1, 2], (card, player, target) => { return target !== player && target.hasEnabledSlot(1); }) .set("ai", target => { return -get.attitude(get.player(), target); }) .forResult(); }, group: ["mbcuizhen_inphase", "mbcuizhen_draw"], async content(event, trigger, player) { const targets = event.targets.slice().sortBySeat(); for (const target of targets) { await target.disableEquip(1); } await game.asyncDelay(); }, subSkill: { inphase: { audio: "mbcuizhen", trigger: { player: "useCardToPlayered", }, filter(event, player) { if (!player.isPhaseUsing()) return false; if (!get.tag(event.card, "damage")) return false; const target = event.target; return target !== player && target.countCards("h") >= target.getHp() && target.hasEnabledSlot(1); }, prompt2: "废除其的武器栏", logTarget: "target", check(event, player) { return get.attitude(player, event.target) <= 0; }, async content(event, trigger, player) { await trigger.target.disableEquip(1); await game.asyncDelayx(); }, }, draw: { audio: "mbcuizhen", trigger: { player: "phaseDrawBegin2" }, forced: true, locked: false, filter(event, player) { return ( !event.numFixed && game.hasPlayer(current => { return current.hasDisabledSlot(1); }) ); }, async content(event, trigger, player) { trigger.num += Math.min( 2, game.countPlayer(current => { return current.countDisabledSlot(1); }) ); }, }, }, }, mbkuili: { audio: 2, trigger: { player: "damageEnd", }, filter(event, player) { return player.countCards("h") > 0 || (event.source && event.source.isIn() && event.source.hasDisabledSlot(1)); }, forced: true, async content(event, trigger, player) { if (player.countCards("h") > 0) { await player.chooseToDiscard(`溃离:请弃置${get.cnNumber(trigger.num)}张手牌`, trigger.num, true); } const source = trigger.source; if (source && source.isIn() && source.hasDisabledSlot(1)) { player.line(source, "green"); await source.enableEquip(1, player); } }, ai: { neg: true, }, }, //曹髦 史?! mbqianlong: { audio: 6, trigger: { player: ["mbqianlong_beginAfter", "mbqianlong_addAfter", "mbweitongAfter"], }, filter(event, player) { let skills = []; if (player.additionalSkills && player.additionalSkills.mbqianlong) skills.addArray(player.additionalSkills.mbqianlong); return player.countMark("mbqianlong") >= 25 * skills.length; }, forced: true, locked: false, beginMarkCount: 20, maxMarkCount: 100, derivation: ["mbcmqingzheng", "mbcmjiushi", "mbcmfangzhu", "mbjuejin"], addMark(player, num) { num = Math.min(num, lib.skill.mbqianlong.maxMarkCount - player.countMark("mbqianlong")); player.addMark("mbqianlong", num); }, group: ["mbqianlong_begin", "mbqianlong_add"], async content(event, trigger, player) { player.addAdditionalSkill("mbqianlong", lib.skill.mbqianlong.derivation.slice(0, Math.floor(player.countMark("mbqianlong") / 25))); }, marktext: "道", intro: { name: "道心(潜龙)", name2: "道心", content: "当前道心数为#", }, subSkill: { begin: { audio: "mbqianlong", trigger: { global: "phaseBefore", player: "enterGame", }, filter(event, player) { return event.name != "phase" || game.phaseNumber == 0; }, forced: true, locked: false, async content(event, trigger, player) { lib.skill.mbqianlong.addMark(player, lib.skill.mbqianlong.beginMarkCount); }, }, add: { audio: "mbqianlong", trigger: { player: ["gainAfter", "damageEnd"], source: "damageSource", global: "loseAsyncAfter", }, filter(event, player) { if (player.countMark("mbqianlong") >= lib.skill.mbqianlong.maxMarkCount) return false; if (event.name === "damage") return event.num > 0; return event.getg(player).length > 0; }, getIndex(event, player, triggername) { if (event.name === "damage") return event.num; return 1; }, forced: true, locked: false, async content(event, trigger, player) { let toAdd = 5 * (1 + (trigger.name === "damage") + (event.triggername === "damageSource")); lib.skill.mbqianlong.addMark(player, toAdd); }, }, }, }, mbweitong: { audio: 1, trigger: { global: "phaseBefore", player: "enterGame", }, filter(event, player) { return ( (event.name != "phase" || game.phaseNumber == 0) && game.hasPlayer(current => { return current !== player && current.group === "wei" && player.hasZhuSkill("mbweitong", current); }) ); }, zhuSkill: true, forced: true, locked: false, async content(event, trigger, player) { lib.skill.mbqianlong.addMark( player, 20 * game.countPlayer(current => { return current !== player && current.group === "wei" && player.hasZhuSkill("mbweitong", current); }) ); }, ai: { combo: "mbqianlong", }, }, mbcmqingzheng: { audio: "sbqingzheng", audioname: ["mb_caomao"], trigger: { player: "phaseUseBegin" }, filter(event, player) { return player.countCards("h") > 0; }, direct: true, content() { "step 0"; var num = 2; var prompt = "###" + get.prompt("sbqingzheng") + "###弃置" + get.cnNumber(num) + "种花色的所有牌"; var next = player.chooseButton([prompt, [lib.suit.map(i => ["", "", "lukai_" + i]), "vcard"]], num); next.set("filterButton", button => { var player = _status.event.player; var cards = player.getCards("h", { suit: button.link[2].slice(6) }); return cards.length > 0 && cards.filter(card => lib.filter.cardDiscardable(card, player, "sbqingzheng")).length == cards.length; }); next.set("ai", button => { var player = _status.event.player; return ( 15 - player .getCards("h", { suit: button.link[2].slice(6) }) .map(i => get.value(i)) .reduce((p, c) => p + c, 0) ); }); next.set("custom", { replace: { button: function (button) { if (!_status.event.isMine()) return; if (button.classList.contains("selectable") == false) return; var cards = _status.event.player.getCards("h", { suit: button.link[2].slice(6), }); if (cards.length) { var chosen = cards.filter(i => ui.selected.cards.includes(i)).length == cards.length; if (chosen) { ui.selected.cards.removeArray(cards); cards.forEach(card => { card.classList.remove("selected"); card.updateTransform(false); }); } else { ui.selected.cards.addArray(cards); cards.forEach(card => { card.classList.add("selected"); card.updateTransform(true); }); } } if (button.classList.contains("selected")) { ui.selected.buttons.remove(button); button.classList.remove("selected"); if (_status.multitarget || _status.event.complexSelect) { game.uncheck(); game.check(); } } else { button.classList.add("selected"); ui.selected.buttons.add(button); } var custom = _status.event.custom; if (custom && custom.add && custom.add.button) { custom.add.button(); } game.check(); }, }, add: next.custom.add, }); "step 1"; if (result.bool) { var cards = result.cards; if (!cards.length) { var suits = result.links.map(i => i[2].slice(6)); cards = player.getCards("h", card => suits.includes(get.suit(card, player))); } event.cards = cards; if (!cards.length) event.finish(); else player .chooseTarget("清正:观看一名其他角色的手牌并弃置其中一种花色的所有牌", (card, player, target) => { return target != player && target.countCards("h"); }) .set("ai", target => { var player = _status.event.player, att = get.attitude(player, target); if (att >= 0) return 0; return 1 - att / 2 + Math.sqrt(target.countCards("h")); }); } else event.finish(); "step 2"; if (result.bool) { var target = result.targets[0]; event.target = target; player.logSkill("sbqingzheng", target); player.discard(cards); var list = []; var dialog = ["清正:弃置" + get.translation(target) + "一种花色的所有牌"]; for (var suit of lib.suit.concat("none")) { if (target.countCards("h", { suit: suit })) { dialog.push('
' + get.translation(suit + "2") + "牌
"); dialog.push(target.getCards("h", { suit: suit })); list.push(suit); } } if (list.length) { player .chooseControl(list) .set("dialog", dialog) .set("ai", () => { return _status.event.control; }) .set( "control", (() => { var getv = cards => cards.map(i => get.value(i)).reduce((p, c) => p + c, 0); return list.sort((a, b) => { return getv(target.getCards("h", { suit: b })) - getv(target.getCards("h", { suit: a })); })[0]; })() ); } } else event.finish(); "step 3"; var cards2 = target.getCards("h", { suit: result.control }); event.cards2 = cards2; target.discard(cards2, "notBySelf").set("discarder", player); "step 4"; if (event.cards2.length < cards.length) target.damage(); }, }, mbcmjiushi: { audio: "rejiushi", inherit: "rejiushi", group: ["rejiushi1", "mbcmjiushi_check", "mbcmjiushi_turnback", "mbcmjiushi_gain"], subSkill: { check: { trigger: { player: "damageBegin3" }, silent: true, firstDo: true, filter(event, player) { return player.isTurnedOver(); }, content() { trigger.mbcmjiushi = true; }, }, turnback: { audio: "rejiushi", audioname: ["mb_caomao"], trigger: { player: "damageEnd" }, check(event, player) { return player.isTurnedOver(); }, filter(event, player) { return event.mbcmjiushi; }, prompt(event, player) { return "是否发动【酒诗】,将武将牌翻面?"; }, content() { delete trigger.mbcmjiushi; player.turnOver(); }, }, gain: { audio: "rejiushi", audioname: ["mb_caomao"], trigger: { player: "turnOverAfter" }, frequent: true, prompt: "是否发动【酒诗】,获得牌堆中的一张锦囊牌?", content() { var card = get.cardPile2(function (card) { return get.type2(card) == "trick"; }); if (card) player.gain(card, "gain2"); }, }, }, }, mbcmfangzhu: { audio: "sbfangzhu", audioname: ["mb_caomao"], inherit: "sbfangzhu", filter(event, player) { return game.hasPlayer(current => current !== player); }, usable: 1, chooseButton: { dialog() { const dialog = ui.create.dialog("放逐:令一名其他角色...", "hidden"); dialog.add([ [ [1, "不能使用手牌中的非锦囊牌直到其回合结束"], [2, "非Charlotte技能失效直到其回合结束"], ], "textbutton", ]); return dialog; }, check(button) { const player = get.player(); if (button.link === 2) { if ( game.hasPlayer(target => { if (target.hasSkill("mbcmfangzhu_ban") || target.hasSkill("fengyin") || target.hasSkill("baiban")) return false; return ( get.attitude(player, target) < 0 && ["name", "name1", "name2"] .map((sum, name) => { if (target[name] && (name != "name1" || target.name != target.name1)) { if (get.character(target[name])) return get.rank(target[name], true); } return 0; }) .reduce((p, c) => { return p + c; }, 0) > 5 ); }) ) return 6; } return button.link === 1 ? 1 : 0; }, backup(links, player) { return { num: links[0], audio: "sbfangzhu", filterCard: () => false, selectCard: -1, filterTarget(card, player, target) { if (target == player) return false; const num = lib.skill.mbcmfangzhu_backup.num, storage = target.getStorage("mbcmfangzhu_ban"); return num != 1 || !storage.length; }, async content(event, trigger, player) { const target = event.target; const num = lib.skill.mbcmfangzhu_backup.num; switch (num) { case 1: target.addTempSkill("mbcmfangzhu_ban", { player: "phaseEnd" }); target.markAuto("mbcmfangzhu_ban", ["trick"]); break; case 2: target.addTempSkill("mbcmfangzhu_baiban", { player: "phaseEnd" }); break; } }, ai: { result: { target(player, target) { switch (lib.skill.mbcmfangzhu_backup.num) { case 1: return -target.countCards("h", card => get.type(card) != "trick") - 1; case 2: return -target.getSkills(null, null, false).reduce((sum, skill) => { return sum + Math.max(get.skillRank(skill, "out"), get.skillRank(skill, "in")); }, 0); } }, }, }, }; }, prompt(links, player) { const str = "###放逐###"; switch (links[0]) { case 1: return str + "令一名其他角色不能使用手牌中的非锦囊牌直到其回合结束"; case 2: return str + "令一名其他角色的非Charlotte技能失效直到其回合结束"; } }, }, ai: { order: 10, result: { player(player) { return game.hasPlayer(current => get.attitude(player, current) < 0) ? 1 : 0; }, }, }, subSkill: { backup: {}, baiban: { inherit: "baiban", marktext: "逐", }, ban: { charlotte: true, onremove: true, mark: true, marktext: "禁", intro: { markcount: () => 0, content(storage) { if (storage.length > 1) return "不能使用手牌"; return "不能使用手牌中的非" + get.translation(storage[0]) + "牌"; }, }, mod: { cardEnabled(card, player) { const storage = player.getStorage("mbcmfangzhu_ban"); const hs = player.getCards("h"), cards = [card]; if (Array.isArray(card.cards)) cards.addArray(card.cards); if (cards.containsSome(...hs) && !storage.includes(get.type2(card))) return false; }, cardSavable(card, player) { const storage = player.getStorage("mbcmfangzhu_ban"); const hs = player.getCards("h"), cards = [card]; if (Array.isArray(card.cards)) cards.addArray(card.cards); if (cards.containsSome(...hs) && !storage.includes(get.type2(card))) return false; }, }, }, }, }, mbjuejin: { audio: 2, enable: "phaseUse", limited: true, skillAnimation: true, animationColor: "thunder", filterCard: () => false, selectCard: [-1, -2], filterTarget: true, selectTarget: -1, multiline: true, async contentBefore(event, trigger, player) { player.awakenSkill("mbjuejin"); }, async content(event, trigger, player) { const target = event.target; const delt = target.getHp(true) - 1, num = Math.abs(delt); await target[delt > 0 ? "loseHp" : "recover"](num); if (num > 0) await target.changeHujia(num, null, true); }, async contentAfter(event, trigger, player) { game.addGlobalSkill("mbjuejin_xiangsicunwei"); player.$fullscreenpop("向死存魏!", "thunder"); }, ai: { order: 0.1, result: { player(player) { let eff = 1; game.countPlayer(current => { const att = get.attitude(player, current), num = Math.abs(current.getHp(true) - 1); const delt = Math.max(0, num + current.hujia - 5); eff -= att * delt; }); return eff > 0 ? 1 : 0; }, }, }, subSkill: { xiangsicunwei: { trigger: { global: ["loseAfter", "equipAfter", "loseAsyncAfter", "cardsDiscardAfter"], }, forced: true, silent: true, firstDo: true, filter(event, player) { const nameList = ["shan", "tao", "jiu"]; return event.getd().some(card => { return nameList.includes(get.name(card, false)) && get.position(card, true) === "d"; }); }, async content(event, trigger, player) { const nameList = ["shan", "tao", "jiu"]; const cards = trigger.getd().filter(card => { return nameList.includes(get.name(card, false)) && get.position(card, true) === "d"; }); await game.cardsGotoSpecial(cards); game.log(cards, "被移出了游戏"); }, }, }, }, //杨奉 mbxuetu: { audio: 2, audioname: ["re_yangfeng"], enable: "phaseUse", usable: 2, filter(event, player) { if (player.countMark("mbxuetu_status") !== 1 && player.getStat("skill").mbxuetu) return false; if (!player.storage.mbxuetu) return player.countCards("he"); return true; }, zhuanhuanji2(skill, player) { return player.countMark("mbxuetu_status") !== 1; }, filterCard(card, player) { if (player.countMark("mbxuetu_status") > 1) return false; if (player.countMark("mbxuetu_status") === 1) { if (player.getStorage("mbxuetu_used").includes(false)) return false; return true; } return !player.storage.mbxuetu; }, selectCard() { const player = get.player(); if (player.countMark("mbxuetu_status") > 1) return -1; if (player.countMark("mbxuetu_status") === 1) { if (player.getStorage("mbxuetu_used").includes(false)) return -1; if (player.getStorage("mbxuetu_used").includes(true)) return 1; return [0, 1]; } return !player.storage.mbxuetu ? 1 : -1; }, check(card) { return 6 - get.value(card); }, prompt() { const player = get.player(), storage = player.storage.mbxuetu, status = player.countMark("mbxuetu_status"); if (status === 0) { if (storage) return "转换技。出牌阶段限一次,你可以失去1点体力,然后令一名角色摸两张牌。"; return "转换技。出牌阶段限一次,你可以弃置一张牌,然后令一名角色回复1点体力。"; } else if (status === 1) { return "出牌阶段各限一次。⒈你可以弃置一张牌,然后令一名角色回复1点体力;⒉你可以失去1点体力,然后令一名角色摸两张牌。"; } else { if (storage) return "转换技。出牌阶段限一次,你可以摸一张牌,然后对一名角色造成1点伤害。"; return "转换技。出牌阶段限一次,你可以回复1点体力,然后令一名角色弃置两张牌。"; } }, position: "he", filterTarget: true, onremove: ["mbxuetu", "mbxuetu_status"], derivation: ["mbxuetu_achieve", "mbxuetu_fail"], async content(event, trigger, player) { const target = event.targets[0], storage = Boolean(player.storage.mbxuetu); const status = player.countMark("mbxuetu_status"); player.changeZhuanhuanji("mbxuetu"); if (status < 2) { if (!player.storage.mbxuetu_used) { player.when(["phaseUseAfter", "mbweiming_achieveAfter"]).then(() => { delete player.storage.mbxuetu_used; }); } player.markAuto("mbxuetu_used", [status === 0 ? storage : !event.cards.length]); if ((status === 0 && !storage) || (status === 1 && event.cards.length)) { await target.recover(); } else { await player.loseHp(); await target.draw(2); } } else { if (!storage) { await player.recover(); await target.chooseToDiscard(2, true, "he"); } else { await player.draw(); await target.damage(); } } }, mark: true, marktext: "☯", intro: { content: (storage, player) => { if (!player.countMark("mbxuetu_status")) { if (storage) return "转换技。出牌阶段限一次,你可以失去1点体力,然后令一名角色摸两张牌。"; return "转换技。出牌阶段限一次,你可以弃置一张牌,然后令一名角色回复1点体力。"; } else { if (storage) return "转换技。出牌阶段限一次,你可以摸一张牌,然后对一名角色造成1点伤害。"; return "转换技。出牌阶段限一次,你可以回复1点体力,然后令一名角色弃置两张牌。"; } }, }, ai: { order(item, player) { const status = player.countMark("mbxuetu_status"); if (status > 1) return Math.max(get.order({ name: "guohe" }), get.order({ name: "chuqibuyi" })); if (status === 1 || player.storage.mbxuetu) return 9; return 2; }, result: { target(player, target) { const status = player.countMark("mbxuetu_status"); if (status > 1) { if (player.storage.mbxuetu) return -get.damageEffect(target, player, player) / 10; return -2; } if ((status === 0 && player.storage.mbxuetu) || (status === 1 && !ui.selected.cards.length)) return 2; const eff = get.recoverEffect(target, player, player); return eff > 0 ? 2 : eff < 0 ? -get.sgnAttitude(player, target) : 0; }, player(player, target) { const status = player.countMark("mbxuetu_status"); if (status > 1) { if (player.storage.mbxuetu) return 1; return get.recoverEffect(player, player) / 6; } if (status === 1 || !player.storage.mbxuetu) return -0.5; const eff = get.effect(player, { name: "losehp" }, player, player); if (eff >= 0) return Math.min(1, eff / 2); const hp = player.getHp() + player.countCards("hes", card => { return player.canSaveCard(card, player); }); return -1.5 * Math.max(0, 3 - hp); }, }, }, }, mbweiming: { audio: 3, dutySkill: true, locked: true, group: ["mbweiming_achieve", "mbweiming_fail", "mbweiming_effect"], intro: { content: "已记录$", }, subSkill: { effect: { audio: "mbweiming1.mp3", trigger: { player: "phaseUseBegin", }, filter(event, player) { return game.hasPlayer(current => { return !player.getStorage("mbweiming").includes(current); }); }, forced: true, direct: true, async content(event, trigger, player) { const targets = await player .chooseTarget("威命:记录一名未记录过的角色", "当你杀死没有被记录过的角色后,则〖威命〗使命成功;如果在你杀死这些角色中的一名之前,有被记录过的角色死亡,则你〖威命〗使命失败。", true) .set("filterTarget", (card, player, target) => { return !player.getStorage("mbweiming").includes(target); }) .set("ai", target => { if (target === player) return 1; return 1 + (Math.sqrt(Math.abs(get.attitude(player, target))) * Math.abs(get.threaten(target))) / Math.sqrt(target.getHp() + 1) / Math.sqrt(target.countCards("hes") + 1); }) .forResultTargets(); if (targets && targets.length > 0) { const target = targets[0]; player.logSkill("mbweiming_effect", target); player.markAuto("mbweiming", target); } }, }, achieve: { audio: "mbweiming2.mp3", trigger: { source: "dieAfter", }, filter(event, player) { return !player.getStorage("mbweiming").includes(event.player); }, dutySkill: true, forced: true, skillAnimation: true, animationColor: "fire", async content(event, trigger, player) { game.log(player, "成功完成使命"); player.awakenSkill("mbweiming"); player.storage.mbxuetu_status = 1; player.unmarkSkill("mbxuetu"); await game.asyncDelayx(); }, }, fail: { audio: "mbweiming3.mp3", trigger: { global: "dieAfter", }, filter(event, player) { return player.getStorage("mbweiming").includes(event.player); }, dutySkill: true, forced: true, async content(event, trigger, player) { game.log(player, "使命失败"); player.awakenSkill("mbweiming"); player.storage.mbxuetu_status = 2; game.broadcastAll(player => { player.tempname.add("re_yangfeng"); }, player); await game.asyncDelayx(); }, }, }, ai: { combo: "mbxuetu", }, }, //霍骏 sidai: { audio: "twsidai", enable: "phaseUse", usable: 1, locked: false, limited: true, skillAnimation: true, animationColor: "fire", filter: function (event, player) { var cards = player.getCards("h", { type: "basic" }); if (!cards.length) return false; for (var i of cards) { if (!game.checkMod(i, player, "unchanged", "cardEnabled2", player)) return false; } return event.filterCard(get.autoViewAs({ name: "sha", storage: { sidai: true } }, cards), player, event); }, viewAs: { name: "sha", storage: { sidai: true } }, filterCard: { type: "basic" }, selectCard: -1, check: () => 1, onuse: function (result, player) { player.awakenSkill("sidai"); player.addTempSkill("sidai_tao"); player.addTempSkill("sidai_shan"); }, ai: { order: function (item, player) { return get.order({ name: "sha" }, player) + 0.1; }, result: { target: function (player, target) { var cards = ui.selected.cards.slice(0); var names = []; for (var i of cards) names.add(i.name); if (names.length < player.hp) return 0; if (player.hasUnknown() && (player.identity != "fan" || !target.isZhu)) return 0; if (get.attitude(player, target) >= 0) return -20; return lib.card.sha.ai.result.target.apply(this, arguments); }, }, }, subSkill: { tao: { trigger: { source: "damageSource" }, filter: function (event, player) { if (!event.card || !event.card.storage || !event.card.storage.sidai || !event.player.isIn()) return false; for (var i of event.cards) { if (i.name == "tao") return true; } return false; }, forced: true, popup: false, content: function () { trigger.player.loseMaxHp(); }, }, shan: { trigger: { player: "useCardToPlayered" }, filter: function (event, player) { if (!event.card || !event.card.storage || !event.card.storage.sidai || !event.target.isIn()) return false; for (var i of event.cards) { if (i.name == "shan") return true; } return false; }, forced: true, popup: false, content: function () { "step 0"; trigger.target.chooseToDiscard("h", { type: "basic" }, "弃置一张基本牌,否则不能响应" + get.translation(trigger.card)).set("ai", function (card) { var player = _status.event.player; if ( player.hasCard("hs", function (cardx) { return cardx != card && get.name(cardx, player) == "shan"; }) ) return 12 - get.value(card); return 0; }); "step 1"; if (!result.bool) trigger.directHit.add(trigger.target); }, }, }, }, jieyu: { audio: "twjieyu", trigger: { player: "phaseJieshuBegin" }, filter: function (event, player) { for (let i = 0; i < ui.discardPile.childElementCount; i++) { if (get.type(ui.discardPile.childNodes[i], false) == "basic") return true; } return false; }, prompt2: function (event, player) { const num = lib.skill.jieyu.getNum(player); return "获得弃牌堆中" + get.cnNumber(num) + "张" + (num > 1 ? "牌名各不相同的" : "") + "基本牌"; }, async content(event, trigger, player) { const num = lib.skill.jieyu.getNum(player, event); let gains = [], names = []; for (let i = 0; i < ui.discardPile.childElementCount; i++) { let card = ui.discardPile.childNodes[i]; if (get.type(card, false) == "basic" && !names.includes(card.name)) { gains.push(card); names.push(card.name); } } if (gains.length) player.gain(gains.randomGets(Math.min(gains.length, num)), "gain2"); }, getNum: function (player, event) { let num = get.mode() == "identity" ? 3 : 4; const history = game.getAllGlobalHistory("everything"); for (let i = history.length - 1; i >= 0; i--) { const evt = history[i]; if (evt.name == "jieyu" && evt.player == player) { if (!event || evt != event) break; } if (evt.name == "useCard" && evt.player != player && evt.targets && evt.targets.includes(player) && get.tag(evt.card, "damage")) { num--; if (num == 1) break; } } return num; }, }, //木鹿大王 shoufa: { audio: 2, trigger: { player: "damageEnd", source: "damageSource", }, filter: function (event, player, name) { if (name == "damageSource" && player.getHistory("sourceDamage").indexOf(event) != 0) return false; return game.hasPlayer(target => { const num = get.mode() == "doudizhu" ? 1 : 2; if (name == "damageEnd" && get.distance(player, target) <= num) return false; if (name == "damageSource" && get.distance(player, target) > num) return false; const zhoufa = player.storage.zhoulin_zhoufa; if (!zhoufa) return true; if (zhoufa == "豹" || zhoufa == "兔") return true; if (zhoufa == "鹰") return target.countCards("he"); return target.countDiscardableCards(player, "e"); }); }, direct: true, async content(event, trigger, player) { const zhoufa = player.storage.zhoulin_zhoufa; const str = zhoufa ? ["令其受到1点无来源伤害", "你随机获得其一张牌", "你随机弃置其装备区的一张牌", "令其摸一张牌"][["豹", "鹰", "熊", "兔"].indexOf(zhoufa)] : "令其随机执行一个效果"; const nodoudizhu = get.mode() == "doudizhu" ? "距离" + (event.triggername == "damageEnd" ? "" : "不") + "大于1的" : "距离" + (event.triggername == "damageEnd" ? "" : "不") + "大于2的"; const { result: { bool, targets }, } = await player .chooseTarget(get.prompt("shoufa"), "选择一名" + nodoudizhu + "角色," + str, (card, player, target) => { const name = _status.event.triggername; const num = get.mode() == "doudizhu" ? 1 : 2; if (name == "damageEnd" && get.distance(player, target) <= num) return false; if (name == "damageSource" && get.distance(player, target) > num) return false; const zhoufa = player.storage.zhoulin_zhoufa; if (!zhoufa) return true; if (zhoufa == "豹" || zhoufa == "兔") return true; if (zhoufa == "鹰") return target.countCards("he"); return target.countDiscardableCards(player, "e"); }) .set("ai", target => { const player = _status.event.player; const zhoufa = player.storage.zhoulin_zhoufa; if (!zhoufa) return -get.attitude(player, target); switch (zhoufa) { case "豹": { return get.damageEffect(target, player, player); } case "鹰": { return get.effect(target, { name: "guohe_copy2" }, player, player); } case "熊": { let att = get.attitude(player, target), eff = 0; target.getCards("e", card => { var val = get.value(card, target); eff = Math.max(eff, -val * att); }); return eff; } case "兔": { return get.effect(target, { name: "draw" }, player, player); } } }) .set("triggername", event.triggername); if (!bool) return; const target = targets[0]; player.logSkill("shoufa", target); const shoufa = zhoufa ? zhoufa : ["豹", "鹰", "熊", "兔"].randomGet(); game.log(target, "执行", "#g" + shoufa, "效果"); switch (shoufa) { case "豹": target.damage("nosource"); break; case "鹰": player.gain(target.getGainableCards(player, "he").randomGet(), target, "giveAuto"); break; case "熊": target.discard(target.getGainableCards(player, "e").randomGet()).discarder = player; break; case "兔": target.draw(); break; } }, }, yuxiang: { mod: { globalFrom(from, to, distance) { if (from.hujia > 0) return distance - 1; }, globalTo(from, to, distance) { if (to.hujia > 0) return distance + 1; }, }, audio: true, trigger: { player: "damageBegin2" }, filter: function (event, player) { return player.hujia > 0 && event.hasNature("fire"); }, forced: true, async content(event, trigger, player) { trigger.num++; }, }, zhoulin: { audio: 2, limited: true, unique: true, enable: "phaseUse", skillAnimation: true, animationColor: "fire", async content(event, trigger, player) { player.awakenSkill("zhoulin"); player.changeHujia(2, null, true); const { result: { control }, } = await player .chooseControl("豹", "鹰", "熊", "兔") .set("ai", () => "豹") .set("prompt", "选择一个固定效果"); if (control) { player.popup(control); game.log(player, "选择了", "#g" + control, "效果"); player.addTempSkill("zhoulin_zhoufa"); player.storage.zhoulin_zhoufa = control; player.markSkill("zhoulin_zhoufa"); game.broadcastAll( function (player, zhoufa) { if (player.marks.zhoulin_zhoufa) player.marks.zhoulin_zhoufa.firstChild.innerHTML = zhoufa; }, player, control ); } }, ai: { order: 12, result: { player: 1 }, }, subSkill: { zhoufa: { charlotte: true, onremove: true, intro: { content: "已选择$效果" }, }, }, }, //陈珪 guimou: { audio: 2, trigger: { global: "phaseBefore", player: ["enterGame", "phaseEnd", "phaseZhunbeiBegin"], }, filter: function (event, player, name) { if (event.name == "phaseZhunbei" || name == "phaseEnd") return true; return event.name != "phase" || game.phaseNumber == 0; }, direct: true, locked: true, content: function* (event, map) { var player = map.player, trigger = map.trigger; if (trigger.name != "phaseZhunbei") { player.logSkill("guimou"); var result, choiceList = ["惩罚期间使用牌最少的角色", "惩罚期间弃置牌最少的角色", "惩罚期间得到牌最少的角色"]; if (trigger.name != "phase" || game.phaseNumber == 0) result = { index: get.rand(0, 2) }; else result = yield player .chooseControl() .set("choiceList", choiceList) .set("ai", () => get.rand(0, 2)); var str = choiceList[result.index]; game.log(player, "选择", "#g" + str); player.addSkill("guimou_" + result.index); return; } var targets = []; for (var i = 0; i <= 2; i++) { var skill = "guimou_" + i; if (player.hasSkill(skill)) { var storage = player.storage[skill], nums = storage[0].slice(); var targetx = nums.sort((a, b) => storage[1][storage[0].indexOf(a)] - storage[1][storage[0].indexOf(b)]); targetx = targetx.filter(target => storage[1][storage[0].indexOf(target)] == storage[1][storage[0].indexOf(targetx[0])]); targets.addArray(targetx); player.removeSkill(skill); } } targets = targets.filter(target => target != player && target.countCards("h")); if (targets.length) { var result = yield player .chooseTarget( "请选择【诡谋】的目标", "观看一名可选择的角色的手牌并选择其中一张牌,然后你可以此牌交给另一名其他角色或弃置此牌", (card, player, target) => { return _status.event.targets.includes(target) && target.countCards("h"); }, true ) .set("ai", target => { return Math.sqrt(Math.min(3, target.countCards("h"))) * get.effect(target, { name: "guohe_copy2" }, player, player); }) .set("targets", targets); if (result.bool) { var target = result.targets[0]; player.logSkill("guimou", target); player.addExpose(0.3); var result2 = yield player .choosePlayerCard(target, "h", "visible", true) .set("ai", button => { return get.value(button.link); }) .set("prompt", "诡谋:请选择" + get.translation(target) + "的一张手牌") .set("prompt2", '
将选择的牌交给另一名其他角色或弃置此牌
'); if (result2.bool) { var cards = result2.links.slice(), result3; if (!game.hasPlayer(targetx => targetx != player && targetx != target)) result3 = { bool: false }; else result3 = yield player .chooseTarget("是否令另一名其他角色获得" + get.translation(cards) + "?", (card, player, target) => { return target != player && target != _status.event.target; }) .set("ai", target => get.attitude(_status.event.player, target)) .set("target", target); if (result3.bool) { var targetx = result3.targets[0]; player.line(targetx); targetx.gain(cards, target, "give"); } else target.discard(cards).discarder = player; } } } }, subSkill: { 0: { charlotte: true, onremove: true, init: function (player, skill) { if (!player.storage[skill]) { player.storage[skill] = [[], []]; var targets = game.filterPlayer().sortBySeat(player); targets.forEach(target => { player.storage[skill][0].push(target); player.storage[skill][1].push(0); }); } }, mark: true, intro: { markcount: storage => 0, content: function (storage, player) { var str = "当前使用牌数排行榜"; var lose = storage[1].slice().sort((a, b) => a - b)[0]; storage[0].forEach(target => { str += "
  • "; var score = storage[1][storage[0].indexOf(target)]; if (score == lose) str += ""; str += " " + get.translation(target) + " "; str += score + "张"; if (score == lose) str += ""; }); return str; }, }, trigger: { global: "useCard1" }, forced: true, popup: false, content: function () { var storage = player.storage["guimou_0"]; if (!storage[0].includes(trigger.player)) { storage[0].push(trigger.player); storage[1].push(0); } storage[1][storage[0].indexOf(trigger.player)]++; }, }, 1: { charlotte: true, onremove: true, init: function (player, skill) { if (!player.storage[skill]) { player.storage[skill] = [[], []]; var targets = game.filterPlayer().sortBySeat(player); targets.forEach(target => { player.storage[skill][0].push(target); player.storage[skill][1].push(0); }); } }, mark: true, intro: { markcount: storage => 0, content: function (storage, player) { var str = "当前弃置牌数排行榜"; var lose = storage[1].slice().sort((a, b) => a - b)[0]; storage[0].forEach(target => { str += "
  • "; var score = storage[1][storage[0].indexOf(target)]; if (score == lose) str += ""; str += " " + get.translation(target) + " "; str += score + "张"; if (score == lose) str += ""; }); return str; }, }, trigger: { global: ["loseAfter", "loseAsyncAfter"] }, filter: function (event, player) { return event.type == "discard" && game.hasPlayer(target => event.getl(target).cards2.length); }, forced: true, popup: false, content: function () { var storage = player.storage["guimou_1"]; var targets = game.filterPlayer(target => trigger.getl(target).cards2.length); targets.forEach(target => { if (!storage[0].includes(target)) { storage[0].push(target); storage[1].push(0); } storage[1][storage[0].indexOf(target)] += trigger.getl(target).cards2.length; }); }, }, 2: { charlotte: true, onremove: true, init: function (player, skill) { if (!player.storage[skill]) { player.storage[skill] = [[], []]; var targets = game.filterPlayer().sortBySeat(player); targets.forEach(target => { player.storage[skill][0].push(target); player.storage[skill][1].push(0); }); } }, mark: true, intro: { markcount: storage => 0, content: function (storage, player) { var str = "当前得到牌数排行榜"; var lose = storage[1].slice().sort((a, b) => a - b)[0]; storage[0].forEach(target => { str += "
  • "; var score = storage[1][storage[0].indexOf(target)]; if (score == lose) str += ""; str += " " + get.translation(target) + " "; str += score + "张"; if (score == lose) str += ""; }); return str; }, }, trigger: { global: ["gainAfter", "loseAsyncAfter"] }, forced: true, popup: false, content: function () { var storage = player.storage["guimou_2"]; var targets = game.filterPlayer(target => trigger.getg(target).length); targets.forEach(target => { if (!storage[0].includes(target)) { storage[0].push(target); storage[1].push(0); } storage[1][storage[0].indexOf(target)] += trigger.getg(target).length; }); }, }, }, }, zhouxian: { audio: 2, trigger: { target: "useCardToTargeted" }, filter: function (event, player) { return event.player != player && get.tag(event.card, "damage"); }, forced: true, logTarget: "player", content: function* (event, map) { var player = map.player, trigger = map.trigger, target = trigger.player; var cards = get.cards(3); yield game.cardsDiscard(cards); player.showCards(cards, get.translation(player) + "发动了【州贤】"); var result = yield target .chooseToDiscard("he", "州贤:弃置一张其中有的类别的牌,或令此牌对" + get.translation(player) + "无效", (card, player) => { return _status.event.cards.some(cardx => get.type2(cardx) == get.type2(card)); }) .set("cards", cards) .set("ai", card => { if (!_status.event.goon) return 0; return 7.5 - get.value(card); }) .set("goon", get.effect(player, trigger.card, target, target) > 0); if (!result.bool) trigger.getParent().excluded.add(player); }, ai: { effect: { target_use: function (card, player, target, current) { if (get.tag(card, "damage") && get.attitude(player, target) < 0 && target != player) { if (_status.event.name == "zhouxian") return; if (get.attitude(player, target) > 0 && current < 0) return "zerotarget"; var bs = player.getDiscardableCards(player, "he"); bs.remove(card); if (card.cards) bs.removeArray(card.cards); else bs.removeArray(ui.selected.cards); var cardx = Array.from(ui.cardPile.childNodes).slice(0, 3); bs = bs.filter(i => cardx.some(j => get.type2(j) == get.type2(i))); if (!bs.length) return "zerotarget"; if (bs.length <= 2) { if (bs.some(bsi => get.value(bsi) < 7)) return [1, 0, 1, -0.5]; return [1, 0, 0.3, 0]; } return [1, 0, 1, -0.5]; } }, }, }, }, //胡班 mbyilie: { audio: 3, trigger: { global: "phaseBefore", player: "enterGame" }, filter: function (event, player) { return !player.storage.mbyilie2 && (event.name != "phase" || game.phaseNumber == 0); }, direct: true, content: function () { "step 0"; player.chooseTarget(get.prompt2("mbyilie"), lib.filter.notMe).set("ai", function (target) { var player = _status.event.player; return Math.max(1 + get.attitude(player, target) * get.threaten(target), Math.random()); }); "step 1"; if (result.bool) { var target = result.targets[0]; player.logSkill("mbyilie", target); player.storage.mbyilie2 = target; player.addSkill("mbyilie2"); } }, marktext: "烈", intro: { name2: "烈", content: "mark", }, group: "mbyilie3", }, mbyilie2: { charlotte: true, audio: "mbyilie", trigger: { global: ["damageBegin4", "damageSource"] }, filter: function (event, player, name) { var target = player.storage.mbyilie2; if (name == "damageSource") return event.source == target && event.player != target && player.isDamaged(); return event.player == target && player.countMark("mbyilie") < 2; }, forced: true, logTarget: function (event, player) { return player.storage.mbyilie2; }, content: function () { if (event.triggername == "damageSource") player.recover(); else { player.addMark("mbyilie", trigger.num); trigger.cancel(); } }, }, mbyilie3: { audio: "mbyilie", trigger: { player: "phaseEnd" }, filter: function (event, player) { return player.hasMark("mbyilie"); }, forced: true, content: function () { "step 0"; player.draw(); "step 1"; var num = player.countMark("mbyilie"); if (num) { player.loseHp(num); player.removeMark("mbyilie", num); } }, }, //向朗 naxue: { audio: 2, trigger: { player: "phaseUseBefore" }, check: function (event, player) { var cards = player.getCards("h", card => player.hasValueTarget(card)); if (!cards.length) return true; if (!(player.hp >= 2 && player.countCards("h") <= player.hp + 1)) return false; return game.hasPlayer(function (target) { if (target.hasJudge("lebu") || target == player) return false; if (get.attitude(player, target) > 4) { return get.threaten(target) / Math.sqrt(target.hp + 1) / Math.sqrt(target.countCards("h") + 1) > 0; } return false; }); }, content: function* (event, map) { var player = map.player; map.trigger.cancel(); var num = player.countDiscardableCards(player, "he"); if (num) { var result = yield player.chooseToDiscard("纳学:是否弃置任意张牌并摸等量的牌?", "he", [1, num]).set("ai", lib.skill.zhiheng.check); if (result.bool) yield player.draw(result.cards.length); } if (player.countCards("h")) { var result2 = yield player.chooseCardTarget({ prompt: "是否交给至多两名其他角色各一张手牌?", prompt2: "先按顺序选中所有要给出的牌,然后再按顺序选择等量的目标角色。", selectCard: [1, 2], filterCard: true, filterTarget: lib.filter.notMe, selectTarget: function () { return ui.selected.cards.length; }, filterOk: () => { return ui.selected.cards.length == ui.selected.targets.length; }, position: "h", ai1: function (card) { if (card.name == "du") return 10; else if (ui.selected.cards.length && ui.selected.cards[0].name == "du") return 0; var player = _status.event.player; if ( ui.selected.cards.length > 4 || !game.hasPlayer(function (current) { return get.attitude(player, current) > 0 && !current.hasSkillTag("nogain"); }) ) return 0; return 1 / Math.max(0.1, get.value(card)); }, ai2: function (target) { var player = _status.event.player, att = get.attitude(player, target); if (ui.selected.cards[0].name == "du") return -att; if (target.hasSkillTag("nogain")) att /= 6; return att; }, }); if (result2.bool) { const list = []; for (let i = 0; i < result2.targets.length; i++) { list.push([result2.targets[i], result2.cards[i]]); player.line(result2.targets[i]); } game.loseAsync({ gain_list: list, player: player, cards: result2.cards, giver: player, animate: "giveAuto", }).setContent("gaincardMultiple"); } } }, }, yijie: { audio: 2, trigger: { player: "die" }, filter: function (event, player) { return game.hasPlayer(target => target != player); }, forced: true, forceDie: true, skillAnimation: true, animationColor: "orange", logTarget: function (event, player) { return game.filterPlayer(target => target != player); }, content: function () { "step 0"; var targets = game.filterPlayer(target => target != player); var sum = targets.reduce((num, target) => (num += target.hp), 0); sum = Math.max(1, Math.floor(sum / targets.length)); event.num = sum; event.targets = targets; "step 1"; var target = targets.shift(); var delta = target.hp - num; if (delta != 0) { target[delta > 0 ? "loseHp" : "recover"](Math.abs(delta)); } if (targets.length) event.redo(); }, }, //阎象 kujian: { audio: "twkujian", inherit: "twkujian", selectCard: [1, 2], content: function () { player.give(cards, target).gaintag.add("twkujianx"); player.addSkill("kujian_draw"); player.addSkill("twkujian_discard"); }, subSkill: { draw: { charlotte: true, audio: "twkujian", trigger: { global: ["useCardAfter", "respondAfter"] }, filter: function (event, player) { return event.player.hasHistory("lose", evt => { if (event != evt.getParent()) return false; for (var i in evt.gaintag_map) { if (evt.gaintag_map[i].includes("twkujianx")) return true; } }); }, forced: true, logTarget: "player", content: function () { "step 0"; game.asyncDraw([player, trigger.player], 2); "step 1"; game.delayx(); }, }, }, }, //手杀差异化孙鲁育 mbmumu: { audio: "mumu", inherit: "new_mumu", filter: function (event, player) { return game.hasPlayer(current => { return current.countCards("e") > 0; }); }, content: function () { "step 0"; player .chooseTarget(get.prompt("mbmumu"), "弃置场上的一张装备牌,或者获得场上的一张防具牌。", function (card, player, target) { return target.countCards("e") > 0; }) .set("ai", function (target) { var player = _status.event.player; var att = get.attitude(player, target); if (target.getEquip(2) && player.hasEmptySlot(2)) { return -2 * att; } return -att; }); "step 1"; if (result.bool && result.targets && result.targets.length) { event.target = result.targets[0]; player.logSkill("mbmumu", event.target); player.line(event.target, "green"); var e = event.target.getEquips(2); event.e = e; if (e.length > 0) { player.chooseControl("弃置一张装备牌", "获得一张防具牌").set("ai", function () { if (_status.event.player.getEquips(2).length > 0) { return "弃置一张装备牌"; } return "获得一张防具牌"; }); } else { event.choice = "弃置一张装备牌"; } } else event.finish(); "step 2"; var choice = event.choice || result.control; if (choice == "弃置一张装备牌") { player.discardPlayerCard(event.target, "e", true); } else { if (event.e) { player.gain(event.e, event.target, "give", "bySelf"); player.addTempSkill("new_mumu2"); } } }, }, mbmeibu: { inherit: "new_meibu", derivation: ["mbzhixi"], content: function () { "step 0"; var check = lib.skill.new_meibu.checkx(trigger, player); player .chooseToDiscard(get.prompt2("mbmeibu", trigger.player), "he") .set("ai", function (card) { if (_status.event.check) return 6 - get.value(card); return 0; }) .set("check", check) .set("logSkill", ["mbmeibu", trigger.player]); "step 1"; if (result.bool) { var target = trigger.player; var card = result.cards[0]; player.line(target, "green"); target.addTempSkills("mbzhixi", "phaseUseAfter"); if (card.name != "sha" && get.type(card) != "trick" && get.color(card) != "black") { target.addTempSkill("new_meibu_range", "phaseUseAfter"); target.markAuto("new_meibu_range", player); } target.markSkillCharacter("mbmeibu", player, "魅步", "锁定技。出牌阶段,若你于此阶段使用过的牌数不小于X,你不能使用牌(X为你的体力值);当你使用锦囊牌时,你结束此阶段。"); } }, }, mbzhixi: { mod: { cardEnabled: function (card, player) { if (player.countMark("mbzhixi") >= player.hp) return false; }, cardUsable: function (card, player) { if (player.countMark("mbzhixi") >= player.hp) return false; }, cardSavable: function (card, player) { if (player.countMark("mbzhixi") >= player.hp) return false; }, }, trigger: { player: "useCard1", }, forced: true, popup: false, firstDo: true, init: function (player, skill) { player.storage[skill] = 0; var evt = _status.event.getParent("phaseUse"); if (evt && evt.player == player) { player.getHistory("useCard", function (evtx) { if (evtx.getParent("phaseUse") == evt) { player.storage[skill]++; } }); } }, onremove: function (player) { player.unmarkSkill("mbmeibu"); delete player.storage.mbzhixi; }, content: function () { player.addMark("mbzhixi", 1, false); if (get.type2(trigger.card) == "trick") { var evt = trigger.getParent("phaseUse"); if (evt && evt.player == player) { evt.skipped = true; game.log(player, "结束了出牌阶段"); } } }, ai: { presha: true, pretao: true, neg: true, nokeep: true, }, }, //庞统 xinlianhuan: { audio: 2, audioname: ["ol_pangtong"], inherit: "lianhuan", group: "xinlianhuan_add", subSkill: { add: { audio: "xinlianhuan", audioname: ["ol_pangtong"], trigger: { player: "useCard2" }, filter: function (event, player) { if (event.card.name != "tiesuo") return false; var info = get.info(event.card); if (info.allowMultiple == false) return false; if (event.targets && !info.multitarget) { if ( game.hasPlayer(current => { return !event.targets.includes(current) && lib.filter.targetEnabled2(event.card, player, current); }) ) return true; } return false; }, charlotte: true, forced: true, popup: false, content: function () { "step 0"; player .chooseTarget(get.prompt("xinlianhuan"), "为" + get.translation(trigger.card) + "额外指定一个目标", (card, player, target) => { return !_status.event.sourcex.includes(target) && lib.filter.targetEnabled2(_status.event.card, player, target); }) .set("sourcex", trigger.targets) .set("ai", function (target) { var player = _status.event.player; return get.effect(target, _status.event.card, player, player); }) .set("card", trigger.card); "step 1"; if (result.bool) { if (!event.isMine() && !event.isOnline()) game.delayex(); } else event.finish(); "step 2"; if (result.bool) { var targets = result.targets; player.logSkill("xinlianhuan_add", targets); trigger.targets.addArray(targets); game.log(targets, "也成为了", trigger.card, "的目标"); } }, }, }, }, //吴班 xinjintao: { audio: "jintao", inherit: "jintao", content: function () { var evt = trigger.getParent("phaseUse"); var index = player .getHistory("useCard", function (evtx) { return evtx.card.name == "sha" && evtx.getParent("phaseUse") == evt; }) .indexOf(trigger); if (index == 0) { game.log(trigger.card, "不可被响应"); trigger.directHit.addArray(game.players); } else { game.log(trigger.card, "伤害+1"); if (typeof trigger.baseDamage != "number") trigger.baseDamage = 1; trigger.baseDamage++; } }, }, //鲍信 mutao: { audio: "twmutao", inherit: "twmutao", content: function () { "step 0"; event.togive = target.getNext(); var cards = target.getCards("h", { name: "sha" }); if (!cards.length) { game.log("但", target, "没有", "#y杀", "!"); event.finish(); } else target.addToExpansion(cards, target, "give").gaintag.add("mutao"); "step 1"; var card = target.getExpansions("mutao").randomGet(); target.give(card, event.togive); "step 2"; if (target.getExpansions("mutao").length) { event.togive = event.togive.getNext(); event.goto(1); } else { target.line(event.togive); event.togive.damage(Math.min(2, event.togive.countCards("h", { name: "sha" })), target); } }, intro: { content: "expansion", markcount: "expansion", }, }, yimou: { audio: "twyimou", inherit: "twyimou", content: function () { "step 0"; if (trigger.player != player) player.addExpose(0.3); var target = get.translation(trigger.player); var choiceList = ["令" + target + "获得牌堆里的一张【杀】", "令" + target + "将一张牌交给另一名角色,然后" + target + "摸一张牌"]; var list = ["选项一"]; if (trigger.player.countCards("h")) list.push("选项二"); else choiceList[1] = '' + choiceList[1] + ""; player .chooseControl(list) .set("prompt", "毅谋:请选择一项") .set("choiceList", choiceList) .set("ai", function () { var evt = _status.event.getTrigger(), list = _status.event.list; var player = _status.event.player; var target = evt.player; if (target.countCards("h") && list.includes("选项二")) return "选项二"; return "选项一"; }) .set("list", list); "step 1"; event.choice = result.control; "step 2"; if (event.choice != "选项二") { var card = get.cardPile2(function (card) { return card.name == "sha"; }); if (card) trigger.player.gain(card, "gain2"); else game.log("但牌堆里已经没有", "#y杀", "了!"); if (event.choice == "选项一") event.finish(); } "step 3"; if (event.choice != "选项一") { if (trigger.player.countCards("h")) trigger.player.chooseCardTarget({ prompt: "毅谋:将一张手牌交给另一名其他角色", filterCard: true, forced: true, filterTarget: lib.filter.notMe, ai1: function (card) { return 1 / Math.max(0.1, get.value(card)); }, ai2: function (target) { var player = _status.event.player, att = get.attitude(player, target); if (target.hasSkillTag("nogain")) att /= 9; return 4 + att; }, }); else event.finish(); } "step 4"; var target = result.targets[0]; trigger.player.line(target); trigger.player.give(result.cards, target); trigger.player.draw(); }, }, //蒋济 jilun: { audio: "twjilun", inherit: "twjilun", filter: function (event, player) { return player.hasSkill("twjichou", null, false, false); }, content: function () { "step 0"; var choices = ["选项一"]; var choiceList = ["摸两张牌", "获得一个“机论”标记"]; if ( !player.getStorage("twjichou").length || !player.getStorage("twjichou").filter(function (name) { return !player.getStorage("jilun").includes(name) && player.hasUseTarget({ name: name }); }).length ) choiceList[1] = '' + choiceList[1] + ""; else choices.push("选项二"); player .chooseControl(choices, "cancel2") .set("choiceList", choiceList) .set("prompt", get.prompt("jilun")) .set("ai", () => { if (_status.event.choiceList.length == 1 || !player.getStorage("twjichou").length) return 0; var val = player.getUseValue({ name: "wuzhong" }); for (var name of player.getStorage("twjichou")) { if (player.getStorage("jilun").includes(name)) continue; if (player.getUseValue({ name: name }) > val) return 1; } return 0; }); "step 1"; if (result.control != "cancel2") { player.logSkill("jilun"); if (result.control == "选项一") player.draw(2); else player.addMark("jilun_mark", 1); } }, group: "jilun_effect", subSkill: { mark: { intro: { content: "mark" }, }, effect: { audio: "twjilun", trigger: { global: "phaseJieshuBegin" }, filter: function (event, player) { return player.hasMark("jilun_mark"); }, forced: true, content: function () { "step 0"; if ( !player.getStorage("twjichou").length || !player.getStorage("twjichou").filter(function (name) { return !player.getStorage("jilun").includes(name) && player.hasUseTarget({ name: name }); }).length ) { if (player.hasMark("jilun_mark")) player.removeMark("jilun_mark", player.countMark("jilun_mark")); event.finish(); return; } var list = []; for (var name of player.getStorage("twjichou")) { if (!player.getStorage("jilun").includes(name)) { list.push(["锦囊", "", name]); } } player .chooseButton(['###机论:请选择你要执行的选项###
  • 失去1枚“机论”标记,视为使用一张〖急筹〗已记录但〖机论〗未记录的普通锦囊牌
  • 失去所有“机论”标记', [list, "vcard"]]) .set("filterButton", function (button) { return _status.event.player.hasUseTarget({ name: button.link[2] }); }) .set("ai", function (button) { return _status.event.getParent().player.getUseValue({ name: button.link[2] }, null, true); }); "step 1"; if (result.bool) { player.removeMark("jilun_mark", 1); var card = { name: result.links[0][2], isCard: true }; player.chooseUseTarget(card, true); player.markAuto("jilun", [card.name]); player.syncStorage("jilun"); } else { player.removeMark("jilun_mark", player.countMark("jilun_mark")); event.finish(); } "step 2"; if (player.hasMark("jilun_mark")) event.goto(0); }, }, }, ai: { combo: "twjichou", }, }, //李遗 jiaohua: { onremove: true, audio: "twjiaohua", enable: "phaseUse", usable: 2, chooseButton: { dialog: function (event, player) { return ui.create.dialog("###教化###选择一种牌的类型,令一名角色从牌堆获得此类型的一张牌"); }, chooseControl: function (event, player) { var list = ["basic", "trick", "equip"].filter(type => !player.getStorage("jiaohua").includes(type)); list.push("cancel2"); return list; }, check: function (event, player) { var list = ["trick", "equip", "basic"].filter(type => !player.getStorage("jiaohua").includes(type)); return list[0]; }, backup: function (result, player) { return { type: result.control, audio: "twjiaohua", filterCard: () => false, selectCard: -1, filterTarget: true, content: function () { "step 0"; var type = lib.skill.jiaohua_backup.type; var card = get.cardPile2(card => get.type2(card) == type); if (card) target.gain(card, "gain2"); else game.log("但牌堆里已经没有", "#y" + get.translation(type) + "牌", "了!"); "step 1"; player.markAuto("jiaohua", [lib.skill.jiaohua_backup.type]); "step 2"; if (!["basic", "trick", "equip"].some(type => !player.getStorage("jiaohua").includes(type))) { player.popup("教化"); player.unmarkAuto("jiaohua", player.getStorage("jiaohua")); game.log(player, "清空了", "#g【教化】", "记录"); } }, ai: { result: { target: 1 }, }, }; }, prompt: function (result, player) { return "令一名角色从牌堆中获得一张" + get.translation(result.control) + "牌"; }, }, ai: { order: 7, result: { player: 1 }, }, intro: { content: "已记录$牌" }, }, //来敏 laishou: { audio: 3, trigger: { player: ["damageBegin4", "phaseZhunbeiBegin"] }, filter: function (event, player) { var num = 9; if (event.name == "damage") return event.num >= player.getHp() && player.maxHp < num; return player.maxHp >= num; }, forced: true, content: function () { if (trigger.name == "damage") { player.gainMaxHp(trigger.num); trigger.cancel(); } else player.die(); }, }, luanqun: { audio: 2, enable: "phaseUse", filter: function (event, player) { return player.countCards("h"); }, usable: 1, content: function () { "step 0"; var targets = game.filterPlayer(current => current.countCards("h")).sortBySeat(); event.targets = targets; var next = player .chooseCardOL(targets, "乱群:请选择要展示的牌", true) .set("ai", function (card) { return -get.value(card); }) .set("source", player); next.aiCard = function (target) { var hs = target.getCards("h"); return { bool: true, cards: [hs.randomGet()] }; }; next._args.remove("glow_result"); "step 1"; var cards = []; event.videoId = lib.status.videoId++; for (var i = 0; i < targets.length; i++) cards.push(result[i].cards[0]); event.cards = cards; game.log(player, "展示了", targets, "的", cards); game.broadcastAll( function (targets, cards, id, player) { var dialog = ui.create.dialog(get.translation(player) + "发动了【乱群】", cards); dialog.videoId = id; var getName = function (target) { if (target._tempTranslate) return target._tempTranslate; var name = target.name; if (lib.translate[name + "_ab"]) return lib.translate[name + "_ab"]; return get.translation(name); }; for (var i = 0; i < targets.length; i++) { dialog.buttons[i].querySelector(".info").innerHTML = getName(targets[i]) + get.translation(cards[i].suit); } }, targets, cards, event.videoId, player ); game.delay(4); "step 2"; game.broadcastAll("closeDialog", event.videoId); var card = cards[targets.indexOf(player)]; var cardx = cards.filter(cardy => cardy != card && get.color(cardy, targets[cards.indexOf(cardy)]) == get.color(card, player)); if (cardx.length) { player .chooseButton(["乱群:是否获得其中的一张牌", cardx]) .set("forceAuto", true) .set("ai", function (button) { var cards = _status.event.list[0]; var targets = _status.event.list[1]; var player = _status.event.player; if (get.attitude(player, targets[cards.indexOf(button.link)]) > 0) return 0; return get.value(button.link, player); }) .set("list", [cards, targets]); } else event.goto(4); "step 3"; if (result.bool) { var card = result.links[0]; player.gain(card, get.owner(card), "give"); } "step 4"; var card = cards[targets.indexOf(player)]; targets = targets.filter(target => get.color(cards[targets.indexOf(target)], target) != get.color(card, player)); if (targets.length) { player.line(targets); targets.forEach(target => { target.addTempSkill("luanqun_effect", { player: "phaseUseAfter" }); target.markAuto("luanqun_effect", [player]); }); } }, ai: { order: 9, result: { player: function (player, target) { if (player.hasSkill("laishou")) return 1; return player.hp >= 2 ? 1 : 0; }, }, }, subSkill: { effect: { charlotte: true, onremove: true, intro: { content: "出牌阶段第一张【杀】只能指定$为目标,且此牌不可被响应" }, mod: { playerEnabled: function (card, player, target) { if (!player.isPhaseUsing()) return; if (card.name == "sha" && !player.getStorage("luanqun_effect").includes(target)) return false; }, }, trigger: { player: "useCard1" }, filter: function (event, player) { return player.isPhaseUsing() && event.card.name == "sha"; }, forced: true, content: function () { trigger.directHit.addArray(player.getStorage("luanqun_effect")); player.removeSkill("luanqun_effect"); }, }, }, }, //☆周不疑 mbhuiyao: { audio: 2, enable: "phaseUse", usable: 1, // filterTarget:lib.filter.notMe, content: function () { "step 0"; player.damage("nosource"); "step 1"; if (game.countPlayer() < 2) event.finish(); if (game.countPlayer() == 2) event._result = { bool: true, targets: [game.findPlayer(i => i != player), player], }; else player .chooseTarget( `慧夭:请选择两名角色`, `令不为你的第一名角色视为对第二名角色造成过1点伤害。`, (card, player, target) => { if (!ui.selected.targets.length) return player != target; return true; }, 2, true ) .set("multitarget", true) .set("targetprompt", ["伤害来源", "受伤角色"]) .set("ai", target => { return target == get.event("aiTargets")[ui.selected.targets.length] ? 10 : 0; }) .set("aiTargets", lib.skill.mbhuiyao.getUnrealDamageTargets(player, [game.filterPlayer(i => i != player), game.filterPlayer()], true)); "step 2"; if (result.bool) { var targets = result.targets; player.line2(targets, "green"); game.delaye(); targets[1].damage(targets[0], "unreal"); } }, getUnrealDamageTargets: (player, lists, forced) => { const targets = [null, null]; let sourceList, targetList; if (lists.length == 2 && lists.every(l => Array.isArray(l))) { sourceList = lists[0]; targetList = lists[1]; } else { sourceList = lists.slice(); targetList = lists.slice(); } const list = targetList .map(current => { const _hp = current.hp, _maxhp = current.maxHp; current.hp = 100; current.maxHp = 100; const att = -get.sgnAttitude(player, current); let val = get.damageEffect(current, player, current) * att; current.getSkills(null, false, false).forEach(skill => { const info = get.info(skill); if (info && info.ai && (info.ai.maixie || info.ai.maixie_hp || info.ai.maixie_defend)) val = Math[val > 0 ? "max" : "min"](val > 0 ? 0.1 : -0.1, val + 2 * att); }); const eff = 100 / val + 15; current.hp = _hp; current.maxHp = _maxhp; return [current, eff]; }) .sort((a, b) => b[1] - a[1])[0]; if (list[1] < 0 && !forced) return targets; const targetx = list[0]; targets[1] = targetx; const list2 = sourceList .filter(i => i != targetx) .map(current => { const _hp = targetx.hp, _maxhp = targetx.maxHp; targetx.hp = 100; targetx.maxHp = 100; const att = -get.sgnAttitude(player, current); const eff = get.damageEffect(targetx, current, current) * att; targetx.hp = _hp; targetx.maxHp = _maxhp; return [current, eff]; }) .sort((a, b) => b[1] - a[1])[0]; if (!list2) return targets; targets[0] = list2[0]; return targets; }, ai: { order: 6, result: { player: function (player) { if (player.getHp() + player.countCards("hs", card => player.canSaveCard(card, player)) <= 1) return 0; var limit = 25; var quesong = player.hasSkill("mbquesong") && !player.getStat().damaged; if (quesong) { limit -= 7.5; } if ( quesong && game.hasPlayer(target => { var att = get.attitude(player, target); if (att < 0) return false; return ( att * Math.sqrt( Math.max( 1, [1, 2, 3, 4].reduce((p, c) => p + target.countEmptySlot(c), 0) ) ) >= 10 || target.getHp() <= 2 ); }) ) return 1; if ( !quesong && game.hasPlayer(target => { if (target == player) return false; var _hp = target.hp, _maxhp = target.maxHp; target.hp = 100; target.maxHp = 100; var att = -get.sgnAttitude(player, target); var val = get.damageEffect(target, player, target) * att; target.getSkills(null, false, false).forEach(skill => { var info = get.info(skill); if (info && info.ai && (info.ai.maixie || info.ai.maixie_hp || info.ai.maixie_defend)) val = Math[val > 0 ? "max" : "min"](val > 0 ? 0.1 : -0.1, val + 2 * att); }); var eff = 100 / val; target.hp = _hp; target.maxHp = _maxhp; if (eff < limit) return false; return true; }) ) return 1; return 0; }, }, }, }, mbquesong: { audio: 2, trigger: { global: "phaseJieshuBegin" }, filter: function (event, player) { return player.getHistory("damage").length; }, direct: true, content: function () { "step 0"; player.chooseTarget(get.prompt2("mbquesong")).set("ai", target => { var player = _status.event.player; if (get.attitude(player, target) <= 0) return 0; var len = lib.skill.mbquesong.getNum(target), hp = target.getHp(); return len + target.isTurnedOver() * 2 + (1.5 * Math.min(4, target.getDamagedHp())) / (hp + 1); }); "step 1"; if (result.bool) { var target = result.targets[0]; event.target = target; player.logSkill("mbquesong", target); var len = lib.skill.mbquesong.getNum(target); if (target.isHealthy()) event._result = { index: 0 }; else { target .chooseControl() .set("choiceList", ["摸" + get.cnNumber(len) + "张牌并复原武将牌", "回复1点体力"]) .set("prompt", "雀颂:请选择一项") .set("ai", () => { var player = _status.event.player; var len = _status.event.len; return get.effect(player, { name: "draw" }, player, player) * len >= get.recoverEffect(player, player, player) ? 0 : 1; }) .set("len", len); } } else event.finish(); "step 2"; if (result.index == 1) { target.recover(); event.finish(); } else target.draw(lib.skill.mbquesong.getNum(target)); "step 3"; target.link(false); "step 4"; target.turnOver(false); }, getNum: function (player) { return player.countCards("e", card => get.subtype(card) != "equip5") >= 3 ? 2 : 3; }, ai: { expose: 0.2, maixie: true, skillTagFilter: function (player, tag) { if (player.getStat().damaged) return false; }, }, }, //郭照 yichong: { initSkill: function (skill) { if (!lib.skill[skill]) { lib.skill[skill] = { charlotte: true, onremove: true, mark: true, marktext: "雀", intro: { markcount: function (storage) { return (storage || 0).toString(); }, content: function (storage) { return "已被掠夺" + (storage || 0) + "张牌"; }, }, }; lib.translate[skill] = "易宠"; lib.translate[skill + "_bg"] = "雀"; } }, getLimit: 1, audio: 2, trigger: { player: "phaseZhunbeiBegin" }, direct: true, content: function () { "step 0"; player.chooseTarget(get.prompt("yichong"), "选择一名其他角色并选择一个花色,获得其此花色的所有牌并令其获得“雀”标记", lib.filter.notMe).set("ai", function (target) { var player = _status.event.player; var att = get.attitude(player, target); if (att > 0) return 0; var getNum = function (player) { var list = []; for (var i of lib.suit) list.push(player.countCards("he", { suit: i }) + 3); return list.sort((a, b) => b - a)[0]; }; return getNum(target) + target.countCards("h") / 10; }); "step 1"; if (result.bool) { var target = result.targets[0]; player.logSkill("yichong", target); event.target = target; player .chooseControl(lib.suit.slice(0).reverse()) .set("prompt", "请声明一个花色") .set("ai", function () { var target = _status.event.target, cards = target.getCards("he"); var suits = lib.suit.slice(0); suits.sort(function (a, b) { var num = function (suit) { return cards.filter(function (card) { return get.suit(card) == suit; }).length; }; return num(b) - num(a); }); return suits[0]; }) .set("target", target); } else event.finish(); "step 2"; var suit = result.control; event.suit = suit; player.chat(get.translation(suit + 2)); game.log(player, "选择了", "#y" + get.translation(suit + 2)); if (target.countCards("e", { suit: suit })) player.gain(target.getCards("e", { suit: suit }), target, "giveAuto"); "step 3"; var suit = event.suit; if (target.countCards("h", { suit: suit })) { player.chooseButton(["选择获得其中一张牌", target.getCards("h", { suit: suit })], true).set("ai", button => get.value(button.link)); } else event.goto(5); "step 4"; if (result.bool) { var card = result.links[0]; if (lib.filter.canBeGained(card, player, target)) player.gain(card, target, "giveAuto", "bySelf"); else game.log("但", card, "不能被", player, "获得!"); } "step 5"; var suit = event.suit; player.storage.yichong = suit; player.markSkill("yichong"); var skill = "yichong_" + player.playerid; game.broadcastAll(lib.skill.yichong.initSkill, skill); game.broadcastAll( function (player, suit) { if (player.marks.yichong) player.marks.yichong.firstChild.innerHTML = get.translation(suit); }, player, suit ); game.countPlayer(function (current) { current.removeSkill("yichong_" + player.playerid); if (current == target) target.addSkill("yichong_" + player.playerid); }); player.addTempSkill("yichong_clear", { player: "phaseBegin" }); }, onremove: true, intro: { content: "拥有“雀”标记的角色得到$牌后,你获得之" }, group: "yichong_gain", subSkill: { gain: { audio: "yichong", trigger: { global: ["gainAfter", "loseAsyncAfter"] }, filter: function (event, player) { if (!player.storage.yichong) return false; return game.hasPlayer(function (current) { if (!event.getg(current).length || !current.hasSkill("yichong_" + player.playerid)) return false; if (current.countMark("yichong_" + player.playerid) >= lib.skill.yichong.getLimit) return false; return event.getg(current).some(card => get.suit(card, current) == player.storage.yichong && lib.filter.canBeGained(card, current, player)); }); }, forced: true, content: function () { "step 0"; var target = game.findPlayer(function (current) { if (!trigger.getg(current).length || !current.hasSkill("yichong_" + player.playerid)) return false; if (current.countMark("yichong_" + player.playerid) >= lib.skill.yichong.getLimit) return false; return trigger.getg(current).some(card => get.suit(card, current) == player.storage.yichong && lib.filter.canBeGained(card, current, player)); }); event.target = target; var cards = trigger.getg(target).filter(card => get.suit(card, target) == player.storage.yichong && lib.filter.canBeGained(card, target, player)); if (cards.length <= lib.skill.yichong.getLimit - target.countMark("yichong_" + player.playerid)) event._result = { bool: true, links: cards }; else { var num = lib.skill.yichong.getLimit - target.countMark("yichong_" + player.playerid); player.chooseButton(["易宠:获得其中的" + get.cnNumber(num) + "张牌", cards], num, true).set("ai", function (button) { return get.value(button.link); }); } "step 1"; if (result.bool) { player.gain(result.links, target, "give"); target.addMark("yichong_" + player.playerid, result.links.length, false); } }, }, clear: { charlotte: true, onremove: function (player) { game.countPlayer(function (current) { current.removeSkill("yichong_" + player.playerid); }); }, }, }, }, wufei: { audio: 2, trigger: { player: ["useCardToPlayered", "damageEnd"] }, filter: function (event, player) { var target = game.findPlayer(current => current.hasSkill("yichong_" + player.playerid)); if (!target) return false; if (event.name == "damage") return target.hp > 3; return event.isFirstTarget && (event.card.name == "sha" || (get.type(event.card) == "trick" && get.tag(event.card, "damage"))); }, direct: true, content: function () { "step 0"; var target = game.findPlayer(current => current.hasSkill("yichong_" + player.playerid)); event.target = target; if (trigger.name == "damage") { player.chooseBool(get.prompt("wufei", target), "令" + get.translation(target) + "受到1点无来源伤害").set("choice", get.damageEffect(target, player, player) > 0); } else { player.logSkill("wufei", target); player.addTempSkill("wufei_effect"); player.markAuto("wufei_effect", [trigger.card]); game.log(target, "成为了", trigger.card, "的伤害来源"); event.finish(); } "step 1"; if (result.bool) { player.logSkill("wufei", target); target.damage("nosource"); } }, subSkill: { effect: { charlotte: true, trigger: { source: "damageBefore" }, filter: function (event, player) { if (!event.card) return false; return player.getStorage("wufei_effect").includes(event.card); }, forced: true, popup: false, firstDo: true, content: function () { var target = game.findPlayer(current => current.hasSkill("yichong_" + player.playerid)); if (!target) delete trigger.source; else trigger.source = target; }, }, }, ai: { combo: "yichong", }, }, //张嶷 xinwurong: { audio: 3, enable: "phaseUse", usable: 1, filterTarget: lib.filter.notMe, content: function () { "step 0"; player .chooseToDuiben(target) .set("title", "谋弈") .set("namelist", ["反抗", "归顺", "镇压", "安抚"]) .set("translationList", [`对方选择镇压:${get.translation(player)}对你造成1点伤害,然后其摸1张牌
    对方选择安抚:${get.translation(player)}受到1点伤害,然后其摸2张牌`, `对方选择镇压:${get.translation(player)}获得你1张牌,然后其交给你2张牌
    对方选择安抚:你须交给${get.translation(player)}两张牌(若你牌数不足2张,则改为其令你跳过你下个摸牌阶段)`, `对方选择反抗:你对${get.translation(target)}造成1点伤害,然后你摸1张牌
    对方选择归顺:你获得${get.translation(target)}1张牌,然后你交给其2张牌`, `对方选择反抗:你受到1点伤害,然后你摸2张牌
    对方选择归顺:${get.translation(target)}须交给你两张牌(若其牌数不足两张,则改为令其跳过其下个摸牌阶段)`]) .set("ai", button => 1 + Math.random()); "step 1"; if (result.bool) { if (result.player == "db_def1") { target.damage(); player.draw(); event.finish(); } else { var cards = target.getCards("he"); if (cards.length < 2) { target.skip("phaseDraw"); target.addTempSkill("xinwurong_skip", { player: "phaseDrawSkipped" }); event.finish(); } else if (cards.length == 2) event._result = { bool: true, cards: cards }; else target.chooseCard("怃戎:交给" + get.translation(player) + "两张牌", 2, true, "he"); } } else { if (result.player == "db_def1") { player.gainPlayerCard(target, "he", true); event.goto(3); } else { player.damage(); player.draw(2); event.finish(); } } "step 2"; if (result.bool) player.gain(result.cards, target, "giveAuto"); event.finish(); "step 3"; var cards = player.getCards("he"); if (!cards.length) event.finish(); else if (cards.length <= 2) event._result = { bool: true, cards: cards }; else player.chooseCard("怃戎:交给" + get.translation(target) + "两张牌", 2, true, "he"); "step 4"; if (result.bool) target.gain(result.cards, player, "giveAuto"); }, ai: { order: 7, result: { player: 1, target: -1, }, }, subSkill: { skip: { charlotte: true, mark: true, intro: { content: "跳过下个摸牌阶段" }, }, }, }, //孙亮 xinkuizhu: { audio: "nzry_kuizhu", trigger: { player: "phaseDiscardAfter" }, filter: function (event, player) { return player.getHistory("lose", function (evt) { return evt.type == "discard" && evt.getParent("phaseDiscard") == event; }).length; }, direct: true, content: function () { "step 0"; var cards = []; player.getHistory("lose", function (evt) { if (evt.type == "discard" && evt.getParent("phaseDiscard") == trigger) cards.addArray(evt.cards2); }); event.num = cards.length; event.str1 = "令至多" + event.num + "名角色摸一张牌"; event.str2 = "对任意名体力值之和为" + event.num + "的角色造成1点伤害"; player .chooseControl("cancel2") .set("ai", function () { if ( game.countPlayer(function (current) { return get.attitude(player, current) < 0 && current.hp == event.num; }) > 0 && event.num <= 3 ) return 1; return 0; }) .set("choiceList", [event.str1, event.str2]) .set("prompt", "是否发动【溃诛】?"); "step 1"; if (result.control == "cancel2") event.finish(); event.control = [event.str1, event.str2][result.index]; "step 2"; var str = "请选择〖溃诛〗的目标"; if (event.bool == false) str = "
    所选目标体力之和不足" + event.num + ",请重选"; if (event.control == event.str2) { player .chooseTarget(str, function (card, player, target) { var targets = ui.selected.targets; var num = 0; for (var i = 0; i < targets.length; i++) num += targets[i].hp; return num + target.hp <= _status.event.num; }) .set("ai", function (target) { if (ui.selected.targets[0] != undefined) return -1; return get.attitude(player, target) < 0; }) .set("promptbar", "none") .set("num", event.num) .set("selectTarget", function () { var targets = ui.selected.targets; var num = 0; for (var i = 0; i < targets.length; i++) num += targets[i].hp; if (num == _status.event.num) return ui.selected.targets.length; return ui.selected.targets.length + 1; }); } else { player.chooseTarget("请选择〖溃诛〗的目标", "令至多" + get.cnNumber(event.num) + "名角色各摸一张牌", [1, event.num]).set("ai", function (target) { return get.attitude(_status.event.player, target); }); } "step 3"; if (result.bool) { var targets = result.targets.sortBySeat(); if (event.control == event.str1) { player.logSkill("xinkuizhu", targets); game.asyncDraw(targets); } else { var num = 0; for (var i = 0; i < targets.length; i++) num += targets[i].hp; if (num < event.num) { event.bool = false; event.goto(2); } else { player.logSkill("xinkuizhu", targets); for (var i of targets) i.damage(); if (targets.length >= 2) player.loseHp(); } } } }, }, xinzhizheng: { audio: "nzry_zhizheng", mod: { playerEnabled: function (card, player, target) { var info = get.info(card); if (target != player && (!info || !info.singleCard || !ui.selected.targets.length) && player.isPhaseUsing() && !target.inRange(player)) return false; }, }, trigger: { player: "phaseUseEnd" }, filter: function (event, player) { return ( player.getHistory("useCard", function (evt) { return evt.getParent("phaseUse") == event; }).length < game.countPlayer(function (current) { return current != player && !current.inRange(player); }) && game.hasPlayer(function (target) { return target != player && !target.inRange(player) && target.countDiscardableCards(player, "he"); }) ); }, forced: true, content: function () { "step 0"; player .chooseTarget("请选择〖掣政〗的目标", "弃置一名攻击范围内不包含你的角色的一张牌", true, function (card, player, target) { return target != player && !target.inRange(player) && target.countDiscardableCards(player, "he"); }) .set("ai", function (target) { var player = _status.event.player; return get.effect(target, { name: "guohe_copy2" }, player, player); }); "step 1"; if (result.bool) { player.line(result.targets); player.discardPlayerCard(result.targets[0], "he", true); } }, }, xinlijun: { unique: true, audio: "nzry_lijun1", trigger: { global: "useCardAfter" }, filter: function (event, player) { if (event.card.name != "sha") return false; if (_status.currentPhase != event.player || event.player.group != "wu") return false; if (!player.hasZhuSkill("xinlijun", event.player) || player == event.player) return false; return event.cards.filterInD().length; }, zhuSkill: true, direct: true, content: function () { "step 0"; trigger.player.chooseBool(get.prompt("xinlijun"), "将" + get.translation(trigger.cards) + "交给" + get.translation(player)).set("choice", get.attitude(trigger.player, player) > 0); "step 1"; if (result.bool) { player.logSkill("xinlijun", trigger.player); player.gain(trigger.cards.filterInD(), "gain2"); player .chooseBool() .set("prompt", "是否令" + get.translation(trigger.player) + "摸一张牌?") .set("choice", get.attitude(player, trigger.player) > 0); } else event.finish(); "step 2"; if (result.bool) trigger.player.draw(); }, }, //十常侍 mbdanggu: { audio: 2, trigger: { player: "enterGame", global: "phaseBefore", }, filter: function (event, player) { return event.name != "phase" || game.phaseNumber == 0; }, derivation: ["mbdanggu_faq", "mbdanggu_faq2"], forced: true, unique: true, onremove: function (player) { delete player.storage.mbdanggu; delete player.storage.mbdanggu_current; if (lib.skill.mbdanggu.isSingleShichangshi(player)) { game.broadcastAll(function (player) { player.name1 = player.name; player.smoothAvatar(false); player.node.avatar.setBackground(player.name, "character"); player.node.name.innerHTML = get.slimName(player.name); delete player.name2; player.classList.remove("fullskin2"); player.node.avatar2.classList.add("hidden"); player.node.name2.innerHTML = ""; if (player == game.me && ui.fakeme) { ui.fakeme.style.backgroundImage = player.node.avatar.style.backgroundImage; } }, player); } }, changshi: [ ["scs_zhangrang", "scstaoluan"], ["scs_zhaozhong", "scschiyan"], ["scs_sunzhang", "scszimou"], ["scs_bilan", "scspicai"], ["scs_xiayun", "scsyaozhuo"], ["scs_hankui", "scsxiaolu"], ["scs_lisong", "scskuiji"], ["scs_duangui", "scschihe"], ["scs_guosheng", "scsniqu"], ["scs_gaowang", "scsmiaoyu"], ], conflictMap: function (player) { if (!_status.changshiMap) { _status.changshiMap = { scs_zhangrang: [], scs_zhaozhong: [], scs_sunzhang: [], scs_bilan: ["scs_hankui"], scs_xiayun: [], scs_hankui: ["scs_bilan"], scs_lisong: [], scs_duangui: ["scs_guosheng"], scs_guosheng: ["scs_duangui"], scs_gaowang: [], }; if (!get.isLuckyStar(player)) { var list = lib.skill.mbdanggu.changshi.map(i => i[0]); for (var i of list) { var select = list.filter(scs => scs != i && !_status.changshiMap[i].includes(i)); _status.changshiMap[i].addArray(select.randomGets(get.rand(0, select.length))); } } } return _status.changshiMap; }, group: "mbdanggu_back", content: function () { "step 0"; var list = lib.skill.mbdanggu.changshi.map(i => i[0]); player.markAuto("mbdanggu", list); game.broadcastAll( function (player, list) { var cards = []; for (var i = 0; i < list.length; i++) { var cardname = "huashen_card_" + list[i]; lib.card[cardname] = { fullimage: true, image: "character/" + list[i], }; lib.translate[cardname] = get.rawName2(list[i]); cards.push(game.createCard(cardname, "", "")); } player.$draw(cards, "nobroadcast"); }, player, list ); "step 1"; var next = game.createEvent("mbdanggu_clique"); next.player = player; next.setContent(lib.skill.mbdanggu.contentx); }, contentx: function () { "step 0"; var list = player.getStorage("mbdanggu").slice(); var first = list.randomRemove(); event.first = first; var others = list.randomGets(4); if (others.length == 1) event._result = { bool: true, links: others }; else { var map = { scs_bilan: "scs_hankui", scs_hankui: "scs_bilan", scs_duangui: "scs_guosheng", scs_guosheng: "scs_duangui", }, map2 = lib.skill.mbdanggu.conflictMap(player); var conflictList = others.filter(changshi => { if (map[first] && others.some(changshi2 => map[first] == changshi2)) return map[first] == changshi; else return map2[first].includes(changshi); }), list = others.slice(); if (conflictList.length) { var conflict = conflictList.randomGet(); list.remove(conflict); game.broadcastAll( function (changshi, player) { if (lib.config.background_speak) { if (player.isUnderControl(true)) game.playAudio("skill", changshi + "_enter"); } }, conflict, player ); } player .chooseButton(["党锢:请选择结党对象", [[first], "character"], '
    可选常侍
    ', [others, "character"]], true) .set("filterButton", button => { return _status.event.canChoose.includes(button.link); }) .set("canChoose", list) .set("ai", button => Math.random() * 10); } "step 1"; if (result.bool) { var first = event.first; var chosen = result.links[0]; var skills = []; var list = lib.skill.mbdanggu.changshi; var changshis = [first, chosen]; player.unmarkAuto("mbdanggu", changshis); player.storage.mbdanggu_current = changshis; for (var changshi of changshis) { for (var cs of list) { if (changshi == cs[0]) skills.push(cs[1]); } } if (lib.skill.mbdanggu.isSingleShichangshi(player)) { game.broadcastAll( function (player, first, chosen) { player.name1 = first; player.node.avatar.setBackground(first, "character"); player.node.name.innerHTML = get.slimName(first); player.name2 = chosen; player.classList.add("fullskin2"); player.node.avatar2.classList.remove("hidden"); player.node.avatar2.setBackground(chosen, "character"); player.node.name2.innerHTML = get.slimName(chosen); if (player == game.me && ui.fakeme) { ui.fakeme.style.backgroundImage = player.node.avatar.style.backgroundImage; } }, player, first, chosen ); } game.log(player, "选择了常侍", "#y" + get.translation(changshis)); if (skills.length) { player.addAdditionalSkill("mbdanggu", skills); var str = ""; for (var i of skills) { str += "【" + get.translation(i) + "】、"; player.popup(i); } str = str.slice(0, -1); game.log(player, "获得了技能", "#g" + str); } } }, isSingleShichangshi: function (player) { var map = lib.skill.mbdanggu.conflictMap(player); return player.name == "shichangshi" && ((map[player.name1] && map[player.name2]) || (map[player.name1] && !player.name2) || (!player.name1 && !player.name2) || (player.name == player.name1 && !player.name2)); }, mod: { aiValue: function (player, card, num) { if (["shan", "tao", "wuxie", "caochuan"].includes(card.name)) return num / 10; }, aiUseful: function () { return lib.skill.mbdanggu.mod.aiValue.apply(this, arguments); }, }, ai: { combo: "mbmowang", nokeep: true, }, intro: { mark: function (dialog, storage, player) { dialog.addText("剩余常侍"); dialog.addSmall([storage, "character"]); if (player.storage.mbdanggu_current && player.isIn()) { dialog.addText("当前常侍"); dialog.addSmall([player.storage.mbdanggu_current, "character"]); } }, }, subSkill: { back: { audio: "mbdanggu", trigger: { global: "restEnd" }, filter: function (event, player) { return event.getTrigger().player == player; }, forced: true, content: function () { "step 0"; delete player.storage.mbdanggu_current; if (lib.skill.mbdanggu.isSingleShichangshi(player)) { game.broadcastAll(function (player) { player.name1 = player.name; player.smoothAvatar(false); player.node.avatar.setBackground(player.name, "character"); player.node.name.innerHTML = get.slimName(player.name); delete player.name2; player.classList.remove("fullskin2"); player.node.avatar2.classList.add("hidden"); player.node.name2.innerHTML = ""; if (player == game.me && ui.fakeme) { ui.fakeme.style.backgroundImage = player.node.avatar.style.backgroundImage; } }, player); } "step 1"; var next = game.createEvent("mbdanggu_clique"); next.player = player; next.setContent(lib.skill.mbdanggu.contentx); player.draw(); }, }, }, }, mbmowang: { audio: 2, trigger: { player: "dieBefore" }, filter: function (event, player) { return player.getStorage("mbdanggu").length && event.getParent().name != "giveup" && player.maxHp > 0; }, derivation: "mbmowang_faq", forced: true, direct: true, priority: 15, group: ["mbmowang_die", "mbmowang_return"], content: function () { if (_status.mbmowang_return && _status.mbmowang_return[player.playerid]) { trigger.cancel(); } else { player.logSkill("mbmowang"); game.broadcastAll(function () { if (lib.config.background_speak) game.playAudio("die", "shichangshiRest"); }); trigger.setContent(lib.skill.mbmowang.dieContent); trigger.includeOut = true; } }, ai: { combo: "mbdanggu", neg: true, }, dieContent: function () { "step 0"; event.forceDie = true; if (source) { game.log(player, "被", source, "杀害"); if (source.stat[source.stat.length - 1].kill == undefined) { source.stat[source.stat.length - 1].kill = 1; } else { source.stat[source.stat.length - 1].kill++; } } else { game.log(player, "阵亡"); } if (player.isIn() && (!_status.mbmowang_return || !_status.mbmowang_return[player.playerid])) { event.reserveOut = true; game.log(player, "进入了修整状态"); game.log(player, "移出了游戏"); //game.addGlobalSkill('mbmowang_return'); if (!_status.mbmowang_return) _status.mbmowang_return = {}; _status.mbmowang_return[player.playerid] = 1; } else event.finish(); if (!game.countPlayer()) game.over(); else if (player.hp != 0) { player.changeHp(0 - player.hp, false).forceDie = true; } game.broadcastAll(function (player) { if (player.isLinked()) { if (get.is.linked2(player)) { player.classList.toggle("linked2"); } else { player.classList.toggle("linked"); } } if (player.isTurnedOver()) { player.classList.toggle("turnedover"); } }, player); game.addVideo("link", player, player.isLinked()); game.addVideo("turnOver", player, player.classList.contains("turnedover")); "step 1"; event.trigger("die"); "step 2"; if (event.reserveOut) { if (!game.reserveDead) { for (var mark in player.marks) { if (mark == "mbdanggu") continue; player.unmarkSkill(mark); } var count = 1; var list = Array.from(player.node.marks.childNodes); if (list.some(i => i.name == "mbdanggu")) count++; while (player.node.marks.childNodes.length > count) { var node = player.node.marks.lastChild; if (node.name == "mbdanggu") { node = node.previousSibling; } node.remove(); } game.broadcast( function (player, count) { while (player.node.marks.childNodes.length > count) { var node = player.node.marks.lastChild; if (node.name == "mbdanggu") { node = node.previousSibling; } node.remove(); } }, player, count ); } for (var i in player.tempSkills) { player.removeSkill(i); } var skills = player.getSkills(); for (var i = 0; i < skills.length; i++) { if (lib.skill[skills[i]].temp) { player.removeSkill(skills[i]); } } event.cards = player.getCards("hejsx"); if (event.cards.length) { player.discard(event.cards).forceDie = true; } } "step 3"; if (event.reserveOut) { game.broadcastAll( function (player, list) { player.classList.add("out"); if (list.includes(player.name1) || player.name1 == "shichangshi") { player.smoothAvatar(false); player.node.avatar.setBackground(player.name1 + "_dead", "character"); } if (list.includes(player.name2) || player.name2 == "shichangshi") { player.smoothAvatar(true); player.node.avatar2.setBackground(player.name2 + "_dead", "character"); } }, player, lib.skill.mbdanggu.changshi.map(i => i[0]) ); } if (source && lib.config.border_style == "auto" && (lib.config.autoborder_count == "kill" || lib.config.autoborder_count == "mix")) { switch (source.node.framebg.dataset.auto) { case "gold": case "silver": source.node.framebg.dataset.auto = "gold"; break; case "bronze": source.node.framebg.dataset.auto = "silver"; break; default: source.node.framebg.dataset.auto = lib.config.autoborder_start || "bronze"; } if (lib.config.autoborder_count == "kill") { source.node.framebg.dataset.decoration = source.node.framebg.dataset.auto; } else { var dnum = 0; for (var j = 0; j < source.stat.length; j++) { if (source.stat[j].damage != undefined) dnum += source.stat[j].damage; } source.node.framebg.dataset.decoration = ""; switch (source.node.framebg.dataset.auto) { case "bronze": if (dnum >= 4) source.node.framebg.dataset.decoration = "bronze"; break; case "silver": if (dnum >= 8) source.node.framebg.dataset.decoration = "silver"; break; case "gold": if (dnum >= 12) source.node.framebg.dataset.decoration = "gold"; break; } } source.classList.add("topcount"); } }, subSkill: { die: { audio: "mbmowang", trigger: { player: "phaseAfter" }, forced: true, forceDie: true, content: function () { "step 0"; if (lib.skill.mbdanggu.isSingleShichangshi(player)) { if (!player.getStorage("mbdanggu").length) { game.broadcastAll(function (player) { player.name1 = player.name; player.smoothAvatar(false); player.node.avatar.setBackground(player.name + "_dead", "character"); player.node.name.innerHTML = get.slimName(player.name); delete player.name2; player.classList.remove("fullskin2"); player.node.avatar2.classList.add("hidden"); player.node.name2.innerHTML = ""; if (player == game.me && ui.fakeme) { ui.fakeme.style.backgroundImage = player.node.avatar.style.backgroundImage; } }, player); } } if (!player.getStorage("mbdanggu").length) { game.delay(); } "step 1"; player.die(); }, }, return: { trigger: { player: "phaseBefore" }, forced: true, charlotte: true, silent: true, forceDie: true, forceOut: true, filter: function (event, player) { return !event._mbmowang_return && event.player.isOut() && _status.mbmowang_return[event.player.playerid]; }, content: function () { "step 0"; trigger._mbmowang_return = true; game.broadcastAll(function (player) { player.classList.remove("out"); }, trigger.player); game.log(trigger.player, "移回了游戏"); delete _status.mbmowang_return[trigger.player.playerid]; trigger.player.recover(trigger.player.maxHp - trigger.player.hp); game.broadcastAll(function (player) { if (player.name1 == "shichangshi") { player.smoothAvatar(false); player.node.avatar.setBackground(player.name1, "character"); } if (player.name2 == "shichangshi") { player.smoothAvatar(true); player.node.avatar2.setBackground(player.name2, "character"); } }, trigger.player); "step 1"; event.trigger("restEnd"); }, }, }, }, //张让 scstaoluan: { audio: 1, enable: "phaseUse", usable: 1, filter: function (event, player) { return player.countCards("hes") > 0; }, chooseButton: { dialog: function (event, player) { var list = []; for (var i = 0; i < lib.inpile.length; i++) { var name = lib.inpile[i]; if (name == "sha") { list.push(["基本", "", "sha"]); for (var j of lib.inpile_nature) list.push(["基本", "", "sha", j]); } else if (get.type(name) == "trick") list.push(["锦囊", "", name]); else if (get.type(name) == "basic") list.push(["基本", "", name]); } return ui.create.dialog("滔乱", [list, "vcard"]); }, filter: function (button, player) { return _status.event.getParent().filterCard({ name: button.link[2] }, player, _status.event.getParent()); }, check: function (button) { var player = _status.event.player; if (player.countCards("hs", button.link[2]) > 0) return 0; if (button.link[2] == "wugu") return; var effect = player.getUseValue(button.link[2]); if (effect > 0) return effect; return 0; }, backup: function (links, player) { return { filterCard: true, audio: "scstaoluan", selectCard: 1, popname: true, check: function (card) { return 6 - get.value(card); }, position: "hes", viewAs: { name: links[0][2], nature: links[0][3] }, }; }, prompt: function (links, player) { return "将一张牌当做" + (get.translation(links[0][3]) || "") + get.translation(links[0][2]) + "使用"; }, }, ai: { order: 4, result: { player: 1, }, threaten: 1.9, }, }, //赵忠 scschiyan: { audio: 1, shaRelated: true, trigger: { player: "useCardToPlayered" }, direct: true, filter: function (event, player) { return event.card.name == "sha" && event.target.hp > 0 && event.target.countCards("he") > 0; }, content: function () { "step 0"; var next = player.choosePlayerCard(trigger.target, "he", get.prompt("scschiyan", trigger.target)); next.set("ai", function (button) { if (!_status.event.goon) return 0; var val = get.value(button.link); if (button.link == _status.event.target.getEquip(2)) return 2 * (val + 3); return val; }); next.set("goon", get.attitude(player, trigger.target) <= 0); next.set("forceAuto", true); "step 1"; if (result.bool) { var target = trigger.target; player.logSkill("scschiyan", target); target.addSkill("scschiyan_get"); target.addToExpansion("giveAuto", result.cards, target).gaintag.add("scschiyan_get"); } }, ai: { unequip_ai: true, directHit_ai: true, skillTagFilter: function (player, tag, arg) { if (get.attitude(player, arg.target) > 0) return false; if (tag == "directHit_ai") return arg.target.hp >= Math.max(1, arg.target.countCards("h") - 1); if (arg && arg.name == "sha" && arg.target.getEquip(2)) return true; return false; }, }, group: "scschiyan_damage", subSkill: { get: { trigger: { global: "phaseEnd" }, forced: true, popup: false, charlotte: true, filter: function (event, player) { return player.getExpansions("scschiyan_get").length > 0; }, content: function () { "step 0"; var cards = player.getExpansions("scschiyan_get"); player.gain(cards, "draw"); game.log(player, "收回了" + get.cnNumber(cards.length) + "张“鸱咽”牌"); "step 1"; player.removeSkill("scschiyan_get"); }, intro: { markcount: "expansion", mark: function (dialog, storage, player) { var cards = player.getExpansions("scschiyan_get"); if (player.isUnderControl(true)) dialog.addAuto(cards); else return "共有" + get.cnNumber(cards.length) + "张牌"; }, }, }, damage: { audio: "scschiyan", trigger: { source: "damageBegin1" }, forced: true, locked: false, logTarget: "player", filter: function (event, player) { var target = event.player; return event.getParent().name == "sha" && player.countCards("h") >= target.countCards("h") && player.countCards("e") >= target.countCards("e"); }, content: function () { trigger.num++; }, }, }, }, //孙璋 scszimou: { audio: 1, trigger: { player: "useCard" }, forced: true, filter: function (event, player) { var evt = event.getParent("phaseUse"); if (!evt || evt.player != player) return false; var num = player.getHistory("useCard", evtx => evtx.getParent("phaseUse") == evt).length; return num == 2 || num == 4 || num == 6; }, content: function () { var evt = trigger.getParent("phaseUse"); var num = player.getHistory("useCard", evtx => evtx.getParent("phaseUse") == evt).length; var cards = []; if (num == 2) { var card = get.cardPile2(card => { return ["jiu", "xionghuangjiu"].includes(card.name); }); if (card) cards.push(card); } else if (num == 4) { var card = get.cardPile2(card => { return card.name == "sha"; }); if (card) cards.push(card); } else if (num == 6) { var card = get.cardPile2(card => { return card.name == "juedou"; }); if (card) cards.push(card); } if (cards.length) player.gain(cards, "gain2"); }, }, //毕岚 scspicai: { audio: 1, enable: "phaseUse", usable: 1, frequent: true, content: function () { "step 0"; event.cards = []; event.suits = []; "step 1"; player .judge(function (result) { var evt = _status.event.getParent("scspicai"); if (evt && evt.suits && evt.suits.includes(get.suit(result))) return 0; return 1; }) .set("callback", lib.skill.scspicai.callback).judge2 = function (result) { return result.bool ? true : false; }; "step 2"; var cards = cards.filterInD(); if (cards.length) player.chooseTarget("将" + get.translation(cards) + "交给一名角色", true).set("ai", function (target) { var player = _status.event.player; var att = get.attitude(player, target) / Math.sqrt(1 + target.countCards("h")); if (target.hasSkillTag("nogain")) att /= 10; return att; }); else event.finish(); "step 3"; if (result.bool) { var target = result.targets[0]; event.target = target; player.line(target, "green"); target.gain(cards, "gain2").giver = player; } else event.finish(); }, callback: function () { "step 0"; var evt = event.getParent(2); event.getParent().orderingCards.remove(event.judgeResult.card); evt.cards.push(event.judgeResult.card); if (event.getParent().result.bool) { evt.suits.push(event.getParent().result.suit); player.chooseBool("是否继续发动【庀材】?").set("frequentSkill", "scspicai"); } else event._result = { bool: false }; "step 1"; if (result.bool) event.getParent(2).redo(); }, ai: { order: 9, result: { player: 1, }, }, }, //夏恽 scsyaozhuo: { audio: 1, enable: "phaseUse", usable: 1, filter: function (event, player) { return game.hasPlayer(function (current) { return player.canCompare(current); }); }, filterTarget: function (card, player, current) { return player.canCompare(current); }, content: function () { "step 0"; player.chooseToCompare(target); "step 1"; if (result.bool) { target.skip("phaseDraw"); target.addTempSkill("scsyaozhuo_skip", { player: "phaseDrawSkipped" }); } else player.chooseToDiscard(2, true, "he"); }, subSkill: { skip: { mark: true, intro: { content: "跳过下一个摸牌阶段" }, }, }, ai: { order: 1, result: { target: function (player, target) { if (target.skipList.includes("phaseDraw") || target.hasSkill("pingkou")) return 0; var hs = player.getCards("h").sort(function (a, b) { return b.number - a.number; }); var ts = target.getCards("h").sort(function (a, b) { return b.number - a.number; }); if (!hs.length || !ts.length) return 0; if (hs[0].number > ts[0].number - 2 && hs[0].number > 5) return -1; return 0; }, }, }, }, //韩悝 scsxiaolu: { audio: 1, enable: "phaseUse", usable: 1, content: function () { "step 0"; player.draw(2); "step 1"; var num = player.countCards("he"); if (!num) event.finish(); else if (num < 2) event._result = { index: 1 }; else player .chooseControl() .set("choiceList", ["将两张牌交给一名其他角色", "弃置两张牌"]) .set("ai", function () { if ( game.hasPlayer(function (current) { return current != player && get.attitude(player, current) > 0; }) ) return 0; return 1; }); "step 2"; if (result.index == 0) { player.chooseCardTarget({ position: "he", filterCard: true, selectCard: 2, filterTarget: function (card, player, target) { return player != target; }, ai1: function (card) { return get.unuseful(card); }, ai2: function (target) { var att = get.attitude(_status.event.player, target); if (target.hasSkillTag("nogain")) att /= 10; if (target.hasJudge("lebu")) att /= 5; return att; }, prompt: "选择两张牌,交给一名其他角色", forced: true, }); } else { player.chooseToDiscard(2, true, "he"); event.finish(); } "step 3"; if (result.bool) { var target = result.targets[0]; player.give(result.cards, target); } }, ai: { order: 9, result: { player: 2 }, }, }, //栗嵩 scskuiji: { audio: 1, enable: "phaseUse", usable: 1, filterTarget: function (card, player, target) { return target != player && target.countCards("h") > 0; }, content: function () { "step 0"; event.list1 = []; event.list2 = []; if (player.countCards("h") > 0) { var chooseButton = player.chooseButton(4, ["你的手牌", player.getCards("h"), get.translation(target.name) + "的手牌", target.getCards("h")]); } else { var chooseButton = player.chooseButton(4, [get.translation(target.name) + "的手牌", target.getCards("h")]); } chooseButton.set("target", target); chooseButton.set("ai", function (button) { var player = _status.event.player; var target = _status.event.target; var ps = []; var ts = []; for (var i = 0; i < ui.selected.buttons.length; i++) { var card = ui.selected.buttons[i].link; if (target.getCards("h").includes(card)) ts.push(card); else ps.push(card); } var card = button.link; var owner = get.owner(card); var val = get.value(card) || 1; if (owner == target) { return 2 * val; } return 7 - val; }); chooseButton.set("filterButton", function (button) { for (var i = 0; i < ui.selected.buttons.length; i++) { if (get.suit(button.link) == get.suit(ui.selected.buttons[i].link)) return false; } return true; }); "step 1"; if (result.bool) { var list = result.links; for (var i = 0; i < list.length; i++) { if (get.owner(list[i]) == player) { event.list1.push(list[i]); } else { event.list2.push(list[i]); } } if (event.list1.length && event.list2.length) { game.loseAsync({ lose_list: [ [player, event.list1], [target, event.list2], ], discarder: player, }).setContent("discardMultiple"); } else if (event.list2.length) { target.discard(event.list2); } else player.discard(event.list1); } }, ai: { order: 13, result: { target: -1, }, }, }, //段珪 scschihe: { audio: 1, trigger: { player: "useCardToPlayered" }, filter: function (event, player) { return event.targets.length == 1 && event.card.name == "sha"; }, prompt2: function (event, player) { var str = "亮出牌堆顶的两张牌并增加伤害;且"; str += "令" + get.translation(event.target) + "不能使用"; str += "这两张牌所包含的花色"; str += "的牌响应" + get.translation(event.card); return str; }, logTarget: "target", locked: false, check: function (event, player) { var target = event.target; if (get.attitude(player, target) > 0) return false; return true; }, content: function () { var num = 2; var evt = trigger.getParent(); var suit = get.suit(trigger.card); var suits = []; if (num > 0) { if (typeof evt.baseDamage != "number") evt.baseDamage = 1; var cards = get.cards(num); player.showCards(cards.slice(0), get.translation(player) + "发动了【叱吓】"); while (cards.length > 0) { var card = cards.pop(); var suitx = get.suit(card, false); suits.add(suitx); if (suit == suitx) evt.baseDamage++; } game.updateRoundNumber(); } evt._scschihe_player = player; var target = trigger.target; target.addTempSkill("scschihe_block"); if (!target.storage.scschihe_block) target.storage.scschihe_block = []; target.storage.scschihe_block.push([evt.card, suits]); lib.skill.scschihe.updateBlocker(target); }, updateBlocker: function (player) { var list = [], storage = player.storage.scschihe_block; if (storage && storage.length) { for (var i of storage) list.addArray(i[1]); } player.storage.scschihe_blocker = list; }, ai: { threaten: 2.5, halfneg: true, }, subSkill: { block: { mod: { cardEnabled: function (card, player) { if (!player.storage.scschihe_blocker) return; var suit = get.suit(card); if (suit == "none" || suit == "unsure") return; var evt = _status.event; if (evt.name != "chooseToUse") evt = evt.getParent("chooseToUse"); if (!evt || !evt.respondTo || evt.respondTo[1].name != "sha") return; if (player.storage.scschihe_blocker.includes(suit)) return false; }, }, trigger: { player: ["damageBefore", "damageCancelled", "damageZero"], target: ["shaMiss", "useCardToExcluded", "useCardToEnd"], global: ["useCardEnd"], }, forced: true, firstDo: true, charlotte: true, popup: false, onremove: function (player) { delete player.storage.scschihe_block; delete player.storage.scschihe_blocker; }, filter: function (event, player) { if (!event.card || !player.storage.scschihe_block) return false; for (var i of player.storage.scschihe_block) { if (i[0] == event.card) return true; } return false; }, content: function () { var storage = player.storage.scschihe_block; for (var i = 0; i < storage.length; i++) { if (storage[i][0] == trigger.card) { storage.splice(i--, 1); } } if (!storage.length) player.removeSkill("scschihe_block"); else lib.skill.scschihe.updateBlocker(target); }, }, }, }, //郭胜 scsniqu: { audio: 1, enable: "phaseUse", usable: 1, filterTarget: true, selectTarget: 1, content: function () { target.damage("fire"); }, ai: { expose: 0.2, order: 5, result: { target: function (player, target) { return get.damageEffect(target, player, target, "fire") / 10; }, }, }, }, //高望 scsanruo: { audio: 1, enable: ["chooseToUse", "chooseToRespond"], prompt: "将一张♥牌当做桃,♦牌当做火杀,♣牌当做闪,♠牌当做无懈可击使用或打出", viewAs: function (cards, player) { var name = false; var nature = null; switch (get.suit(cards[0], player)) { case "club": name = "shan"; break; case "diamond": name = "sha"; nature = "fire"; break; case "spade": name = "wuxie"; break; case "heart": name = "tao"; break; } if (name) return { name: name, nature: nature }; return null; }, check: function (card) { var player = _status.event.player; if (_status.event.type == "phase") { var max = 0; var name2; var list = ["sha", "tao"]; var map = { sha: "diamond", tao: "heart" }; for (var i = 0; i < list.length; i++) { var name = list[i]; if ( player.countCards("hes", function (card) { return (name != "sha" || get.value(card) < 5) && get.suit(card, player) == map[name]; }) > 0 && player.getUseValue({ name: name, nature: name == "sha" ? "fire" : null }) > 0 ) { var temp = get.order({ name: name, nature: name == "sha" ? "fire" : null }); if (temp > max) { max = temp; name2 = map[name]; } } } if (name2 == get.suit(card, player)) return name2 == "diamond" ? 5 - get.value(card) : 20 - get.value(card); return 0; } return 1; }, position: "hes", filterCard: function (card, player, event) { event = event || _status.event; var filter = event._backup.filterCard; var name = get.suit(card, player); if (name == "club" && filter({ name: "shan", cards: [card] }, player, event)) return true; if (name == "diamond" && filter({ name: "sha", cards: [card], nature: "fire" }, player, event)) return true; if (name == "spade" && filter({ name: "wuxie", cards: [card] }, player, event)) return true; if (name == "heart" && filter({ name: "tao", cards: [card] }, player, event)) return true; return false; }, filter: function (event, player) { var filter = event.filterCard; if (filter(get.autoViewAs({ name: "sha", nature: "fire" }, "unsure"), player, event) && player.countCards("hes", { suit: "diamond" })) return true; if (filter(get.autoViewAs({ name: "shan" }, "unsure"), player, event) && player.countCards("hes", { suit: "club" })) return true; if (filter(get.autoViewAs({ name: "tao" }, "unsure"), player, event) && player.countCards("hes", { suit: "heart" })) return true; if (filter(get.autoViewAs({ name: "wuxie" }, "unsure"), player, event) && player.countCards("hes", { suit: "spade" })) return true; return false; }, precontent: function () { "step 0"; player.addTempSkill("scsanruo_effect"); }, ai: { respondSha: true, respondShan: true, skillTagFilter: function (player, tag) { var name; switch (tag) { case "respondSha": name = "diamond"; break; case "respondShan": name = "club"; break; case "save": name = "heart"; break; } if (!player.countCards("hes", { suit: name })) return false; }, order: function (item, player) { if (player && _status.event.type == "phase") { var max = 0; var list = ["sha", "tao"]; var map = { sha: "diamond", tao: "heart" }; for (var i = 0; i < list.length; i++) { var name = list[i]; if ( player.countCards("hes", function (card) { return (name != "sha" || get.value(card) < 5) && get.suit(card, player) == map[name]; }) > 0 && player.getUseValue({ name: name, nature: name == "sha" ? "fire" : null, }) > 0 ) { var temp = get.order({ name: name, nature: name == "sha" ? "fire" : null, }); if (temp > max) max = temp; } } max /= 1.1; return max; } return 2; }, }, hiddenCard: function (player, name) { if (name == "wuxie" && _status.connectMode && player.countCards("hes") > 0) return true; if (name == "wuxie") return player.countCards("hes", { suit: "spade" }) > 0; if (name == "tao") return player.countCards("hes", { suit: "heart" }) > 0; }, subSkill: { effect: { audio: "scsanruo", trigger: { player: ["useCard", "respond"], }, filter: function (event, player) { return event.skill == "scsanruo"; }, direct: true, forced: true, charlotte: true, content: function () { "step 0"; var name = trigger.card.name; var next = game.createEvent("scsanruo_" + name); next.player = player; next.setContent(lib.skill.scsanruo_effect[name == "shan" ? "sha" : name] || function () {}); }, sha: function () { "step 0"; var trigger = event.getParent().getTrigger(); if (trigger.name == "useCard") { var target = lib.skill.chongzhen.logTarget(trigger, player); } else { var target = trigger.source; } event.target = target; if (!target || !target.countGainableCards(player, "he")) event._result = { bool: false }; else player .chooseBool(get.prompt("scsanruo_effect", target), "获得该角色的一张牌") .set("ai", () => { return _status.event.goon; }) .set("goon", get.attitude(player, target) < 1); "step 1"; if (result.bool) { player.logSkill("scsanruo_effect", target); player.gainPlayerCard(target, "he", true); } }, tao: function () { "step 0"; player .chooseTarget(get.prompt("scsanruo"), "获得一名其他角色的一张牌", (card, player, target) => { return target.countGainableCards(player, "he") && target != player; }) .set("ai", target => { return 1 - get.attitude(_status.event.player, target); }); "step 1"; if (result.bool) { var target = result.targets[0]; player.logSkill("scsanruo_effect", target); player.gainPlayerCard(target, "he", true); } }, wuxie: function () { "step 0"; var trigger = event.getParent().getTrigger(); if (!trigger.respondTo) { event.finish(); return; } var target = trigger.respondTo[0]; event.target = target; if (!target || !target.countGainableCards(player, player == target ? "e" : "he")) event._result = { bool: false }; else player .chooseBool(get.prompt("scsanruo_effect", target), "获得该角色的一张牌") .set("ai", () => { return _status.event.goon; }) .set("goon", get.attitude(player, target) < 1); "step 1"; if (result.bool) { player.logSkill("scsanruo_effect", target); player.gainPlayerCard(target, player == target ? "e" : "he", true); } }, }, }, }, scsmiaoyu: { audio: "scsanruo", enable: ["chooseToUse", "chooseToRespond"], prompt: "将至多两张♦牌当作火【杀】,♥牌当作【桃】,♣牌当作【闪】,♠牌当作【无懈可击】使用或打出", viewAs: function (cards, player) { var name = false; var nature = null; switch (get.suit(cards[0], player)) { case "club": name = "shan"; break; case "diamond": name = "sha"; nature = "fire"; break; case "spade": name = "wuxie"; break; case "heart": name = "tao"; break; } //返回判断结果 if (name) return { name: name, nature: nature }; return null; }, check: function (card) { if (ui.selected.cards.length) return 0; var player = _status.event.player; if (_status.event.type == "phase") { var max = 0; var name2; var list = ["sha", "tao"]; var map = { sha: "diamond", tao: "heart" }; for (var i = 0; i < list.length; i++) { var name = list[i]; if ( player.countCards("hes", function (card) { return (name != "sha" || get.value(card) < 5) && get.suit(card, player) == map[name]; }) > 0 && player.getUseValue({ name: name, nature: name == "sha" ? "fire" : null }) > 0 ) { var temp = get.order({ name: name, nature: name == "sha" ? "fire" : null }); if (temp > max) { max = temp; name2 = map[name]; } } } if (name2 == get.suit(card, player)) return name2 == "diamond" ? 5 - get.value(card) : 20 - get.value(card); return 0; } return 1; }, selectCard: [1, 2], complexCard: true, position: "hes", filterCard: function (card, player, event) { if (ui.selected.cards.length) return get.suit(card, player) == get.suit(ui.selected.cards[0], player); event = event || _status.event; var filter = event._backup.filterCard; var name = get.suit(card, player); if (name == "club" && filter({ name: "shan", cards: [card] }, player, event)) return true; if (name == "diamond" && filter({ name: "sha", cards: [card], nature: "fire" }, player, event)) return true; if (name == "spade" && filter({ name: "wuxie", cards: [card] }, player, event)) return true; if (name == "heart" && filter({ name: "tao", cards: [card] }, player, event)) return true; return false; }, filter: function (event, player) { var filter = event.filterCard; if (filter(get.autoViewAs({ name: "sha", nature: "fire" }, "unsure"), player, event) && player.countCards("hes", { suit: "diamond" })) return true; if (filter(get.autoViewAs({ name: "shan" }, "unsure"), player, event) && player.countCards("hes", { suit: "club" })) return true; if (filter(get.autoViewAs({ name: "tao" }, "unsure"), player, event) && player.countCards("hes", { suit: "heart" })) return true; if (filter(get.autoViewAs({ name: "wuxie" }, "unsure"), player, event) && player.countCards("hes", { suit: "spade" })) return true; return false; }, precontent: function () { player.addTempSkill("scsmiaoyu_num"); player.addTempSkill("scsmiaoyu_discard"); }, ai: { respondSha: true, respondShan: true, skillTagFilter: function (player, tag) { var name; switch (tag) { case "respondSha": name = "diamond"; break; case "respondShan": name = "club"; break; case "save": name = "heart"; break; } if (!player.countCards("hes", { suit: name })) return false; }, order: function (item, player) { if (player && _status.event.type == "phase") { var max = 0; var list = ["sha", "tao"]; var map = { sha: "diamond", tao: "heart" }; for (var i = 0; i < list.length; i++) { var name = list[i]; if ( player.countCards("hes", function (card) { return (name != "sha" || get.value(card) < 5) && get.suit(card, player) == map[name]; }) > 0 && player.getUseValue({ name: name, nature: name == "sha" ? "fire" : null, }) > 0 ) { var temp = get.order({ name: name, nature: name == "sha" ? "fire" : null, }); if (temp > max) max = temp; } } max /= 1.1; return max; } return 2; }, }, hiddenCard: function (player, name) { if (name == "wuxie" && _status.connectMode && player.countCards("hs") > 0) return true; if (name == "wuxie") return player.countCards("hes", { suit: "spade" }) > 0; if (name == "tao") return player.countCards("hes", { suit: "heart" }) > 0; }, subSkill: { num: { charlotte: true, trigger: { player: "useCard" }, filter: function (event) { return ["sha", "tao"].includes(event.card.name) && event.skill == "scsmiaoyu" && event.cards && event.cards.length == 2; }, forced: true, popup: false, content: function () { trigger.baseDamage++; }, }, discard: { charlotte: true, trigger: { player: ["useCardAfter", "respondAfter"] }, autodelay: function (event) { return event.name == "respond" ? 0.5 : false; }, filter: function (event, player) { return ["shan", "wuxie"].includes(event.card.name) && event.skill == "scsmiaoyu" && event.cards && event.cards.length == 2 && _status.currentPhase && _status.currentPhase != player && _status.currentPhase.countDiscardableCards(player, "he"); }, forced: true, popup: false, content: function () { player.line(_status.currentPhase, "green"); player.discardPlayerCard(_status.currentPhase, "he", true); }, }, }, }, //牵招 mbshihe: { audio: 2, enable: "phaseUse", usable: 1, filter: function (event, player) { return game.hasPlayer(current => player.canCompare(current)); }, filterTarget: function (card, player, target) { return player.canCompare(target); }, content: function () { "step 0"; player.chooseToCompare(target); "step 1"; if (result.bool) { target.addTempSkill("mbshihe_prevent", { player: "phaseAfter" }); target.markAuto("mbshihe_prevent", [player]); } else { var cards = player.getCards("he", card => { return lib.filter.cardDiscardable(card, player, "mbshihe"); }); if (cards.length > 0) player.discard(cards.randomGet()); } }, ai: { order: 6, result: { player: function (player, target) { if ((get.realAttitude || get.attitude)(target, player) >= 0 || get.damageEffect(player, target, player) >= 0) return 0; var card = player.getCards("h").sort(function (a, b) { return get.number(b) - get.number(a); })[0]; return get.number(card) >= 10 || (get.number(card) >= 7 && target.countCards("h") <= 2) ? 1 : -1; }, }, }, subSkill: { prevent: { trigger: { source: "damageBegin2" }, filter: function (event, player) { if (get.mode() == "identity") return player.getStorage("mbshihe_prevent").includes(event.player); return player.getStorage("mbshihe_prevent").some(target => event.player.isFriendOf(target)); }, onremove: true, forced: true, charlotte: true, content: function () { trigger.cancel(); }, mark: true, marktext: "吓", intro: { content: function (storage, player) { var targets = storage.filter(i => i.isIn()); return "被" + get.translation(targets) + "吓到了,对他" + (targets.length > 1 ? "们" : "") + (get.mode() != "identity" ? "和他的友方角色" : "") + "打不出伤害"; }, }, ai: { effect: { player: function (card, player, target, current) { if (get.tag(card, "damage")) { var bool = false; if (get.mode() == "identity" && player.getStorage("mbshihe_prevent").includes(target)) bool = true; if (get.mode() != "identity" && player.getStorage("mbshihe_prevent").some(targetx => target.isFriendOf(targetx))) bool = true; if (bool) return "zeroplayertarget"; } }, }, }, }, }, }, mbzhenfu: { audio: 2, trigger: { player: "phaseJieshuBegin" }, filter: function (event, player) { return player.hasHistory("lose", evt => { return evt.type == "discard"; }); }, direct: true, content: function () { "step 0"; player .chooseTarget(get.prompt("mbzhenfu"), "令一名其他角色获得1点护甲", (card, player, target) => { return target != player && target.hujia < 5; }) .set("ai", target => { return Math.max(0, get.threaten(target)) * get.attitude(_status.event.player, target); }); "step 1"; if (result.bool) { var target = result.targets[0]; player.logSkill("mbzhenfu", target); target.changeHujia(1, null, true); } }, ai: { expose: 0.2, }, }, //☆胃炎 mbguli: { audio: 2, enable: "phaseUse", filterCard: true, selectCard: -1, position: "h", filter: function (event, player) { if (player.hasSkill("mbguli_used")) return false; var hs = player.getCards("h"); if (!hs.length) return false; for (var card of hs) { var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); if (mod2 === false) return false; } return event.filterCard(get.autoViewAs({ name: "sha" }, hs)); }, viewAs: { name: "sha", storage: { mbguli: true }, }, onuse: function (links, player) { player.addTempSkill("mbguli_used", "phaseUseAfter"); }, ai: { order: 1, threaten: 1.14, unequip_ai: true, skillTagFilter: function (player, tag, arg) { if (arg && arg.name == "sha" && arg.card && arg.card.storage && arg.card.storage.mbguli) return true; return false; }, }, subSkill: { used: { audio: "mbguli", trigger: { global: "useCardAfter" }, charlotte: true, prompt2: "失去1点体力,然后将手牌摸至体力上限", check: function (event, player) { var num = player.maxHp - player.countCards("h"); return (num >= 3 && player.hp >= 2) || (num >= 2 && player.hp >= 3); }, filter: function (event, player) { return ( event.card.storage && event.card.storage.mbguli && game.hasPlayer2(current => { return current.hasHistory("sourceDamage", evt => evt.card == event.card); }) ); }, content: function () { "step 0"; player.loseHp(); "step 1"; player.drawTo(player.maxHp); }, group: "mbguli_unequip", }, unequip: { trigger: { player: "useCardToPlayered", }, filter: function ({ card }) { return card.name == "sha" && card.storage && card.storage.mbguli; }, forced: true, popup: false, logTarget: "target", content: function () { trigger.target.addTempSkill("qinggang2"); trigger.target.storage.qinggang2.add(trigger.card); trigger.target.markSkill("qinggang2"); }, }, }, }, mbaosi: { audio: 2, trigger: { source: "damageSource" }, forced: true, filter: function (event, player) { return player.inRange(event.player) && player.isPhaseUsing() && event.player.isIn() && !player.getStorage("mbaosi_inf").includes(event.player); }, logTarget: "player", content: function () { player.addTempSkill("mbaosi_inf", "phaseUseAfter"); player.markAuto("mbaosi_inf", [trigger.player]); }, subSkill: { inf: { charlotte: true, onremove: true, forced: true, intro: { content: "对$使用牌无次数限制" }, mod: { cardUsableTarget: function (card, player, target) { if (player.getStorage("mbaosi_inf").includes(target)) return true; }, }, }, }, }, // 界曹休 xinqingxi: { audio: 2, usable: 1, trigger: { source: "damageBegin1" }, check: function (event, player) { return get.attitude(player, event.player) < 0; }, filter: function (event, player) { return event.player != player; }, content: function () { "step 0"; var num = Math.max(1, 4 - get.distance(player, trigger.player)); if (trigger.player.countCards("h") < num) { event._result = { bool: false }; } else { trigger.player.chooseToDiscard(num, "弃置" + get.cnNumber(num) + "张手牌,或令" + get.translation(player) + "对你造成的此伤害+1").set("ai", function (card) { var player = _status.event.player; if (player.hp == 1) { if (get.type(card) == "basic") { return 8 - get.value(card); } else { return 10 - get.value(card); } } else { if (num > 2) { return 0; } return 8 - get.value(card); } }); } "step 1"; if (!result.bool) { trigger.num++; } }, }, // 界朱桓 xinpingkou: { audio: 2, trigger: { player: "phaseEnd" }, direct: true, filter: function (event, player) { return player.getHistory("skipped").length > 0; }, content: function () { "step 0"; player .chooseTarget([1, player.getHistory("skipped").length], get.prompt2("xinpingkou"), function (card, player, target) { return target != player; }) .set("ai", function (target) { var player = _status.event.player; return get.damageEffect(target, player, player); }); "step 1"; if (result.bool) { player.logSkill("xinpingkou", result.targets); event.targets = result.targets.slice(0).sortBySeat(); } else { event.finish(); } "step 2"; if (event.targets && event.targets.length) { event.targets.shift().damage(); event.redo(); } "step 3"; var card = get.cardPile2(card => get.type(card, false) == "equip"); if (card) player.gain(card, "gain2"); }, ai: { combo: "fenli", effect: { target: function (card) { if (card.name == "lebu" || card.name == "bingliang") return 0.5; }, }, }, }, // 彭羕 spdaming: { audio: 3, trigger: { global: "phaseBefore", player: "enterGame" }, forced: true, locked: false, global: "spdaming_give", filter: function (event, player) { return event.name != "phase" || game.phaseNumber == 0; }, change: function (player, num) { if (!player.storage.spdaming) player.storage.spdaming = 0; if (!num) return; player.storage.spdaming += num; player.markSkill("spdaming"); game.log(player, (num > 0 ? "获得了" : "减少了") + get.cnNumber(Math.abs(num)) + "点“达命”值"); }, content: function () { lib.skill.spdaming.change(player, 1); }, intro: { name: "达命值", markcount: function (storage, player) { return (storage || 0).toString(); }, content: "当前有#点“达命”值", }, subSkill: { used: { charlotte: true }, give: { audio: 2, enable: "phaseUse", nopop: true, filter: function (event, player) { if (!player.countCards("he")) return false; return game.hasPlayer(current => { return current != player && current.hasSkill("spdaming") && !current.hasSkill("spdaming_used"); }); }, selectCard: 1, filterCard: true, filterTarget: function (card, player, target) { return target.hasSkill("spdaming") && !target.hasSkill("spdaming_used"); }, selectTarget: function () { var player = _status.event.player; var targets = game.filterPlayer(current => { return current != player && current.hasSkill("spdaming") && !current.hasSkill("spdaming_used"); }); return targets.length > 1 ? 1 : -1; }, complexSelect: true, prompt: function () { var player = _status.event.player; var targets = game.filterPlayer(function (current) { return current != player && current.hasSkill("spdaming") && !current.hasSkill("spdaming_used"); }); return "将一张牌交给" + get.translation(targets) + (targets.length > 1 ? "中的一人" : ""); }, position: "he", discard: false, lose: false, delay: false, check: function (card) { var player = _status.event.player; if ( game.hasPlayer(current => { return lib.skill.spdaming_give.filterTarget(null, player, current) && get.attitude(player, current) > 0; }) ) { return 6 + Math.random() - get.value(card) / 15; } return 0; }, content: function () { "step 0"; game.trySkillAudio("spdaming", target); player.give(cards, target); if (!game.hasPlayer(current => current != player && current != target)) event.finish(); target.addTempSkill("spdaming_used", "phaseUseAfter"); "step 1"; var type = get.type(cards[0], "trick", target); event.cardtype = type; var str = get.translation(type), user = get.translation(player); target .chooseTarget("达命:选择另一名其他角色", "若该角色有" + str + "牌,其将一张该类型的牌交给" + user + ",你获得1点“达命”值;否则你将" + get.translation(cards) + "交给" + user, (card, player, target) => { return target != player && target != _status.event.getParent().player; }) .set("ai", target => 1 - get.attitude(_status.event.player, target)); "step 2"; if (result.bool) { var targetx = result.targets[0], type = event.cardtype; target.line(targetx); event.targetx = targetx; if (targetx.countCards("he", { type: type }) > 0) { targetx .chooseCard("交给" + get.translation(player) + "一张" + get.translation(type) + "牌", "he", true, card => { return get.type(card) == _status.event.getParent().cardtype; }) .set("ai", card => 10 - get.value(card)); } else { var cards = cards.filter(i => get.owner(i) == target); if (cards.length) target.give(cards, player); event.finish(); } } else event.finish(); "step 3"; if (result.bool) { event.targetx.give(result.cards, player); event.targetx.line(player); lib.skill.spdaming.change(target, 1); game.delayx(); } }, ai: { expose: 0.2, order: 10, result: { target: 1 }, }, }, }, }, spxiaoni: { audio: 2, enable: "phaseUse", usable: 1, locked: false, filter: function (event, player) { return (player.storage.spdaming || 0) > 0; }, chooseButton: { dialog: function (event, player) { var list = []; for (var name of lib.inpile) { if (name == "sha") { list.push(["基本", "", "sha"]); for (var i of lib.inpile_nature) list.push(["基本", "", "sha", i]); } if (!get.tag({ name: name }, "damage")) continue; if (get.type2(name) == "trick") list.push(["锦囊", "", name]); } return ui.create.dialog("嚣逆", [list, "vcard"]); }, filter: function (button, player) { return lib.filter.filterCard({ name: button.link[2] }, player, _status.event.getParent()); }, check: function (button) { var player = _status.event.player; if (player.countCards("hs", button.link[2]) > 0) return 0; var effect = player.getUseValue(button.link[2]); if (effect > 0) return effect; return 0; }, backup: function (links, player) { return { filterCard: true, audio: "spxiaoni", selectCard: 1, popname: true, check: function (card) { return 6 - get.value(card); }, position: "hes", viewAs: { name: links[0][2], nature: links[0][3] }, onuse: function (result, player) { lib.skill.spdaming.change(player, -result.targets.length); }, }; }, prompt: function (links, player) { return "将一张牌当" + (get.translation(links[0][3]) || "") + "【" + get.translation(links[0][2]) + "】使用"; }, }, mod: { maxHandcardBase: function (player, num) { return Math.min(Math.max(0, player.storage.spdaming || 0), player.hp); }, }, ai: { order: 4, result: { player: 1, }, threaten: 1.4, combo: "spdaming", }, subSkill: { backup: {}, }, }, // 灭霸 zhujian: { audio: 2, enable: "phaseUse", usable: 1, filterTarget: function (card, player, target) { return target.countCards("e") > 0; }, selectTarget: [2, Infinity], multiline: true, multitarget: true, filter: function (event, player) { return game.countPlayer(current => current.countCards("e") > 0) >= 2; }, content: function () { game.asyncDraw(targets); }, ai: { order: 8, result: { target: 1 }, }, }, duansuo: { audio: 2, enable: "phaseUse", usable: 1, filterTarget: function (card, player, target) { return target.isLinked(); }, selectTarget: [1, Infinity], multiline: true, multitarget: true, filter: function (event, player) { return game.countPlayer(current => current.isLinked()); }, content: function () { "step 0"; event.targets = targets.sortBySeat(); for (var i of event.targets) { i.link(false); } "step 1"; for (var i of targets) { i.damage("fire"); } }, ai: { order: 2, result: { target: -1 }, }, }, // 界朱治 sbanguo: { audio: 3, trigger: { global: "phaseBefore", player: "enterGame" }, forced: true, locked: false, direct: true, group: ["sbanguo_move", "sbanguo_damage", "sbanguo_dying"], filter: function (event, player) { return game.hasPlayer(current => current != player) && (event.name != "phase" || game.phaseNumber == 0); }, content: function () { "step 0"; player.chooseTarget("安国:令一名其他角色获得“安国”标记", lib.filter.notMe, true); "step 1"; if (result.bool) { var target = result.targets[0]; player.logSkill("sbanguo", target); target.addMark("sbanguo_mark", 1, false); target.addAdditionalSkill("sbanguo_" + player.playerid, "sbanguo_mark"); target.addMark("sbanguo_marked", 1, false); } }, subSkill: { mark: { onremove: true, marktext: "安", charlotte: true, intro: { name: "安国", name2: "安国", content: "已拥有“安国”标记", }, mod: { maxHandcardBase: function (player, num) { return player.maxHp; }, }, }, move: { audio: "sbanguo", direct: true, trigger: { player: "phaseUseBegin" }, filter: function (event, player) { return game.hasPlayer(current => current.hasSkill("sbanguo_mark")) && game.hasPlayer(current => !current.hasMark("sbanguo_marked") && current != player); }, content: function () { "step 0"; var targets = game.filterPlayer(current => current.hasSkill("sbanguo_mark")); var prompt2 = targets.length == 1 ? "将" + get.translation(targets[0]) + "的“安国”交给一名未获得过“安国”的其他角色" : "选择一名有“安国”的角色,将该标记交给一名未获得过“安国”的其他角色"; player .chooseTarget(get.prompt("sbanguo"), prompt2, targets.length == 1 ? 1 : 2, (card, player, target) => { if (ui.selected.targets.length == 0 && _status.event.targets.length > 1) return target.hasSkill("sbanguo_mark"); return !target.hasMark("sbanguo_marked") && target != player; }) .set("ai", target => { var player = _status.event.player; if (ui.selected.targets.length == 0 && _status.event.targets.length > 1) return -get.attitude(player, target); return get.attitude(player, _status.event.targets[0]) < get.attitude(player, target); }) .set("targets", targets); "step 1"; if (result.bool) { var targets = result.targets; if (targets.length == 1) { var target1 = game.filterPlayer(current => current.hasSkill("sbanguo_mark"))[0]; var target2 = targets[0]; } else { var target1 = targets[0]; var target2 = targets[1]; } player.logSkill("sbanguo_move", target2, false); player.line2([target1, target2], "green"); var map = target1.additionalSkills; for (var key in map) { if (key.indexOf("sbanguo_") != 0) continue; var id = parseInt(key.slice(8)); target1.removeAdditionalSkill("sbanguo_" + id); target2.addMark("sbanguo_mark", 1, false); target2.addAdditionalSkill("sbanguo_" + id, "sbanguo_mark"); target2.addMark("sbanguo_marked", 1, false); } } }, }, damage: { audio: "sbanguo", forced: true, locked: false, trigger: { player: "damageBegin4" }, filter: function (event, player) { if (!game.hasPlayer(current => current.hasSkill("sbanguo_mark"))) return false; if (event.source && event.source.isIn() && event.source.hasSkill("sbanguo_mark")) return false; return event.num >= player.hp; }, content: function () { trigger.cancel(); }, ai: { nofire: true, nothunder: true, nodamage: true, effect: { target: function (card, player, target, current) { if (!game.hasPlayer(current => current.hasSkill("sbanguo_mark"))) return; if (player.hasSkill("sbanguo_mark")) return; if (get.tag(card, "damage")) { if (target.hp <= 1) return [0, 0]; return 0.5; } }, }, }, }, dying: { audio: "sbanguo", forced: true, locked: false, trigger: { global: "dying" }, filter: function (event, player) { var skills = event.player.additionalSkills["sbanguo_" + player.playerid]; return skills && skills.length; }, logTarget: "player", content: function () { "step 0"; trigger.player.removeAdditionalSkill("sbanguo_" + player.playerid); var num = 1 - trigger.player.hp; if (num > 0) trigger.player.recover(num); "step 1"; var hp = player.hp - 1, maxhp = player.maxHp - 1; if (hp > 0 && maxhp > 0) { player .chooseControl() .set("prompt", "安国:请选择一项") .set("choiceList", ["失去" + hp + "点体力,令" + get.translation(trigger.player) + "获得1点护甲", "减" + maxhp + "点体力上限,令" + get.translation(trigger.player) + "获得1点护甲"]) .set("ai", () => "选项一"); } else if (hp > 0) event._result = { control: "选项一" }; else if (maxhp > 0) event._result = { control: "选项二" }; else event.finish(); "step 2"; if (result.control == "选项一") { var num = player.hp - 1; if (num > 0) player.loseHp(num); } else { var num = player.maxHp - 1; if (num > 0) player.loseMaxHp(num); } trigger.player.changeHujia(1, null, true); }, }, }, }, // 界吴懿 sbbenxi: { audio: 3, trigger: { player: "phaseUseBegin", }, filter: function (event, player) { return player.countDiscardableCards(player, "he") > 0; }, direct: true, content: function () { "step 0"; player .chooseToDiscard(get.prompt2("sbbenxi"), [1, Infinity], "he") .set("logSkill", "sbbenxi") .set("ai", card => { var player = _status.event.player; if (ui.selected.cards.length < _status.event.num) return 100 - (get.useful(card, player) + player.getUseValue(card) / 3); return 0; }) .set( "num", (function () { var count = 0; var list = [], list2 = []; var targets = game.filterPlayer(current => get.distance(player, current) >= 1); var cards = player.getCards("hs", card => { return player.hasUseTarget(card, false) && ["basic", "trick"].includes(get.type(card, false, player)) && get.info(card).allowMultiple != false; }); var cards2 = player .getCards("he") .filter(i => lib.filter.cardDiscardable(i, player, "sbbenxi")) .sort((a, b) => { return get.useful(a, player) + player.getUseValue(a) / 3 - (get.useful(b, player) + player.getUseValue(b) / 3); }); for (var i = 0; i < cards2.length; i++) { count = 0; list = []; for (var card of cards) { var num = i + 1; if (cards2.slice(0, num).includes(card)) continue; if (get.tag(card, "damage") && i > 0) count += get.effect(player, { name: "draw" }, player); var targets2 = targets.filter(current => { return player.canUse(card, current, false) && get.distance(player, current) <= num && get.effect(current, card, player, player) > 0; }); targets2 = targets2.map(target => get.effect(target, card, player, player)).sort((a, b) => b - a); targets2.slice(0, num).forEach(eff => (count += eff)); list.push(count - 1.2 * get.value(cards2[i])); } var val = list.sort((a, b) => b - a)[0]; if (!isNaN(val)) list2.push([val, i]); } list2 = list2.filter(i => i[0] > 0); if (!list2.length) return 0; return list2.sort((a, b) => b[0] - a[0])[0][1]; })() ); "step 1"; if (result.bool) { var num = result.cards.length; player.addTempSkill("sbbenxi_effect", "phaseUseAfter"); player.addTempSkill("sbbenxi_effect2", "phaseUseAfter"); player.addMark("sbbenxi_effect2", num, false); } }, subSkill: { effect: { audio: "sbbenxi", trigger: { player: "useCard2" }, forced: true, charlotte: true, direct: true, onremove: true, filter: function (event, player) { var type = get.type(event.card, false); return type == "basic" || type == "trick"; }, content: function () { "step 0"; var num = player.countMark("sbbenxi_effect2"); player.removeSkill("sbbenxi_effect"); player.addTempSkill("sbbenxi_effect3", "phaseUseAfter"); player.markAuto("sbbenxi_effect3", [trigger.card]); var filter = function (event, player) { var card = event.card, info = get.info(card); if (info.allowMultiple == false) return false; if (event.targets && !info.multitarget) { if ( game.hasPlayer(function (current) { return !event.targets.includes(current) && lib.filter.targetEnabled2(card, player, current) && get.distance(player, current) == 1; }) ) { return true; } } return false; }; if (!filter(trigger, player)) event.finish(); else { var prompt = "为" + get.translation(trigger.card) + "增加至多" + get.cnNumber(num) + "个距离为1的目标?"; trigger.player .chooseTarget(get.prompt("sbbenxi_effect"), prompt, [1, num], function (card, player, target) { var player = _status.event.player; return !_status.event.targets.includes(target) && lib.filter.targetEnabled2(_status.event.card, player, target) && get.distance(player, target) == 1; }) .set("ai", function (target) { var trigger = _status.event.getTrigger(); var player = _status.event.player; return get.effect(target, trigger.card, player, player); }) .set("card", trigger.card) .set("targets", trigger.targets); } "step 1"; if (result.bool) { if (!event.isMine() && !event.isOnline()) game.delayx(); } else event.finish(); "step 2"; player.logSkill("sbbenxi_effect", result.targets); game.log(result.targets, "也成为了", trigger.card, "的目标"); trigger.targets.addArray(result.targets); }, ai: { effect: { target_use(card, player, target) { if (player.canUse(card, target) && get.distance(player, target) != 1) return 1.2; }, }, }, }, effect2: { audio: "sbbenxi", trigger: { global: "useCardAfter", }, forced: true, charlotte: true, onremove: true, filter: function (event, player) { return ( player.getStorage("sbbenxi_effect3").includes(event.card) && game.hasPlayer2(current => { return current.hasHistory("damage", evt => { return event.card == evt.card; }); }) ); }, content: function () { player.draw(5); }, mod: { aiOrder: function (player, card, num) { var evt = _status.event.getParent("phaseUse"); if (!evt || evt.player != player) return; if ( player.hasHistory("useCard", evtx => { return evtx.getParent("phaseUse") == evt && ["basic", "trick"].includes(get.type(evtx.card)); }) ) return; if (get.tag(card, "damage") || get.type(card) == "equip") return num + 10; }, globalFrom: function (from, to, distance) { return distance - from.countMark("sbbenxi_effect2"); }, }, marktext: "奔", intro: { content: function (storage, player) { var str = "于此阶段至其他角色的距离-" + storage; if (player.hasSkill("sbbenxi_effect")) str += ";使用下一张基本牌或普通锦囊牌选择目标后,可以增加" + get.cnNumber(storage) + "个目标"; return str; }, }, }, effect3: { forced: true, charlotte: true, popup: false, onremove: true, }, }, }, // 杨阜 jiebing: { audio: 2, trigger: { player: "damageEnd", }, direct: true, forced: true, filter: function (event, player) { return game.hasPlayer(current => { return current != event.source && current != player && current.countGainableCards(player, "he"); }); }, content: function () { "step 0"; player .chooseTarget("借兵:选择一名其他角色", get.skillInfoTranslation("jiebing"), true, (card, player, target) => { return player != target && target != _status.event.getTrigger().source && target.countGainableCards(player, "he"); }) .set("ai", target => get.effect(target, { name: "shunshou_copy2" }, player, player) /** (target.countCards('he')>1?1.5:1)*/); "step 1"; if (result.bool) { var target = result.targets[0]; player.logSkill("jiebing", target); if (target.ai.shown > 0) player.addExpose(0.15); var cards = target.getGainableCards(player, "he").randomGets(1); event.cards = cards; player.gain(target, cards, "give", "bySelf"); player.showCards(cards, "借兵"); } else event.finish(); "step 2"; for (var card of cards) { if (get.type(card) == "equip" && player.hasUseTarget(card) && get.owner(card) == player) { player.chooseUseTarget(card, true); } } }, ai: { maixie: true, maixie_hp: true, effect: { target: function (card, player, target) { if (get.tag(card, "damage")) { if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; if (player != target && !player.getFriends().length) return; if ( game.hasPlayer(current => { return current != player && get.attitude(player, current) > 0 && current.countGainableCards(target, "he") > 0; }) ) return [1, 1]; } }, }, }, }, hannan: { audio: 2, enable: "phaseUse", usable: 1, filter: function (event, player) { return !player.hasSkillTag("noCompareSource"); }, filterTarget: function (card, player, target) { return player.canCompare(target); }, content: function () { "step 0"; player.chooseToCompare(target); "step 1"; if (!result.tie) { var players = [player, target]; if (result.bool) players.reverse(); players[1].line(players[0], "thunder"); players[0].damage(players[1], 2); } }, ai: { order: 7, result: { target: function (player, target) { var hs = player.getCards("h").sort(function (a, b) { return get.number(b) - get.number(a); }); var ts = target.getCards("h").sort(function (a, b) { return get.number(b) - get.number(a); }); if (!hs.length || !ts.length) return 0; if (get.number(hs[0]) > get.number(ts[0]) || get.number(hs[0]) - ts.length >= 9 + Math.min(2, player.hp / 2)) return get.sgnAttitude(player, target) * get.damageEffect(target, player, player); return 0; }, }, }, }, // 曹嵩 yijin: { audio: 3, trigger: { player: "phaseUseBegin" }, forced: true, direct: true, group: ["yijin_upstart", "yijin_die"], filter: function (event, player) { if (!game.hasPlayer(current => current != player && !lib.skill.yijin.getKane(current).length)) return false; return lib.skill.yijin.getKane(player).length; }, getKane: function (player) { var list = lib.skill.yijin.derivation; return list.filter(mark => player.hasMark(mark)); }, derivation: ["yijin_wushi", "yijin_jinmi", "yijin_guxiong", "yijin_tongshen", "yijin_yongbi", "yijin_houren"], getValue: function (player, mark, target) { let dis = Math.sqrt(get.distance(player, target, "absolute")); if (target.isTurnedOver()) dis++; let draw = get.effect(target, { name: "draw" }, target, target); switch (mark.slice(6)) { case "wushi": if (target.hasJudge("bingliang")) return 12 / (1 + target.getCardUsable("sha", true)); return (5 * draw) / dis + 12 / (1 + target.getCardUsable("sha", true)); case "jinmi": if (target.hasJudge("lebu") && !target.hasCard({ name: "wuxie" }, "hs")) return (draw * target.needsToDiscard(2.2)) / dis; return get.effect(target, { name: "lebu" }, player, target) + (draw * target.needsToDiscard(2.2)) / dis; case "guxiong": if (target.hasJudge("lebu")) return (-draw * target.needsToDiscard(3)) / dis; return (get.effect(target, { name: "losehp" }, target, target) * 2) / dis - (draw * target.needsToDiscard(3)) / dis; case "tongshen": if (target.isMin()) return 0; var eff = -get.damageEffect(target, player, target); if (eff <= 0) return 0; if (target.hp < 2) return eff * dis * 2; if (target.hp < 3 && target.countCards("he") < 3) return eff * dis * 1.5; if (target.hp > 3) return (eff * dis) / target.hp; return eff * dis; case "yongbi": if (target.hasJudge("bingliang") && !target.hasCard({ name: "wuxie" }, "hs")) return 0; return (get.effect(target, { name: "bingliang" }, player, target) * 2) / dis; case "houren": return (Math.min(5, 2 + target.getDamagedHp()) * get.recoverEffect(target, player, target)) / dis; } }, content: function () { "step 0"; player .chooseTarget("亿金:令一名其他角色获得1枚“金”", true, (card, player, target) => { return player != target && !lib.skill.yijin.getKane(target).length; }) .set("ai", target => { let player = _status.event.player, att = get.attitude(player, target), kane = lib.skill.yijin.getKane(player); if (Math.abs(att) > 1) att = Math.sign(att) * Math.sqrt(Math.abs(att)); return Math.max.apply( Math.max, kane.map(i => { return att * lib.skill.yijin.getValue(player, i, target); }) ); }); "step 1"; if (result.bool) { var target = result.targets[0]; event.target = target; player.logSkill("yijin", target); var kane = lib.skill.yijin.getKane(player); var choiceList = kane.map(i => { return '
    【' + get.translation(lib.translate[i + "_ab"] || get.translation(i).slice(0, 2)) + "】
    " + "
    " + get.skillInfoTranslation(i, player) + "
    "; }); player .chooseControl(kane) .set("choiceList", choiceList) .set("displayIndex", false) .set("prompt", "选择令" + get.translation(target) + "获得的“金”") .set("ai", () => { let controls = _status.event.controls, player = _status.event.player, target = _status.event.getParent().target, att = get.attitude(player, target); if (Math.abs(att) > 1) att = Math.sign(att) * Math.sqrt(Math.abs(att)); let list = controls.map(i => { return [i, att * lib.skill.yijin.getValue(player, i, target)]; }); list.sort((a, b) => b[1] - a[1]); if (list.length) return list[0][0]; return controls.randomGet(); }); } else event.finish(); "step 2"; var kane = result.control; player.removeMark(kane, 1); player.popup(kane, "metal"); player.addSkill("yijin_clear"); target.addMark(kane, 1); target.addAdditionalSkill("yijin_" + player.playerid, kane); game.delayx(); }, subSkill: { mark: { mark: true, marktext: "金", intro: { name: "金(膴仕)", name2: "金(膴仕)", markcount: function (storage, player) { return lib.skill.yijin.getKane(player).length; }, content: function (storage, player) { return "剩余金:" + get.translation(lib.skill.yijin.getKane(player)); }, }, }, upstart: { audio: "yijin", trigger: { global: "phaseBefore", player: "enterGame", }, forced: true, filter: function (event, player) { return event.name != "phase" || game.phaseNumber == 0; }, content: function () { var kane = lib.skill.yijin.derivation; for (var mark of kane) { player.addMark(mark, 1, false); player.unmarkSkill(mark); } player.addSkill("yijin_mark"); }, }, die: { audio: "yijin", trigger: { player: "phaseBegin" }, forced: true, check: () => false, filter: function (event, player) { return !lib.skill.yijin.getKane(player).length; }, content: function () { player.die(); }, }, clear: { trigger: { global: "phaseAfter", player: "die", }, charlotte: true, forced: true, popup: false, forceDie: true, filter: function (event, player) { if (event.name == "die") return true; return lib.skill.yijin.getKane(event.player).length && event.player.additionalSkills["yijin_" + player.playerid]; }, content: function () { "step 0"; if (trigger.name == "die") { game.countPlayer(current => { var skills = current.additionalSkills["yijin_" + player.playerid]; if (skills && skills.length) { current.removeAdditionalSkill("yijin_" + player.playerid); for (var i of skills) { trigger.player.removeSkill(i); } } }); event.finish(); return; } else { const skills = trigger.player.additionalSkills["yijin_" + player.playerid]; for (const mark of skills) trigger.player.removeMark(mark, 1); } "step 1"; trigger.player.removeAdditionalSkill("yijin_" + player.playerid); }, }, wushi: { charlotte: true, forced: true, trigger: { player: "phaseDrawBegin2" }, content: function () { trigger.num += 4; }, mod: { cardUsable: function (card, player, num) { if (card.name == "sha") return num + 1; }, }, marktext: "金", intro: { name: "金(膴仕)", name2: "金(膴仕)", content: "摸牌阶段多摸四张牌;使用【杀】的次数上限+1", }, }, jinmi: { charlotte: true, forced: true, trigger: { player: "phaseBegin" }, content: function () { player.skip("phaseUse"); player.skip("phaseDiscard"); }, marktext: "金", intro: { name: "金(金迷)", name2: "金(金迷)", content: "回合开始时,跳过下一个出牌阶段和弃牌阶段", }, }, guxiong: { charlotte: true, forced: true, trigger: { player: "phaseUseBegin" }, content: function () { player.loseHp(); }, ai: { neg: true, nokeep: true, }, mod: { maxHandcard: function (player, num) { return num - 3; }, }, marktext: "金", intro: { name: "金(贾凶)", name2: "金(贾凶)", content: "出牌阶段开始时,失去1点体力;手牌上限-3", }, }, tongshen: { charlotte: true, forced: true, trigger: { player: "damageBegin4" }, filter: function (event) { return !event.hasNature("thunder"); }, content: function () { trigger.cancel(); }, ai: { nofire: true, nodamage: true, effect: { target: function (card, player, target, current) { if (get.tag(card, "damage") && !get.tag(card, "thunderDamage")) return [0, 0]; }, }, }, marktext: "金", intro: { name: "金(通神)", name2: "金(通神)", content: "当你受到非雷电伤害时,防止之", }, }, yongbi: { charlotte: true, forced: true, trigger: { player: "phaseZhunbeiBegin" }, content: function () { player.skip("phaseDraw"); }, ai: { neg: true, nokeep: true, }, marktext: "金", intro: { name: "金(拥蔽)", name2: "金(拥蔽)", content: "准备阶段,跳过下一个摸牌阶段", }, }, houren: { charlotte: true, forced: true, trigger: { player: "phaseEnd" }, content: function () { player.recover(3); }, marktext: "金", intro: { name: "金(厚任)", name2: "金(厚任)", content: "回合结束时,回复3点体力", }, }, }, }, guanzong: { audio: 2, enable: "phaseUse", usable: 1, filter: function (event, player) { return game.countPlayer(current => current != player) >= 2; }, filterTarget: lib.filter.notMe, selectTarget: 2, multitarget: true, targetprompt: ["伤害来源", "受伤角色"], content: function () { targets[1].damage(targets[0], "unreal"); }, ai: { result: { target: function (player, target) { if (game.countPlayer(i => i != player) < 2) return 0; var list = game .filterPlayer(current => current != player) .map(current => { var _hp = current.hp, _maxhp = current.maxHp; current.hp = 10; current.maxHp = 10; var att = -get.sgnAttitude(player, current); var val = get.damageEffect(current, player, current) * att; current.getSkills(null, false, false).forEach(skill => { var info = get.info(skill); if (info && info.ai && (info.ai.maixie || info.ai.maixie_hp || info.ai.maixie_defend)) val = Math[val > 0 ? "max" : "min"](val > 0 ? 0.1 : -0.1, val + 2 * att); }); var eff = 100 / val + 15; current.hp = _hp; current.maxHp = _maxhp; return [current, eff]; }) .sort((a, b) => b[1] - a[1])[0]; if (list[1] < 0) return 0; var targetx = list[0], sign = get.sgnAttitude(player, target); if (ui.selected.targets.length) return target == targetx ? sign : 0; return ( sign * (game .filterPlayer(current => { return current != player && current != targetx; }) .map(current => { var _hp = targetx.hp, _maxhp = targetx.maxHp; targetx.hp = 10; targetx.maxHp = 10; var eff = -get.damageEffect(targetx, current, current); targetx.hp = _hp; targetx.maxHp = _maxhp; return [current, eff]; }) .sort((a, b) => b[1] - a[1])[0][0] == target ? 10 : 1) ); }, }, order: 9.5, expose: 0.2, }, }, //马日磾 chengye: { audio: 3, liujing_filter: [ function (card) { return get.type(card, false) == "trick" && get.tag(card, "damage", null, false) > 0; }, card => get.type(card, false) == "basic", card => get.name(card, false) == "wuxie", card => get.name(card, false) == "wuzhong", card => get.name(card, false) == "lebu", card => get.type(card, false) == "equip", ], getLiujing: function (player, index) { var filter = lib.skill.chengye.liujing_filter[index], expansion = player.getExpansions("chengye"); for (var i of expansion) { if (filter(i)) return i; } return false; }, trigger: { global: ["useCardAfter", "loseAfter", "cardsDiscardAfter", "loseAsyncAfter", "equipAfter"], }, forced: true, filter: function (event, player) { if (player == event.player) return false; if (event.name == "useCard") { if (!event.card.isCard) return false; var cards = event.cards.filterInD(); if (!cards.length) return false; } else if (event.name != "cardsDiscard") { var cards = event.getd(null, "cards2").filter(function (card) { if (get.position(card, true) != "d") return false; var type = get.type(card, false); return type == "delay" || type == "equip"; }); cards.removeArray(event.getd(player, "cards2")); if (!cards.length) return false; } else { var evtx = event.getParent(); if (evtx.name != "orderingDiscard") return false; var evt2 = evtx.relatedEvent || evtx.getParent(); if (evt2.name != "phaseJudge" || evt2.player == player) return; var cards = event.cards.filter(function (card) { if (get.position(card, true) != "d") return false; var type = get.type(card, false); return type == "delay"; }); if (!cards.length) return false; } for (var i = 0; i < 6; i++) { if (lib.skill.chengye.getLiujing(player, i)) continue; for (var j of cards) { if (lib.skill.chengye.liujing_filter[i](j)) return true; } } return false; }, content: function () { var cards, cards2 = []; if (trigger.name == "useCard") { cards = trigger.cards.filterInD(); } else if (trigger.name != "cardsDiscard") { cards = trigger.getd().filter(function (card) { if (card.original == "j" || get.position(card, true) != "d") return false; var type = get.type(card, false); return type == "delay" || type == "equip"; }); cards.removeArray(trigger.getd(player)); } else { cards = trigger.cards.filter(function (card) { if (get.position(card, true) != "d") return false; var type = get.type(card, false); return type == "delay"; }); } for (var i = 0; i < 6; i++) { if (lib.skill.chengye.getLiujing(player, i)) continue; for (var j of cards) { if (lib.skill.chengye.liujing_filter[i](j)) { cards.remove(j); cards2.push(j); break; } } if (!cards.length) break; } player.addToExpansion(cards2, "gain2").gaintag.add("chengye"); }, onremove: function (player, skill) { var cards = player.getExpansions(skill); if (cards.length) player.loseToDiscardpile(cards); }, marktext: "经", intro: { name: "六经", markcount: "expansion", content: "expansion", mark: function (dialog, storage, player) { var list = ["《诗经》", "《尚书》", "《仪礼》", "《易经》", "《乐经》", "《春秋》"]; var desc = ["伤害类锦囊牌", "基本牌", "无懈可击", "无中生有", "乐不思蜀", "装备牌"]; for (var i = 0; i < 6; i++) { dialog.addText(list[i]); var card = lib.skill.chengye.getLiujing(player, i); if (!card) dialog.addText("(缺少 " + desc[i] + ")"); else dialog.addSmall([card]); } }, }, group: "chengye_gain", subSkill: { gain: { audio: "chengye", trigger: { player: "phaseUseBegin" }, filter: function (event, player) { return player.getExpansions("chengye").length >= 6; }, forced: true, content: function () { player.gain(player.getExpansions("chengye"), "gain2"); }, }, }, }, buxu: { audio: 2, enable: "phaseUse", filter: function (event, player) { var num = (player.getStat("skill").buxu || 0) + 1; return player.countCards("he") >= num && player.getExpansions("chengye").length < 6; }, chooseButton: { chooseControl: function (event, player) { var list = ["诗经", "尚书", "仪礼", "易经", "乐经", "春秋"]; var choices = []; for (var i = 0; i < 6; i++) { if (!lib.skill.chengye.getLiujing(player, i)) choices.push(list[i]); } choices.push("cancel2"); return choices; }, check: function (event, player) { var list = [4, 3, 5, 0, 2, 1]; for (var i of list) { if (!lib.skill.chengye.getLiujing(player, i)) { return ["诗经", "尚书", "仪礼", "易经", "乐经", "春秋"][i]; } } return "cancel2"; }, dialog: function (event, player) { var num = (player.getStat("skill").buxu || 0) + 1; return ui.create.dialog("###补叙###弃置" + get.cnNumber(num) + "张牌并补充一张“六经”"); }, prompt: function (links, player) { var num = (player.getStat("skill").buxu || 0) + 1; return "弃置" + get.cnNumber(num) + "张牌并补充一张《" + links.control + "》"; }, backup: function (links, player) { return { audio: "buxu", index: ["诗经", "尚书", "仪礼", "易经", "乐经", "春秋"].indexOf(links.control), filterCard: true, position: "he", selectCard: (player.getStat("skill").buxu || 0) + 1, ai1: function (card) { var player = _status.event.player; if ( player.needsToDiscard(0, (i, player) => { return !ui.selected.cards.includes(i) && !player.canIgnoreHandcard(i); }) ) return 10 / Math.max(0.1, get.value(card)); return 5 - (player.getStat("skill").buxu || 0) - get.value(card); }, ai2: () => 1, content: function () { var filter = lib.skill.chengye.liujing_filter[lib.skill.buxu_backup.index]; var card = get.cardPile(filter); if (card) player.addToExpansion(card, "gain2").gaintag.add("chengye"); }, ai: { result: { player: 1 } }, }; }, }, ai: { combo: "chengye", order: 0.2, result: { player: 1 }, }, }, //阮慧 mingcha: { audio: 2, trigger: { player: "phaseDrawBegin1" }, forced: true, locked: false, filter: event => !event.numFixed, content: function () { "step 0"; var cards = game.cardsGotoOrdering(get.cards(3)).cards, cards2 = cards.slice(0); event.cards = cards.filter(function (i) { return get.number(i) < 9; }); // while(cards2.length>0){ // var card=cards2.pop(); // card.fix(); // ui.cardPile.insertBefore(card,ui.cardPile.firstChild); // } // game.updateRoundNumber(); player.showCards(cards, get.translation(player) + "发动了【明察】"); if (!event.cards.length) event.finish(); "step 1"; player.chooseBool("是否放弃摸牌并获得" + get.translation(cards)).set("goon", trigger.num - cards.length <= 1); "step 2"; if (result.bool) { trigger.changeToZero(); player.gain(cards, "gain2"); } else event.finish(); "step 3"; player .chooseTarget("是否随机获得其他角色的一张牌?", function (card, player, target) { return target != player && target.countCards("he") > 0; }) .set("ai", function (target) { return 3 - get.attitude(player, target); }); "step 4"; if (result.bool) { var target = result.targets[0], cards = target.getGainableCards(player, "he"); player.line(target, "green"); if (cards.length) player.gain(cards.randomGet(), target, "giveAuto", "bySelf"); } }, }, jingzhong: { audio: 2, trigger: { player: "phaseDiscardAfter" }, filter: function (event, player) { var num = 0; player.getHistory("lose", function (evt) { if (evt.type == "discard" && evt.getParent("phaseDiscard") == event) { for (var i of evt.cards2) { if (get.color(i, player) == "black") num++; } } }); return num > 1; }, direct: true, content: function () { "step 0"; player.chooseTarget(get.prompt("jingzhong"), "获得一名其他角色下回合出牌阶段内使用的牌", lib.filter.notMe).set("ai", function (target) { return Math.sqrt(target.countCards("h")) * get.threaten(target); }); "step 1"; if (result.bool) { var target = result.targets[0]; player.logSkill("jingzhong", target); player.addSkill("jingzhong_effect"); player.markAuto("jingzhong_effect", [target]); game.delayx(); } }, subSkill: { effect: { trigger: { global: "useCardAfter" }, forced: true, charlotte: true, filter: function (event, player) { if (!player.getStorage("jingzhong_effect").includes(event.player) || !event.cards.filterInD().length) return false; var evt = event.getParent("phaseUse"); if (!evt || evt.player != event.player) return false; return ( player.getHistory("useSkill", function (evtx) { return evtx.skill == "jingzhong_effect" && evtx.event.getParent("phaseUse") == evt; }).length < 3 ); }, logTarget: "player", content: function () { player.gain(trigger.cards.filterInD(), "gain2"); }, mark: true, intro: { content: "已指定$为目标" }, group: "jingzhong_remove", }, remove: { trigger: { global: "phaseAfter" }, forced: true, charlotte: true, popup: false, firstDo: true, filter: function (event, player) { return player.getStorage("jingzhong_effect").includes(event.player); }, content: function () { var storage = player.getStorage("jingzhong_effect"); storage.remove(trigger.player); if (!storage.length) player.removeSkill("jingzhong_effect"); }, }, }, }, //全琮 sbyaoming: { audio: 2, chargeSkill: true, enable: "phaseUse", filter: function (event, player) { return player.countMark("charge") > 0; }, filterTarget: true, prompt: function () { var num = _status.event.player.storage.sbyaoming_status; var list = ["弃置一名手牌数不小于你的角色的一张牌", ";或令一名手牌数不大于你的角色摸一张牌"]; if (typeof num == "number") list[num] += "(上次选择)"; return list[0] + list[1]; }, content: function () { "step 0"; player.removeMark("charge", 1); var num = target.countCards("h"), num2 = player.countCards("h"); if (num == num2 && target.countCards("he") > 0) { var choice = get.attitude(player, target) > 0 ? 1 : 0; var str = get.translation(target), choiceList = ["弃置" + str + "的一张牌", "令" + str + "摸一张牌"]; if (typeof player.storage.sbyaoming_status == "number") choiceList[player.storage.sbyaoming_status] += "(上次选择)"; var next = player.chooseControl().set("choiceList", choiceList); next.set("ai_choice", choice); next.set("ai", () => _status.event.ai_choice); } else event._result = { index: num > num2 ? 0 : 1 }; "step 1"; if (result.index == 0) { player.discardPlayerCard(target, true, "he"); } else target.draw(); if (typeof player.storage.sbyaoming_status == "number" && result.index != player.storage.sbyaoming_status) { player.addMark("charge", 1); delete player.storage.sbyaoming_status; } else { player.storage.sbyaoming_status = result.index; } }, ai: { order: 6, result: { player: function (player, target) { var att = get.attitude(player, target), eff = [0, 0]; var hs = player.countCards("h"), ht = target.countCards("h"); if (hs >= ht) { eff[0] = get.effect(target, { name: "draw" }, player, player); if (player.storage.sbyaoming_status == 0) eff[0] *= 1.2; } if (hs <= ht) { eff[1] = get.effect(target, { name: "guohe_copy2" }, player, player); if (player.storage.sbyaoming_status == 1) eff[1] *= 1.2; } return Math.max.apply(Math, eff); }, }, }, group: ["sbyaoming_damage", "sbyaoming_init"], subSkill: { damage: { trigger: { player: "damageEnd" }, direct: true, content: function () { "step 0"; var num = Math.min(trigger.num, 4 - player.countMark("charge")); if (num > 0) { player.logSkill("sbyaoming_damage"); player.addMark("charge", num); game.delayx(); } "step 1"; player.chooseTarget(get.prompt("sbyaoming"), lib.skill.sbyaoming.prompt()).set("ai", function (target) { var player = _status.event.player; return get.effect(target, "sbyaoming", player, player); }); "step 2"; if (result.bool) { player.useSkill("sbyaoming", result.targets); } }, }, init: { trigger: { global: "phaseBefore", player: "enterGame", }, forced: true, locked: false, filter: function (event, player) { return (event.name != "phase" || game.phaseNumber == 0) && player.countMark("charge") < 4; }, content: function () { player.addMark("charge", Math.min(2, 4 - player.countMark("charge"))); }, }, }, }, //手杀界荀彧 rejieming: { audio: 2, trigger: { player: "damageEnd", }, direct: true, content: function () { "step 0"; event.count = trigger.num; "step 1"; player.chooseTarget(get.prompt("rejieming"), "令一名角色摸两张牌。然后若其手牌数少于体力上限,你摸一张牌").set("ai", function (target) { var att = get.attitude(_status.event.player, target); if (att > 2) { if (target.maxHp - target.countCards("h") > 2) return 2 * att; return att; } return att / 3; }); "step 2"; if (result.bool) { event.current = result.targets[0]; player.logSkill("rejieming", event.current); player.line(event.current, "thunder"); event.current.draw(2); event.count--; } else event.finish(); "step 3"; if (event.current.countCards("h") < event.current.maxHp) { player.draw(); } "step 4"; if (event.count > 0 && player.hasSkill("rejieming")) event.goto(1); }, ai: { maixie: true, maixie_hp: true, effect: { target: function (card, player, target, current) { if (get.tag(card, "damage") && target.hp > 1) { if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; var max = 0; var players = game.filterPlayer(); for (var i = 0; i < players.length; i++) { if (get.attitude(target, players[i]) > 0) { max = Math.max(Math.min(5, players[i].hp) - players[i].countCards("h"), max); } } switch (max) { case 0: return 2; case 1: return 1.5; case 2: return [1, 2]; default: return [0, max]; } } if ((card.name == "tao" || card.name == "caoyao") && target.hp > 1 && target.countCards("h") <= target.hp) return [0, 0]; }, }, }, }, //沮授 xinjianying: { audio: 2, subfrequent: ["draw"], enable: "phaseUse", usable: 1, filter: function (event, player) { if (!player.countCards("he")) return false; for (var i of lib.inpile) { if (i != "du" && get.type(i, false) == "basic") { if (event.filterCard({ name: i }, player, event)) return true; if (i == "sha") { for (var j of lib.inpile_nature) { if (event.filterCard({ name: i, nature: j }, player, event)) return true; } } } } return false; }, onChooseToUse: function (event) { if (event.type == "phase" && !game.online) { var last = event.player.getLastUsed(); if (last && last.getParent("phaseUse") == event.getParent()) { var suit = get.suit(last.card, false); if (suit != "none") event.set("xinjianying_suit", suit); } } }, chooseButton: { dialog: function (event, player) { var list = []; var suit = event.xinjianying_suit || "", str = get.translation(suit); for (var i of lib.inpile) { if (i != "du" && get.type(i, false) == "basic") { if (event.filterCard({ name: i }, player, event)) list.push(["基本", str, i]); if (i == "sha") { for (var j of lib.inpile_nature) { if (event.filterCard({ name: i, nature: j }, player, event)) list.push(["基本", str, i, j]); } } } } return ui.create.dialog("渐营", [list, "vcard"]); }, check: function (button) { if (button.link[2] == "jiu") return 0; return _status.event.player.getUseValue({ name: button.link[2], nature: button.link[3], }); }, backup: function (links, player) { var next = { audio: "xinjianying", filterCard: true, popname: true, position: "he", viewAs: { name: links[0][2], nature: links[0][3], }, ai1: function (card) { return 7 - _status.event.player.getUseValue(card, null, true); }, }; if (_status.event.xinjianying_suit) next.viewAs.suit = _status.event.xinjianying_suit; return next; }, prompt: function (links) { return "将一张牌当做" + (get.translation(links[0][3]) || "") + get.translation(links[0][2]) + (_status.event.xinjianying_suit ? "(" + get.translation(_status.event.xinjianying_suit) + ")" : "") + "使用"; }, }, ai: { order: function (item, player) { if (_status.event.xinjianying_suit) return 16; return 3; }, result: { player: 7 }, }, group: ["xinjianying_draw", "jianying_mark"], init: function (player) { if (player.isPhaseUsing()) { var evt = _status.event.getParent("phaseUse"); var history = player.getHistory("useCard", function (evt2) { return evt2.getParent("phaseUse") == evt; }); if (history.length) { var trigger = history[history.length - 1]; player.storage.jianying_mark = trigger.card; player.markSkill("jianying_mark"); game.broadcastAll( function (player, suit) { if (player.marks.jianying_mark) player.marks.jianying_mark.firstChild.innerHTML = get.translation(suit); }, player, get.suit(trigger.card, player) ); player.when("phaseUseAfter").then(() => { player.unmarkSkill("jianying_mark"); delete player.storage.jianying_mark; }); } } }, onremove: function (player) { player.unmarkSkill("jianying_mark"); delete player.storage.jianying_mark; }, subSkill: { draw: { inherit: "jianying", audio: "xinjianying" }, }, }, //步练师 reanxu: { audio: 2, enable: "phaseUse", usable: 1, filter: function (event, player) { return ( game.countPlayer() > 2 && game.hasPlayer(function (current) { return current != player && current.countCards("he"); }) ); }, selectTarget: 2, filterTarget: function (card, player, target) { if (target == player) return false; if (!ui.selected.targets.length) return target.countCards("he") > 0; return target != ui.selected.targets[0] && ui.selected.targets[0].countGainableCards(target, "he") > 0; }, multitarget: true, targetprompt: ["被拿牌", "得到牌"], content: function () { "step 0"; targets[1].gainPlayerCard(targets[0], "he", true); "step 1"; if ( targets[0].getHistory("lose", function (evt) { return evt.getParent(3) == event && !evt.es.length; }).length ) player.draw(); "step 2"; if (targets[0].isIn() && targets[1].isIn() && targets[0].countCards("h") != targets[1].countCards("h")) { event.target = targets[targets[0].countCards("h") > targets[1].countCards("h") ? 1 : 0]; player.chooseBool("是否令" + get.translation(event.target) + "摸一张牌?").set("ai", function () { var evt = _status.event.getParent(); return get.attitude(evt.player, evt.target) > 0; }); } else event.finish(); "step 3"; if (result.bool) target.draw(); }, ai: { expose: 0.2, threaten: 2, order: 9, result: { player: function (player, target) { if (ui.selected.targets.length) return 0.01; return target.countCards("e") ? 0 : 0.5; }, target: function (player, target) { if (ui.selected.targets.length) { player = target; target = ui.selected.targets[0]; if (get.attitude(player, target) > 1) { return 0; } return target.countCards("h") - player.countCards("h") > (target.countCards("e") ? 2 : 1) ? 2 : 1; } else { if (get.attitude(player, target) <= 0) return target.countCards("he", function (card) { return card.name == "tengjia" || get.value(card) > 0; }) > 0 ? -1.5 : 1.5; return target.countCards("he", function (card) { return card.name != "tengjia" && get.value(card) <= 0; }) > 0 ? 1.5 : -1.5; } }, }, }, }, //蒋干 spdaoshu: { audio: 3, group: "spdaoshu_effect", subSkill: { effect: { audio: "spdaoshu1", trigger: { global: "phaseUseBegin" }, filter: function (event, player) { var goon = event.player != player && (get.mode() == "identity" || get.mode() == "guozhan" || event.player.isEnemyOf(player)); return goon && event.player.countCards("h") > 0 && event.player.hasUseTarget({ name: "jiu", isCard: true }, null, true); }, round: 1, logTarget: "player", prompt2: () => lib.translate.spdaoshu_info, check: function (event, player) { var target = event.player; var att = get.attitude(player, target); if (att > 0) return false; if (att == 0) return !player.inRangeOf(target); return true; }, content: function () { "step 0"; event.target = trigger.player; event.target.chooseUseTarget("jiu", true); "step 1"; if (!target.countCards("h")) { event.finish(); return; } var list = []; for (var i of lib.inpile) { if (get.type(i) == "basic") list.push(i); } if (!list.length) { event.finish(); return; } target .chooseControl(list) .set("prompt", "请声明一种基本牌") .set("ai", () => _status.event.rand) .set("rand", get.rand(0, list.length - 1)); "step 2"; event.cardname = result.control; target.chat("我声明" + get.translation(event.cardname)); game.log(target, "声明的牌名为", "#y" + get.translation(event.cardname)); game.delayx(); player .chooseControl("有!", "没有!") .set("prompt", "你觉得" + get.translation(target) + "的手牌区里有" + get.translation(event.cardname) + "吗?") .set("ai", function () { return _status.event.choice; }) .set( "choice", (function () { var rand = { sha: 0.273, shan: 0.149, tao: 0.074, jiu: 0.031, }[event.cardname] || 0.1; return 1 - Math.pow(1 - rand, target.countCards("h")) > 0.5 ? "有!" : "没有!"; })() ); "step 3"; player.chat(result.control); game.log(player, "认为", "#y" + result.control); game.delayx(); "step 4"; var bool1 = result.index == 0; var bool2 = target.hasCard(function (card) { return get.name(card, target) == event.cardname; }, "h"); if (bool1 == bool2) { player.popup("判断正确", "wood"); game.broadcastAll(function () { if (lib.config.background_speak) game.playAudio("skill", "spdaoshu2"); }); player.gainPlayerCard(target, "h", 2, true); //var cards=target.getCards('h',function(card){ // return lib.filter.canBeGained(card,player,target); //}).randomGets(5); //if(cards.length>0) player.gain(cards,target,'giveAuto','bySelf'); } else { player.popup("判断错误", "fire"); game.broadcastAll(function () { if (lib.config.background_speak) game.playAudio("skill", "spdaoshu3"); }); //player.addTempSkill('spdaoshu_respond'); } }, ai: { expose: 0.3 }, }, respond: { trigger: { global: "useCard1" }, forced: true, popup: false, filter: function (event, player) { return event.player == _status.currentPhase; }, content: function () { trigger.directHit.add(player); }, }, }, }, spdaoshu1: { audio: true }, mbdaoshu: { audio: 3, group: "mbdaoshu_use", subSkill: { use: { audio: "mbdaoshu1", enable: "phaseUse", filter: function (event, player) { return game.hasPlayer(target => target != player && target.countCards("h") > 2); }, filterTarget: function (card, player, target) { return target != player && target.countCards("h") > 2; }, usable: 1, prompt: () => lib.translate.mbdaoshu_info, content: function* (event, map) { var player = map.player, target = event.target; var targets = [player], names = lib.inpile.randomGets(3); if (!names.length) return; var map = {}; names.forEach(name => (map[get.translation(name)] = name)); if (get.mode() != "identity" && get.mode() != "guozhan") targets.addArray(player.getFriends()); targets.remove(target); targets.sortBySeat(); var result = yield target .chooseButton(["盗书:请选择伪装的牌和牌名", target.getCards("h"), [Object.keys(map), "tdnodes"]], 2, true) .set("filterButton", button => { var map = _status.event.map; if (!ui.selected.buttons.length) return true; if (typeof button.link == typeof ui.selected.buttons[0].link) return false; if (typeof button.link == "string") return get.name(ui.selected.buttons[0].link, false) != map[button.link]; return map[ui.selected.buttons[0].link] != get.name(button.link, false); }) .set("ai", button => { var map = _status.event.map; if (!ui.selected.buttons.length) { if (typeof button.link == "object") { if (Object.values(map).some(name => lib.card.list.some(card => card[0] == get.suit(button.link, false) && card[1] == get.number(button.link, false) && card[2] == name))) return 5; return 3.5 + Math.random(); } return 0; } if (typeof button.link == "string") { var cardx = ui.selected.buttons[0].link; if (lib.card.list.some(card => card[0] == get.suit(cardx, false) && card[1] == get.number(cardx, false) && card[2] == map[button.link])) return 2 + Math.random(); return 1; } return 0; }) .set("map", map); if (result.bool) { var guessWinner = []; if (typeof result.links[0] == "string") result.links.reverse(); var OriginCard = result.links[0], ChangeName = map[result.links[1]], cards = target.getCards("h").slice(); var card = game.createCard(ChangeName, get.suit(OriginCard, false), get.number(OriginCard, false)); cards[cards.indexOf(OriginCard)] = card; if (_status.connectMode) { var list = targets.map(target2 => [target2, ["请猜测" + get.translation(target) + "伪装的手牌", cards], true]); var result2 = yield player .chooseButtonOL(list) .set("switchToAuto", () => (_status.event.result = "ai")) .set("processAI", () => { var cards = _status.event.cards.slice(); var card = cards.find(card => lib.card.list.some(cardx => cardx[2] == card.name) && !lib.card.list.some(cardx => cardx[2] == card.name && cardx[0] == get.suit(card, false) && cardx[0] == get.number(card, false))); return { bool: true, links: card ? card : cards.randomGet(), }; }) .set("cards", cards); for (var i in result2) { if (result2[i].links[0] == card) guessWinner.push(lib.playerOL[i]); } } else { var guessTargets = targets.slice(); while (guessTargets.length) { var target2 = guessTargets.shift(); var result2 = yield target2 .chooseButton(["请猜测" + get.translation(target) + "伪装的手牌", cards], true) .set("ai", button => { var cards = _status.event.cards.slice(); var card = cards.find(card => lib.card.list.some(cardx => cardx[2] == get.name(card, false)) && !lib.card.list.some(cardx => cardx[2] == get.name(card, false) && cardx[0] == get.suit(card, false) && cardx[0] == get.number(card, false))); return button.link == card ? 3 : 1 + Math.random(); }) .set("cards", cards); if (result2.bool) { if (result2.links[0] == card) guessWinner.push(target2); } } } targets.forEach(target2 => { if (guessWinner.includes(target2)) { target2.popup("判断正确", "wood"); game.log(target2, "猜测", "#g正确"); game.broadcastAll(() => { if (lib.config.background_speak) game.playAudio("skill", "mbdaoshu2"); }); target2.line(target); target.damage(1, target2); } else { target2.popup("判断错误", "fire"); game.log(target2, "猜测", "#y错误"); game.broadcastAll(() => { if (lib.config.background_speak) game.playAudio("skill", "mbdaoshu3"); }); if (target2.countCards("h") >= 2) target2.discard(target2.getCards("h").randomGets(2)); else target2.loseHp(); } }); } }, ai: { order: 9, result: { target: function (player, target) { return -1 / target.countCards("h"); }, }, }, }, }, }, mbdaoshu1: { audio: true }, spdaizui: { audio: 2, trigger: { player: "damageBegin2" }, limited: true, logTarget: "source", filter: function (event, player) { return event.num >= player.hp && event.source && event.source.isIn() && event.cards && event.cards.filterInD().length > 0; }, prompt2: function (event) { return "防止即将受到的" + get.cnNumber(event.num) + "点伤害,并令" + get.translation(event.source) + "将" + get.translation(event.cards.filterInD()) + "置于武将牌上且回合结束时收回"; }, skillAnimation: true, animationColor: "thunder", content: function () { player.awakenSkill("spdaizui"); trigger.source.addSkill("spdaizui2"); trigger.source.addToExpansion(trigger.cards.filterInD(), "gain2").gaintag.add("spdaizui2"); trigger.cancel(); }, }, spdaizui2: { trigger: { global: "phaseEnd" }, forced: true, charlotte: true, filter: function (event, player) { return player.getExpansions("spdaizui2").length > 0; }, content: function () { "step 0"; var cards = player.getExpansions("spdaizui2"); player.gain(cards, "gain2"); "step 1"; player.removeSkill("spdaizui2"); }, marktext: "释", intro: { markcount: "expansion", content: "expansion", }, }, //裴秀 xingtu: { trigger: { player: "useCard" }, filter: function (event, player) { var evt = lib.skill.dcjianying.getLastUsed(player, event); if (!evt || !evt.card) return false; var num1 = get.number(event.card), num2 = get.number(evt.card); return typeof num1 == "number" && typeof num2 == "number" && num2 % num1 == 0; }, forced: true, content: function () { player.draw(); }, mod: { cardUsable: function (card, player) { if (typeof card == "object") { var evt = lib.skill.dcjianying.getLastUsed(player); if (!evt || !evt.card) return; var num1 = get.number(card), num2 = get.number(evt.card); if (num1 === "unsure" || (typeof num1 == "number" && typeof num2 == "number" && num1 % num2 == 0)) return Infinity; } }, aiOrder: function (player, card, num) { if (typeof card == "object") { var evt = lib.skill.dcjianying.getLastUsed(player); if (!evt || !evt.card) return; var num1 = get.number(card), num2 = (num2 = get.number(evt.card)); if (num1 === "unsure" || (typeof num1 == "number" && typeof num2 == "number" && num2 % num1 == 0)) return num + 5; } }, }, init: function (player) { player.addSkill("xingtu_mark"); var history = player.getAllHistory("useCard"); if (history.length) { var trigger = history[history.length - 1], num = get.number(trigger.card); player.storage.xingtu_mark = num; player[typeof num != "number" ? "unmarkSkill" : "markSkill"]("xingtu_mark"); } }, onremove: function (player) { player.removeSkill("xingtu_mark"); player.removeGaintag("xingtu1"); player.removeGaintag("xingtu2"); delete player.storage.xingtu_mark; }, subSkill: { mark: { charlotte: true, trigger: { player: ["useCard1", "gainAfter"], global: "loseAsyncAfter", }, filter: function (event, player, name) { if (!player.countCards("h")) return false; return name == "useCard1" || event.getg(player).length; }, direct: true, firstDo: true, content: function () { "step 0"; player.removeGaintag("xingtu1"); player.removeGaintag("xingtu2"); if (event.triggername == "useCard1") { var num = get.number(trigger.card, player); player.storage.xingtu_mark = num; player[typeof num != "number" ? "unmarkSkill" : "markSkill"]("xingtu_mark"); if (typeof num != "number") event.finish(); } "step 1"; var cards1 = [], cards2 = [], num = player.storage.xingtu_mark; player.getCards("h").forEach(card => { var numx = get.number(card, player); if (typeof numx == "number") { if (numx % num == 0) cards1.push(card); if (num % numx == 0) cards2.push(card); } }); player.addGaintag(cards1, "xingtu1"); player.addGaintag(cards2, "xingtu2"); }, intro: { content: "上一张牌的点数:#" }, }, }, }, juezhi: { enable: "phaseUse", filter: function (event, player) { return player.countCards("he") > 1; }, filterCard: true, position: "he", selectCard: [2, Infinity], check: function (card) { if (ui.selected.cards.length > 1) return 0; var player = _status.event.player; if (player.hasSkill("xingtu") && player.storage.xingtu) { var cards = player.getCards("he"); var num = player.storage.xingtu, stop = false; for (var i = 0; i <= cards.length; i++) { if (i != cards.length) { var num1 = get.number(cards[i], player); if (typeof num1 != "number") continue; for (var j = 0; j < cards.length; j++) { if (i == j) continue; var num2 = get.number(cards[j], player); if (typeof num2 != "number") continue; var sum = num1 + num2; if (sum % num == 0 || num % sum == 0) { stop = true; break; } } if (stop) break; } } if (i != cards.length) { var cardx = [cards[i], cards[j]]; if (cardx.includes(card)) return 10 - get.value(card); } } return 5 - get.value(card); }, content: function () { var num = 0; for (var i of cards) num += get.number(i, player); num = num % 13; if (num == 0) num = 13; var card = get.cardPile2(function (card) { return get.number(card, false) == num; }); if (card) player.gain(card, "gain2"); }, ai: { order: 1, result: { player: 1 }, }, }, reganlu: { enable: "phaseUse", usable: 1, audio: 2, selectTarget: 2, delay: 0, filterTarget: function (card, player, target) { if (target.isMin()) return false; if (ui.selected.targets.length == 0) return true; if (ui.selected.targets[0].countCards("e") == 0 && target.countCards("e") == 0) return false; return target == player || ui.selected.targets[0] == player || Math.abs(ui.selected.targets[0].countCards("e") - target.countCards("e")) <= player.maxHp - player.hp; }, multitarget: true, multiline: true, content: function () { targets[0].swapEquip(targets[1]); }, ai: { order: 10, threaten: function (player, target) { return 0.8 * Math.max(1 + target.maxHp - target.hp); }, result: { target: function (player, target) { var list1 = []; var list2 = []; var num = player.maxHp - player.hp; var players = game.filterPlayer(); for (var i = 0; i < players.length; i++) { if (get.attitude(player, players[i]) > 0) list1.push(players[i]); else if (get.attitude(player, players[i]) < 0) list2.push(players[i]); } list1.sort(function (a, b) { return a.countCards("e") - b.countCards("e"); }); list2.sort(function (a, b) { return b.countCards("e") - a.countCards("e"); }); var delta; for (var i = 0; i < list1.length; i++) { for (var j = 0; j < list2.length; j++) { delta = list2[j].countCards("e") - list1[i].countCards("e"); if (delta <= 0) continue; if (delta <= num || list1[i] == player || list2[j] == player) { if (target == list1[i] || target == list2[j]) { return get.attitude(player, target); } return 0; } } } return 0; }, }, }, }, //孙休 mobilexingxue: { audio: 2, trigger: { player: "phaseJieshuBegin" }, filter: function (event, player) { return (player.storage.mobileyanzhu ? player.maxHp : player.hp) > 0; }, direct: true, content: function () { "step 0"; var num = player.storage.mobileyanzhu ? player.maxHp : player.hp; player.chooseTarget([1, num], get.prompt2("mobilexingxue")).set("ai", function (target) { var att = get.attitude(_status.event.player, target); if (target.countCards("he")) return att; return att / 10; }); "step 1"; if (result.bool) { player.logSkill("mobilexingxue", result.targets); event.targets = result.targets; event.targets2 = event.targets.slice(0); event.targets.sort(lib.sort.seat); } else { event.finish(); } "step 2"; if (event.targets.length) { var target = event.targets.shift(); target.draw(); event.current = target; } else { event.finish(); } "step 3"; if (event.current && event.current.countCards("he")) { if (!player.storage.mobileyanzhu || event.targets2.length == 1) event.current.chooseCard("选择一张牌置于牌堆顶", "he", true); else event.current.chooseCardTarget({ prompt: "将一张牌置于牌堆顶,或交给其他目标角色", filterCard: true, position: "he", filterTarget: function (card, player, target) { return target != player && _status.event.getParent().targets2.includes(target); }, forced: true, selectTarget: [0, 1], ai1: card => 6 - get.value(card), ai2: target => get.attitude(_status.event.player, target), }); } else { event.goto(2); } "step 4"; if (result && result.cards) { event.card = result.cards[0]; if (!result.targets || !result.targets.length) { event.current.lose(result.cards, ui.cardPile, "insert"); game.broadcastAll(function (player) { var cardx = ui.create.card(); cardx.classList.add("infohidden"); cardx.classList.add("infoflip"); player.$throw(cardx, 1000, "nobroadcast"); }, event.current); } else { event.current.give(result.cards, result.targets[0]); } } else { event.card = null; } "step 5"; event.goto(2); }, derivation: "mobilexingxuex", }, mobileyanzhu: { audio: 2, enable: "phaseUse", usable: 1, filterTarget: function (card, player, target) { return target.countCards("hej") > 0 && target != player; }, content: function () { "step 0"; if (target.countCards("e")) { target .chooseBool("是否将装备区内的所有牌交给" + get.translation(player) + "?", "若选择“取消”,则其将获得你区域里的一张牌") .set("ai", function () { if (_status.event.effect > 0) return false; if (_status.event.player.countCards("e") >= 3) return false; return true; }) .set("effect", get.effect(target, { name: "shunshou" }, player, target)); } else { player.gainPlayerCard(target, true, "he"); event.finish(); } "step 1"; if (result.bool) { var es = target.getCards("e"); target.give(es, player, "give"); player.removeSkills("mobileyanzhu"); player.storage.mobileyanzhu = true; player.popup("兴学"); game.log(player, "修改了技能", "#g【兴学】"); } else { player.gainPlayerCard(target, true, "hej"); } }, ai: { order: 6, result: { target: function (player, target) { var ne = target.countCards("e"), nj = target.countCards("j"); if (nj) return 2.5; if (!ne) return -2; if (ne >= 2) return -ne; return 0; }, }, }, }, //毛玠 bingqing: { audio: 2, trigger: { player: "useCardAfter" }, direct: true, filter: function (event, player) { var suit = get.suit(event.card); if (!lib.suit.includes(suit)) return false; var evt = event.getParent("phaseUse"); if (!evt || player != evt.player) return false; var list = [], history = player.getHistory("useCard"); if (history.length < 2) return false; for (var i of history) { if (i.getParent("phaseUse") != evt) continue; var suit2 = get.suit(i.card); if (!lib.suit.includes(suit2)) continue; if (i != event && suit2 == suit) return false; if (i.finished) list.add(suit2); } return list.length > 1 && list.length < 5; }, content: function () { "step 0"; var suit = get.suit(trigger.card); var evt = event.getParent("phaseUse"); var list = [], history = player.getHistory("useCard"); for (var i of history) { if (i.getParent("phaseUse") != evt) continue; var suit2 = get.suit(i.card); if (!lib.suit.includes(suit2)) continue; if (i.finished) list.add(suit2); } var prompt, filterTarget, ai; switch (list.length) { case 2: prompt = "令一名角色摸两张牌"; filterTarget = function (card, player, target) { return true; }; ai = function (target) { var player = _status.event.player; var att = get.attitude(player, target); if (target.hasSkill("nogain")) att /= 10; return att / Math.sqrt(Math.min(5, 1 + target.countCards("h"))); }; break; case 3: prompt = "弃置一名角色区域内的一张牌"; filterTarget = function (card, player, target) { return target.hasCard(function (card) { return lib.filter.canBeDiscarded(card, player, target); }, "hej"); }; ai = function (target) { var player = _status.event.player; return get.effect(target, { name: "guohe_copy" }, player, player); }; break; case 4: prompt = "对一名其他角色造成1点伤害"; filterTarget = function (card, player, target) { return target != player; }; ai = function (target) { var player = _status.event.player; return get.damageEffect(target, player, player); }; break; default: event.finish(); return; } event.num = list.length; player.chooseTarget(get.prompt("bingqing"), prompt, filterTarget).set("ai", ai); "step 1"; if (result.bool) { var target = result.targets[0]; player.logSkill("bingqing", target); event.target = target; event.goto(num); } else event.finish(); "step 2"; target.draw(2); event.finish(); "step 3"; player.discardPlayerCard(target, true, "hej"); event.finish(); "step 4"; target.damage(); }, }, yingfeng: { trigger: { player: "phaseZhunbeiBegin" }, direct: true, content: function () { "step 0"; player .chooseTarget(get.prompt("yingfeng"), "令一名角色获得“奉”标记", function (card, player, target) { return !target.hasSkill("yingfeng_mark"); }) .set("ai", function (target) { var player = _status.event.player, att = get.attitude(player, target); if (att <= 0) return 0; var eff = 0.1; var preTarget = game.findPlayer(function (current) { return current != target && current.hasSkill("yingfeng_mark"); }); if (preTarget) { if (get.attitude(player, preTarget) < 0) eff += 4; else if (preTarget.hasValueTarget({ name: "sha" }, false) && !preTarget.hasValueTarget({ name: "sha" })) eff -= 3; } if (target.hasValueTarget({ name: "sha" }, false) && !target.hasValueTarget({ name: "sha" })) eff += 3; if (player == target) att *= 1.2; return 0.01 + att * eff; }); "step 1"; if (result.bool) { var target = result.targets[0]; player.logSkill("yingfeng", target); target.addAdditionalSkill("yingfeng_" + player.playerid, "yingfeng_mark"); game.countPlayer(function (current) { if (current != target && current.hasSkill("yingfeng_mark")) { current.removeSkill("yingfeng_mark"); current.removeAdditionalSkill("yingfeng_" + player.playerid); } }); } }, subSkill: { mark: { charlotte: true, mark: true, marktext: "奉", mod: { targetInRange: () => true, }, intro: { content: "使用牌无距离限制" }, }, }, }, //猩黄忠 spshidi: { audio: 2, trigger: { player: ["phaseZhunbeiBegin", "phaseJieshuBegin"] }, forced: true, zhuanhuanji: "number", filter: function (event, player) { return player.countMark("spshidi") % 2 == ["phaseJieshu", "phaseZhunbei"].indexOf(event.name); }, content: function () { player.changeZhuanhuanji("spshidi"); }, mod: { globalFrom: function (from, to, distance) { if (from.countMark("spshidi") % 2 == 0) return distance - 1; }, globalTo: function (from, to, distance) { if (to.countMark("spshidi") % 2 == 1) return distance + 1; }, aiOrder: function (player, card, num) { if (player.countMark("spshidi") % 2 == 0 && card.name == "sha" && get.color(card) == "black") return num + 0.1; }, }, mark: true, marktext: "☯", intro: { content: function (storage, player) { return "已转换过" + (storage || 0) + "次"; }, }, ai: { directHit_ai: true, skillTagFilter: function (player, tag, arg) { if (!arg || !arg.card || !arg.target || arg.card.name != "sha") return false; return player.countMark("spshidi") % 2 == 0 && get.color(arg.card) == "black"; }, }, group: ["spshidi_use", "spshidi_beused"], subSkill: { use: { trigger: { player: "useCard" }, forced: true, filter: function (event, player) { return event.card.name == "sha" && player.countMark("spshidi") % 2 == 0 && get.color(event.card, false) == "black"; }, content: function () { trigger.directHit.addArray(game.players); }, }, beused: { trigger: { target: "useCardToTargeted" }, forced: true, filter: function (event, player) { return event.card.name == "sha" && player.countMark("spshidi") % 2 == 1 && get.color(event.card, false) == "red"; }, content: function () { trigger.directHit.add(player); }, }, }, }, spyishi: { audio: 2, trigger: { source: "damageBegin2" }, filter: function (event, player) { return player != event.player && event.player.countCards("e") > 0; }, check: function (event, player) { return ( get.damageEffect(event.player, player, player) <= 0 || (get.attitude(player, event.player) <= 0 && !event.player.hasSkillTag("noe") && event.player.hasCard(function (card) { return get.value(card) > 9 - event.player.hp; }, "e")) ); }, logTarget: "player", content: function () { trigger.num--; player.gainPlayerCard(trigger.player, "e", true); }, }, spqishe: { enable: "chooseToUse", viewAs: { name: "jiu" }, filterCard: { type: "equip" }, position: "hes", viewAsFilter: function (player) { return player.hasCard({ type: "equip" }, "ehs"); }, check: function (card) { if (_status.event.type == "dying") return 1 / (get.value(card) || 0.5); return 5 - get.value(card); }, locked: false, mod: { maxHandcard: function (player, num) { return num + player.countCards("e"); }, }, }, //虞翻 rezongxuan: { inherit: "zongxuan", group: "rezongxuan_place", }, rezongxuan_place: { audio: "rezongxuan", enable: "phaseUse", usable: 1, content: function () { "step 0"; player.draw(); "step 1"; player.chooseCard("he", true, "将一张牌置于牌堆顶"); "step 2"; if (result && result.cards) { event.card = result.cards[0]; player.lose(result.cards, ui.cardPile, "insert"); game.log(player, "将", get.position(event.card) == "h" ? "一张牌" : event.card, "置于牌堆顶"); game.broadcastAll(function (player) { var cardx = ui.create.card(); cardx.classList.add("infohidden"); cardx.classList.add("infoflip"); player.$throw(cardx, 1000, "nobroadcast"); }, player); } else event.finish(); }, ai: { order: 1, result: { player: 1 }, }, }, //孙寒华 chongxu: { enable: "phaseUse", usable: 1, content: function () { "step 0"; player.chooseToPlayBeatmap(lib.skill.chongxu.beatmaps.randomGet()); "step 1"; var score = Math.floor(Math.min(5, result.accuracy / 17)); event.score = score; game.log(player, "的演奏评级为", "#y" + result.rank[0], ",获得积分点数", "#y" + score, "分"); if (score < 3) { if (score >= 2) player.draw(); event.finish(); return; } var list = []; if (player.countMark("miaojian") < 2 && player.hasSkill("miaojian")) list.push("修改【妙剑】"); if (player.countMark("shhlianhua") < 2 && player.hasSkill("shhlianhua")) list.push("修改【莲华】"); if (list.length) { list.push("全部摸牌"); player.chooseControl(list).set("prompt", "冲虚:修改技能" + (score == 5 ? "并摸一张牌" : "") + ";或摸" + Math.floor(score / 2) + "张牌"); } else event._result = { control: "全部摸牌" }; "step 2"; var score = event.score; if (result.control != "全部摸牌") { score -= 3; var skill = result.control == "修改【妙剑】" ? "miaojian" : "shhlianhua"; player.addMark(skill, 1, false); game.log(player, "修改了技能", "#g【" + get.translation(skill) + "】"); } if (score > 1) player.draw(Math.floor(score / 2)); }, ai: { order: 10, result: { player: 1, }, }, beatmaps: [ { //歌曲名称 name: "鳥の詩", //歌曲文件名(默认在audio/effect文件夹下 若要重定向到扩展 请写为'ext:扩展名称/文件名'的格式) filename: "tori_no_uta", //每个音符的开始时间点(毫秒,相对未偏移的开始播放时间) timeleap: [1047, 3012, 4978, 5469, 5961, 6452, 6698, 7435, 8909, 10875, 12840], //开始播放时间的偏移量(毫秒) current: -110, //判定栏高度(相对整个对话框高度比例) judgebar_height: 0.16, //Good/Great/Prefect的位置判定范围(百分比,相对于整个对话框。以滑条的底部作为判定基准) range1: [84, 110], range2: [90, 104], range3: [94, 100], //滑条每相对于整个对话框下落1%所需的时间(毫秒) speed: 25, }, { name: "竹取飛翔 ~ Lunatic Princess", filename: "taketori_hishou", timeleap: [1021, 1490, 1959, 2896, 3834, 4537, 4771, 5709, 6646, 7585, 8039, 8494, 9403, 10291, 11180, 11832, 12049, 12920, 13345, 13771, 14196], current: -110, judgebar_height: 0.16, range1: [84, 110], range2: [90, 104], range3: [94, 100], speed: 25, node_color: "linear-gradient(rgba(250, 170, 190, 1), rgba(240, 160, 180, 1))", judgebar_color: "linear-gradient(rgba(240, 120, 243, 1), rgba(245, 106, 230, 1))", }, { name: "ignotus", filename: "ignotus", //Number of tracks //轨道数量 number_of_tracks: 4, //Customize the track to generate for every note (0 is the first track) //自定义每个音符生成的轨道(0是第一个轨道) mapping: [0, 2, 3, 1, 1, 0, 3, 0, 0, 3, 0, 0, 2, 1, 2], //Convert from beats (0 is the first beat) to timeleap //将节拍(0是第一拍)转换为开始时间点 timeleap: game.generateBeatmapTimeleap(170, [0, 4, 8, 12, 14, 16, 16.5, 23.5, 24, 31, 32, 40, 45, 46, 47]), current: -110, judgebar_height: 0.16, range1: [84, 110], range2: [90, 104], range3: [94, 100], speed: 25, node_color: "linear-gradient(rgba(240, 250, 240, 1), rgba(230, 240, 230, 1))", judgebar_color: "linear-gradient(rgba(161, 59, 150, 1), rgba(58, 43, 74, 1))", }, { name: "Super Mario 3D World Theme", filename: "sm3dw_overworld", //Random (Randomly choose tracks to generate notes each play) //随机(每次演奏时音符会随机选择轨道生成) mapping: "random", timeleap: [0, 1071, 1518, 2054, 4018, 4286, 5357, 6429, 7500, 8571, 9643, 10714, 11786, 12321, 12589, 12857, 13929, 15000, 16071, 17143, 18214, 18482, 18750, 19018, 19286, 20357], current: -110, judgebar_height: 0.16, range1: [84, 110], range2: [90, 104], range3: [94, 100], speed: 25, node_color: "linear-gradient(rgba(120, 130, 240, 1), rgba(100, 100, 230, 1))", judgebar_color: "linear-gradient(rgba(230, 40, 30, 1), rgba(220, 30, 10, 1))", }, { name: "只因你太美", filename: "chicken_you_are_so_beautiful", number_of_tracks: 7, mapping: [3, 6, 4, 5, 6, 2, 3, 2, 1, 2, 0, 4, 3, 6, 5, 4, 3, 6, 3, 2, 3, 1, 0, 1, 2, 3, 4, 5, 6], timeleap: game.generateBeatmapTimeleap(107, [2, 3.5, 4.5, 5.5, 6.5, 8.5, 10, 11.5, 12.5, 13.5, 14.5, 15.5, 18, 19.5, 20.5, 21.5, 22.5, 24.5, 26, 27.5, 28.5, 29.5, 30.5, 31, 31.5, 32, 32.5, 33, 33.5]), //Hitsound file name (By default in the audio/effect folder. To redirect to the extension, please write in the format of 'ext:extension_name') //打击音文件名(默认在audio/effect文件夹下 若要重定向到扩展 请写为'ext:扩展名称'的格式) hitsound: "chickun.wav", current: -110, judgebar_height: 0.16, range1: [84, 110], range2: [90, 104], range3: [94, 100], speed: 25, node_color: "linear-gradient(#99f, #66c)", judgebar_color: "linear-gradient(#ccf, #99c)", }, { name: "Croatian Rhapsody", filename: "croatian_rhapsody", mapping: [4, 1, 2, 1, 0, 0, 4, 5, 1, 3, 2, 1, 0, 0], timeleap: game.generateBeatmapTimeleap(96, [4, 6, 8, 9, 10, 11, 12, 13.5, 14, 15.5, 16, 17, 18, 19]), current: -110, judgebar_height: 0.16, range1: [84, 110], range2: [90, 104], range3: [94, 100], speed: 25, node_color: "linear-gradient(#fff, #ccc)", judgebar_color: "linear-gradient(#fff, #ccc)", }, { name: "罗刹海市", filename: "rakshasa_sea_city", number_of_tracks: 7, mapping: "random", timeleap: game.generateBeatmapTimeleap(150, [0, 2, 4, 6, 7, 9, 11, 13, 14, 16, 18, 20, 21, 23, 25, 27]), current: -110, judgebar_height: 0.16, range1: [84, 110], range2: [90, 104], range3: [94, 100], speed: 25, node_color: "linear-gradient(#333, #000)", judgebar_color: "linear-gradient(#c66, #933)", }, { name: "Pigstep (Stereo Mix)", filename: "pigstep", number_of_tracks: 16, timeleap: game.generateBeatmapTimeleap(170, [3, 4, 6, 6.5, 7.5, 11, 12, 14, 14.5, 15.5, 19, 20, 22, 22.5, 23.5, 27, 28, 30, 30.5, 31.5, 35, 36, 38, 38.5, 39.5, 43, 44, 46, 46.5, 47.5, 51, 52, 54, 54.5, 55.5, 59, 60, 62, 62.5]), current: -110, judgebar_height: 0.16, range1: [84, 110], range2: [90, 104], range3: [94, 100], speed: 25, node_color: "linear-gradient(#066, #033)", judgebar_color: "linear-gradient(#633, #300)", }, ], derivation: "chongxu_faq", }, miaojian: { audio: 2, enable: "phaseUse", usable: 1, filter: function (event, player) { var level = player.countMark("miaojian"); if (event.filterCard({ name: "sha", nature: "stab" }, player, event)) { if (level == 2) return true; if ( level == 1 && player.hasCard(function (card) { return get.type2(card) == "basic"; }, "hs") ) return true; if ( level == 0 && player.hasCard(function (card) { return get.name(card) == "sha"; }, "hs") ) return true; } if (event.filterCard({ name: "wuzhong" }, player, event)) { if (level == 2) return true; if ( level == 1 && player.hasCard(function (card) { return get.type2(card) != "basic"; }, "hes") ) return true; if ( level == 0 && player.hasCard(function (card) { return get.type2(card) == "trick"; }, "hs") ) return true; } return false; }, chooseButton: { dialog: function () { return ui.create.dialog("妙剑", [ [ ["基本", "", "sha", "stab"], ["锦囊", "", "wuzhong"], ], "vcard", ]); }, filter: function (button, player) { var event = _status.event.getParent(), level = player.countMark("miaojian"); if (button.link[2] == "sha") { if (!event.filterCard({ name: "sha", nature: "stab" }, player, event)) return false; if (level == 2) return true; if (level == 1) return player.hasCard(function (card) { return get.type2(card) == "basic"; }, "hs"); return ( level == 0 && player.hasCard(function (card) { return get.name(card) == "sha"; }, "hs") ); } if (button.link[2] == "wuzhong") { if (!event.filterCard({ name: "wuzhong" }, player, event)) return false; if (level == 2) return true; if (level == 1) return player.hasCard(function (card) { return get.type2(card) != "basic"; }, "hes"); return ( level == 0 && player.hasCard(function (card) { return get.type2(card) == "trick"; }, "hs") ); } }, check: function (button) { var card = { name: button.link[2], nature: button.link[3] }, player = _status.event.player; return get.value(card, player) * get.sgn(player.getUseValue(card)); }, backup: function (links, player) { var index = links[0][2] == "sha" ? 0 : 1, level = player.countMark("miaojian"); var next = { audio: "miaojian", filterCard: [ [ function (card) { return get.name(card) == "sha"; }, function (card) { return get.type(card) == "basic"; }, () => false, ], [ function (card) { return get.type2(card) == "trick"; }, function (card) { return get.type(card) != "basic"; }, () => false, ], ][index][level], position: "hes", check: function (card) { if (card) return 6.5 - get.value(card); return 1; }, viewAs: [ { name: "sha", nature: "stab", }, { name: "wuzhong", }, ][index], }; if (level == 2) { next.selectCard = -1; next.viewAs.isCard = true; } return next; }, prompt: function (links, player) { var index = links[0][2] == "sha" ? 0 : 1, level = player.countMark("miaojian"); return [ ["将一张【杀】当做刺【杀】使用", "将一张基本牌当做刺【杀】使用", "请选择刺【杀】的目标"], ["将一张锦囊牌当做【无中生有】使用", "将一张非基本牌当做【无中生有】使用", "请选择【无中生有】的目标"], ][index][level]; }, }, onremove: true, derivation: ["miaojian1", "miaojian2"], subSkill: { backup: { audio: "miaojian" } }, ai: { order: 7, result: { player: 1 }, }, }, shhlianhua: { audio: 2, derivation: ["shhlianhua1", "shhlianhua2"], trigger: { target: "useCardToTargeted" }, forced: true, locked: false, filter: event => event.card.name == "sha", content: function () { "step 0"; player.draw(); var level = player.countMark("shhlianhua"); if (!level) event.finish(); else if (level == 2) event.goto(2); else player .judge(function (result) { return get.suit(result) == "spade" ? 1 : -1; }) .set("judge2", result => result.bool); "step 1"; if (result.bool) trigger.excluded.add(player); event.finish(); "step 2"; var eff = get.effect(player, trigger.card, trigger.player, trigger.player); trigger.player .chooseToDiscard("he", "弃置一张牌,或令" + get.translation(trigger.card) + "对" + get.translation(player) + "无效") .set("ai", function (card) { if (_status.event.eff > 0) { return 10 - get.value(card); } return 0; }) .set("eff", eff); "step 3"; if (result.bool == false) { trigger.getParent().excluded.add(player); } }, ai: { effect: { target_use(card, player, target, current) { if (card.name == "sha" && current < 0) return 0.7; }, }, }, }, //阎圃 huantu: { audio: 2, trigger: { global: "phaseDrawBefore" }, direct: true, filter: function (event, player) { return player.countCards("he") > 0 && !player.hasSkill("huantu_round") && player.inRange(event.player); }, checkx: function (event, player) { var target = event.player; return get.attitude(player, target) > 0 && (target.hasSkill("pingkou") || target.skipList.includes("phaseUse") || (target.isDamaged() && target.hp <= 2) || target.needsToDiscard()); }, content: function () { "step 0"; player .chooseCard(get.prompt("huantu", trigger.player), "交给其一张牌并令其暂时跳过摸牌阶段", "he") .set("ai", function (card) { if (!_status.event.checkx) return 0; return 1 + Math.random(); }) .set("checkx", lib.skill.huantu.checkx(trigger, player)); "step 1"; if (result.bool) { player.addTempSkill("huantu_round", "roundStart"); player.logSkill("huantu", trigger.player); player.give(result.cards, trigger.player); trigger.cancel(); player.addTempSkill("huantu_effect"); } }, subSkill: { round: { charlotte: true, mark: true, intro: { content: "本轮已发动" }, }, effect: { audio: "huantu", trigger: { global: "phaseJieshuBegin" }, forced: true, charlotte: true, logTarget: "player", filter: function (event, player) { return event.player.isIn(); }, content: function () { "step 0"; var str = get.translation(trigger.player); player .chooseControl() .set("choiceList", ["令" + str + "回复1点体力并摸两张牌", "摸三张牌,然后交给" + str + "两张手牌"]) .set("choice", trigger.player.isDamaged() ? 0 : 1); "step 1"; if (result.index == 0) { trigger.player.recover(); trigger.player.draw(2); event.finish(); } else { event.target = trigger.player; player.draw(3); } "step 2"; var hs = player.getCards("h"); if (hs.length && target.isIn() && player.isIn()) { if (hs.length <= 2) event._result = { bool: true, cards: hs }; else player.chooseCard("h", 2, true, "交给" + get.translation(target) + "两张手牌"); } else event.finish(); "step 3"; if (result.bool) player.give(result.cards, trigger.player); }, }, }, }, bihuo: { trigger: { global: "dyingAfter" }, logTarget: "player", limited: true, skillAnimation: true, animationColor: "gray", filter: function (event, player) { return event.player.isIn(); }, check: function (event, player) { return get.attitude(player, event.player) > 0; }, content: function () { player.awakenSkill("bihuo"); trigger.player.draw(3); trigger.player.addTempSkill("bihuo_effect", "roundStart"); trigger.player.addMark("bihuo_effect", game.countPlayer(), false); }, subSkill: { effect: { onremove: true, charlotte: true, mod: { globalTo: function (from, to, distance) { return distance + to.countMark("bihuo_effect"); }, }, intro: { content: "其他角色至你的距离+#" }, }, }, }, //马元义 jibing: { audio: 2, enable: ["chooseToUse", "chooseToRespond"], filter: function (event, player) { return player.getExpansions("jibing").length > 0 && (event.filterCard(get.autoViewAs({ name: "sha" }, "unsure"), player, event) || event.filterCard(get.autoViewAs({ name: "shan" }, "unsure"), player, event)); }, chooseButton: { dialog: function (event, player) { var dialog = ui.create.dialog("集兵", "hidden"); if (event.filterCard(get.autoViewAs({ name: "sha" }, "unsure"), player, event) && event.filterCard(get.autoViewAs({ name: "shan" }, "unsure"), player, event)) { dialog._chooseButton = 2; var list = ["sha", "shan"]; dialog.add([ list.map(i => { return [i, get.translation(i)]; }), "tdnodes", ]); } else dialog._cardName = event.filterCard(get.autoViewAs({ name: "sha" }, "unsure"), player, event) ? "sha" : "shan"; dialog.add(player.getExpansions("jibing")); return dialog; }, filter: function (button) { var evt = _status.event, player = _status.event.player; if (evt.dialog) { if (!evt.dialog._chooseButton) { var evt2 = _status.event.getParent(); return evt2.filterCard(get.autoViewAs({ name: evt.dialog._cardName }, [button.link]), player, evt2); } if (ui.selected.buttons.length) { var str = ui.selected.buttons[0].link; if (typeof str != "string" || typeof button.link == "string") return false; var evt2 = _status.event.getParent(); return evt2.filterCard(get.autoViewAs({ name: str }, [button.link]), player, evt2); } return typeof button.link == "string"; } return false; }, select: function () { return _status.event.dialog ? _status.event.dialog._chooseButton || 1 : 1; }, backup: function (links, player) { var card, name; if (links.length == 2) { name = links[0]; card = links[1]; } else { card = links[0]; var event = _status.event; name = event.filterCard(get.autoViewAs({ name: "sha" }, [card]), player, event) ? "sha" : "shan"; } return { audio: "jibing", filterCard: function (card) { return card == lib.skill.jibing_backup.card; }, selectCard: -1, position: "x", viewAs: { name: name }, card: card, }; }, prompt: function (links, player) { return "请选择【杀】的目标"; }, }, ai: { respondSha: true, respondShan: true, skillTagFilter: function (player, tag, arg) { return player.getExpansions("jibing").length > 0; }, order: function (item, player) { if (player.hasSkill("binghuo")) return 6; return 1; }, result: { player: 1, }, }, group: "jibing_place", subSkill: { place: { audio: "jibing", trigger: { player: "phaseDrawBegin1" }, prompt2: "摸牌阶段开始时,若你的“兵”数小于势力数,则你可以改为将牌堆顶的两张牌置于你的武将牌上,称为“兵”。", filter: function (event, player) { return !event.numFixed && player.getExpansions("jibing").length < game.countGroup(); }, content: function () { trigger.changeToZero(); var cards = get.cards(2); player.addToExpansion(cards, "gain2").gaintag.add("jibing"); }, }, backup: { audio: "jibing" }, }, intro: { content: "expansion", markcount: "expansion" }, onremove: function (player, skill) { var cards = player.getExpansions(skill); if (cards.length) player.loseToDiscardpile(cards); }, }, wangjing: { audio: 2, trigger: { player: ["useCard", "respond"] }, filter: function (event, player) { if (event.skill != "jibing_backup") return false; var target = lib.skill.wangjing.logTarget(event, player); return target && target.isMaxHp(); }, logTarget: function (event, player) { if (event.name == "respond") return event.source; if (event.card.name == "sha") return event.targets[0]; return event.respondTo[0]; }, forced: true, content: function () { player.draw(); }, ai: { combo: "jibing", mingzhi: false, effect: { target: function (card, player, target, current) { if ((get.tag(card, "respondShan") || get.tag(card, "respondSha")) && target.getExpansions("jibing").length > 0 && player.isMaxHp()) { if (get.attitude(target, player) <= 0) { return [0, 0, 1, 0.3]; } } }, }, }, }, moucuan: { audio: 2, derivation: "binghuo", trigger: { player: "phaseZhunbeiBegin" }, forced: true, juexingji: true, skillAnimation: true, animationColor: "metal", filter: function (event, player) { return player.getExpansions("jibing").length >= game.countGroup(); }, content: function () { player.awakenSkill("moucuan"); player.loseMaxHp(); player.addSkills("binghuo"); }, ai: { combo: "jibing" }, }, binghuo: { audio: 2, trigger: { global: "phaseJieshuBegin" }, direct: true, filter: function (event, player) { return ( player.hasHistory("useCard", function (evt) { return evt.skill == "jibing_backup"; }) || player.hasHistory("respond", function (evt) { return evt.skill == "jibing_backup"; }) ); }, content: function () { "step 0"; player.chooseTarget(get.prompt2("binghuo")).set("ai", function (target) { var player = _status.event.player; return get.damageEffect(target, player, player); }); "step 1"; if (result.bool) { var target = result.targets[0]; event.target = target; player.logSkill("binghuo", target); target.judge(function (card) { if (get.color(card) == "black") return -2; return 0.1; }).judge2 = function (result) { return result.bool === false ? true : false; }; } else event.finish(); "step 2"; if (result.bool == false) target.damage("thunder"); }, ai: { combo: "jibing", expose: 0.2 }, }, //司马孚 xunde: { audio: 2, trigger: { global: "damageEnd" }, filter: function (event, player) { return event.player.isIn() && get.distance(player, event.player) <= 1; }, logTarget: "player", check: function (event, player) { return get.attitude(player, event.player) > 0 && (!event.source || get.attitude(player, event.source) < 0); }, content: function () { "step 0"; player.judge().set("callback", function () { if (event.judgeResult.number > 5) { var player = event.getParent(2)._trigger.player; if (get.position(card, true) == "o") player.gain(card, "gain2"); } }); "step 1"; if (result.number < 7) { var source = trigger.source; if (source && source.isIn() && source.countCards("h") > 0) { player.line(source); source.chooseToDiscard("h", true); } } }, }, chenjie: { audio: 2, trigger: { global: "judge" }, filter: function (event, player) { var suit = get.suit(event.player.judging[0], event.player); return ( player.countCards("hes", function (card) { if (_status.connectMode && get.position(card) != "e") return true; return get.suit(card) == suit; }) > 0 ); }, direct: true, preHidden: true, content: function () { "step 0"; var suit = get.suit(trigger.player.judging[0], trigger.player); player .chooseCard(get.translation(trigger.player) + "的" + (trigger.judgestr || "") + "判定为" + get.translation(trigger.player.judging[0]) + "," + get.prompt("chenjie"), "hes", function (card) { if (get.suit(card) != _status.event.suit) return false; var player = _status.event.player; var mod2 = game.checkMod(card, player, "unchanged", "cardEnabled2", player); if (mod2 != "unchanged") return mod2; var mod = game.checkMod(card, player, "unchanged", "cardRespondable", player); if (mod != "unchanged") return mod; return true; }) .set("ai", function (card) { var trigger = _status.event.getTrigger(); var player = _status.event.player; var judging = _status.event.judging; var result = trigger.judge(card) - trigger.judge(judging); var attitude = get.attitude(player, trigger.player); if (attitude == 0 || result == 0) return 0.1; if (attitude > 0) { return result + 0.01; } else { return 0.01 - result; } }) .set("judging", trigger.player.judging[0]) .set("suit", suit) .setHiddenSkill(event.name); "step 1"; if (result.bool) { event.card = result.cards[0]; player.respond(result.cards, "highlight", "chenjie", "noOrdering"); } else { event.finish(); } "step 2"; if (result.bool) { if (trigger.player.judging[0].clone) { trigger.player.judging[0].clone.classList.remove("thrownhighlight"); game.broadcast(function (card) { if (card.clone) { card.clone.classList.remove("thrownhighlight"); } }, trigger.player.judging[0]); game.addVideo("deletenode", player, get.cardsInfo([trigger.player.judging[0].clone])); } game.cardsDiscard(trigger.player.judging[0]); trigger.player.judging[0] = card; trigger.orderingCards.add(card); game.log(trigger.player, "的判定牌改为", card); player.draw(2); } }, ai: { rejudge: true, tag: { rejudge: 0.1, }, }, }, //傅佥 jueyong: { audio: 2, trigger: { target: "useCardToTarget" }, forced: true, filter: function (event, player) { return event.card.name != "jiu" && event.card.name != "tao" && event.targets.length == 1 && event.card.isCard && event.cards.length == 1 && event.getParent(2).name != "jueyong_timeout" && get.position(event.cards[0], true) == "o" && event.card.name == event.cards[0].name && (!player.storage.jueyong || player.storage.jueyong[0].length < player.getHp()); }, content: function () { trigger.targets.remove(player); trigger.getParent().triggeredTargets2.remove(player); trigger.untrigger(); var card = trigger.cards[0]; player.addToExpansion(card, "gain2").gaintag.add("jueyong"); if (!player.storage.jueyong) player.storage.jueyong = [[], []]; player.storage.jueyong[0].push(card); player.storage.jueyong[1].push(trigger.player); game.delayx(); }, onremove: function (player, skill) { var cards = player.getExpansions(skill); if (cards.length) player.loseToDiscardpile(cards); delete player.storage[skill]; }, intro: { markcount: function (storage) { if (!storage) return 0; return storage[0].length; }, mark: function (dialog, storage, player) { if (!storage) return; dialog.addAuto(storage[0]); dialog.addText(get.translation(storage[1])); }, onunmark: function (storage, player) { player.storage.jueyong = [[], []]; }, }, ai: { reverseEquip: true, effect: { target_use(card, player, target, current) { if (get.type(card) == "equip" && !get.tag(card, "gifts") && target.storage.jueyong && target.storage.jueyong[1].length) { var result1 = get.equipResult(player, target, card.name), subtype = get.subtype(card); for (var i of target.storage.jueyong[0]) { if (get.subtype(i, false) == subtype && get.equipResult(target, target, i.name) >= result1) return "zerotarget"; } } }, }, }, group: "jueyong_timeout", subSkill: { timeout: { audio: "jueyong", trigger: { player: "phaseJieshuBegin" }, forced: true, filter: function (event, player) { return player.storage.jueyong && player.storage.jueyong[0].length > 0; //=Math.max(1,player.getDamagedHp()); }, content: function () { var list = player.storage.jueyong, card = list[0].shift(), source = list[1].shift(); if (player.getExpansions("jueyong").includes(card)) { if (source && source.isIn() && source.canUse(card, player, false)) source.useCard(card, player, false); else player.loseToDiscardpile(card); } if (list[0].length) event.redo(); }, }, }, }, poxiang: { audio: 2, enable: "phaseUse", usable: 1, filter: (event, player) => player.countCards("he") > 0, filterCard: true, filterTarget: lib.filter.notMe, position: "he", discard: false, lose: false, delay: false, check: function (card) { var player = _status.event.player; if ( !player.storage.jueyong || !player.storage.jueyong[0].length || (player.hp <= 1 && !player.storage.jueyong[0].some(function (card) { return get.tag(card, "damage") > 0; })) || !player.storage.jueyong[0].some(function (card) { return get.effect(player, card, player.storage.jueyong[1][player.storage.jueyong[0].indexOf(card)], player) < 0; }) ) return -1; return 20 - get.value(card); }, content: function () { "step 0"; player.give(cards, target); player.draw(3).gaintag = ["poxiang"]; player.addTempSkill("poxiang_mark"); "step 1"; var cards = player.getExpansions("jueyong"); if (cards.length) player.loseToDiscardpile(cards); player.unmarkSkill("jueyong"); player.loseHp(); "step 2"; //player.skip('phaseDiscard'); game.delayx(); }, ai: { order: 12, result: { player: 4, target: 1, }, }, subSkill: { mark: { charlotte: true, onremove: function (player) { player.removeGaintag("poxiang"); }, mod: { ignoredHandcard: function (card, player) { if (card.hasGaintag("poxiang")) { return true; } }, cardDiscardable: function (card, player, name) { if (name == "phaseDiscard" && card.hasGaintag("poxiang")) { return false; } }, }, }, }, }, //曹真 disordersidi: { audio: 2 }, discretesidi: { audio: "disordersidi", trigger: { player: "useCardAfter" }, direct: true, filter: function (event, player) { return ( get.type(event.card, false) != "delay" && game.hasPlayer(function (current) { return player != current && (!player.storage.discretesidi || !player.storage.discretesidi.includes(current)); }) ); }, content: function () { "step 0"; player .chooseTarget(get.prompt("discretesidi"), "选择两名角色a,b建立二元序偶,或仅选择一名角色,建立二元序偶", [1, 2], function (card, player, target) { if (ui.selected.targets.length) return true; return target != player && (!player.storage.discretesidi || !player.storage.discretesidi.includes(target)); }) .set("complexTarget", true) .set("complexSelect", true) .set("targetprompt", ["第一元素", "第二元素"]) .set("ai", function (target) { var player = _status.event.player; if (!ui.selected.targets.length) { if (target.getEnemies().length == 1) return 2 + Math.random(); return 1 + Math.random(); } var targetx = ui.selected.targets[0]; if (targetx.getEnemies().includes(target) && targetx.inRange(target)) return Math.random() - 0.5; return 0; }).animate = false; "step 1"; if (result.bool && result.targets.length) { var targets = result.targets; player.logSkill("discretesidi", targets[0]); if (targets.length == 1) targets.push(targets[0]); if (!player.storage.discretesidi) player.storage.discretesidi = []; if (!player.storage.discretesidi2) player.storage.discretesidi2 = []; player.storage.discretesidi.push(targets[0]); player.storage.discretesidi2.push(targets[1]); player.markSkill("discretesidi"); game.delayx(); } }, intro: { content: function (storage, player) { if ((player == game.me || player.isUnderControl()) && !game.observe) { var str = "R={ "; for (var i = 0; i < storage.length; i++) { str += "<" + get.translation(storage[i]) + ", " + get.translation(player.storage.discretesidi2[i]) + ">"; if (i < storage.length - 1) str += ", "; } str += " }"; return str; } return "已指定" + get.translation(storage) + "为目标"; }, }, onremove: function (player) { delete player.storage.discretesidi; delete player.storage.discretesidi2; }, group: ["discretesidi_clear", "discretesidi_exec"], subSkill: { clear: { trigger: { global: ["useCardToPlayered", "die"] }, forced: true, popup: false, locked: false, filter: function (event, player) { if (!player.storage.discretesidi || !player.storage.discretesidi.includes(event.player)) return false; if (event.name == "die") return true; if (get.type(event.card, false) != "delay") { var index = player.storage.discretesidi.indexOf(event.player); return index != -1 && (player.storage.discretesidi2[index] != event.target || event.targets.length != 1); } return false; }, content: function () { player.storage.discretesidi2.splice(player.storage.discretesidi.indexOf(trigger.player), 1); player.unmarkAuto("discretesidi", [trigger.player]); }, }, exec: { audio: "disordersidi", trigger: { global: "useCardToPlayered" }, forced: true, locked: false, filter: function (event, player) { if (get.type(event.card, false) == "delay" || !player.storage.discretesidi || event.targets.length != 1) return false; var index = player.storage.discretesidi.indexOf(event.player); return index != -1 && player.storage.discretesidi2[index] == event.target; }, logTarget: "player", content: function () { "step 0"; player.storage.discretesidi2.splice(player.storage.discretesidi.indexOf(trigger.player), 1); player.unmarkAuto("discretesidi", [trigger.player]); if (trigger.target == player) { player.draw(); event.finish(); return; } var target = trigger.player; event.target = target; player .chooseControl("cancel2") .set("choiceList", ["取消" + get.translation(trigger.card) + "的所有目标并对" + get.translation(target) + "造成1点伤害", "摸两张牌"]) .set("ai", function () { var player = _status.event.player, evt = _status.event.getTrigger(); if (get.damageEffect(evt.player, player, player) > 0 && get.effect(evt.target, evt.card, evt.player, player) < 0) return 0; return 1; }); "step 1"; if (result.index == 0) { trigger.cancel(); trigger.targets.length = 0; trigger.getParent().triggeredTargets1.length = 0; if (!_status.dying.length) target.damage(); } else if (result.index == 1) player.draw(2); }, }, }, }, //孙鲁班 xinzenhui: { audio: 2, trigger: { player: "useCardToPlayer" }, filter: function (event, player) { if (event.targets.length != 1) return false; var card = event.card; if (card.name != "sha" && (get.type(card, null, false) != "trick" || get.color(card, false) != "black")) return false; if (!player.isPhaseUsing() || player.hasSkill("xinzenhui2")) return false; return game.hasPlayer(function (current) { return current != player && current != event.target && lib.filter.targetEnabled2(card, player, current) && lib.filter.targetInRange(card, player, current); }); }, direct: true, content: function () { "step 0"; player .chooseTarget(get.prompt2("xinzenhui"), function (card, player, target) { if (player == target) return false; var evt = _status.event.getTrigger(); return !evt.targets.includes(target) && lib.filter.targetEnabled2(evt.card, player, target) && lib.filter.targetInRange(evt.card, player, target); }) .set("ai", function (target) { var trigger = _status.event.getTrigger(); var player = _status.event.player; return Math.max(target.countGainableCards(player, "he") ? get.effect(target, { name: "shunshou_copy2" }, player, player) : 0, get.effect(target, trigger.card, player, player)); }); "step 1"; if (result.bool) { player.addTempSkill("xinzenhui2", "phaseUseAfter"); var target = result.targets[0], str = get.translation(target); event.target = target; player.logSkill("xinzenhui", target); if (!target.countGainableCards(player, "he")) event._result = { index: 0 }; else player .chooseControl() .set("choiceList", ["令" + str + "也成为" + get.translation(trigger.card) + "的目标", "获得" + str + "的一张牌,然后其成为" + get.translation(trigger.card) + "的使用者"]) .set("ai", function () { var trigger = _status.event.getTrigger(); var player = _status.event.player, target = _status.event.getParent().target; return (target.countGainableCards(player, "he") ? get.effect(target, { name: "shunshou_copy2" }, player, player) : 0) > get.effect(target, trigger.card, player, player) ? 1 : 0; }); } else event.finish(); "step 2"; if (result.index == 1) { trigger.untrigger(); trigger.getParent().player = event.target; game.log(event.target, "成为了", trigger.card, "的使用者"); player.gainPlayerCard(target, true, "he"); } else { game.log(event.target, "成为了", trigger.card, "的额外目标"); trigger.getParent().targets.push(event.target); } }, }, xinzenhui2: {}, xinjiaojin: { audio: 2, trigger: { player: "damageBegin4" }, filter: function (event, player) { return player.countCards("he", { type: "equip" }) && event.source && event.source.hasSex("male"); }, direct: true, content: function () { "step 0"; var next = player.chooseToDiscard("he", "骄矜:是否弃置一张装备牌防止伤害?", function (card, player) { return get.type(card) == "equip"; }); next.set("ai", function (card) { var player = _status.event.player; if (player.hp == 1 || _status.event.getTrigger().num > 1) { return 9 - get.value(card); } if (player.hp == 2) { return 8 - get.value(card); } return 7 - get.value(card); }); next.logSkill = "xinjiaojin"; "step 1"; if (result.bool) { game.delay(0.5); trigger.cancel(); } }, }, //新华歆 yuanqing: { audio: 2, trigger: { player: "phaseUseEnd" }, forced: true, filter: function (event, player) { return player.hasHistory("useCard", function (evt) { return evt.getParent("phaseUse") == event; }); }, content: function () { var map = {}, cards = []; player.getHistory("useCard", function (evt) { if (evt.getParent("phaseUse") == trigger) { var type = get.type2(evt.card, false); if (!map[type]) map[type] = []; } }); for (var i = 0; i < ui.discardPile.childNodes.length; i++) { var card = ui.discardPile.childNodes[i], type = get.type2(card, false); if (map[type]) map[type].push(card); } for (var i in map) { if (map[i].length) cards.push(map[i].randomGet()); } if (cards.length) { player.$gain2(cards, false); game.cardsGotoSpecial(cards, "toRenku"); game.log(player, "将", cards, "置入了仁库"); game.delayx(); } }, init: function (player) { player.storage.renku = true; }, }, shuchen: { audio: 2, init: function (player) { player.storage.renku = true; }, trigger: { global: "dying" }, forced: true, filter: function (event, player) { return _status.renku.length > 3; }, logTarget: "player", content: function () { player.gain(_status.renku, "gain2", "fromRenku"); _status.renku.length = 0; game.updateRenku(); trigger.player.recover(); }, }, //谯周 zhiming: { audio: 2, trigger: { player: ["phaseZhunbeiBegin", "phaseDiscardEnd"] }, frequent: true, content: function () { "step 0"; player.draw(); "step 1"; if (player.countCards("he") > 0) { var next = player.chooseCard("he", "是否将一张牌置于牌堆顶?"); if (trigger.name == "phaseZhunbei") { next.set("ai", function (card) { var player = _status.event.player, js = player.getCards("j"); if (js.length) { var judge = get.judge(js[0]); if (judge && judge(card) >= 0) return 20 - get.value(card); } return 0; }); } else next.set("ai", function (card) { var player = _status.event.player, js = player.next.getCards("j"); if (js.length) { var judge = get.judge(js[0]); if (judge && (judge(card) + 0.01) * get.attitude(player, player.next) > 0) return 20 - get.value(card); } return 0; }); } else event.finish(); "step 2"; if (result.bool) { player.$throw(get.position(result.cards[0]) == "e" ? result.cards[0] : 1, 1000); game.log(player, "将", get.position(result.cards[0]) == "e" ? result.cards[0] : "#y一张手牌", "置于了牌堆顶"); player.lose(result.cards, ui.cardPile, "insert"); } else event.finish(); "step 3"; game.updateRoundNumber(); game.delayx(); }, ai: { guanxing: true }, }, xingbu: { audio: 2, trigger: { player: "phaseJieshuBegin" }, prompt2: "亮出牌堆顶的三张牌,并可以根据其中红色牌的数量,令一名其他角色获得一种效果", content: function () { "step 0"; var cards = get.cards(3); //for(var i=cards.length-1;i--;i>=0){ // ui.cardPile.insertBefore(cards[i],ui.cardPile.firstChild); //} game.updateRoundNumber(); event.cards = cards; //game.cardsGotoOrdering(cards); player.showCards(cards, get.translation(player) + "发动了【星卜】"); "step 1"; var num = 0; for (var i of cards) { if (get.color(i, false) == "red") num++; } player.chooseTarget("是否选择一名其他角色获得星卜效果(" + get.cnNumber(num) + "张)?", lib.filter.notMe).set("ai", function (target) { var player = _status.event.player, num = _status.event.getParent().num; var att = get.attitude(player, target); if (num < 3) att *= -1; if (num == 2 && target.hasJudge("lebu")) att *= -1.4; return att; }); if (num == 0) num = 1; event.num = num; "step 2"; if (result.bool) { var skill = "xingbu_effect" + num, target = result.targets[0]; player.line(target, "green"); game.log(player, "选择了", target); target.addTempSkill(skill, { player: "phaseEnd" }); target.addMark(skill, 1, false); game.delayx(); } }, subSkill: { effect1: { charlotte: true, onremove: true, intro: { content: "准备阶段开始时弃置#张手牌" }, trigger: { player: "phaseZhunbeiBegin" }, forced: true, filter: function (event, player) { return player.countCards("h") > 0; }, content: function () { player.chooseToDiscard("h", true, player.countMark("xingbu_effect1")); }, }, effect2: { charlotte: true, onremove: true, intro: { content: "使用【杀】的次数上限-#,跳过弃牌阶段" }, mod: { cardUsable: function (card, player, num) { if (card.name == "sha") return num - player.countMark("xingbu_effect2"); }, }, trigger: { player: "phaseDiscardBegin" }, forced: true, content: function () { trigger.cancel(); }, }, effect3: { charlotte: true, onremove: true, intro: { content: "摸牌阶段多摸2*#张牌,使用【杀】的次数上限+#。" }, trigger: { player: ["phaseDrawBegin2"] }, forced: true, filter: function (event, player) { return !event.numFixed; }, content: function () { if (trigger.name == "phaseDraw") trigger.num += player.countMark("xingbu_effect3") * 2; }, mod: { cardUsable: function (card, player, num) { if (card.name == "sha") return num + player.countMark("xingbu_effect3"); }, }, }, }, }, //顾雍 xinshenxing: { audio: 2, enable: "phaseUse", filter: function (event, player) { return (player.getStat("skill").xinshenxing || 0) < player.hp && player.countCards("he") > 1; }, selectCard: 2, position: "he", check: function (card) { if (!ui.selected.cards.length || get.color(card) != get.color(ui.selected.cards[0])) return 6.5 - get.value(card); return 6.5 - get.value(card) - get.value(ui.selected.cards[0]); }, filterCard: true, content: function () { player.draw(get.color(cards) == "none" ? 2 : 1); }, ai: { order: 1, result: { player: 1 }, }, }, xinbingyi: { audio: "bingyi", audioname: ["xin_guyong"], trigger: { player: "phaseJieshuBegin" }, filter: function (event, player) { return player.countCards("h") > 0; }, filterx: function (event, player) { var cards = player.getCards("h"); if (cards.length == 1) return true; var color = get.color(cards[0], player), type = get.type2(cards[0], player); for (var i = 1; i < cards.length; i++) { if (color && get.color(cards[i], player) != color) color = false; if (type && get.type2(cards[i], player) != type) type = false; if (!color && !type) return false; } return true; }, direct: true, content: function () { "step 0"; if (lib.skill.xinbingyi.filterx(trigger, player)) { player .chooseTarget(get.prompt("xinbingyi"), "展示所有手牌,并选择至多" + get.cnNumber(player.countCards("h")) + "名角色各摸一张牌", [0, player.countCards("h")], function (card, player, target) { return true; }) .set("ai", function (target) { return get.attitude(_status.event.player, target); }); } else player.chooseBool(get.prompt("bingyi"), "展示所有手牌").ai = function () { return false; }; "step 1"; if (result.bool) { player.logSkill("xinbingyi"); player.showHandcards(get.translation(player) + "发动了【秉壹】"); event.targets = result.targets; } else { event.finish(); } "step 2"; if (targets && targets.length) { player.line(targets, "green"); targets.sortBySeat(); game.asyncDraw(targets); } }, ai: { expose: 0.1, }, }, //钟会 requanji: { audio: 2, trigger: { player: ["damageEnd", "phaseUseEnd"] }, frequent: true, locked: false, notemp: true, filter: function (event, player) { if (event.name == "phaseUse") return player.countCards("h") > player.hp; return event.num > 0; }, content: function () { "step 0"; event.count = trigger.num || 1; "step 1"; event.count--; player.draw(); "step 2"; if (player.countCards("h")) { player.chooseCard("将一张手牌置于武将牌上作为“权”", true); } else { event.goto(4); } "step 3"; if (result.cards && result.cards.length) { player.addToExpansion(result.cards, player, "give").gaintag.add("quanji"); } "step 4"; if (event.count > 0 && player.hasSkill(event.name) && !get.is.blocked(event.name, player)) { player.chooseBool(get.prompt2("requanji")).set("frequentSkill", event.name); } else event.finish(); "step 5"; if (result.bool) { player.logSkill("requanji"); event.goto(1); } }, mod: { maxHandcard(player, num) { return num + player.getExpansions("quanji").length; }, aiOrder(player, card, num) { if (num <= 0 || typeof card !== "object" || !player.isPhaseUsing() || !player.hasSkill("zili") || player.needsToDiscard()) return num; if (player.getExpansions("quanji").length < 3 && player.getUseValue(card) < Math.min(4, (player.hp * player.hp) / 4)) return 0; }, }, onremove: function (player, skill) { var cards = player.getExpansions("quanji"); if (cards.length) player.loseToDiscardpile(cards); }, ai: { maixie: true, maixie_hp: true, threaten: 0.8, effect: { target: function (card, player, target) { if (get.tag(card, "damage")) { if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; if (!target.hasFriend()) return; if (target.hp >= 4) return [0.5, get.tag(card, "damage") * 2]; if (!target.hasSkill("paiyi") && target.hp > 1) return [0.5, get.tag(card, "damage") * 1.5]; if (target.hp == 3) return [0.5, get.tag(card, "damage") * 1.5]; if (target.hp == 2) return [1, get.tag(card, "damage") * 0.5]; } }, }, }, }, //蔡夫人 xinqieting: { audio: 2, trigger: { global: "phaseEnd" }, direct: true, filter: function (event, player) { return ( player != event.player && event.player.getHistory("sourceDamage", function (evt) { return evt.player != event.player; }).length == 0 ); }, content: function () { "step 0"; var list = ["摸一张牌"], target = trigger.player, str = get.translation(target); event.target = target; event.addIndex = 0; if (target.countCards("h") > 0) list.push("观看" + str + "的两张手牌并获得其中一张"); else event.addIndex++; if ( target.countCards("e", function (card) { return player.canEquip(card); }) > 0 ) list.push("将" + str + "装备区内的一张牌移动至自己的装备区"); player .chooseControl("cancel2") .set("choiceList", list) .set("prompt", get.prompt("xinqieting", target)) .set("ai", function () { var evt = _status.event.getParent(); if (get.attitude(evt.player, evt.target) > 0) return 0; var val = evt.target.hasSkillTag("noe") ? 6 : 0; if ( evt.target.countCards("e", function (card) { return evt.player.canEquip(card) && get.value(card, evt.target) > val && get.effect(evt.player, card, evt.player, evt.player) > 0; }) > 0 ) return 2 - evt.addIndex; if (evt.target.countCards("h") > 0) return 1; return 0; }); "step 1"; if (result.control != "cancel2") { player.logSkill("xinqieting", target); if (result.index == 0) { player.draw(); event.finish(); } else if (result.index + event.addIndex == 1) { player.choosePlayerCard(target, "h", 2, true); player.addExpose(0.2); event.goto(3); } else { player.addExpose(0.1); player .choosePlayerCard(target, "e", true) .set("filterButton", function (button) { return _status.event.player.canEquip(button.link); }) .set("ai", function (button) { var player = _status.event.player; return get.effect(player, button.link, player, player); }); } } else event.finish(); "step 2"; if (result.bool) { var card = result.cards[0]; target.$give(card, player, false); game.delay(0.5); player.equip(card); } event.finish(); "step 3"; if (result.bool) player.chooseButton(["选择获得一张牌", result.cards], true); else event.finish(); "step 4"; if (result.bool) { var card = result.links[0]; if (lib.filter.canBeGained(card, player, target)) player.gain(card, target, "giveAuto", "bySelf"); else game.log("但", card, "不能被", player, "获得!"); } }, }, mobilezhongyong: { audio: 2, trigger: { player: "useCardAfter" }, direct: true, filter: function (event, player) { if (event.card.name != "sha" || !event.isPhaseUsing(player)) return false; if (event.cards.filterInD().length > 0) return true; var list = lib.skill.mobilezhongyong.getResponds(event); if (list.length) { for (var evt of list) { if (evt.cards.filterInD("od").length > 0) return true; } } return false; }, getResponds: function (event) { var list = []; for (var i of event.targets) { list.addArray( i.getHistory("useCard", function (evt) { return evt.card.name == "shan" && evt.respondTo && evt.respondTo[1] == event.card; }) ); } return list; }, content: function () { "step 0"; event.shas = trigger.cards.filterInD(); var list = lib.skill.mobilezhongyong.getResponds(trigger); if (list.length) { event.shans = []; for (var evt of list) { event.shans.addArray(evt.cards.filterInD("od")); } event.goto(2); } else player.chooseBool(get.prompt("mobilezhongyong"), "获得" + get.translation(event.shas)).set("ai", function () { var evt = _status.event.getParent(); return get.value(evt.shas, evt.player) > 0; }); "step 1"; if (result.bool) { player.logSkill("mobilezhongyong"); player.addTempSkill("mobilezhongyong_buff"); player.gain(event.shas, "gain2").gaintag.add("mobilezhongyong"); } event.finish(); "step 2"; var shans = get.translation(event.shans), choiceList = ["获得" + shans]; if ( game.hasPlayer(function (current) { return current != player && !trigger.targets.includes(current); }) ) { if (event.shas.length) choiceList[0] += ",然后可以令另一名其他角色获得" + get.translation(event.shas); choiceList.push("令另一名其他角色获得" + shans + ",然后你于本回合内使用【杀】的次数上限+1且下一张【杀】的伤害值基数+1"); } player .chooseControl("cancel2") .set("choiceList", choiceList) .set("prompt", get.prompt("mobilezhongyong")) .set("ai", function () { var evt = _status.event.getParent(), player = evt.player, tri = _status.event.getTrigger(); if ( game.hasPlayer(function (current) { return current != player && !tri.targets.includes(current) && get.attitude(player, current) > 0; }) && player.countCards("hs", function (card) { return get.name(card) == "sha" && player.hasValueTarget(card); }) > player.getCardUsable({ name: "sha" }) ) return 1; return 0; }); "step 3"; if (result.index == 0) { player.logSkill("mobilezhongyong"); player.addTempSkill("mobilezhongyong_buff"); player.gain(event.shans, "gain2").gaintag.add("mobilezhongyong"); } else event.goto(6); "step 4"; event.shas = event.shas.filterInD("od"); if ( event.shas.length && game.hasPlayer(function (current) { return current != player && !trigger.targets.includes(current); }) ) { player .chooseTarget("是否令一名其他角色获得" + get.translation(event.shas) + "?", function (card, player, target) { return target != player && !_status.event.getTrigger().targets.includes(target); }) .set("ai", function (target) { var player = _status.event.player, att = get.attitude(player, target); if (att <= 0) return att; if (target.hasSkillTag("nogain")) return att / 10; if (!target.hasSha()) return 2 * att; return att; }); } else event.finish(); "step 5"; if (result.bool) { var target = result.targets[0]; player.line(target, "green"); target.gain(event.shas, "gain2"); } event.finish(); "step 6"; player .chooseTarget("令一名其他角色获得" + get.translation(event.shans), true, function (card, player, target) { return target != player && !_status.event.getTrigger().targets.includes(target); }) .set("ai", function (target) { var player = _status.event.player, att = get.attitude(player, target); if (att <= 0) return att; if (target.hasSkillTag("nogain")) return att / 10; if (!target.hasShan()) return 2 * att; return att; }); "step 7"; if (result.bool) { var target = result.targets[0]; player.logSkill("mobilezhongyong", target); target.gain(event.shans, "gain2"); player.addTempSkill("mobilezhongyong_buff"); player.addMark("mobilezhongyong_buff", 1, false); player.addMark("mobilezhongyong_damage", 1, false); } }, subSkill: { buff: { mod: { cardEnabled2: function (card, player) { if (get.itemtype(card) == "card" && card.hasGaintag("mobilezhongyong")) return false; }, cardUsable: function (card, player, num) { if (card.name == "sha") return num + player.countMark("mobilezhongyong_buff"); }, }, trigger: { player: "useCard1" }, firstDo: true, forced: true, charlotte: true, popup: false, filter: function (event, player) { return event.card.name == "sha" && player.countMark("mobilezhongyong_damage") > 0; }, content: function () { trigger.baseDamage += player.storage.mobilezhongyong_damage; delete player.storage.mobilezhongyong_damage; }, onremove: function (player) { delete player.storage.mobilezhongyong_buff; delete player.storage.mobilezhongyong_damage; player.removeGaintag("mobilezhongyong"); }, }, }, }, rejieyue: { audio: 2, trigger: { player: "phaseJieshuBegin" }, direct: true, filter: function (event, player) { return player.countCards("he") > 0; }, content: function () { "step 0"; player.chooseCardTarget({ prompt: get.prompt2("rejieyue"), filterCard: true, position: "he", filterTarget: lib.filter.notMe, ai1: function (card) { var player = _status.event.player; if (get.name(card) == "du") return 20; if (get.position(card) == "e" && get.value(card) <= 0) return 14; if ( get.position(card) == "h" && game.hasPlayer(function (current) { return current != player && get.attitude(player, current) > 0 && current.getUseValue(card) > player.getUseValue(card) && current.getUseValue(card) > player.getUseValue(card); }) ) return 12; if ( game.hasPlayer(function (current) { return current != player && get.attitude(player, current) > 0; }) ) { if (card.name == "wuxie") return 11; if (card.name == "shan" && player.countCards("h", "shan") > 1) return 9; } return 6 / Math.max(1, get.value(card)); }, ai2: function (target) { var player = _status.event.player; var card = ui.selected.cards[0]; var att = get.attitude(player, target); if (card.name == "du") return -6 * att; if (att > 0) { if (get.position(card) == "h" && target.getUseValue(card) > player.getUseValue(card)) return 4 * att; if (get.value(card, target) > get.value(card, player)) return 2 * att; return 1.2 * att; } return (-att * Math.min(4, target.countCards("he"))) / 4; }, }); "step 1"; if (result.bool) { var target = result.targets[0]; event.target = target; player.logSkill("rejieyue", target); player.give(result.cards, target); } else event.finish(); "step 2"; var num = 0; if (target.countCards("h")) num++; if (target.countCards("e")) num++; if (num > 0) { var next = target.chooseCard("he", num, "选择保留每个区域的各一张牌,然后弃置其余的牌。或点取消,令" + get.translation(player) + "摸三张牌", function (card) { for (var i = 0; i < ui.selected.cards.length; i++) { if (get.position(ui.selected.cards[i]) == get.position(card)) return false; } return true; }); next.set("complexCard", true); next.set("goon", get.attitude(target, player) >= 0); next.set("maxNum", num); next.set("ai", function (card) { if (_status.event.goon) return -1; var num = _status.event.maxNum; if (ui.selected.cards.length >= num - 1) { var cards = player.getCards("he", function (cardx) { return cardx != card && !ui.selected.cards.includes(cardx); }); var val = 0; for (var cardx of cards) val += get.value(cardx); if (val >= 14) return 0; } return get.value(card); }); } else event._result = { bool: false }; "step 3"; if (!result.bool) player.draw(3); else { var cards = target.getCards("he"); cards.removeArray(result.cards); if (cards.length) target.discard(cards); } }, ai: { threaten: 1.3, expose: 0.2, }, }, tiansuan: { audio: 2, enable: "phaseUse", filter: function (event, player) { return !player.storage.tiansuan2; }, content: function () { "step 0"; player .chooseControl("上上签", "上签", "中签", "下签", "下下签", "cancel2") .set("prompt", "天算:是否增加其中一个命运签的权重?") .set("ai", function () { return Math.random() < 0.5 ? 0 : 4; }); "step 1"; var list = [0, 1, 1, 2, 2, 2, 3, 3, 4]; if (result.control != "cancel2") list.push(result.index); var num = list.randomGet(); event.num = num; var str = get.translation(player) + "抽取的命运签为:" + lib.skill["tiansuan2_" + num].name; game.log(player, "抽取出了", "#g" + lib.skill["tiansuan2_" + num].name); event.dialog = ui.create.dialog(str); event.videoId = lib.status.videoId++; game.broadcast("createDialog", event.videoId, str); game.pause(); setTimeout(function () { game.resume(); }, 1500); "step 2"; event.dialog.close(); game.broadcast("closeDialog", event.videoId); player.chooseTarget(true, "令一名角色获得“" + lib.skill["tiansuan2_" + num].name + "”").set("ai", lib.skill["tiansuan2_" + num].aiCheck); "step 3"; if (result.bool) { var target = result.targets[0]; player.line(target, "green"); game.log(player, "令", target, "获得了命运签"); player.storage.tiansuan2 = target; player.storage.tiansuan3 = "tiansuan2_" + num; player.addTempSkill("tiansuan2", { player: "phaseBegin" }); target.addSkill("tiansuan2_" + num); if (num < 2 && target.countGainableCards(player, target == player ? "e" : "he") > 0) { var next = player.gainPlayerCard(target, target == player ? "e" : "he", true); if (num == 0) next.visible = true; } else game.delayx(); } }, derivation: "tiansuan_faq", ai: { order: 7, result: { player: 1, }, }, }, tiansuan2: { charlotte: true, onremove: function (player, skill) { if (player.storage.tiansuan2) player.storage.tiansuan2.removeSkill(player.storage.tiansuan3); delete player.storage.tiansuan2; delete player.storage.tiansuan3; }, }, tiansuan2_0: { name: "上上签", trigger: { player: "damageBegin4" }, forced: true, charlotte: true, content: function () { trigger.cancel(); }, mark: true, intro: { content: "当你受到伤害时,防止此伤害。", }, aiCheck: function (target) { if (target.hasSkill("tiansuan2_0")) return 0; var player = _status.event.player; var att = get.attitude(player, target); if ( target.countCards("e", function (card) { return get.value(card, target) <= 0; }) ) att *= 2; return att / Math.sqrt(Math.max(1, target.hp)); }, ai: { effect: { target: function (card, player, target, current) { if (get.tag(card, "damage") && !player.hasSkillTag("jueqing", false, target)) return "zerotarget"; }, }, }, }, tiansuan2_1: { name: "上签", trigger: { player: "damageBegin4" }, forced: true, charlotte: true, filter: function (event, player) { return event.num > 1; }, content: function () { trigger.num = 1; }, group: "tiansuan2_damage", mark: true, intro: { content: "当你受到伤害时,你令伤害值改为1;当你受到1点伤害后,你摸一张牌。", }, aiCheck: function (target) { if (target.hasSkill("tiansuan2_1")) return 0; var player = _status.event.player; var att = get.attitude(player, target); if ( target.countCards("e", function (card) { return get.value(card, target) <= 0; }) ) att *= 2; if (target.hp == 1) return att / 2; return att / Math.sqrt(Math.max(1, target.hp)); }, ai: { filterDamage: true, skillTagFilter: function (player, tag, arg) { if (arg && arg.player) { if (arg.player.hasSkillTag("jueqing", false, player)) return false; } }, effect: { target: function (card, player, target, current) { if (target && target.hp > 1 && get.tag(card, "damage") && !player.hasSkillTag("jueqing", false, target)) return 0.8; }, }, }, }, tiansuan2_damage: { trigger: { player: "damageEnd" }, charlotte: true, content: function () { player.draw(trigger.num); }, }, tiansuan2_2: { name: "中签", trigger: { player: "damageBegin4" }, forced: true, charlotte: true, filter: function (event, player) { return event.num > 1; }, content: function () { trigger.num = 1; }, mark: true, intro: { content: "当你受到伤害时,你令伤害属性改为火属性并将伤害值改为1。", }, aiCheck: function (target) { if (target.hasSkill("tiansuan2_2")) return 0; var player = _status.event.player; target.addSkill("tiansuan2_ai"); var num = get.damageEffect(target, player, player, "fire"); target.removeSkill("tiansuan2_ai"); return num; }, group: ["tiansuan2_fire", "tiansuan2_ai"], }, tiansuan2_ai: { ai: { filterDamage: true, skillTagFilter: function (player, tag, arg) { if (arg && arg.player) { if (arg.player.hasSkillTag("jueqing", false, player)) return false; } }, }, }, tiansuan2_fire: { trigger: { player: "damageBefore" }, forced: true, charlotte: true, filter: function (event, player) { return !event.hasNature("fire"); }, content: function () { game.setNature(trigger, "fire"); }, }, tiansuan2_3: { name: "下签", trigger: { player: "damageBegin3" }, forced: true, charlotte: true, content: function () { trigger.num++; }, mark: true, intro: { content: "当你受到伤害时,你令此伤害+1。", }, aiCheck: function (target) { if (target.hasSkill("tiansuan2_3")) return 0; var player = _status.event.player; var att = get.attitude(player, target); return -att / Math.sqrt(Math.max(1, target.hp)); }, ai: { effect: { target: function (card, player, target, current) { if (get.tag(card, "damage") && !player.hasSkillTag("jueqing", false, target) && current < 0) return 1.3; }, }, }, }, tiansuan2_4: { name: "下下签", trigger: { player: "damageBegin3" }, forced: true, charlotte: true, content: function () { trigger.num++; }, mod: { cardEnabled: function (card, player) { if (card.name == "tao" || card.name == "jiu") return false; }, cardSavable: function (card, player) { if (card.name == "tao" || card.name == "jiu") return false; }, }, mark: true, intro: { content: "当你受到伤害时,你令此伤害+1。你不能使用【酒】或【桃】。", }, aiCheck: function (target) { if (target.hasSkill("tiansuan2_4")) return 0; var player = _status.event.player; var att = get.attitude(player, target); return -att / Math.sqrt(Math.max(1, target.hp)); }, ai: { effect: { target: function (card, player, target, current) { if (get.tag(card, "damage") && !player.hasSkillTag("jueqing", false, target) && current < 0) return 1.3; }, }, }, }, relieren: { shaRelated: true, audio: 2, audioname: ["boss_lvbu3"], trigger: { player: "useCardToPlayered" }, filter: function (event, player) { return event.card.name == "sha" && player.canCompare(event.target); }, check: function (event, player) { return get.attitude(player, event.target) < 0; }, //priority:5, content: function () { "step 0"; player.chooseToCompare(trigger.target).clear = false; "step 1"; if (result.bool) { if (trigger.target.countGainableCards(player, "he")) player.gainPlayerCard(trigger.target, true, "he"); ui.clear(); } else { var card1 = result.player; var card2 = result.target; if (get.position(card1) == "d") trigger.target.gain(card1, "gain2"); if (get.position(card2) == "d") player.gain(card2, "gain2"); } }, }, retiaoxin: { audio: "tiaoxin", audioname: ["sp_jiangwei", "xiahouba", "re_jiangwei"], enable: "phaseUse", usable: 1, filterTarget: function (card, player, target) { return target != player && target.countCards("he"); }, content: function () { "step 0"; target .chooseToUse( function (card, player, event) { if (get.name(card) != "sha") return false; return lib.filter.filterCard.apply(this, arguments); }, "挑衅:对" + get.translation(player) + "使用一张杀,或令其弃置你的一张牌" ) .set("targetRequired", true) .set("complexSelect", true) .set("filterTarget", function (card, player, target) { if (target != _status.event.sourcex && !ui.selected.targets.includes(_status.event.sourcex)) return false; return lib.filter.filterTarget.apply(this, arguments); }) .set("sourcex", player); "step 1"; if (result.bool == false && target.countCards("he") > 0) { player.discardPlayerCard(target, "he", true); } else { event.finish(); } }, ai: { order: 4, expose: 0.2, result: { target: -1, player: function (player, target) { if (!target.canUse("sha", player)) return 0; if (target.countCards("h") == 0) return 0; if (target.countCards("h") == 1) return -0.1; if (player.hp <= 2) return -2; if (player.countCards("h", "shan") == 0) return -1; return -0.5; }, }, threaten: 1.1, }, }, //南华老仙 yufeng: { inherit: "yufeng_old", content: function () { "step 0"; if (_status.connectMode) event.time = lib.configOL.choose_timeout; event.videoId = lib.status.videoId++; var maxScore = Math.max(2, 1 + player.countMark("yufeng")); if (player.isUnderControl()) { game.swapPlayerAuto(player); } var switchToAuto = function () { game.pause(); game.countChoose(); setTimeout(function () { _status.imchoosing = false; var max = Math.max(2, 1 + player.countMark("yufeng")); var score = Math.random() < 0.5 ? max : get.rand(1, max); event._result = { bool: true, score: score, win: score >= max, }; if (event.dialog) event.dialog.close(); if (event.control) event.control.close(); game.resume(); }, 5000); }; var createDialog = function (player, id) { if (_status.connectMode) lib.configOL.choose_timeout = "30"; if (player == game.me) return; var str = get.translation(player) + "正在表演《御风飞行》...
    "; ui.create.dialog(str).videoId = id; }; var chooseButton = function (maxScore) { lib.skill.yufeng.$playFlappyBird(maxScore); }; //event.switchToAuto=switchToAuto; game.broadcastAll(createDialog, player, event.videoId); if (event.isMine()) { chooseButton(maxScore); } else if (event.isOnline()) { event.player.send(chooseButton, maxScore); event.player.wait(); game.pause(); } else { switchToAuto(); } "step 1"; game.broadcastAll( function (id, time) { if (_status.connectMode) lib.configOL.choose_timeout = time; var dialog = get.idDialog(id); if (dialog) { dialog.close(); } }, event.videoId, event.time ); var result = event.result || result; player.popup(get.cnNumber(result.score) + "分", result.win ? "wood" : "fire"); game.log(player, "御风飞行", result.win ? "#g成功" : "#y失败"); game.log(player, "获得了", "#g" + result.score + "分"); var max = player.countMark("yufeng"); if (!result.win) { if (result.score) player.draw(result.score); if (max) player.removeMark("yufeng", max, false); event.finish(); } else { if (max < 2) player.addMark("yufeng", 1, false); event.score = result.score; player .chooseTarget("请选择【御风】的目标", [1, result.score], function (card, player, target) { return target != player && !target.hasSkill("yufeng2"); }) .set("ai", function (target) { var player = _status.event.player; var att = -get.attitude(player, target), attx = att * 2; if (att <= 0 || target.hasSkill("xinfu_pdgyingshi")) return 0; if (target.hasJudge("lebu")) attx -= att; if (target.hasJudge("bingliang")) attx -= att; return attx / Math.max(2.25, Math.sqrt(target.countCards("h") + 1)); }); } "step 2"; if (result.bool) { result.targets.sortBySeat(); player.line(result.targets, "green"); game.log(result.targets, "获得了", "#y“御风”", "效果"); for (var i of result.targets) i.addSkill("yufeng2"); if (event.score > result.targets.length) player.draw(event.score - result.targets.length); } else player.draw(event.score); }, $playFlappyBird: function (maxScore, title) { //Forked from: https://github.com/aaarafat/JS-Flappy-Bird const event = _status.event; const dialog = ui.create.dialog("forcebutton", "hidden"); dialog.textPrompt = dialog.add('
    准备好了吗?
    '); dialog.classList.add("fixed"); dialog.classList.add("scroll1"); dialog.classList.add("scroll2"); dialog.classList.add("fullwidth"); dialog.classList.add("fullheight"); dialog.classList.add("noupdate"); const updateText = function (str) { dialog.textPrompt.innerHTML = '
    ' + str + "
    "; }; const canvas = document.createElement("canvas"); dialog.appendChild(canvas); canvas.style.position = "absolute"; canvas.style.width = "276px"; canvas.style.height = "414px"; canvas.style.left = "calc(50% - 141px)"; canvas.style.top = "calc(50% - 200px)"; canvas.width = 276; canvas.height = 414; canvas.style.border = "3px solid"; const RAD = Math.PI / 180; const ctx = canvas.getContext("2d"); let frames = 0; let dx = 0.1; let previousDOMHighResTimeStamp = performance.now(); let deltaTime = 0; const state = { curr: 0, getReady: 0, Play: 1, gameOver: 2, gameSuccess: 3, }; const SFX = { start: new Audio(), flap: new Audio(), score: new Audio(), hit: new Audio(), die: new Audio(), played: false, }; const gnd = { sprite: new Image(), x: 0, y: 0, draw: function () { this.y = parseFloat(canvas.height - this.sprite.height); ctx.drawImage(this.sprite, this.x, this.y); }, update: function () { if (state.curr == state.gameOver || state.curr == state.gameSuccess) return; this.x -= dx * deltaTime; const halfWidth = this.sprite.width / 4; if (this.x <= -halfWidth) this.x += halfWidth; }, }; const bg = { sprite: new Image(), x: 0, y: 0, draw: function () { let y = parseFloat(canvas.height - this.sprite.height); ctx.drawImage(this.sprite, this.x, y); }, }; const pipe = { top: { sprite: new Image() }, bot: { sprite: new Image() }, gap: 127, moved: true, pipes: [], numberOfPipes: 1, timeElapsed: 0, draw: function () { for (let i = 0; i < this.pipes.length; i++) { let p = this.pipes[i]; ctx.drawImage(this.top.sprite, p.x, p.y); ctx.drawImage(this.bot.sprite, p.x, p.y + parseFloat(this.top.sprite.height) + this.gap); } }, update: function () { if (state.curr != state.Play) return; this.timeElapsed += deltaTime; if (this.timeElapsed >= 1600) { this.timeElapsed -= 1600; this.pipes.push({ x: parseFloat(canvas.width), y: -210 * Math.min(Math.random() * 0.8 + 1.2, 1.8), }); } this.pipes.forEach(pipe => { pipe.x -= dx * deltaTime; }); if (this.pipes.length && this.pipes[0].x < -this.top.sprite.width) { this.pipes.shift(); this.moved = true; } }, }; const bird = { animations: [{ sprite: new Image() }, { sprite: new Image() }, { sprite: new Image() }, { sprite: new Image() }], rotatation: 0, x: 50, y: 100, speed: 0, gravity: 0.0004, thrust: 0.18, frame: 0, timeElapsed: 0, totalTimeElapsed: 0, draw: function () { let h = this.animations[this.frame].sprite.height; let w = this.animations[this.frame].sprite.width; ctx.save(); ctx.translate(this.x, this.y); ctx.rotate(this.rotatation * RAD); ctx.drawImage(this.animations[this.frame].sprite, -w / 2, -h / 2); ctx.restore(); }, update: function () { this.totalTimeElapsed += deltaTime; let r = parseFloat(this.animations[0].sprite.width) / 2; switch (state.curr) { case state.getReady: case state.gameSuccess: this.rotatation = 0; this.timeElapsed += deltaTime; if (this.timeElapsed >= 200) { this.timeElapsed -= 200; this.y += Math.sin((this.totalTimeElapsed / 10) * RAD); this.frame++; } break; case state.Play: this.timeElapsed += deltaTime; if (this.timeElapsed >= 100) { this.timeElapsed -= 100; this.frame++; } this.y += this.speed * deltaTime; this.setRotation(); this.speed += this.gravity * deltaTime; if (UI.score.curr >= maxScore) { state.curr = state.gameSuccess; this.timeElapsed = 0; updateText(`${title || "御风飞行"}表演成功!`); setTimeout(switchToAuto, 2000); } else if (this.y + r >= gnd.y || this.collisioned()) { state.curr = state.gameOver; this.timeElapsed = 0; updateText(`${title || "御风飞行"}表演失败……`); setTimeout(switchToAuto, 2000); } break; case state.gameOver: this.frame = 1; if (this.y + r < gnd.y) { this.y += this.speed * deltaTime; this.setRotation(); this.speed += this.gravity * deltaTime; } else { this.speed = 0; this.y = gnd.y - r; this.rotatation = 90; if (!SFX.played) { Promise.resolve(SFX.die.play()).catch(() => void 0); SFX.played = true; } } break; } const animationsLength = this.animations.length; if (this.frame >= animationsLength) this.frame -= animationsLength; }, flap: function () { if (this.y <= 0) return; const flap = SFX.flap; flap.currentTime = 0; if (flap.paused) Promise.resolve(flap.play()).catch(() => void 0); this.speed = -this.thrust; }, setRotation: function () { if (this.speed <= 0) { this.rotatation = Math.max(-25, (-25 * this.speed) / (-1 * this.thrust)); } else if (this.speed > 0) { this.rotatation = Math.min(90, (90 * this.speed) / (this.thrust * 2)); } }, collisioned: function () { if (!pipe.pipes.length) return; let bird = this.animations[0].sprite; let x = pipe.pipes[0].x; let y = pipe.pipes[0].y; let r = bird.height / 4 + bird.width / 4; let roof = y + parseFloat(pipe.top.sprite.height); let floor = roof + pipe.gap; let w = parseFloat(pipe.top.sprite.width); if (this.x + r >= x) { if (this.x + r < x + w) { if (this.y - r <= roof || this.y + r >= floor) { Promise.resolve(SFX.hit.play()).catch(() => void 0); return true; } } else if (pipe.moved) { updateText(`当前分数:${++UI.score.curr}`); const score = SFX.score; score.currentTime = 0; if (score.paused) Promise.resolve(score.play()).catch(() => void 0); pipe.moved = false; } } }, }; const UI = { getReady: { sprite: new Image() }, gameOver: { sprite: new Image() }, gameClear: { sprite: new Image() }, tap: [{ sprite: new Image() }, { sprite: new Image() }], score: { curr: 0, best: 0, }, x: 0, y: 0, tx: 0, ty: 0, frame: 0, timeElapsed: 0, draw: function () { switch (state.curr) { case state.getReady: this.y = parseFloat(canvas.height - this.getReady.sprite.height) / 2; this.x = parseFloat(canvas.width - this.getReady.sprite.width) / 2; this.tx = parseFloat(canvas.width - this.tap[0].sprite.width) / 2; this.ty = this.y + this.getReady.sprite.height - this.tap[0].sprite.height; ctx.drawImage(this.getReady.sprite, this.x, this.y); ctx.drawImage(this.tap[this.frame].sprite, this.tx, this.ty); break; case state.gameOver: case state.gameSuccess: this.y = parseFloat(canvas.height - this.gameOver.sprite.height) / 2; this.x = parseFloat(canvas.width - this.gameOver.sprite.width) / 2; this.tx = parseFloat(canvas.width - this.tap[0].sprite.width) / 2; this.ty = this.y + this.gameOver.sprite.height - this.tap[0].sprite.height; ctx.drawImage((state.curr == state.gameOver ? this.gameOver : this.gameClear).sprite, this.x, this.y); } }, update: function () { if (state.curr == state.Play) return; this.timeElapsed += deltaTime; if (this.timeElapsed >= 200) { this.timeElapsed -= 200; this.frame++; } const tapLength = this.tap.length; if (this.frame >= tapLength) this.frame -= tapLength; }, }; gnd.sprite.src = lib.assetURL + "image/flappybird/ground.png"; bg.sprite.src = lib.assetURL + "image/flappybird/BG.png"; pipe.top.sprite.src = lib.assetURL + "image/flappybird/toppipe.png"; pipe.bot.sprite.src = lib.assetURL + "image/flappybird/botpipe.png"; UI.gameOver.sprite.src = lib.assetURL + "image/flappybird/gameover.png"; UI.gameClear.sprite.src = lib.assetURL + "image/flappybird/gameclear.png"; UI.getReady.sprite.src = lib.assetURL + "image/flappybird/getready.png"; UI.tap[0].sprite.src = lib.assetURL + "image/flappybird/tap/t0.png"; UI.tap[1].sprite.src = lib.assetURL + "image/flappybird/tap/t1.png"; bird.animations[0].sprite.src = lib.assetURL + "image/flappybird/bird/b0.png"; bird.animations[1].sprite.src = lib.assetURL + "image/flappybird/bird/b1.png"; bird.animations[2].sprite.src = lib.assetURL + "image/flappybird/bird/b2.png"; bird.animations[3].sprite.src = lib.assetURL + "image/flappybird/bird/b0.png"; SFX.start.src = lib.assetURL + "audio/effect/flappybird_start.wav"; SFX.flap.src = lib.assetURL + "audio/effect/flappybird_flap.wav"; SFX.score.src = lib.assetURL + "audio/effect/flappybird_score.wav"; SFX.hit.src = lib.assetURL + "audio/effect/flappybird_hit.wav"; SFX.die.src = lib.assetURL + "audio/effect/flappybird_die.wav"; const gameLoop = domHighResTimeStamp => { if (frames < 0) return; deltaTime = domHighResTimeStamp - previousDOMHighResTimeStamp; previousDOMHighResTimeStamp = domHighResTimeStamp; update(); draw(); frames++; window.requestAnimationFrame(gameLoop); }; const update = function () { bird.update(); gnd.update(); pipe.update(); UI.update(); }; const draw = function () { ctx.fillStyle = "#30c0df"; ctx.fillRect(0, 0, canvas.width, canvas.height); bg.draw(); pipe.draw(); bird.draw(); gnd.draw(); UI.draw(); }; const click = function () { switch (state.curr) { case state.getReady: state.curr = state.Play; bird.timeElapsed = 0; Promise.resolve(SFX.start.play()).catch(() => void 0); updateText(`当前分数:${UI.score.curr}`); break; case state.Play: bird.flap(); } }; const switchToAuto = function () { event._result = { bool: true, score: UI.score.curr, win: UI.score.curr >= maxScore, }; dialog.close(); game.resume(); _status.imchoosing = false; frames = -1; document.removeEventListener(lib.config.touchscreen ? "touchstart" : "mousedown", click); }; dialog.open(); game.pause(); game.countChoose(); document.addEventListener(lib.config.touchscreen ? "touchstart" : "mousedown", click); window.requestAnimationFrame(gameLoop); }, }, yufeng_old: { audio: 2, enable: "phaseUse", usable: 1, content: function () { "step 0"; if (_status.connectMode) event.time = lib.configOL.choose_timeout; event.videoId = lib.status.videoId++; if (player.isUnderControl()) { game.swapPlayerAuto(player); } var switchToAuto = function () { game.pause(); game.countChoose(); setTimeout(function () { _status.imchoosing = false; var max = Math.max(2, 1 + game.me.countMark("yufeng")); var score = Math.random() < 0.5 ? max : get.rand(1, max); event._result = { bool: true, score: score, win: score >= max, }; if (event.dialog) event.dialog.close(); if (event.control) event.control.close(); game.resume(); }, 5000); }; var createDialog = function (player, id) { if (_status.connectMode) lib.configOL.choose_timeout = "30"; if (player == game.me) return; var str = get.translation(player) + "正在表演《御风飞行》...
    "; ui.create.dialog(str).videoId = id; }; var chooseButton = function () { var roundmenu = false; if (ui.roundmenu && ui.roundmenu.display != "none") { roundmenu = true; ui.roundmenu.style.display = "none"; } var event = _status.event; event.settleed = false; event.score = 0; event.dialog = ui.create.dialog("forcebutton", "hidden"); event.dialog.textPrompt = event.dialog.add('
    准备好了吗?准备好了的话就点击屏幕开始吧!
    '); var max = Math.max(2, 1 + game.me.countMark("yufeng")); event.dialog.textPrompt.style["z-index"] = 10; event.switchToAuto = function () { event._result = { bool: true, score: event.score, win: event.score >= max, }; event.dialog.close(); game.resume(); _status.imchoosing = false; if (roundmenu) ui.roundmenu.style.display = ""; }; event.dialog.classList.add("fixed"); event.dialog.classList.add("scroll1"); event.dialog.classList.add("scroll2"); event.dialog.classList.add("fullwidth"); event.dialog.classList.add("fullheight"); event.dialog.classList.add("noupdate"); event.dialog.style.overflow = "hidden"; event.dialog.open(); var height = event.dialog.offsetHeight; var width = event.dialog.offsetWidth; var top = 50; var speed = 0; var start = false; var bird = ui.create.div(""); bird.style["background-image"] = "linear-gradient(rgba(240, 235, 3, 1), rgba(230, 225, 5, 1))"; bird.style["border-radius"] = "3px"; var pipes = []; bird.style.position = "absolute"; bird.style.height = "40px"; bird.style.width = "40px"; bird.style.left = Math.ceil(width / 3) + "px"; bird.style.top = (top / 100) * height + "px"; bird.updatePosition = function () { bird.style.transform = "translateY(" + ((top / 100) * height - bird.offsetTop) + "px)"; }; event.dialog.appendChild(bird); var isDead = function () { if (top > 100 || top < 0) return true; var btop = top; var bleft = 100 / 3; var bdown = btop + 5; var bright = bleft + 5; for (var i of pipes) { var left2 = i.left; var right2 = left2 + 10; var bottom2 = i.height1; var top2 = i.height2; if (left2 > bright || right2 < bleft) continue; if (btop < bottom2) return true; if (bdown > top2) return true; return false; } return false; }; var fly = function () { if (!start) { start = true; event.dialog.textPrompt.innerHTML = '
    当前分数:' + event.score + "
    "; speed = -4; event.fly = setInterval(function () { top += speed; if (top < 0) top = 0; bird.updatePosition(); for (var i of pipes) { i.left -= 0.5; i.updateLeft(); } speed += 0.5; if (speed > 2.5) speed = 2.5; if (isDead() == true) { event.settle(); } }, 35); var addPipe = function () { var num = get.rand(5, 55); var pipe1 = ui.create.div(""); pipe1.style["background-image"] = "linear-gradient(rgba(57, 133, 4, 1), rgba(60, 135, 6, 1))"; pipe1.style["border-radius"] = "3px"; pipe1.style.position = "absolute"; pipe1.height1 = num; pipe1.height2 = num + 50; pipe1.left = 110; pipe1.num = 1; pipe1.style.height = Math.ceil((height * num) / 100) + "px"; pipe1.style.width = width / 10 + "px"; pipe1.style.left = (pipe1.left * width) / 100 + "px"; pipe1.style.top = "0px"; var pipe2 = ui.create.div(""); pipe2.style["background-image"] = "linear-gradient(rgba(57, 133, 4, 1), rgba(60, 135, 6, 1))"; pipe2.style["border-radius"] = "3px"; pipe1.pipe2 = pipe2; pipe2.style.position = "absolute"; pipe2.style.height = Math.ceil(((100 - pipe1.height2) * height) / 100) + "px"; pipe2.style.width = width / 10 + "px"; pipe2.style.left = (pipe1.left * width) / 100 + "px"; pipe2.style.top = Math.ceil((pipe1.height2 * height) / 100) + "px"; pipes.add(pipe1); event.dialog.appendChild(pipe1); event.dialog.appendChild(pipe2); pipe1.updateLeft = function () { this.style.transform = "translateX(" + ((this.left / 100) * width - this.offsetLeft) + "px)"; this.pipe2.style.transform = "translateX(" + ((this.left / 100) * width - this.pipe2.offsetLeft) + "px)"; if (this.left < 25 && !this.score) { this.score = true; event.score++; event.dialog.textPrompt.innerHTML = '
    当前分数:' + event.score + "
    "; if (event.score >= max) { event.settle(); } } if (this.left < -15) { this.remove(); this.pipe2.remove(); pipes.remove(this); } }; }; event.addPipe = setInterval(addPipe, 2500); } else if (speed > 0) { speed = -4; } }; document.addEventListener(lib.config.touchscreen ? "touchstart" : "mousedown", fly); event.settle = function () { clearInterval(event.fly); clearInterval(event.addPipe); document.removeEventListener(lib.config.touchscreen ? "touchstart" : "mousedown", fly); setTimeout(function () { event.switchToAuto(); }, 1000); }; game.pause(); game.countChoose(); }; //event.switchToAuto=switchToAuto; game.broadcastAll(createDialog, player, event.videoId); if (event.isMine()) { chooseButton(); } else if (event.isOnline()) { event.player.send(chooseButton); event.player.wait(); game.pause(); } else { switchToAuto(); } "step 1"; game.broadcastAll( function (id, time) { if (_status.connectMode) lib.configOL.choose_timeout = time; var dialog = get.idDialog(id); if (dialog) { dialog.close(); } }, event.videoId, event.time ); var result = event.result || result; player.popup(get.cnNumber(result.score) + "分", result.win ? "wood" : "fire"); game.log(player, "御风飞行", result.win ? "#g成功" : "#y失败"); game.log(player, "获得了", "#g" + result.score + "分"); var max = player.countMark("yufeng"); if (!result.win) { if (result.score) player.draw(result.score); if (max) player.removeMark("yufeng", max, false); event.finish(); } else { if (max < 2) player.addMark("yufeng", 1, false); event.score = result.score; player .chooseTarget("请选择【御风】的目标", [1, result.score], function (card, player, target) { return target != player && !target.hasSkill("yufeng2"); }) .set("ai", function (target) { var player = _status.event.player; var att = -get.attitude(player, target), attx = att * 2; if (att <= 0 || target.hasSkill("xinfu_pdgyingshi")) return 0; if (target.hasJudge("lebu")) attx -= att; if (target.hasJudge("bingliang")) attx -= att; return attx / Math.max(2.25, Math.sqrt(target.countCards("h") + 1)); }); } "step 2"; if (result.bool) { result.targets.sortBySeat(); player.line(result.targets, "green"); game.log(result.targets, "获得了", "#y“御风”", "效果"); for (var i of result.targets) i.addSkill("yufeng2"); if (event.score > result.targets.length) player.draw(event.score - result.targets.length); } else player.draw(event.score); }, ai: { order: 10, result: { player: 1 }, threaten: 3.2, }, }, yufeng2: { trigger: { player: "phaseZhunbeiBegin" }, audio: false, forced: true, charlotte: true, content: function () { "step 0"; player.removeSkill("yufeng2"); player.judge(); "step 1"; if (result.color == "red") player.skip("phaseDraw"); else { player.skip("phaseUse"); player.skip("phaseDiscard"); } }, mark: true, intro: { content: "准备阶段时进行判定,结果为红则跳过摸牌阶段,为黑则跳过出牌阶段和弃牌阶段", }, ai: { order: 7, result: { player: 1, }, }, }, tianshu: { audio: 2, trigger: { player: "phaseUseBegin" }, filter: function (event, player) { return ( player.countCards("he") && !game.hasPlayer(function (current) { return current.countCards("ej", "taipingyaoshu"); }) ); }, direct: true, content: function () { "step 0"; player.chooseCardTarget({ prompt: get.prompt2("tianshu"), filterCard: true, position: "he", ai1: function (card) { return 5 - get.value(card); }, ai2: function (target) { var player = _status.event.player; if (get.attitude(player, target) > 0 && !target.hasEmptySlot(2)) return 0; return get.attitude(player, target); }, }); "step 1"; if (!result.bool) { event.finish(); return; } var target = result.targets[0]; event.target = target; player.logSkill("tianshu", target); player.discard(result.cards); if (!lib.inpile.includes("taipingyaoshu")) { lib.inpile.push("taipingyaoshu"); event.card = game.createCard2("taipingyaoshu", "heart", 3); } else { event.card = get.cardPile(function (card) { return card.name == "taipingyaoshu"; }); } if (!event.card) event.finish(); else target.gain(event.card, "gain2"); "step 2"; if (target.getCards("h").includes(card) && get.name(card, target) == "taipingyaoshu") target.chooseUseTarget(card, "nopopup", true); }, }, //界伏寿 xinzhuikong: { audio: 2, trigger: { global: "phaseZhunbeiBegin" }, check: function (event, player) { if (get.attitude(player, event.player) < -2) { var cards = player.getCards("h"); if (cards.length > player.hp) return true; for (var i = 0; i < cards.length; i++) { var useful = get.useful(cards[i]); if (useful < 5) return true; if (cards[i].number > 7 && useful < 7) return true; } } return false; }, logTarget: "player", filter: function (event, player) { return !player.hasSkill("xinzhuikong2") && player.hp <= event.player.hp && player.canCompare(event.player); }, content: function () { "step 0"; player.addTempSkill("xinzhuikong2", "roundStart"); player.chooseToCompare(trigger.player).set("small", player.hp > 1 && get.effect(player, { name: "sha" }, trigger.player, player) > 0 && Math.random() < 0.9); "step 1"; if (result.bool) { trigger.player.addTempSkill("zishou2"); event.finish(); } else if (result.target && get.position(result.target) == "d") player.gain(result.target, "gain2", "log"); "step 2"; var card = { name: "sha", isCard: true }; if (trigger.player.canUse(card, player, false)) trigger.player.useCard(card, player, false); }, }, xinzhuikong2: { charlotte: true }, xinqiuyuan: { audio: 2, trigger: { target: "useCardToTarget" }, direct: true, filter: function (event, player) { return ( event.card.name == "sha" && game.hasPlayer(function (current) { return current != player && !event.targets.includes(current) && lib.filter.targetEnabled(event.card, event.player, current); }) ); }, content: function () { "step 0"; player .chooseTarget(get.prompt2("xinqiuyuan"), function (card, player, target) { var evt = _status.event.getTrigger(); return target != player && !evt.targets.includes(target) && lib.filter.targetEnabled(evt.card, evt.player, target); }) .set("ai", function (target) { var trigger = _status.event.getTrigger(); var player = _status.event.player; return get.effect(target, trigger.card, trigger.player, player) + 0.1; }); "step 1"; if (result.bool) { var target = result.targets[0]; player.logSkill("xinqiuyuan", target); event.target = target; target .chooseCard( function (card, player) { var name = get.name(card, player); return name != "sha" && get.type(name) == "basic"; }, "h", "交给" + get.translation(player) + "一张不为【杀】的基本牌,或成为此杀的额外目标" ) .set("ai", function (card) { return get.attitude(target, _status.event.sourcex) >= 0 ? 1 : -1; }) .set("sourcex", player); game.delay(); } else { event.finish(); } "step 2"; if (result.bool) { target.give(result.cards, player); game.delay(); } else { trigger.getParent().targets.push(event.target); trigger.getParent().triggeredTargets2.push(event.target); game.log(event.target, "成为了", trigger.card, "的额外目标"); } }, ai: { expose: 0.2, effect: { target_use(card, player, target) { if (card.name != "sha") return; var players = game.filterPlayer(); if (get.attitude(player, target) <= 0) { for (var i = 0; i < players.length; i++) { var target2 = players[i]; if (player != target2 && target != target2 && player.canUse(card, target2, false) && get.effect(target2, { name: "shacopy", nature: card.nature, suit: card.suit }, player, target) > 0 && get.effect(target2, { name: "shacopy", nature: card.nature, suit: card.suit }, player, player) < 0) { if (target.hp == target.maxHp) return 0.3; return 0.6; } } } else { for (var i = 0; i < players.length; i++) { var target2 = players[i]; if (player != target2 && target != target2 && player.canUse(card, target2, false) && get.effect(target2, { name: "shacopy", nature: card.nature, suit: card.suit }, player, player) > 0) { if (player.canUse(card, target2)) return; if (target.hp == target.maxHp) return [0, 1]; return [0, 0]; } } } }, }, }, }, //界潘璋马忠 xinduodao: { audio: 2, trigger: { player: "damageEnd" }, logTarget: "source", filter: function (event, player) { var source = event.source; if (!source) return false; var cards = source.getEquips(1); return cards.some(card => lib.filter.canBeGained(card, player, source)); }, prompt2: function (event, player) { var source = event.source; var cards = source.getEquips(1).filter(card => lib.filter.canBeGained(card, player, source)); return "获得其装备区中的" + get.translation(cards); }, check: function (event, player) { return (get.attitude(player, event.source) + 0.1) * get.value(event.source.getEquip(1), event.source); }, content: function () { var source = trigger.source; var cards = source.getEquips(1).filter(card => lib.filter.canBeGained(card, player, source)); player.gain(cards, source, "give", "bySelf"); }, }, xinanjian: { audio: 2, trigger: { player: "useCardToPlayered" }, forced: true, logTarget: "target", filter: function (event, player) { return event.card.name == "sha" && !player.inRangeOf(event.target); }, content: function () { "step 0"; var card = get.translation(trigger.card); var target = get.translation(trigger.target); player .chooseControl() .set("prompt", "暗箭:请选择一项") .set("choiceList", ["令" + target + "不能响应" + card, "令" + card + "对" + target + "的伤害值基数+1"]) .set("ai", function () { var target = _status.event.getTrigger().target; var player = _status.event.player; var num = target.mayHaveShan( player, "use", target.getCards("h", i => { return i.hasGaintag("sha_notshan"); }) ) ? 0 : 1; if (get.attitude(player, target) > 0) num = 1 - num; return num; }); "step 1"; if (result.index == 0) { game.log(player, "令", trigger.card, "不能被", trigger.target, "响应"); trigger.directHit.push(trigger.target); } else { game.log(player, "令", trigger.card, "对", trigger.target, "的伤害+1"); var id = trigger.target.playerid; var map = trigger.customArgs; if (!map[id]) map[id] = {}; if (!map[id].extraDamage) map[id].extraDamage = 0; map[id].extraDamage++; } }, ai: { directHit_ai: true, skillTagFilter: function (player, tag, arg) { if (!arg || !arg.card || !arg.target || arg.card.name != "sha" || arg.target.inRange(player) || get.attitude(player, arg.target) > 0) return false; }, }, }, //界郭笨 mobilejingce: { audio: 2, trigger: { player: "phaseJieshuBegin" }, frequent: true, filter: function (event, player) { var num = 0; game.getGlobalHistory("cardMove", function (evt) { if (evt.name != "cardsDiscard") return; var evtx = evt.getParent(); if (evtx.name != "orderingDiscard") return false; var evt2 = evtx.relatedEvent || evtx.getParent(); if (evt2 && (evt2.name == "useCard" || evt2.name == "respond")) num += evt.cards.length; }); return num >= player.hp; }, content: function () { player.draw(2); }, group: "mobilejingce_count", intro: { content: function (num, player) { if (num == 0) return "一张都没有?就这?"; if (num < player.hp) return "才" + get.cnNumber(num) + "张?就这?"; return "卧槽,牛逼啊,居然" + get.cnNumber(num) + "张了!"; }, }, }, mobilejingce_count: { trigger: { global: ["cardsDiscardEnd", "phaseBefore"], player: "phaseAfter", }, silent: true, firstDo: true, filter: function (evt, player) { if (evt.name == "phase") return true; if (player != _status.currentPhase) return false; var evtx = evt.getParent(); if (evtx.name != "orderingDiscard") return false; var evt2 = evtx.relatedEvent || evtx.getParent(); return evt2 && (evt2.name == "useCard" || evt2.name == "respond"); }, content: function () { if (trigger.name == "phase") player.unmarkSkill("mobilejingce"); else { var num = 0; game.getGlobalHistory("cardMove", function (evt) { if (evt.name != "cardsDiscard") return; var evtx = evt.getParent(); if (evtx.name != "orderingDiscard") return false; var evt2 = evtx.relatedEvent || evtx.getParent(); if (evt2 && (evt2.name == "useCard" || evt2.name == "respond")) num += evt.cards.length; }); player.storage.mobilejingce = num; player.markSkill("mobilejingce"); } }, }, //公孙康 juliao: { mod: { globalTo: function (from, to, distance) { return distance + game.countGroup() - 1; }, }, }, taomie: { audio: 3, group: ["taomie1", "taomie2", "taomie3"], trigger: { source: "damageBegin1" }, forced: true, locked: false, direct: true, filter: function (event, player) { return event.player.hasMark("taomie"); }, content: function () { "step 0"; player.logSkill(Math.random() < 0.5 ? "taomie2" : "taomie3", trigger.player); var target = get.translation(trigger.player); player .chooseControl() .set("prompt", "讨灭:请选择一项") .set("choiceList", ["令即将对" + target + "造成的伤害+1", "获得" + target + "的一张牌,并可将其交给另一名其他角色", "依次执行以上所有选项,并移去" + target + "的“讨灭”标记"]) .set("ai", function () { var evt = _status.event.getTrigger(); var player = _status.event.player; var target = evt.player; var bool1 = !target.hasSkillTag("filterDamage", null, { player: player, card: evt.card, }); var bool2 = get.effect(target, { name: "shunshou" }, player, player) > 0; if (bool1 && bool2 && target.hp <= evt.num + 1) return 2; if (bool1) return 0; return 1; }); "step 1"; if (result.index == 2) { trigger.taomie_player = trigger.player; trigger.player.addTempSkill("taomie4"); } if (result.index != 1) { trigger.num++; } if (result.index != 0 && trigger.player.countGainableCards(player, "hej") > 0) { player.gainPlayerCard(trigger.player, "hej", true); } else event.finish(); "step 2"; var card = result.cards[0]; if ( card && player.getCards("h").includes(card) && game.hasPlayer(function (current) { return current != player && current != trigger.player; }) ) { event.card = card; player .chooseTarget("是否将" + get.translation(card) + "交给一名其他角色?", function (card, player, target) { return target != player && target != _status.event.getTrigger().player; }) .set("ai", function (target) { var player = _status.event.player; var card = _status.event.getParent().card; if (target.hasSkillTag("nogain") || !player.needsToDiscard() || (get.tag(card, "damage") && player.hasValueTarget(card, null, false) && get.effect(_status.event.getTrigger().player, card, null, false) > 0)) return 0; return get.attitude(player, target) / (1 + target.countCards("h")); }); } else event.finish(); "step 3"; if (result.bool) { var target = result.targets[0]; player.line(target); player.give(card, target); } }, mod: { inRangeOf: function (from, to) { if (from.hasMark("taomie")) return true; }, inRange: function (from, to) { if (to.hasMark("taomie")) return true; }, }, intro: { content: "mark", }, ai: { effect: { player: function (card, player, target) { if (target && get.tag(card, "damage") && target.hasMark("taomie")) { if (player.hasSkillTag("jueqing", false, target)) return; if (get.attitude(player, target) > 0) { return 0.7; } return 1.2; } }, }, }, }, taomie1: { audio: true, trigger: { player: "damageEnd", source: "damageSource", }, logTarget: function (trigger, player) { if (player == trigger.player) return trigger.source; return trigger.player; }, filter: function (event, player) { var target = lib.skill.taomie1.logTarget(event, player); return target && target.isIn() && !target.hasMark("taomie"); }, check: function (event, player) { var target = lib.skill.taomie1.logTarget(event, player); if (get.attitude(player, target) > 0) return false; var target0 = game.findPlayer(function (current) { return current.hasMark("taomie"); }); if (!target0) return true; var eff1 = 0, eff2 = 0; player.countCards("h", function (card) { if (!get.tag(card, "damage")) return false; if (player.hasValueTarget(card, null, true) > 0) { if (player.canUse(card, target, null, true)) { var eff = get.effect(target, card, player, player); if (eff > 0) eff1 += eff; } if (player.canUse(card, target0, null, true)) { var eff = get.effect(target0, card, player, player); if (eff > 0) eff2 += eff; } } }); return eff1 > eff2; }, prompt2: function (event, player) { var target = lib.skill.taomie1.logTarget(event, player); var str = "令" + get.translation(target) + "获得“讨灭”标记"; if ( game.hasPlayer(function (current) { return current.hasMark("taomie"); }) ) str += ",并移去场上已有的“讨灭”标记"; return str; }, content: function () { game.countPlayer(function (current) { var num = current.countMark("taomie"); if (num) current.removeMark("taomie"); }); lib.skill.taomie1.logTarget(trigger, player).addMark("taomie", 1); }, }, taomie2: { audio: true }, taomie3: { audio: true }, taomie4: { trigger: { global: ["damageAfter", "damageCancelled", "damageZero"], player: "dieBegin", }, forced: true, popup: false, charlotte: true, filter: function (event, player) { return player.hasMark("taomie") && (event.name == "die" || event.taomie_player == player); }, content: function () { player.removeMark("taomie", player.countMark("taomie")); player.removeSkill("taomie2"); }, }, //铁骑飞 liyong: { audio: "retishen", trigger: { player: "shaMiss" }, forced: true, filter: function (event, player) { return player.isPhaseUsing(); }, content: function () { trigger.getParent().liyong = true; player.addTempSkill("liyong2", "phaseUseEnd"); }, }, liyong2: { audio: "retishen", mark: true, intro: { content: "铁骑!强命!加伤!然后掉血嘞…", }, trigger: { player: "useCardToPlayered" }, forced: true, filter: function (event, player) { if (!event.card || event.card.name != "sha") return false; var evt = event.getParent(); if (evt.liyong) return false; var history = player.getHistory("useCard", function (evt) { return evt.card.name == "sha"; }); var evt2 = history[history.indexOf(evt) - 1]; return evt2 && evt2.liyong; }, logTarget: "target", content: function () { var target = trigger.target; target.addTempSkill("fengyin"); trigger.directHit.add(target); var id = target.playerid; var map = trigger.customArgs; if (!map[id]) map[id] = {}; if (!map[id].extraDamage) map[id].extraDamage = 0; map[id].extraDamage++; trigger.getParent().liyong2 = true; }, group: ["liyong3", "liyong4"], }, liyong3: { trigger: { source: "damageSource" }, forced: true, popup: false, filter: function (event, player) { return event.card && event.card.name == "sha" && event.player.isIn() && event.getParent(2).liyong2 == true; }, content: function () { player.loseHp(); }, }, liyong4: { trigger: { player: "useCardAfter" }, forced: true, silent: true, filter: function (evt, player) { if (!evt.card || evt.card.name != "sha") return false; if (evt.liyong) return false; var history = player.getHistory("useCard", function (evt) { return evt.card.name == "sha"; }); var evt2 = history[history.indexOf(evt) - 1]; return evt2 && evt2.liyong; }, content: function () { player.removeSkill("liyong2"); }, }, //韩遂 xinniluan: { trigger: { global: "phaseJieshuBegin" }, direct: true, filter: function (event, player) { return ( player != event.player && event.player.isIn() && event.player.getHistory("useCard", function (evt) { if (evt.targets && evt.targets.length) { var targets = evt.targets.slice(0); while (targets.includes(event.player)) targets.remove(event.player); return targets.length > 0; } return false; }).length > 0 && (_status.connectMode || player.hasSha()) ); }, content: function () { "step 0"; player.chooseToUse({ logSkill: "xinniluan", preTarget: trigger.player, prompt: "是否发动【逆乱】,对" + get.translation(trigger.player) + "使用一张【杀】?", filterCard: function (card, player) { return get.name(card) == "sha" && lib.filter.filterCard.apply(this, arguments); }, filterTarget: function (card, player, target) { return target == _status.event.preTarget && lib.filter.targetEnabled.apply(this, arguments); }, addCount: false, }); "step 1"; if ( result.bool && player.getHistory("sourceDamage", function (evt) { return evt.getParent(4) == event; }).length && trigger.player.countDiscardableCards(player, "he") > 0 ) player.discardPlayerCard(trigger.player, true, "he").boolline = true; }, }, xiaoxi_hansui: { audio: 2, enable: ["chooseToRespond", "chooseToUse"], filterCard: function (card, player) { return get.color(card) == "black"; }, position: "hse", viewAs: { name: "sha" }, viewAsFilter: function (player) { if (!player.countCards("hse", { color: "black" })) return false; }, prompt: "将一张黑色牌当杀使用或打出", check: function (card) { return 4.5 - get.value(card); }, ai: { skillTagFilter: function (player) { if (!player.countCards("hes", { color: "black" })) return false; }, respondSha: true, }, }, //胡车儿 daoji: { audio: 2, enable: "phaseUse", usable: 1, filter: function (event, player) { return ( player.countCards("he", function (card) { return get.type(card) != "basic"; }) && game.hasPlayer(function (target) { return target != player && target.countCards("e") > 0; }) ); }, filterCard: function (card) { return get.type(card) != "basic"; }, position: "he", filterTarget: function (card, player, target) { return target != player && target.countCards("e") > 0; }, check: function (card) { var player = _status.event.player; if ( game.hasPlayer(function (current) { return current != player && get.attitude(player, current) < 0 && get.damageEffect(current, player, player) > 0 && current.getEquip(1); }) ) return 8 - get.value(card); return 5 - get.value(card); }, content: function () { "step 0"; player.gainPlayerCard(target, "e", true).set("ai", function (button) { var card = button.link; var player = _status.event.player; if (get.subtype(card) == "equip1" && get.damageEffect(_status.event.target, player, player) > 0) return 6 + get.value(card); return get.value(card); }); "step 1"; if (!result || !result.bool || !result.cards || !result.cards.length) { event.finish(); return; } var card = result.cards[0]; event.card = card; if (player.getCards("h").includes(card) && get.type(card) == "equip") player.chooseUseTarget(card, true).nopopup = true; "step 2"; if (get.subtype(card, false) == "equip1") target.damage(); }, ai: { order: 6, result: { target: function (player, current) { if (get.damageEffect(current, player, player) > 0 && current.getEquip(1)) return -1.5; return -1; }, }, }, }, //司马师夫妇 //垃圾 baiyi: { enable: "phaseUse", usable: 1, filterTarget: lib.filter.notMe, selectTarget: 2, limited: true, skillAnimation: false, //animationColor:'thunder', filter: function (event, player) { return player.isDamaged() && game.players.length > 2; }, multitarget: true, multiline: true, changeSeat: true, contentBefore: function () { player.$fullscreenpop("败移", "thunder"); }, content: function () { player.awakenSkill("baiyi"); game.broadcastAll( function (target1, target2) { game.swapSeat(target1, target2); }, targets[0], targets[1] ); }, ai: { order: function () { return get.order({ name: "tao" }) + 1; }, result: { target: function (player, target) { if (player.hasUnknown() && target != player.next && target != player.previous) return 0; var distance = Math.pow(get.distance(player, target, "absolute"), 2); if (!ui.selected.targets.length) return distance; var distance2 = Math.pow(get.distance(player, ui.selected.targets[0], "absolute"), 2); return Math.min(0, distance - distance2); }, }, }, }, jinglve: { audio: 2, enable: "phaseUse", usable: 1, filter: function (event, player) { if (player.hasSkill("jinglve2")) return false; return game.hasPlayer(function (current) { return current != player && current.countCards("h") > 0; }); }, filterTarget: function (card, player, target) { return target != player && target.countCards("h") > 0; }, content: function () { "step 0"; if (!player.storage.jinglve4) player.storage.jinglve4 = []; player.storage.jinglve4.add(target); player.chooseButton(["选择一张牌作为「死士」", target.getCards("h")], true).set("ai", function (button) { var target = _status.event.getParent().target; var card = button.link; var val = target.getUseValue(card); if (val > 0) return val; return get.value(card); }); "step 1"; if (result.bool) { player.storage.jinglve2 = target; player.storage.jinglve3 = result.links[0]; player.addSkill("jinglve2"); } }, ai: { order: 12, result: { target: -1, }, }, }, jinglve2: { mark: true, intro: { name: "死士", mark: function (dialog, content, player) { dialog.addText("记录目标"); dialog.add([content]); if (player == game.me || player.isUnderControl()) { dialog.addText("死士牌"); dialog.add([player.storage.jinglve3]); } }, }, onremove: function (player) { delete player.storage.jinglve2; delete player.storage.jinglve3; }, trigger: { global: ["dieEnd", "loseEnd", "gainEnd"] }, silent: true, lastDo: true, charlotte: true, filter: function (event, player) { if (event.name != "gain" && event.player != player.storage.jinglve2) return false; return event.name == "die" || (event.cards.includes(player.storage.jinglve3) && (event.name == "gain" || (event.position != ui.ordering && event.position != ui.discardPile))); }, content: function () { player.removeSkill("jinglve2"); }, group: "jinglve3", }, jinglve3: { audio: "jinglve", trigger: { global: ["loseAfter", "useCard", "phaseAfter", "cardsDiscardAfter", "loseAsyncAfter"], }, filter: function (event, player) { if (event.player && event.player != player.storage.jinglve2) return false; var card = player.storage.jinglve3; if (event.name == "phase") return event.player.getCards("hej").includes(card); if (event.name == "useCard") return event.cards.includes(card); return get.position(card, true) == "d" && event.getd().includes(card); }, forced: true, charlotte: true, logTarget: "player", content: function () { if (trigger.name == "useCard") { trigger.all_excluded = true; trigger.targets.length = 0; } else { if (trigger.name == "phase") { player.gain(player.storage.jinglve3, trigger.player, "giveAuto", "bySelf"); } else if (get.position(player.storage.jinglve3, true) == "d") player.gain(player.storage.jinglve3, "gain2"); } player.removeSkill("jinglve2"); }, }, shanli: { audio: 2, trigger: { player: "phaseZhunbeiBegin" }, juexingji: true, forced: true, skillAnimation: true, animationColor: "thunder", filter: function (event, player) { return player.storage.baiyi && player.getStorage("jinglve4").length > 1; }, content: function () { "step 0"; player.awakenSkill("shanli"); player.loseMaxHp(); player.chooseTarget(true, "选择【擅立】的目标").set("ai", function (target) { var att = get.attitude(_status.event.player, target); if (target == game.me || (target.isUnderControl() && target.isOnline())) return 2 * att; return att; }); "step 1"; var target = result.targets[0]; event.target = target; player.line(target, "green"); game.log(player, "拥立", target); var list = []; if (!_status.characterlist) { if (_status.connectMode) var list = get.charactersOL(); else { var list = []; for (var i in lib.character) { if (lib.filter.characterDisabled2(i) || lib.filter.characterDisabled(i)) continue; list.push(i); } } game.countPlayer2(function (current) { list.remove(current.name); list.remove(current.name1); list.remove(current.name2); if (current.storage.rehuashen && current.storage.rehuashen.character) list.removeArray(current.storage.rehuashen.character); }); _status.characterlist = list; } _status.characterlist.randomSort(); var chara = []; var skills = []; for (var i of _status.characterlist) { if (i == "key_yuri") continue; var character = lib.character[i]; if (character && character[3]) { for (var j of character[3]) { if (skills.includes(j) || j == "yuri_wangxi" || target.hasSkill("j")) continue; var info = get.info(j); if (info && info.zhuSkill) { skills.add(j); chara.add(i); continue; } } } if (skills.length >= 3) break; } if (!skills.length) { event.finish(); return; } event.chara = chara; event.skills = skills; player.chooseControl(skills).set("dialog", ["选择令" + get.translation(target) + "获得一个技能", [chara, "character"]]); "step 2"; target.addSkills(result.control); target.setAvatarQueue(target.name1 || target.name, [event.chara[event.skills.indexOf(result.control)]]); }, ai: { combo: "baiyi", }, }, hongyi: { audio: 2, enable: "phaseUse", usable: 1, //filter:function(event,player){ // return player.countCards('he')>=Math.min(2,game.dead.length); //}, //selectCard:function(){ // return Math.min(2,game.dead.length); //}, //filterCard:true, filterTarget: lib.filter.notMe, check: function (card) { var num = Math.min(2, game.dead.length); if (!num) return 1; if (num == 1) return 7 - get.value(card); return 5 - get.value(card); }, position: "he", content: function () { player.addTempSkill("hongyi2", { player: "phaseBeginStart" }); player.storage.hongyi2.add(target); player.markSkill("hongyi2"); }, ai: { order: 1, result: { target: function (player, target) { if (target.hasJudge("lebu")) return -0.5; return -1 - target.countCards("h"); }, }, }, }, hongyi2: { audio: "hongyi", trigger: { global: "damageBegin1" }, charlotte: true, forced: true, logTarget: "source", filter: function (event, player) { return player.storage.hongyi2.includes(event.source); }, content: function () { "step 0"; trigger.source.judge(); "step 1"; if (result.color == "black") trigger.num--; else trigger.player.draw(); }, onremove: true, intro: { content: "已选中$为技能目标", }, init: function (player, skill) { if (!player.storage[skill]) player.storage[skill] = []; }, }, requanfeng: { audio: "quanfeng", enable: "chooseToUse", limited: true, skillAnimation: true, animationColor: "thunder", filter: function (event, player) { return event.type == "dying" && player == event.dying; }, content: function () { player.awakenSkill("requanfeng"); player.gainMaxHp(2); player.recover(4); }, ai: { save: true, skillTagFilter: function (player, tag, arg) { return player == arg; }, order: 10, result: { player: 1, }, }, group: "requanfeng_gain", }, requanfeng_gain: { audio: "quanfeng", trigger: { global: "die" }, filter: function (event, player) { return ( player.hasSkill("hongyi") && event.player.getStockSkills("仲村由理", "天下第一").filter(function (skill) { var info = get.info(skill); return info && !info.hiddenSkill && !info.zhuSkill && !info.charlotte; }).length > 0 ); }, logTarget: "player", skillAnimation: true, animationColor: "thunder", prompt2: "(限定技)失去技能【劝封】,并获得该角色武将牌上的所有技能,然后加1点体力上限并回复1点体力", check: (event, player) => { if ( event.player .getStockSkills("仲村由理", "天下第一") .filter(skill => { let info = get.info(skill); return info && !info.hiddenSkill && !info.zhuSkill && !info.charlotte; }) .some(i => { let info = get.info(i); if (info && info.ai) return info.ai.neg || info.ai.halfneg; }) ) return false; return true; }, content: function () { player.awakenSkill("requanfeng"); player.removeSkills("hongyi"); var skills = trigger.player.getStockSkills("仲村由理", "天下第一").filter(function (skill) { var info = get.info(skill); return info && !info.hiddenSkill && !info.zhuSkill && !info.charlotte; }); if (skills.length) { player.addSkills(skills); game.broadcastAll(function (list) { game.expandSkills(list); for (var i of list) { var info = lib.skill[i]; if (!info) continue; if (!info.audioname2) info.audioname2 = {}; info.audioname2.yanghuiyu = "quanfeng"; } }, skills); } player.gainMaxHp(); player.recover(); }, }, quanfeng: { audio: 2, trigger: { global: "die" }, filter: function (event, player) { return ( event.player.getStockSkills("仲村由理", "天下第一").filter(function (skill) { var info = get.info(skill); return info && !info.juexingji && !info.hiddenSkill && !info.zhuSkill && !info.charlotte && !info.limited && !info.dutySkill; }).length > 0 ); }, logTarget: "player", skillAnimation: true, limited: true, forced: true, animationColor: "thunder", content: function () { "step 0"; player.awakenSkill("quanfeng"); var list = trigger.player.getStockSkills("仲村由理", "天下第一").filter(function (skill) { var info = get.info(skill); return info && !info.juexingji && !info.hiddenSkill && !info.zhuSkill && !info.charlotte && !info.limited && !info.dutySkill; }); if (list.length == 1) event._result = { control: list[0] }; else player .chooseControl(list) .set("prompt", "选择获得" + get.translation(trigger.player) + "的一个技能") .set("forceDie", true) .set("ai", function () { return list.randomGet(); }); "step 1"; player.addSkills(result.control); game.broadcastAll(function (skill) { var list = [skill]; game.expandSkills(list); for (var i of list) { var info = lib.skill[i]; if (!info) continue; if (!info.audioname2) info.audioname2 = {}; info.audioname2.yanghuiyu = "quanfeng"; } }, result.control); player.gainMaxHp(); player.recover(); }, }, //手杀界朱然 //设计师你改技能有瘾🐴 mobiledanshou: { trigger: { global: "phaseJieshuBegin" }, audio: 2, direct: true, filter: function (event, player) { if (player == event.player) return false; var num = event.player.getHistory("useCard", function (evt) { return evt.targets.includes(player); }).length; return num == 0 || (event.player.isIn() && num <= player.countCards("he")); }, content: function () { "step 0"; var num = trigger.player.getHistory("useCard", function (evt) { return evt.targets.includes(player); }).length; event.num = num; if (num == 0) { if (player.hasSkill("mobiledanshou")) event._result = { bool: true }; else player.chooseBool("是否发动【胆守】摸一张牌?", lib.translate.mobiledanshou_info); } else event.goto(2); "step 1"; if (result.bool) { player.logSkill("mobiledanshou"); player.draw(); } event.finish(); "step 2"; player .chooseToDiscard(num, get.prompt("mobiledanshou", trigger.player), "弃置" + get.translation(num) + "张牌并对其造成1点伤害", "he") .set("ai", function (card) { if (!_status.event.goon) return 0; var num = _status.event.getParent().num; if (num == 1) return 8 - get.value(card); if (num == 2) return 6.5 - get.value(card); return 5 - get.value(card); }) .set("goon", get.damageEffect(trigger.player, player, player) > 0).logSkill = ["mobiledanshou", trigger.player]; "step 3"; if (result.bool) { player.addExpose(0.2); trigger.player.damage(); } }, }, //丁原 //程序员和设计师至少有一个脑子有坑 beizhu: { audio: 3, enable: "phaseUse", usable: 1, filter: function (event, player) { return game.hasPlayer(function (target) { return lib.skill.beizhu.filterTarget(null, player, target); }); }, filterTarget: function (card, player, target) { return target != player && target.countCards("h") > 0; }, content: function () { "step 0"; player.addTempSkill("beizhu_draw"); player.viewHandcards(target); "step 1"; var cards = target.getCards("h", "sha"); if (cards.length) { event.cards = cards; event.goto(5); } else player.discardPlayerCard("he", target, "visible", true); "step 2"; player.chooseBool("是否令" + get.translation(target) + "获得一张【杀】?").set("choice", get.attitude(player, target) > 0); "step 3"; if (result.bool) { var card = get.cardPile2(function (card) { return card.name == "sha"; }); if (card) target.gain(card, "gain2"); } else event.finish(); "step 4"; game.updateRoundNumber(); event.finish(); "step 5"; var hs = target.getCards("h"); cards = cards.filter(function (card) { return ( hs.includes(card) && get.name(card, target) == "sha" && target.canUse( { name: "sha", isCard: true, cards: [card], }, player, false ) ); }); if (cards.length) { var card = cards.randomRemove(1)[0]; target.useCard(player, false, card).card.beizhu = true; event.redo(); } }, ai: { order: 7, threaten: 1.14 + 5.14, result: { player: function (player, target) { var eff = get.effect(target, { name: "guohe_copy2" }, player, player); var cards = target.getCards("h", { name: "sha" }); if (!cards.length) return eff; return eff / (cards.length + 3); }, }, }, }, beizhu_draw: { trigger: { player: "damageEnd" }, forced: true, popup: false, charlotte: true, filter: function (event, player) { return event.card && event.card.beizhu; }, content: function () { player.draw(trigger.num); }, }, //新简雍 xinqiaoshui: { audio: 2, enable: "phaseUse", usable: 1, filterTarget: function (card, player, target) { return player.canCompare(target); }, filter: function (event, player) { return player.countCards("h") > 0; }, content: function () { "step 0"; player.chooseToCompare(target); "step 1"; if (result.bool) player.addTempSkill("qiaoshui3", "phaseUseEnd"); else { player.addTempSkill("qiaoshui2", "phaseUseEnd"); } }, ai: { order: function (item, player) { if ( player.countCards("h", function (card) { return player.hasValueTarget(card); }) ) return 10; return 1; }, result: { target: function (player, target) { if ( player.countCards("h", function (card) { return player.hasValueTarget(card); }) ) { if (player.hasSkill("qiaoshui3")) return 0; var nd = !player.needsToDiscard(); if ( player.hasCard(function (card) { if (get.position(card) != "h") return false; var val = get.value(card); if (nd && val < 0) return true; if (val <= 5) { return card.number >= 12; } if (val <= 6) { return card.number >= 13; } return false; }) ) return -1; return 0; } return -1; }, }, }, }, xinjyzongshi: { audio: 2, trigger: { player: ["chooseToCompareAfter", "compareMultipleAfter"], target: ["chooseToCompareAfter", "compareMultipleAfter"], }, filter: function (event, player) { if (event.preserve) return false; if (event.name == "compareMultiple") return true; return !event.compareMultiple; }, frequent: true, content: function () { "step 0"; var str = '
    牌堆顶'; var cards = get.cards(); if (trigger.name == "chooseToCompare" && trigger.compareMeanwhile) { var result = trigger.result; var list = [[result.num1[0], result.player]]; list.addArray( result.num2.map(function (card, i) { return [card, result.targets[i]]; }) ); list.sort(function (a, b) { return a[0] - b[0]; }); if (list[0][0] < list[1][0] && get.position(list[0][1], true) == "o") { str += "/拼点牌"; cards.push(list[0][1]); } } else { if (player == trigger.player) { if (trigger.num1 > trigger.num2 && get.position(trigger.card2, true) == "o") { str += "/拼点牌"; cards.push(trigger.card2); } else if (trigger.num1 < trigger.num2 && get.position(trigger.card1, true) == "o") { str += "/拼点牌"; cards.push(trigger.card1); } } else { if (trigger.num1 < trigger.num2 && get.position(trigger.card1, true) == "o") { str += "/拼点牌"; cards.push(trigger.card1); } else if (trigger.num1 > trigger.num2 && get.position(trigger.card2, true) == "o") { str += "/拼点牌"; cards.push(trigger.card2); } } } str += "
    "; event.cards = cards; player.chooseButton(["纵适:选择要获得的牌", str, cards], true).set("ai", get.buttonValue); "step 1"; if (result.bool) { var draw = result.links[0] == cards[0]; player.gain(result.links, draw ? "draw" : "gain2").log = false; game.log(player, "获得了", draw ? "牌堆顶的一张牌" : result.links); if (!draw) { cards[0].fix(); ui.cardPile.insertBefore(cards[0], ui.cardPile.firstChild); game.updateRoundNumber(); } } }, }, //通渠张恭 rezhenxing: { audio: "xinfu_zhenxing", trigger: { player: ["damageEnd", "phaseJieshuBegin"], }, frequent: true, content: function () { "step 0"; event.cards = get.cards(3); player .chooseButton(["【镇行】:请选择要获得的牌", event.cards]) .set("filterButton", function (button) { var cards = _status.event.cards; for (var i = 0; i < cards.length; i++) { if (button.link != cards[i] && get.suit(cards[i]) == get.suit(button.link)) return false; } return true; }) .set("ai", function (button) { return get.value(button.link); }) .set("cards", event.cards); "step 1"; for (var i = event.cards.length - 1; i >= 0; i--) { if (result.bool && result.links.includes(event.cards[i])) { player.gain(event.cards[i], "gain2"); } else { event.cards[i].fix(); ui.cardPile.insertBefore(event.cards[i], ui.cardPile.childNodes[0]); } } game.updateRoundNumber(); }, }, //芙蓉,手杀界廖化,手杀界曹彰 rejiangchi: { audio: 2, trigger: { player: "phaseUseBegin", }, direct: true, content: function () { "step 0"; var list = ["弃牌", "摸牌", "取消"]; if (!player.countCards("he")) list.remove("弃牌"); player .chooseControl(list, function () { var player = _status.event.player; if (list.includes("弃牌")) { if (player.countCards("h") > 3 && player.countCards("h", "sha") > 1) { return "弃牌"; } if (player.countCards("h", "sha") > 2) { return "弃牌"; } } if (!player.countCards("h", "sha")) { return "摸牌"; } return "cancel2"; }) .set("prompt", get.prompt2("rejiangchi")); "step 1"; if (result.control == "弃牌") { player.chooseToDiscard(true, "he"); player.addTempSkill("jiangchi2", "phaseUseEnd"); player.logSkill("rejiangchi"); } else if (result.control == "摸牌") { player.draw(); player.addTempSkill("rejiangchi3", "phaseUseEnd"); player.logSkill("rejiangchi"); } }, }, rejiangchi3: { mod: { cardEnabled: function (card) { if (card.name == "sha") return false; }, }, }, refuli: { skillAnimation: true, animationColor: "soil", audio: 2, unique: true, limited: true, enable: "chooseToUse", mark: true, filter: function (event, player) { if (event.type != "dying") return false; if (player != event.dying) return false; return true; }, content: function () { "step 0"; player.awakenSkill("refuli"); event.num = game.countGroup(); if (event.num > player.hp) player.recover(event.num - player.hp); "step 1"; if (player.isMaxHp(true)) player.turnOver(); }, ai: { save: true, skillTagFilter: function (player, arg, target) { return player == target; }, result: { player: 10, }, threaten: function (player, target) { if (!target.storage.refuli) return 0.9; }, }, }, redangxian: { trigger: { player: "phaseBegin" }, forced: true, audio: "dangxian", audioname: ["guansuo", "xin_liaohua"], content: function () { "step 0"; var card = get.discardPile(function (card) { return card.name == "sha"; }); if (card) player.gain(card, "gain2"); "step 1"; game.updateRoundNumber(); var next = player.phaseUse(); event.next.remove(next); trigger.next.push(next); }, }, xuewei: { audio: 2, trigger: { player: "phaseZhunbeiBegin" }, direct: true, content: function () { "step 0"; player.chooseTarget(get.prompt2("xuewei"), lib.filter.notMe).set("ai", function (target) { var player = _status.event.player; if (player == get.zhu(player) && player.hp <= 2) return 0; return get.attitude(player, target) - 4; }).animate = false; "step 1"; if (result.bool) { var target = result.targets[0]; player.logSkill("xuewei"); player.addTempSkill("xuewei2", { player: "phaseBegin" }); player.storage.xuewei2 = target; } }, ai: { threaten: 1.05, }, }, xuewei2: { audio: "xuewei", forced: true, onremove: true, trigger: { global: "damageBegin4" }, charlotte: true, filter: function (event, player) { return event.player == player.storage.xuewei2; }, logTarget: "player", content: function () { player.removeSkill("xuewei2"); trigger.cancel(); player.damage(trigger.num, trigger.source || "nosource"); if (trigger.source && trigger.source.isIn()) trigger.source.damage(trigger.num, trigger.nature, player); }, }, liechi: { trigger: { player: "dying" }, forced: true, filter: function (event, player) { return event.getParent().name == "damage" && event.source && event.source.countCards("he"); }, audio: 2, content: function () { trigger.source.chooseToDiscard("he", true); }, }, rejiuchi: { group: ["jiuchi"], audioname: ["re_dongzhuo"], trigger: { source: "damage" }, forced: true, popup: false, locked: false, audio: "jiuchi", filter: function (event, player) { return event.card && event.card.name == "sha" && event.getParent(2).jiu == true && !player.hasSkill("rejiuchi_air"); }, content: function () { player.logSkill("jiuchi"); player.addTempSkill("rejiuchi_air"); }, subSkill: { air: {}, }, }, //苏飞,新贾逵 tongqu: { audio: 2, trigger: { global: ["phaseBefore", "dying", "phaseDrawBegin2"], player: ["enterGame", "phaseZhunbeiBegin"], }, direct: true, filter: function (event, player) { if (event.name == "phaseDraw") return event.player.hasMark("tongqu"); if (event.name == "dying") return event.player.hasMark("tongqu"); if (event.name == "phaseZhunbei") return game.hasPlayer(function (current) { return !current.hasMark("tongqu"); }); return !player.hasMark("tongqu") && (event.name != "phase" || game.phaseNumber == 0); }, content: function () { "step 0"; if (trigger.name == "phaseDraw") { player.logSkill("tongqu", trigger.player); trigger.player.draw("nodelay"); trigger.player.addTempSkill("tongqu2", "phaseDrawAfter"); event.finish(); } else if (trigger.name == "dying") { player.logSkill("tongqu", trigger.player); trigger.player.removeMark("tongqu", 1); event.finish(); } else if (trigger.name == "phaseZhunbei") { player .chooseTarget(get.prompt2("tongqu"), function (card, player, target) { return !target.hasMark("tongqu"); }) .set("ai", function (target) { if (_status.event.player.hp < 3) return 0; return get.attitude(_status.event.player, target); }); } else { player.logSkill("tongqu"); player.addMark("tongqu", 1); event.finish(); } "step 1"; if (result.bool) { var target = result.targets[0]; player.loseHp(); player.logSkill("tongqu", target); target.addMark("tongqu", 1); } }, marktext: "渠", intro: { content: "mark", name2: "渠" }, }, tongqu2: { trigger: { player: "phaseDrawEnd" }, forced: true, silent: true, filter: function (event, player) { var bool = game.hasPlayer(function (current) { return current != player && current.hasMark("tongqu"); }); return ( player.countCards("he", function (card) { if (bool) return true; return lib.filter.cardDiscardable(card, player); }) > 0 ); }, content: function () { "step 0"; player.chooseCardTarget({ forced: true, position: "he", filterCard: true, filterTarget: function (card, player, target) { return player != target && target.hasMark("tongqu"); }, selectTarget: function () { if (ui.selected.cards.length && !lib.filter.cardDiscardable(ui.selected.cards[0], _status.event.player)) return [1, 1]; return [0, 1]; }, prompt: "弃置一张牌,或将一张牌交给一名有“渠”的其他角色", ai1: function (card) { var player = _status.event.player; if (get.name(card) == "du") return 20; if (get.position(card) == "e" && get.value(card) <= 0) return 14; if ( get.position(card) == "h" && game.hasPlayer(function (current) { return current != player && current.hasMark("tongqu") && get.attitude(player, current) > 0 && current.getUseValue(card) > player.getUseValue(card) && current.getUseValue(card) > player.getUseValue(card); }) ) return 12; if ( game.hasPlayer(function (current) { return current != player && current.hasMark("tongqu") && get.attitude(player, current) > 0; }) ) { if (card.name == "wuxie") return 11; if (card.name == "shan" && player.countCards("h", "shan") > 1) return 9; } return 6 / Math.max(1, get.value(card)); }, ai2: function (target) { var player = _status.event.player; var card = ui.selected.cards[0]; var att = get.attitude(player, target); if (card.name == "du") return -6 * att; if (att > 0) { if (get.position(card) == "h" && target.getUseValue(card) > player.getUseValue(card)) return 4 * att; if (target.hasUseTarget(card)) return 2 * att; return 1.2 * att; } return 0; }, }); "step 1"; if (result.bool) { if (result.targets.length) { event.target = result.targets[0]; player.give(result.cards, event.target); event.card = result.cards[0]; } else { player.discard(result.cards); event.finish(); } } "step 2"; if (target.getCards("h").includes(card) && get.type(card) == "equip") { target.chooseUseTarget(card, true); } }, }, xinwanlan: { audio: "wanlan", trigger: { global: "damageBegin4" }, filter: function (event, player) { return event.player.hp <= event.num && player.countCards("e") >= 1; }, logTarget: "player", check: function (event, player) { if (get.attitude(player, event.player) < 4) return false; if (player.countCards("hs", card => player.canSaveCard(card, event.player)) >= 1 + event.num - event.player.hp) return false; if (event.player == player || event.player == get.zhu(player)) return true; return !player.hasUnknown(); }, content: function () { player.discard(player.getCards("e")); trigger.cancel(); }, }, zhengjian: { audio: 2, trigger: { player: "phaseJieshuBegin" }, locked: true, direct: true, content: function () { "step 0"; player.chooseTarget("请选择【诤荐】的目标", lib.translate.zhengjian_info).set("ai", function (target) { if (target.hasSkill("zhengjian_mark")) return 0; if (player == target) return 0.5; return get.attitude(_status.event.player, target) * (1 + target.countCards("h")); }); "step 1"; if (result.bool) { var target = result.targets[0]; player.logSkill("zhengjian", target); target.addSkill("zhengjian_mark"); } }, group: "zhengjian_draw", ai: { notemp: true, }, }, zhengjian_draw: { audio: "zhengjian", trigger: { player: "phaseBegin" }, forced: true, filter: function (event) { return game.hasPlayer(function (current) { return current.hasSkill("zhengjian_mark"); }); }, logTarget: function (event) { return game.filterPlayer(function (current) { return current.hasSkill("zhengjian_mark"); }); }, content: function () { "step 0"; var list = game.filterPlayer(function (current) { return current.countMark("zhengjian_mark") > 0; }); if (list.length > 1) { event.delay = true; game.asyncDraw(list, function (target) { return Math.min(5, target.maxHp, target.countMark("zhengjian_mark")); }); } else if (list.length == 1) list[0].draw(Math.min(5, list[0].maxHp, list[0].countMark("zhengjian_mark"))); "step 1"; game.countPlayer(function (current) { current.removeSkill("zhengjian_mark"); }); if (event.delay) game.delayx(); }, }, zhengjian_mark: { trigger: { player: ["useCard1", "respond"] }, silent: true, firstDo: true, onremove: true, charlotte: true, content: function () { player.addMark("zhengjian_mark", 1, false); }, init: function (player, skill) { if (!player.storage[skill]) player.storage[skill] = 0; }, mark: true, intro: { content: "已使用/打出过#张牌", }, }, gaoyuan: { audio: 2, trigger: { target: "useCardToTarget" }, direct: true, filter: function (event, player) { if (event.card.name != "sha") return false; if (player.countCards("he") == 0) return false; return game.hasPlayer(function (current) { return current != event.player && current != player && current.hasSkill("zhengjian_mark") && lib.filter.targetEnabled(event.card, event.player, current); }); }, content: function () { "step 0"; var next = player.chooseCardTarget({ position: "he", filterCard: lib.filter.cardDiscardable, filterTarget: function (card, player, target) { var trigger = _status.event; if (target != player && target != trigger.source) { if (target.hasSkill("zhengjian_mark") && lib.filter.targetEnabled(trigger.card, trigger.source, target)) return true; } return false; }, ai1: function (card) { return get.unuseful(card) + 9; }, ai2: function (target) { if (_status.event.player.countCards("h", "shan")) { return -get.attitude(_status.event.player, target); } if (get.attitude(_status.event.player, target) < 5) { return 6 - get.attitude(_status.event.player, target); } if (_status.event.player.hp == 1 && player.countCards("h", "shan") == 0) { return 10 - get.attitude(_status.event.player, target); } if (_status.event.player.hp == 2 && player.countCards("h", "shan") == 0) { return 8 - get.attitude(_status.event.player, target); } return -1; }, prompt: get.prompt("gaoyuan"), prompt2: "弃置一张牌,将此【杀】转移给一名有“诤”的角色", source: trigger.player, card: trigger.card, }); "step 1"; if (result.bool) { var target = result.targets[0]; player.logSkill(event.name, target); player.discard(result.cards); var evt = trigger.getParent(); evt.triggeredTargets2.remove(player); evt.targets.remove(player); evt.targets.push(target); } }, ai: { combo: "zhengjian", }, }, //一 将 成 名 zhilve: { audio: 2, trigger: { player: "phaseZhunbeiBegin" }, forced: true, content: function () { "step 0"; if (!player.canMoveCard()) event._result = { index: 1 }; else player .chooseControl() .set("choiceList", ["移动场上的一张牌", "本回合的摸牌阶段多摸一张牌且第一张杀无距离次数限制"]) .set("ai", function () { return 1; }); "step 1"; if (result.index == 1) { player.addTempSkill("zhilve_yingzi"); if ( !player.getHistory("useCard", function (card) { return card.card.name == "sha"; }).length ) player.addTempSkill("zhilve_xiandeng"); event.finish(); } else player.moveCard(true); "step 2"; if (result.position == "e") player.loseHp(); else player.addTempSkill("zhilve_dis"); }, subSkill: { dis: { mod: { maxHandcard: function (player, num) { return num - 1; }, }, }, yingzi: { trigger: { player: "phaseDrawBegin2" }, popup: false, forced: true, filter: function (event, player) { return !event.numFixed; }, content: function () { trigger.num++; }, }, xiandeng: { mod: { targetInRange: function (card, player) { if (card.name == "sha") return true; }, }, trigger: { player: "useCard1" }, forced: true, popup: false, firstDo: true, filter: function (event, player) { return event.card.name == "sha"; }, content: function () { player.removeSkill(event.name); if (trigger.addCount !== false) { trigger.addCount = false; var stat = player.getStat("card"); if (stat && stat.sha) stat.sha--; } }, }, }, }, xhzhiyan: { enable: "phaseUse", audio: 2, filter: function (event, player) { return player.countCards("h") != player.maxHp; }, filterCard: true, selectCard: function () { var player = _status.event.player; var num = Math.max(0, player.countCards("h") - player.maxHp); return [num, num]; }, check: function (card) { var player = _status.event.player; if ( player.getUseValue(card) <= 0 && game.hasPlayer(function (current) { return current != player && get.value(card, current) * get.attitude(player, current) > 0; }) ) return 1; return 0; }, content: function () { "step 0"; if (!cards.length) { player.draw(player.maxHp - player.countCards("h")); player.addTempSkill("zishou2"); event.finish(); } else { cards = cards.filterInD("d"); if (cards.length) player.chooseButton(["是否将其中的一张牌交给一名其他角色?", cards]).set("", function (button) { var player = _status.event.player; if ( game.hasPlayer(function (current) { return current != player && get.value(button.link, current) * get.attitude(player, current) > 0; }) ) return Math.abs(get.value(button.link)); return 0; }); else event.finish(); } "step 1"; if (result.bool && game.hasPlayer(current => current != player)) { event.card = result.links[0]; player.chooseTarget(true, lib.filter.notMe, "选择一名其他角色获得" + get.translation(event.card)).set("ai", function (target) { return get.value(_status.event.getParent().card, target) * get.attitude(_status.event.player, target); }); } else event.finish(); "step 2"; var target = result.targets[0]; player.line(target, "green"); target.gain(card, "gain2", "log"); }, ai: { order: function (obj, player) { if (player.countCards("h") > player.maxHp) return 10; return 0.5; }, result: { player: 1, }, }, }, //水 果 忍 者 zhengjing_guanju: { audio: true }, zhengjing: { audio: 2, enable: "phaseUse", usable: 1, filter: function (event, player) { return !player.hasSkill("zhengjing3"); }, content: function () { "step 0"; //game.trySkillAudio('zhengjing_guanju',player); if (_status.connectMode) event.time = lib.configOL.choose_timeout; var cards = []; var names = []; while (true) { var card = get.cardPile(function (carde) { return carde.name != "du" && !names.includes(carde.name); }); if (card) { cards.push(card); names.push(card.name); if (get.mode() == "doudizhu") { if (cards.length == 1 && !get.isLuckyStar(player) && Math.random() < 0.33) break; if (cards.length == 2 && !get.isLuckyStar(player) && Math.random() < 0.5) break; if (cards.length >= 3) break; } else { if (cards.length == 3 && !get.isLuckyStar(player) && Math.random() < 0.33) break; if (cards.length == 4 && !get.isLuckyStar(player) && Math.random() < 0.5) break; if (cards.length >= 5) break; } } else break; } event.cards = cards; if (!cards.length) { event.finish(); return; } event.videoId = lib.status.videoId++; if (player.isUnderControl()) { game.swapPlayerAuto(player); } var switchToAuto = function () { names.remove("du"); game.pause(); game.countChoose(); setTimeout(function () { _status.imchoosing = false; event._result = { bool: true, links: names.slice(0), }; if (event.dialog) event.dialog.close(); if (event.control) event.control.close(); game.resume(); }, 5000); }; var createDialog = function (player, id) { if (_status.connectMode) lib.configOL.choose_timeout = "30"; if (player == game.me) return; var str = get.translation(player) + "正在整理经书...
    "; ui.create.dialog(str).videoId = id; }; var chooseButton = function (list) { var roundmenu = false; if (ui.roundmenu && ui.roundmenu.display != "none") { roundmenu = true; ui.roundmenu.style.display = "none"; } var event = _status.event; event.settleed = false; event.finishedx = []; event.map = {}; var names = list.slice(0); event.zhengjing_nodes = []; names.push("du"); names.randomSort(); var names2 = names.slice(0); for (var i = 0; i < 2; i++) { names2.randomSort(); names = names.concat(names2); } event.zhengjing = names; for (var i of list) { event.map[i] = 0; } event.dialog = ui.create.dialog("forcebutton", "hidden"); event.dialog.textPrompt = event.dialog.add('
    及时点击卡牌,但不要点到毒了!
    '); var str = '
    '; for (var i of list) { str += get.translation(i) + ":" + Math.min(2, event.map[i]) + "/2 "; } str += "
    "; event.dialog.textPrompt2 = event.dialog.add(str); event.switchToAuto = function () { event._result = { bool: true, links: event.finishedx.slice(0), }; event.dialog.close(); game.resume(); _status.imchoosing = false; if (roundmenu) ui.roundmenu.style.display = ""; }; event.dialog.classList.add("fixed"); event.dialog.classList.add("scroll1"); event.dialog.classList.add("scroll2"); event.dialog.classList.add("fullwidth"); event.dialog.classList.add("fullheight"); event.dialog.classList.add("noupdate"); event.dialog.open(); event.settle = function (du) { if (event.settleed) return; event.settleed = true; event.dialog.textPrompt2.innerHTML = ""; if (du) { if (lib.config.background_speak) game.playAudio("skill", "zhengjing_boom"); event.dialog.textPrompt.innerHTML = '
    叫你别点毒你非得点 这下翻车了吧
    '; } else { if (lib.config.background_speak) game.playAudio("skill", "zhengjing_finish"); event.dialog.textPrompt.innerHTML = '
    整理经典结束!共整理出' + get.cnNumber(event.finishedx.length) + "份经典
    "; } while (event.zhengjing_nodes.length) { event.zhengjing_nodes.shift().delete(); } setTimeout(function () { event.switchToAuto(); }, 1000); }; var click = function () { var name = this.name; if (name == "du") { event.zhengjing.length = 0; event.settle(true); } else { if (lib.config.background_speak) game.playAudio("skill", "zhengjing_click"); event.map[name]++; if (event.map[name] > 1) event.finishedx.add(name); if (event.finishedx.length < list.length) { var str = '
    '; for (var i of list) { str += get.translation(i) + ":" + Math.min(2, event.map[i]) + "/2 "; } str += "
    "; event.dialog.textPrompt2.innerHTML = str; } else { event.zhengjing.length = 0; event.settle(); } } event.zhengjing_nodes.remove(this); this.style.transition = "all 0.5s"; this.style.transform = "scale(1.2)"; this.delete(); }; var addNode = function () { if (event.zhengjing.length) { var card = ui.create.card(ui.special, "noclick", true); card.init(["", "", event.zhengjing.shift()]); card.addEventListener(lib.config.touchscreen ? "touchstart" : "mousedown", click); event.zhengjing_nodes.push(card); card.style.position = "absolute"; var rand1 = Math.round(Math.random() * 100); var rand2 = Math.round(Math.random() * 100); var rand3 = Math.round(Math.random() * 40) - 20; card.style.left = "calc(" + rand1 + "% - " + rand1 + "px)"; card.style.top = "calc(" + rand2 + "% - " + rand2 + "px)"; card.style.transform = "scale(0.8) rotate(" + rand3 + "deg)"; card.style.opacity = 0; event.dialog.appendChild(card); ui.refresh(card); card.style.opacity = 1; card.style.transform = "scale(1) rotate(" + rand3 + "deg)"; } if (event.zhengjing_nodes.length > (event.zhengjing.length > 0 ? 2 : 0)) event.zhengjing_nodes.shift().delete(); if (event.zhengjing.length || event.zhengjing_nodes.length) setTimeout(function () { addNode(); }, 800); else event.settle(); }; game.pause(); game.countChoose(); addNode(); }; //event.switchToAuto=switchToAuto; game.broadcastAll(createDialog, player, event.videoId); if (event.isMine()) { chooseButton(names); } else if (event.isOnline()) { event.player.send(chooseButton, names); event.player.wait(); game.pause(); } else { switchToAuto(); } "step 1"; game.broadcastAll( function (id, time) { if (_status.connectMode) lib.configOL.choose_timeout = time; var dialog = get.idDialog(id); if (dialog) { dialog.close(); } }, event.videoId, event.time ); var result = event.result || result; for (var i = 0; i < cards.length; i++) { //if(cards.length==1) break; if (!result.links.includes(cards[i].name)) cards.splice(i--, 1); } if (cards.length) { player.showCards(cards, get.translation(player) + "整理出了以下经典"); game.cardsGotoOrdering(cards); } else { game.log(player, "并没有整理出经典"); player.popup("杯具"); event.finish(); } "step 2"; game.updateRoundNumber(); player.chooseTarget(true, "将整理出的经典置于一名角色的武将牌上").set("ai", function (target) { if (target.hasSkill("xinfu_pdgyingshi")) return 0; var player = _status.event.player; var cards = _status.event.getParent().cards; var att = get.attitude(player, target); return -att; //if(cards.length==1) return -att; // if(player==target) att/=2; // if(target.hasSkill('pingkou')) att*=1.4; // att*=(1+target.countCards('j')/2); // return att; }); "step 3"; if (result.bool) { var target = result.targets[0]; event.target = target; player.line(target, "thunder"); } "step 4"; if (cards.length == 1) { event._result = { bool: true, moved: [cards, []] }; return; } var next = player.chooseToMove("整经:请分配整理出的经典", true); next.set("list", [["置于" + get.translation(target) + "的武将牌上", cards], ["自己获得"]]); next.set("filterMove", function (from, to, moved) { if (moved[0].length == 1 && to == 1 && from.link == moved[0][0]) return false; return true; }); next.set("filterOk", function (moved) { return moved[0].length > 0; }); next.set("processAI", function (list) { var cards = list[0][1].slice(0).sort(function (a, b) { return get.value(a) - get.value(b); }); return [cards.splice(0, 1), cards]; }); "step 5"; if (result.bool) { var cards = result.moved[0], gains = result.moved[1]; target.addSkill("zhengjing2"); target.addToExpansion(cards, "gain2").gaintag.add("zhengjing2"); if (gains.length) player.gain(gains, "gain2"); } }, ai: { order: 10, result: { player: 1 }, threaten: 3.2, }, }, //恁就是仲村由理? zhengjing2: { trigger: { player: "phaseZhunbeiBegin" }, forced: true, charlotte: true, intro: { content: "expansion", markcount: "expansion" }, onremove: function (player, skill) { var cards = player.getExpansions(skill); if (cards.length) player.loseToDiscardpile(cards); }, content: function () { "step 0"; player.gain(player.getExpansions("zhengjing2"), "gain2"); player.skip("phaseJudge"); player.skip("phaseDraw"); "step 1"; player.removeSkill("zhengjing2"); }, }, zhengjing3: {}, //邓芝 jimeng: { audio: 2, trigger: { player: "phaseUseBegin" }, direct: true, filter: function (event, player) { return game.hasPlayer(function (current) { return current.countGainableCards(player, "he") > 0; }); }, content: function () { "step 0"; player .chooseTarget(get.prompt2("jimeng"), function (card, player, target) { return target != player && target.countGainableCards(player, "he") > 0; }) .set("ai", function (target) { var player = _status.event.player; if (player.hp > 1 && get.attitude(player, target) < 2) return 0; return get.effect(target, { name: "shunshou" }, player, player); }); "step 1"; if (result.bool) { var target = result.targets[0]; event.target = target; player.logSkill("jimeng", target); player.gainPlayerCard(target, "he", true); } else event.finish(); "step 2"; var hs = player.getCards("he"); if (player.hp > 0 && hs.length) { if (hs.length <= player.hp) event._result = { bool: true, cards: hs }; else player.chooseCard(player.hp, true, "交给" + get.translation(target) + get.cnNumber(player.hp) + "张牌", "he", true); } else event.finish(); "step 3"; player.give(result.cards, target); }, }, shuaiyan: { audio: 2, trigger: { player: "phaseDiscardBegin" }, filter: function (event, player) { return player.countCards("h") > 1; }, check: function (event, player) { return game.hasPlayer(function (current) { return current != player && current.countCards("he") && lib.skill.shuaiyan.check2(current, player); }); }, check2: function (target, player) { if (get.itemtype(player) != "player") player = _status.event.player; return -get.attitude(player, target) / target.countCards("he"); }, content: function () { "step 0"; player.showHandcards(get.translation(player) + "发动了【率言】"); "step 1"; var filter = function (card, player, target) { return player != target && target.countCards("he") > 0; }; if ( game.hasPlayer(function (current) { return filter("我约等于白板", player, current); }) ) { player.chooseTarget(true, filter, "选择一名其他角色,令其交给你一张牌").set("ai", lib.skill.shuaiyan.check2); } else event.finish(); "step 2"; var target = result.targets[0]; event.target = target; player.line(target, "green"); target.chooseCard("he", true, "交给" + get.translation(player) + "一张牌"); "step 3"; target.give(result.cards, player); }, }, relihuo: { audio: 2, group: ["relihuo_baigei", "relihuo_damage"], trigger: { player: "useCard1" }, filter: function (event, player) { if (event.card.name == "sha" && !game.hasNature(event.card)) return true; }, check: function (event, player) { return false; }, content: function () { game.setNature(trigger.card, "fire"); trigger.relihuo = true; }, }, relihuo_damage: { trigger: { source: "damageBegin1" }, forced: true, audio: "relihuo", filter: function (event, player) { return event.getParent(2).relihuo == true && event.player.isLinked(); }, content: function () { trigger.num++; }, }, relihuo_baigei: { trigger: { player: "useCardAfter" }, forced: true, audio: "relihuo", filter: function (event, player) { if (event.card.name != "sha" || !game.hasNature(event.card, "fire")) return false; var num = 0; player.getHistory("sourceDamage", function (evt) { if (evt.card == event.card) num += evt.num; }); return num > 1; }, content: function () { var num = 0; player.getHistory("sourceDamage", function (evt) { if (evt.card == trigger.card) num += evt.num; }); player.loseHp(Math.floor(num / 2)); }, }, gongsun: { audio: 2, trigger: { player: "phaseUseBegin" }, direct: true, filter: function (event, player) { return player.countCards("he") > 1; }, content: function () { "step 0"; player.chooseCardTarget({ prompt: get.prompt2("gongsun"), selectCard: 2, filterCard: lib.filter.cardDiscardable, filterTarget: lib.filter.notMe, position: "he", ai1: function (card) { var friend = 0, enemy = 0, player = _status.event.player; var num = game.countPlayer(function (target) { var att = get.attitude(player, target); if (att < 0) enemy++; if (target != player && att > 0) friend++; return true; }); if (num > friend + enemy + 2) return 0; if (friend < enemy) return 0; if (card.name == "sha") return 10 - enemy; return 10 - enemy - get.value(card); }, ai2: function (target) { return -get.attitude(_status.event.player, target) * (1 + target.countCards("h")); }, }); "step 1"; if (result.bool) { var target = result.targets[0]; event.target = target; player.logSkill("gongsun", target); player.discard(result.cards); player.addTempSkill("gongsun_shadow", { player: ["phaseBegin", "die"] }); var list = []; for (var i = 0; i < lib.inpile.length; i++) { var name = lib.inpile[i]; if (get.type(name) == "trick") list.push(["锦囊", "", name]); else if (get.type(name) == "basic") list.push(["基本", "", name]); } player.chooseButton(["请选择一个牌名", [list, "vcard"], true]).set("ai", function (button) { return button.link[2] == "sha" ? 1 : 0; }); } else event.finish(); "step 2"; player.storage.gongsun_shadow.push([target, result.links[0][2]]); player.popup(result.links[0][2], "soil"); game.log(player, "选择了", "" + get.translation(result.links[0][2])); player.markSkill("gongsun_shadow"); }, }, gongsun_shadow: { global: "gongsun_shadow2", init: function (player, skill) { if (!player.storage[skill]) player.storage[skill] = []; }, marktext: "损", onremove: true, intro: { content: function (shadow) { var str = ""; for (var i = 0; i < shadow.length; i++) { if (i > 0) str += "
    "; str += get.translation(shadow[i][0]); str += ":"; str += get.translation(shadow[i][1]); } return str; }, }, mod: { cardEnabled: function (card, player) { var list = player.storage.gongsun_shadow; for (var i = 0; i < list.length; i++) { if (list[i][1] == card.name) return false; } }, cardRespondable: function (card, player) { var list = player.storage.gongsun_shadow; for (var i = 0; i < list.length; i++) { if (list[i][1] == card.name) return false; } }, cardSavable: function (card, player) { var list = player.storage.gongsun_shadow; for (var i = 0; i < list.length; i++) { if (list[i][1] == card.name) return false; } }, cardDiscardable: function (card, player) { var list = player.storage.gongsun_shadow; for (var i = 0; i < list.length; i++) { if (list[i][1] == card.name) return false; } }, }, }, gongsun_shadow2: { mod: { cardEnabled: function (card, player) { if ( game.hasPlayer(function (current) { var list = current.storage.gongsun_shadow; if (!list) return false; for (var i = 0; i < list.length; i++) { if (list[i][0] == player && list[i][1] == card.name) return true; } return false; }) ) return false; }, cardSavable: function (card, player) { if ( game.hasPlayer(function (current) { var list = current.storage.gongsun_shadow; if (!list) return false; for (var i = 0; i < list.length; i++) { if (list[i][0] == player && list[i][1] == card.name) return true; } return false; }) ) return false; }, cardRespondable: function (card, player) { if ( game.hasPlayer(function (current) { var list = current.storage.gongsun_shadow; if (!list) return false; for (var i = 0; i < list.length; i++) { if (list[i][0] == player && list[i][1] == card.name) return true; } return false; }) ) return false; }, cardDiscardable: function (card, player) { if ( game.hasPlayer(function (current) { var list = current.storage.gongsun_shadow; if (!list) return false; for (var i = 0; i < list.length; i++) { if (list[i][0] == player && list[i][1] == card.name) return true; } return false; }) ) return false; }, }, }, duoduan: { audio: 2, trigger: { target: "useCardToTargeted" }, direct: true, filter: function (event, player) { return event.card.name == "sha" && player.countCards("he") > 0 && !player.hasSkill("duoduan_im"); }, content: function () { "step 0"; player .chooseCard("he", get.prompt2("duoduan"), lib.filter.cardRecastable) .set("ai", function (card) { if (_status.event.goon) return 8 - get.value(card); return 0; }) .set( "goon", (function () { if (get.attitude(trigger.player, player) > 0) return true; if (!trigger.player.countCards("he")) return true; if (!player.hasShan()) return true; return event.getRand() < 0.5; })() ); "step 1"; if (result.bool) { player.addTempSkill("duoduan_im"); player.logSkill("duoduan", trigger.player); player.recast(result.cards); } else event.finish(); "step 2"; var sha = get.translation(trigger.card); if ( !trigger.player.countCards("he", function (card) { return lib.filter.cardDiscardable(card, trigger.player, "duoduan"); }) ) event.finish(); else player .chooseControl() .set("choiceList", ["令其摸两张牌,然后令" + sha + "对你无效", "令其弃置一张牌,然后你不可响应" + sha]) .set("prompt", "度断:令" + get.translation(trigger.player) + "执行一项") .set("ai", function () { var player = _status.event.player; var source = _status.event.getTrigger().player; if (get.attitude(player, source) > 0) return 0; if (!player.hasShan() && player.hp >= 2) return 1; return 0; }); "step 3"; if (result.index == 0) event.goto(5); else trigger.player.chooseToDiscard("弃置一张牌令" + get.translation(player) + "不能闪避此【杀】", "he", true); "step 4"; if (result.bool) { trigger.directHit.add(player); } event.finish(); "step 5"; trigger.player.draw(2); trigger.excluded.add(player); }, }, duoduan_im: { //'im' refers to 'Iwasawa Masami' in 'Angel Beats!' //Although she disappeared in the Episode 3 of the anime, but her route in the game is really worth to play. }, chengzhao: { audio: 2, trigger: { global: "phaseJieshuBegin" }, filter: function (event, player) { var num = 0; player.getHistory("gain", function (evt) { num += evt.cards.length; }); if (num < 2) return false; return ( player.countCards("h") > 0 && game.hasPlayer(function (current) { return player != current && player.canCompare(current); }) ); }, direct: true, content: function () { "step 0"; player .chooseTarget(get.prompt2("chengzhao"), function (card, player, target) { return player.canCompare(target); }) .set("ai", function (target) { return -get.attitude(_status.event.player, target) / target.countCards("h"); }); "step 1"; if (result.bool) { var target = result.targets[0]; event.target = target; player.logSkill("chengzhao", target); player.chooseToCompare(target); } else event.finish(); "step 2"; if (result.bool) { var card = { name: "sha", isCard: true }; if (player.canUse(card, target, false)) player.useCard(card, target, false).card.chengzhao = true; } }, ai: { unequip: true, skillTagFilter: function (player, tag, arg) { if (!arg || !arg.card || arg.card.chengzhao != true) return false; }, }, }, rezhengrong: { trigger: { player: "useCardAfter" }, direct: true, audio: "drlt_zhenrong", filter: function (event, player) { if (!event.targets) return false; if (!event.isPhaseUsing(player)) return false; var bool = false; for (var i = 0; i < event.targets.length; i++) { if (event.targets[i] != player) { bool = true; break; } } if (!bool) return false; return ( player .getAllHistory("useCard", function (evt) { if (!evt.isPhaseUsing(player)) return false; for (var i = 0; i < evt.targets.length; i++) { if (evt.targets[i] != player) return true; } return false; }) .indexOf(event) % 2 == 1 ); }, content: function () { "step 0"; player .chooseTarget(get.prompt("rezhengrong"), "将一名其他角色的随机一张牌置于你的武将牌上,成为「荣」", function (card, player, target) { return target != player && target.countCards("he") > 0; }) .set("ai", function (target) { return (1 - get.attitude(_status.event.player, target)) / target.countCards("he"); }); "step 1"; if (result.bool) { var target = result.targets[0]; event.target = result.targets[0]; player.logSkill("rezhengrong", target); var card = target.getCards("he").randomGet(); player.addToExpansion(card, target, "give").gaintag.add("rezhengrong"); } }, marktext: "荣", onremove: function (player, skill) { var cards = player.getExpansions(skill); if (cards.length) player.loseToDiscardpile(cards); }, intro: { content: "expansion", markcount: "expansion", }, }, rehongju: { trigger: { player: "phaseZhunbeiBegin" }, audio: "drlt_hongju", forced: true, unique: true, juexingji: true, skillAnimation: true, animationColor: "thunder", derivation: "reqingce", filter: function (event, player) { return player.getExpansions("rezhengrong").length >= 3 && game.dead.length > 0; }, content: function () { "step 0"; player.awakenSkill("rehongju"); player.draw(player.getExpansions("rezhengrong").length); "step 1"; if (player.countCards("h") == 0) event.goto(3); else { var dialog = ["请选择要交换的手牌和「荣」,或点「取消」", '
    「征荣」牌
    ', player.getExpansions("rezhengrong"), '
    手牌区
    ', player.getCards("h")]; var next = player.chooseButton(dialog); next.set("filterButton", function (button) { var ss = _status.event.player.getExpansions("rezhengrong"); var hs = _status.event.player.getCards("h"); var sn = 0; var hn = 0; var ub = ui.selected.buttons; for (var i = 0; i < ub.length; i++) { if (ss.includes(ub[i].link)) sn++; else hn++; } return !((sn >= hs.length && ss.includes(button.link)) || (hn >= ss.length && hs.includes(button.link))); }); next.set("selectButton", function () { if (ui.selected.buttons.length == 0) return 2; var ss = _status.event.player.getExpansions("rezhengrong"); var hs = _status.event.player.getCards("h"); var sn = 0; var hn = 0; var ub = ui.selected.buttons; for (var i = 0; i < ub.length; i++) { if (ss.includes(ub[i].link)) sn++; else hn++; } if (sn != hn) return 2 * Math.max(sn, hn); else { if (sn == ss.length || hn == hs.length || sn == hs.length || hn == ss.length) return ub.length; return [ub.length, ub.length + 1]; } }); next.set("ai", function () { return -1; }); } "step 2"; if (result.bool) { var gains = []; var pushs = []; var expansions = player.getExpansions("rezhengrong"); for (var i = 0; i < result.links.length; i++) { var card = result.links[i]; if (expansions.includes(card)) gains.push(card); else pushs.push(card); } player.addToExpansion(pushs, player, "give").gaintag.add("rezhengrong"); player.gain(gains, "gain2"); } "step 3"; player.addSkills("reqingce"); player.loseMaxHp(); }, ai: { combo: "rezhengrong", }, }, reqingce: { enable: "phaseUse", audio: "drlt_qingce", filter: function (event, player) { return player.getExpansions("rezhengrong").length > 0; }, chooseButton: { dialog: function (event, player) { return ui.create.dialog("请选择要移去的「荣」", player.getExpansions("rezhengrong"), "hidden"); }, backup: function (links, player) { return { card: links[0], filterCard: function () { return false; }, selectCard: -1, filterTarget: function (card, player, target) { return target.countDiscardableCards(player, "ej") > 0; }, delay: false, audio: "drlt_qingce", content: lib.skill.reqingce.contentx, ai: { result: { target: function (player, target) { var att = get.attitude(player, target); if ( att > 0 && (target.countCards("j") > 0 || target.countCards("e", function (card) { return get.value(card, target) < 0; })) ) return 2; if (att < 0 && target.countCards("e") > 0 && !target.hasSkillTag("noe")) return -1; return 0; }, }, }, }; }, prompt: function (links, player) { return "弃置一名角色装备区或判定区内的一张牌"; }, }, contentx: function () { "step 0"; var card = lib.skill.reqingce_backup.card; player.loseToDiscardpile(card); "step 1"; if (target.countDiscardableCards(player, "ej") > 0) { player.discardPlayerCard("ej", true, target); } }, ai: { combo: "rezhengrong", order: 8, result: { player: function (player) { if ( game.hasPlayer(function (current) { var att = get.attitude(player, current); if ((att > 0 && current.countCards("j") > 0) || (att < 0 && current.countCards("e") > 0)) return true; return false; }) ) return 1; return 0; }, }, }, }, fengji: { audio: 2, trigger: { player: "phaseZhunbeiBegin" }, forced: true, filter: function (event, player) { return typeof player.storage.fengji == "number" && player.countCards("h") >= player.storage.fengji; }, content: function () { player.draw(2); player.addTempSkill("fengji3"); }, group: "fengji2", intro: { content: "上回合结束时的手牌数:#", }, }, fengji2: { trigger: { player: "phaseEnd" }, silent: true, content: function () { player.storage.fengji = player.countCards("h"); if (player.hasSkill("fengji")) player.markSkill("fengji"); }, }, fengji3: { mod: { maxHandcardBase: function (player, num) { return player.maxHp; }, }, }, zhouxuan: { audio: 2, enable: "phaseUse", usable: 1, filter: function (event, player) { return player.countCards("he") > 0; }, filterCard: true, position: "he", filterTarget: lib.filter.notMe, check: function (card) { return 6 - get.value(card); }, content: function () { "step 0"; player.addSkill("zhouxuan2"); target.addTempSkill("zhouxuan_ai", { player: "phaseUseAfter" }); player.storage.zhouxuan2 = {}; player.storage.zhouxuan2.player = target; var list = []; var basic = []; for (var i = 0; i < lib.inpile.length; i++) { var name = lib.inpile[i]; var type = get.type(name, "trick"); if (type == "basic") { list.push(name); basic.push(name); } else list.add(type); } event.basic = basic; player .chooseControl(list) .set("prompt", "请选择一种基本牌的名称或非基本牌的类别") .set("ai", function () { var player = _status.event.player; var target = player.storage.zhouxuan2.player; var cards = target.getCards("h", function (card) { return target.hasUseTarget(card); }); var map = {}; for (var i = 0; i < cards.length; i++) { var type = get.type(cards[i], "trick"); map[type == "basic" ? get.name(cards[i]) : type] = true; } if (map.equip) return "equip"; if (map.trick) return "trick"; if (map.sha) return "sha"; if (map.tao) return "tao"; return 0; }); "step 1"; player.storage.zhouxuan2.card = result.control; if (event.basic.includes(result.control)) player.storage.zhouxuan2.isbasic = true; player.markSkill("zhouxuan2"); }, ai: { order: 1, result: { player: function (player, target) { if (get.attitude(player, target) > 0) return ( Math.max(1, target.hp) * target.countCards("h", function (card) { return target.getUseValue(card) > 0; }) ); return 0; }, }, }, }, zhouxuan_ai: { mod: { aiOrder: function (player, card, num) { if ( game.hasPlayer(function (current) { return current.storage.zhouxuan2 && current.storage.zhouxuan2.player == player && get.attitude(player, current) > 0 && (current.storage.zhouxuan2.isbasic ? card.name : get.type(card, "trick")) == current.storage.zhouxuan2.card; }) ) return num + 10; }, }, }, zhouxuan2: { intro: { mark: function (player, storage) { return get.translation(storage.player) + "使用或打出下一张牌时,若此牌为" + get.translation(storage.card) + (storage.isbasic ? "" : "牌") + ",你观看牌堆顶的三张牌并分配给任意角色"; }, }, audio: "zhouxuan", forced: true, charlotte: true, trigger: { global: ["useCard", "respond"] }, filter: function (event, player) { if (event.zhouxuanable) return true; if (player.storage.zhouxuan2) { var map = player.storage.zhouxuan2; if (map.player != event.player) return false; delete player.storage.zhouxuan2; player.unmarkSkill("zhouxuan2"); if (map.card != (map.isbasic ? event.card.name : get.type(event.card, "trick"))) return false; event.zhouxuanable = true; return true; } return false; }, logTarget: "player", content: function () { "step 0"; event.cards = game.cardsGotoOrdering(get.cards(3)).cards; if (_status.connectMode) game.broadcastAll(function () { _status.noclearcountdown = true; }); event.given_map = {}; "step 1"; if (event.cards.length > 1) { player.chooseCardButton("周旋:请选择要分配的牌", true, event.cards, [1, event.cards.length]).set("ai", function (button) { if (ui.selected.buttons.length == 0) return 1; return 0; }); } else if (event.cards.length == 1) { event._result = { links: event.cards.slice(0), bool: true }; } else { event.finish(); } "step 2"; if (result.bool) { event.cards.removeArray(result.links); event.togive = result.links.slice(0); player .chooseTarget("选择一名角色获得" + get.translation(result.links), true) .set("ai", function (target) { var 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("enemy", get.value(event.togive[0], player, "raw") < 0); } "step 3"; if (result.targets.length) { var id = result.targets[0].playerid, map = event.given_map; if (!map[id]) map[id] = []; map[id].addArray(event.togive); } if (cards.length > 0) event.goto(1); "step 4"; if (_status.connectMode) { game.broadcastAll(function () { delete _status.noclearcountdown; game.stopCountChoose(); }); } var list = []; for (var i in event.given_map) { var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i]; player.line(source, "green"); list.push([source, event.given_map[i]]); } game.loseAsync({ gain_list: list, giver: player, animate: "draw", }).setContent("gaincardMultiple"); }, }, reshanxi: { audio: "shanxi", trigger: { player: "phaseUseBegin" }, direct: true, filter: function (event, player) { return ( player.hp > 0 && player.countCards("h", function (card) { if (_status.connectMode) return true; return get.color(card) == "red" && get.type(card) == "basic"; }) > 0 ); }, content: function () { "step 0"; player.chooseCardTarget({ filterCard: function (card) { return get.color(card) == "red" && get.type(card) == "basic" && lib.filter.cardDiscardable.apply(this, arguments); }, filterTarget: function (card, player, target) { return player != target && target.countCards("he") > 0; }, prompt: get.prompt("reshanxi"), prompt2: "弃置一张红色基本牌并选择一名其他角色,将其的至多X张牌置于其武将牌上直到回合结束。(X为你的体力值)", ai1: function () { return -1; }, }); "step 1"; if (result.bool) { event.target = result.targets[0]; player.logSkill("reshanxi", event.target); player.discard(result.cards); } else event.finish(); "step 2"; var max = Math.min(player.hp, target.countCards("he")); if (max > 0 && target.isIn()) { player .choosePlayerCard("he", target, true, [1, max]) .set("forceAuto", true) .set("prompt", "将" + get.translation(target) + "的至多" + get.cnNumber(max) + "张牌置于其武将牌上"); } else event.finish(); "step 3"; target.addSkill("reshanxi2"); target.addToExpansion(result.cards, "giveAuto", target).gaintag.add("reshanxi2"); }, }, reshanxi2: { trigger: { global: "phaseEnd" }, forced: true, popup: false, charlotte: true, onremove: function (player, skill) { var cards = player.getExpansions(skill); if (cards.length) player.loseToDiscardpile(cards); }, content: function () { "step 0"; var cards = player.getExpansions("reshanxi2"); if (cards.length) player.gain(cards, "draw"); "step 1"; player.removeSkill("reshanxi2"); }, intro: { markcount: "expansion", mark: function (dialog, storage, player) { var cards = player.getExpansions("reshanxi2"); if (player.isUnderControl(true)) dialog.addAuto(cards); else return "共有" + get.cnNumber(cards.length) + "张牌"; }, }, }, reqizhou: { trigger: { player: ["equipEnd", "loseEnd"] }, forced: true, popup: false, derivation: ["reyingzi", "qixi", "rexuanfeng"], filter: function (event, player) { if (player.equiping) return false; var suits = []; var es = player.getCards("e"); for (var i = 0; i < es.length; i++) { suits.add(get.suit(es[i])); } if (suits.length > 3) suits.length = 3; if (player.additionalSkills.reqizhou) { return player.additionalSkills.reqizhou.length != suits.length; } else { return suits.length > 0; } }, content: function () { lib.skill.reqizhou.init(player, "reqizhou"); }, init: function (player, skill) { var suits = []; var es = player.getCards("e"); for (var i = 0; i < es.length; i++) { suits.add(get.suit(es[i])); } if (suits.length > 3) suits.length = 3; player.removeAdditionalSkill(skill); switch (suits.length) { case 1: player.addAdditionalSkill(skill, ["reyingzi"]); break; case 2: player.addAdditionalSkill(skill, ["reyingzi", "qixi"]); break; case 3: player.addAdditionalSkill(skill, ["reyingzi", "qixi", "rexuanfeng"]); break; } }, ai: { threaten: 1.2, }, }, zhaohan: { audio: 2, trigger: { player: "phaseZhunbeiBegin" }, forced: true, filter: function (event, player) { return player.phaseNumber < 8; }, check: function (event, player) { return player.phaseNumber < 3; }, content: function () { if (player.phaseNumber < 5) { player.gainMaxHp(); player.recover(); } else player.loseMaxHp(); }, }, rangjie: { audio: 2, trigger: { player: "damageEnd" }, direct: true, content: function () { "step 0"; event.count = trigger.num; "step 1"; event.count--; var choiceList = ["获得一张指定类型的牌"]; if (player.canMoveCard()) choiceList.push("移动场上的一张牌"); player .chooseControl("cancel2") .set("choiceList", choiceList) .set("prompt", get.prompt("rangjie")) .set("ai", function () { var player = _status.event.player; if (player.canMoveCard(true)) return 1; return 0; }); "step 2"; if (result.control == "cancel2") event.finish(); else { player.logSkill("rangjie"); player.draw(); if (result.index == 0) { player .chooseControl("basic", "trick", "equip") .set("prompt", "选择获得一种类型的牌") .set("ai", function () { var player = _status.event.player; if (player.hp <= 3 && !player.countCards("h", { name: ["shan", "tao"] })) return "basic"; if (player.countCards("he", { type: "equip" }) < 2) return "equip"; return "trick"; }); } else { player.moveCard(true); event.goto(4); } } "step 3"; var card = get.cardPile2(function (card) { return get.type(card, "trick") == result.control; }); if (card) player.gain(card, "gain2", "log"); "step 4"; if (event.count > 0 && player.hasSkill("rangjie")) event.goto(1); }, ai: { maixie: true, maixie_hp: true, effect: { target: function (card, player, target) { if (get.tag(card, "damage")) { if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; if (!target.hasFriend()) return; var num = 1; if (get.attitude(player, target) > 0) { if (player.needsToDiscard()) num = 0.7; else num = 0.5; } if (target.hp >= 4) return [1, num * 2]; if (target.hp == 3) return [1, num * 1.5]; if (target.hp == 2) return [1, num * 0.5]; } }, }, }, }, yizheng: { audio: 2, enable: "phaseUse", usable: 1, filter: function (event, player) { return game.hasPlayer(function (current) { return current.hp <= player.hp && player.canCompare(current); }); }, filterTarget: function (card, player, current) { return current.hp <= player.hp && player.canCompare(current); }, content: function () { "step 0"; player.chooseToCompare(target); "step 1"; if (result.bool) { target.skip("phaseDraw"); target.addTempSkill("yizheng2", { player: "phaseDrawSkipped" }); } else player.loseMaxHp(); }, ai: { order: 1, result: { player: (player, target) => { let hs = player.getCards("h").sort(function (a, b) { return get.number(b) - get.number(a); }); if (!hs.length) return 0; let a = get.number(hs[0]), b = 4; if (player.getDamagedHp()) b = 2; return -b * (1 - Math.pow((a - 1) / 13, target.countCards("h"))); }, target: (player, target) => { if (target.skipList.includes("phaseDraw") || target.hasSkill("pingkou") || target.hasSkill("xinpingkou")) return 0; let hs = player.getCards("h").sort(function (a, b) { return get.number(b) - get.number(a); }); if (!hs.length) return 0; return -Math.pow((get.number(hs[0]) - 1) / 13, target.countCards("h")) * 2; }, }, }, }, yizheng2: { mark: true, intro: { content: "跳过下回合的摸牌阶段" }, }, rw_zhuge_skill: { equipSkill: true, audio: true, firstDo: true, trigger: { player: "useCard1" }, forced: true, filter: function (event, player) { return !event.audioed && event.card.name == "sha" && player.countUsed("sha", true) > 1 && event.getParent().type == "phase"; }, content: function () { trigger.audioed = true; }, mod: { cardUsable: function (card, player, num) { var cards = player.getEquips("rewrite_zhuge"); if (card.name == "sha") { if (!cards.length || player.hasSkill("rw_zhuge_skill", null, false) || cards.some(card => card != _status.rw_zhuge_temp && !ui.selected.cards.includes(card))) { if (get.is.versus() || get.is.changban()) { return num + 3; } return Infinity; } } }, cardEnabled2: function (card, player) { if (!_status.event.addCount_extra || player.hasSkill("rw_zhuge_skill", null, false)) return; var cards = player.getEquips("rewrite_zhuge"); if (card && cards.includes(card)) { try { var cardz = get.card(); } catch (e) { return; } if (!cardz || cardz.name != "sha") return; _status.rw_zhuge_temp = card; var bool = lib.filter.cardUsable(get.autoViewAs({ name: "sha" }, ui.selected.cards.concat([card])), player); delete _status.rw_zhuge_temp; if (!bool) return false; } }, }, }, xinqingjian: { audio: "qingjian", trigger: { player: "gainAfter", global: "loseAsyncAfter", }, direct: true, usable: 1, filter: function (event, player) { return event.getg(player).length && event.getParent("phaseDraw").player != player && player.countCards("he") > 0; }, content: function () { "step 0"; player.chooseCard(get.prompt2("xinqingjian"), "he", [1, player.countCards("he")]).ai = function () { return -1; }; "step 1"; if (result.bool) { player.logSkill("xinqingjian"); player.addSkill("xinqingjian2"); player.addToExpansion(result.cards, "giveAuto", player).gaintag.add("xinqingjian2"); } else player.storage.counttrigger.xinqingjian--; }, }, xinqingjian2: { audio: "xinqingjian", charlotte: true, trigger: { global: "phaseEnd" }, forced: true, filter: function (event, player) { return player.getExpansions("xinqingjian2").length > 0; }, onremove: function (player, skill) { var cards = player.getExpansions(skill); if (cards.length) player.loseToDiscardpile(cards); }, content: function () { "step 0"; var cards = player.getExpansions("xinqingjian2"); player.chooseTarget(true, lib.filter.notMe).set("createDialog", ["清俭:将这些牌交给一名角色" + (cards.length > 1 ? ",然后摸一张牌" : ""), cards]); "step 1"; if (result.bool) { var target = result.targets[0]; player.line(target, "thunder"); if (player.give(player.getExpansions("xinqingjian2"), target).cards.length > 1) player.draw(); } "step 2"; player.removeSkill("xinqingjian2"); }, intro: { markcount: "expansion", mark: function (dialog, storage, player) { var cards = player.getExpansions("xinqingjian2"); if (player.isUnderControl(true)) dialog.addAuto(cards); else return "共有" + get.cnNumber(cards.length) + "张牌"; }, }, }, zhongzuo: { audio: 2, trigger: { global: "phaseJieshuBegin" }, direct: true, filter: function (event, player) { return player.getHistory("damage").length > 0 || player.getHistory("sourceDamage").length > 0; }, content: function () { "step 0"; player.chooseTarget(get.prompt("zhongzuo"), "令一名角色摸两张牌。若其已受伤,则你摸一张牌。").set("ai", function (target) { if (target.hasSkillTag("nogain")) return target.isDamaged() ? 0 : 1; let att = get.attitude(_status.event.player, target); if (att <= 0) return 0; if (target.isDamaged()) return 1 + att / 5; return att / 5; }); "step 1"; if (result.bool) { var target = result.targets[0]; player.logSkill("zhongzuo", target); target.draw(2); if (target.isDamaged()) player.draw(); } }, }, wanlan: { audio: 2, trigger: { global: "dying" }, check: function (event, player) { if (get.attitude(player, event.player) < 4) return false; if (player.countCards("hs", card => player.canSaveCard(card, event.player)) >= 1 - event.player.hp) return false; if (event.player == player || event.player == get.zhu(player)) return true; if (_status.currentPhase && get.damageEffect(_status.currentPhase, player, player) < 0) return false; return !player.hasUnknown(); }, limited: true, unique: true, filter: function (event, player) { return event.player.hp <= 0; }, skillAnimation: true, animationColor: "thunder", logTarget: "player", content: function () { "step 0"; player.awakenSkill("wanlan"); var hs = player.getCards("h"); if (hs.length) player.discard(hs); "step 1"; var num = 1 - trigger.player.hp; if (num) trigger.player.recover(num); "step 2"; if (_status.currentPhase && _status.currentPhase.isIn()) { var next = _status.currentPhase.damage(); event.next.remove(next); trigger.after.push(next); } }, }, rezhiyi: { audio: "zhiyi", trigger: { global: "phaseJieshuBegin" }, forced: true, filter: function (event, player) { return ( player.getHistory("useCard", function (card) { return get.type(card.card) == "basic"; }).length > 0 || player.getHistory("respond", function (card) { return get.type(card.card) == "basic"; }).length > 0 ); }, content: function () { "step 0"; var list = []; player.getHistory("useCard", function (evt) { if (get.type(evt.card) != "basic") return; var name = evt.card.name; if (name == "sha") { var nature = evt.card.nature; switch (nature) { case "fire": name = "huosha"; break; case "thunder": name = "leisha"; break; case "kami": name = "kamisha"; break; case "ice": name = "icesha"; break; case "stab": name = "cisha"; break; } } list.add(name); }); player.getHistory("respond", function (evt) { if (get.type(evt.card) != "basic") return; var name = evt.card.name; if (name == "sha") { var nature = evt.card.nature; switch (nature) { case "fire": name = "huosha"; break; case "thunder": name = "leisha"; break; case "kami": name = "kamisha"; break; case "ice": name = "icesha"; break; case "stab": name = "cisha"; break; } } list.add(name); }); player.chooseButton( [ "执义:选择要使用的牌,或点取消摸一张牌", [ list.map(function (name) { return ["基本", "", name]; }), "vcard", ], ], function (button) { return _status.event.player.getUseValue({ name: button.link[2], nature: button.link[3], }); }, function (button) { return _status.event.player.hasUseTarget({ name: button.link[2], nature: button.link[3], }); } ); "step 1"; if (!result.bool) player.draw(); else player.chooseUseTarget({ name: result.links[0][2], isCard: true, nature: result.links[0][3] }, true); }, }, zhiyi: { audio: 2, trigger: { player: ["useCard", "respond"] }, forced: true, filter: function (event, player) { if (get.type(event.card) != "basic") return false; var history = player .getHistory("useCard", function (evt) { return get.type(evt.card) == "basic"; }) .concat( player.getHistory("respond", function (evt) { return get.type(evt.card) == "basic"; }) ); return history.length == 1 && history[0] == event; }, content: function () { "step 0"; var info = get.info(trigger.card); if (!info || !info.enable) event._result = { index: 0 }; else { var evt = trigger; if (evt.respondTo && evt.getParent("useCard").name == "useCard") evt = evt.getParent("useCard"); event.evt = evt; player .chooseControl() .set("prompt", "执义:请选择一项") .set("choiceList", [ "摸一张牌", "于" + get.translation(evt.card) + "的使用结算结束之后视为使用一张" + get.translation({ name: trigger.card.name, nature: trigger.card.nature, isCard: true, }), ]) .set("ai", function () { return _status.event.choice; }) .set( "choice", (function () { var card = { name: trigger.card.name, nature: trigger.card.nature, isCard: true, }; if (card.name == "sha") { if (player.getUseValue(card) > 0) return 1; } else if (card.name == "tao") { var hp = player.maxHp - player.hp; if (trigger.targets.includes(player)) hp--; return hp > 0 ? 1 : 0; } return 0; })() ); } "step 1"; if (result.index == 0) { player.draw(); } else { var next = player.chooseUseTarget({ name: trigger.card.name, nature: trigger.card.nature, isCard: true }, false, true); _status.event.next.remove(next); event.evt.after.push(next); next.logSkill = "zhiyi"; } }, }, //表演测试 qiaosi_map: { charlotte: true }, qiaosi: { audio: "xinfu_qiaosi", derivation: "qiaosi_map", enable: "phaseUse", usable: 1, content: function () { "step 0"; event.videoId = lib.status.videoId++; if (player.isUnderControl()) { game.swapPlayerAuto(player); } var switchToAuto = function () { game.pause(); game.countChoose(); setTimeout(function () { _status.imchoosing = false; event._result = { bool: true, links: ["qiaosi_c1", "qiaosi_c6"].concat(["qiaosi_c2", "qiaosi_c3", "qiaosi_c4", "qiaosi_c5"].randomGets(1)), }; if (event.dialog) event.dialog.close(); if (event.controls) { for (var i of event.controls) i.close(); } game.resume(); }, 5000); }; var createDialog = function (player, id) { if (player == game.me) return; var str = get.translation(player) + "正在表演...
    "; for (var i = 1; i < 7; i++) { str += get.translation("qiaosi_c" + i); if (i % 3 != 0) str += "  "; if (i == 3) str += "
    "; } ui.create.dialog(str, "forcebutton").videoId = id; }; var chooseButton = function (player) { var event = _status.event; player = player || event.player; event.status = { qiaosi_c1: 0, qiaosi_c2: 0, qiaosi_c3: 0, qiaosi_c4: 0, qiaosi_c5: 0, qiaosi_c6: 0, }; event.map = { qiaosi_c1: [40, 60], qiaosi_c2: [80, 120], qiaosi_c3: [90, 110], qiaosi_c4: [90, 110], qiaosi_c5: [80, 120], qiaosi_c6: [40, 60], }; event.finishedx = []; event.str = '请开始你的表演
    qiaosi_c1% qiaosi_c2% qiaosi_c3%
    qiaosi_c4%qiaosi_c5% qiaosi_c6%'; event.dialog = ui.create.dialog(event.str, "forcebutton", "hidden"); event.dialog.addText("
  • 点击下方的按钮,可以增加按钮对应的角色的「表演完成度」。对于不同的角色,点击时增加的完成度不同,最终获得的牌也不同。一次表演最多只能完成3名角色的进度。", false); event.dialog.open(); for (var i in event.status) { event.dialog.content.childNodes[0].innerHTML = event.dialog.content.childNodes[0].innerHTML.replace(i, event.status[i]); } for (var i = 0; i < event.dialog.buttons.length; i++) { event.dialog.buttons[i].classList.add("pointerdiv"); } (event.switchToAuto = function () { event._result = { bool: true, links: event.finishedx.slice(0), }; event.dialog.close(); for (var i of event.controls) i.close(); game.resume(); _status.imchoosing = false; }), (event.controls = []); for (var i = 1; i <= 6; i++) event.controls.push( ui.create.control("qiaosi_c" + i, function (link) { var event = _status.event; if (event.finishedx.includes(link)) return; event.status[link] += get.rand.apply(get, event.map[link]); if (event.status[link] >= 100) { event.status[link] = 100; var str = event.str.slice(0); for (var i in event.status) { str = str.replace(i, event.status[i]); } event.dialog.content.childNodes[0].innerHTML = str; event.finishedx.push(link); if (event.finishedx.length >= 3) { event._result = { bool: true, links: event.finishedx.slice(0), }; event.dialog.close(); for (var i of event.controls) i.close(); game.resume(); _status.imchoosing = false; } } else { var str = event.str.slice(0); for (var i in event.status) { str = str.replace(i, event.status[i]); } event.dialog.content.childNodes[0].innerHTML = str; } }) ); for (var i = 0; i < event.dialog.buttons.length; i++) { event.dialog.buttons[i].classList.add("selectable"); } game.pause(); game.countChoose(); }; //event.switchToAuto=switchToAuto; game.broadcastAll(createDialog, player, event.videoId); if (event.isMine()) { chooseButton(); } else if (event.isOnline()) { event.player.send(chooseButton, event.player); event.player.wait(); game.pause(); } else { switchToAuto(); } "step 1"; game.broadcastAll("closeDialog", event.videoId); var map = event.result || result; //game.print(map); if (!map || !map.bool || !map.links) { game.log(player, "表演失败"); event.finish(); return; } var list = map.links; if (!list.length) { game.log(player, "表演失败"); event.finish(); return; } var cards = []; var list2 = []; if (list.includes("qiaosi_c1")) { list2.push("trick"); list2.push("trick"); } if (list.includes("qiaosi_c2")) { if (list.includes("qiaosi_c1")) list2.push(["sha", "jiu"]); else list2.push(Math.random() < 0.66 ? "equip" : ["sha", "jiu"]); } if (list.includes("qiaosi_c3")) { list2.push([Math.random() < 0.66 ? "sha" : "jiu"]); } if (list.includes("qiaosi_c4")) { list2.push([Math.random() < 0.66 ? "shan" : "tao"]); } if (list.includes("qiaosi_c5")) { if (list.includes("qiaosi_c6")) list2.push(["shan", "tao"]); else list2.push(Math.random() < 0.66 ? "trick" : ["shan", "tao"]); } if (list.includes("qiaosi_c6")) { list2.push("equip"); list2.push("equip"); } while (list2.length) { var filter = list2.shift(); var card = get.cardPile(function (x) { if (cards.includes(x)) return false; if (typeof filter == "string" && get.type(x, "trick") == filter) return true; if (typeof filter == "object" && filter.includes(x.name)) return true; }); if (card) cards.push(card); else { var card = get.cardPile(function (x) { return !cards.includes(x); }); if (card) cards.push(card); } } if (cards.length) { event.cards = cards; event.num = cards.length; player.showCards(cards); } else event.finish(); "step 2"; player.gain(event.cards, "gain2"); "step 3" if (!player.countCards("he")) event.finish(); else player.chooseControl().set("choiceList", ["将" + get.cnNumber(event.num) + "张牌交给一名其他角色", "弃置" + get.cnNumber(event.num) + "张牌"]).set("ai", function () { if (game.hasPlayer(function (current) { return current != player && get.attitude(player, current) > 2; })) return 0; return 1; }); "step 4"; if (result.index == 0) { player.chooseCardTarget({ position: "he", filterCard: true, selectCard: Math.min(event.num, player.countCards("he")), filterTarget: function (card, player, target) { return player != target; }, ai1: function (card) { return 1; }, ai2: function (target) { var att = get.attitude(_status.event.player, target); if (target.hasSkillTag("nogain")) att /= 10; if (target.hasJudge("lebu")) att /= 5; return att; }, prompt: "选择" + get.cnNumber(event.num) + "张牌,交给一名其他角色。", forced: true, }); } else { player.chooseToDiscard(event.num, true, "he"); event.finish(); } "step 5"; if (result.bool) { var target = result.targets[0]; player.give(result.cards, target); } }, ai: { order: 10, result: { player: 1 }, threaten: 3.2, }, }, refuhai: { audio: "xinfu_fuhai", enable: "phaseUse", usable: 1, content: function () { "step 0"; event.current = player.next; event.upper = []; event.lower = []; event.acted = []; event.num = 0; event.stopped = false; "step 1"; event.acted.push(event.current); event.current.chooseControl("潮起", "潮落").set("prompt", "潮鸣起乎?潮鸣落乎?").ai = function () { return Math.random() < 0.5 ? 0 : 1; }; "step 2"; if (!event.chosen) event.chosen = result.control; if (event.chosen != result.control) event.stopped = true; if (!event.stopped) event.num++; if (result.control == "潮起") { event.upper.push(event.current); } else event.lower.push(event.current); event.current = event.current.next; if (event.current != player && !event.acted.includes(event.current)) event.goto(1); "step 3"; for (var i = 0; i < event.acted.length; i++) { var bool = event.upper.includes(event.acted[i]); game.log(event.acted[i], "选择了", bool ? "#g潮起" : "#y潮落"); event.acted[i].popup(bool ? "潮起" : "潮落", bool ? "wood" : "orange"); } game.delay(1); "step 4"; if (num > 1) player.draw(num); }, ai: { order: 10, result: { player: 1 }, }, }, rebiaozhao: { audio: "biaozhao", intro: { content: "expansion", markcount: "expansion", }, trigger: { player: "phaseJieshuBegin", }, direct: true, filter: function (event, player) { return player.countCards("he") > 0 && !player.getExpansions("rebiaozhao").length; }, content: function () { "step 0"; player.chooseCard("he", get.prompt("rebiaozhao"), "将一张牌置于武将牌上作为“表”").ai = function (card) { return 6 - get.value(card); }; "step 1"; if (result.bool) { player.logSkill("rebiaozhao"); player.addToExpansion(player, "give", result.cards).gaintag.add("rebiaozhao"); } }, onremove: function (player, skill) { var cards = player.getExpansions(skill); if (cards.length) player.loseToDiscardpile(cards); }, ai: { notemp: true }, group: ["rebiaozhao2", "rebiaozhao3"], }, rebiaozhao2: { trigger: { global: ["loseAfter", "cardsDiscardAfter", "loseAsyncAfter", "equipAfter"], }, forced: true, audio: "biaozhao", filter: function (event, player) { var cards = player.getExpansions("rebiaozhao"), cards2 = event.getd(); if (!cards.length || !cards2.length) return false; var num = get.number(cards[0]); var cards = event.getd(); for (var card of cards) { if (get.number(card) == num) return true; } return false; }, content: function () { player.loseToDiscardpile(player.getExpansions("rebiaozhao")); player.loseHp(); }, }, rebiaozhao3: { trigger: { player: "phaseZhunbeiBegin", }, forced: true, charlotte: true, audio: "biaozhao", filter: function (event, player) { return player.getExpansions("rebiaozhao").length > 0; }, content: function () { "step 0"; player.loseToDiscardpile(player.getExpansions("rebiaozhao")); "step 1"; player.chooseTarget("令一名角色摸三张牌并回复1点体力", true).ai = function (target) { var num = 2; if (target.isDamaged()) num++; return num * get.attitude(_status.event.player, target); }; "step 2"; if (result.bool) { var target = result.targets[0]; player.line(target, "green"); target.draw(3); target.recover(); } }, }, reqianxin: { audio: "xinfu_qianxin", enable: "phaseUse", usable: 1, filterCard: true, selectCard: function () { return [1, Math.min(2, game.players.length - 1)]; }, check: function (card) { return 6 - get.value(card); }, discard: false, lose: false, delay: false, content: function () { var targets = game .filterPlayer(function (current) { return current != player; }) .randomGets(cards.length); var map = []; for (var i = 0; i < targets.length; i++) { var target = targets[i]; target.addSkill("reqianxin2"); target.storage.reqianxin2.push([cards[i], player]); map.push([target, cards[i]]); } game.loseAsync({ gain_list: map, player: player, cards: cards, giver: player, animate: "giveAuto", }).setContent("gaincardMultiple"); }, ai: { order: 1, result: { player: 1, }, }, }, reqianxin2: { trigger: { player: "phaseZhunbeiBegin" }, forced: true, popup: false, charlotte: true, init: function (player, skill) { if (!player.storage[skill]) player.storage[skill] = []; }, onremove: true, filter: function (event, player) { var list = player.storage.reqianxin2; if (Array.isArray(list)) { var hs = player.getCards("h"); for (var i = 0; i < list.length; i++) { if (hs.includes(list[i][0]) && list[i][1].isIn()) return true; } } return false; }, content: function () { "step 0"; var current = player.storage.reqianxin2.shift(); event.source = current[1]; if (!event.source.isIn() || !player.getCards("h").includes(current[0])) event.goto(3); "step 1"; source.logSkill("reqianxin", player); player .chooseControl() .set("choiceList", ["令" + get.translation(source) + "摸两张牌", "令自己本回合的手牌上限-2"]) .set("prompt", get.translation(source) + "发动了【遣信】,请选择一项") .set("source", source) .set("ai", function () { var player = _status.event.player; if (get.attitude(player, _status.event.source) > 0) return 0; if (player.maxHp - player.countCards("h") > 1) return 1; return Math.random() > 0.5 ? 0 : 1; }); "step 2"; if (result.index == 0) source.draw(2); else { player.addTempSkill("reqianxin3"); player.addMark("reqianxin3", 2, false); } "step 3"; if (player.storage.reqianxin2.length) event.goto(0); else player.removeSkill("reqianxin2"); }, }, reqianxin3: { onremove: true, mod: { maxHandcard: function (player, num) { return num - player.countMark("reqianxin3"); }, }, }, renshi: { audio: 2, trigger: { player: "damageBegin4" }, forced: true, filter: function (event, player) { return player.isDamaged() && event.card && event.card.name == "sha"; }, content: function () { "step 0"; trigger.cancel(); if (trigger.cards) { var cards = trigger.cards.filterInD(); if (cards.length) player.gain(cards, "gain2", "log"); } "step 1"; player.loseMaxHp(); }, ai: { halfneg: true, filterDamage: true, skillTagFilter: function (player, tag, arg) { if (arg && arg.card && arg.card.name == "sha") return true; return false; }, }, }, wuyuan: { audio: 2, enable: "phaseUse", usable: 1, filter: function (event, player) { return player.countCards("h", "sha") > 0; }, filterCard: { name: "sha" }, filterTarget: lib.filter.notMe, check: function (card) { var player = _status.event.player; if ( get.color(card) == "red" && game.hasPlayer(function (current) { return current != player && current.isDamaged() && get.attitude(player, current) > 2; }) ) return 2; if (get.natureList(card).length) return 1.5; return 1; }, discard: false, lose: false, delay: false, content: function () { "step 0"; player.give(cards, target, "give"); player.recover(); "step 1"; var num = 1; if (get.natureList(cards[0]).length) num++; target.draw(num); if (get.color(cards[0]) == "red") target.recover(); }, ai: { order: 1, result: { player: function (player, target) { if (player.isDamaged()) return 1; return 0; }, target: function (player, target) { if (ui.selected.cards.length) { var num = 1; if (get.natureList(ui.selected.cards[0]).length) num++; if (target.hasSkillTag("nogain")) num = 0; if (get.color(ui.selected.cards[0]) == "red") return num + 2; else return num + 1; } return 1; }, }, }, }, huaizi: { mod: { maxHandcardBase: function (player, num) { return player.maxHp; }, }, //audio:2, //trigger:{player:'phaseDiscardBegin'}, forced: true, firstDo: true, filter: function (event, player) { return player.isDamaged() && player.countCards("h") > player.hp; }, content: function () {}, }, rexushen: { derivation: ["new_rewusheng", "redangxian"], audio: "xinfu_xushen", limited: true, enable: "phaseUse", filter: function (event, player) { return game.hasPlayer(function (current) { return current.hasSex("male"); }); }, skillAnimation: true, animationColor: "fire", content: function () { player.addSkill("rexushen2"); player.awakenSkill("rexushen"); player.loseHp( game.countPlayer(function (current) { return current.hasSex("male"); }) ); }, ai: { order: 10, result: { player: function (player) { if ( player.hp != game.countPlayer(function (current) { return current.hasSex("male"); }) ) return 0; return game.hasPlayer(function (current) { return get.attitude(player, current) > 4 && current.countCards("h", "tao"); }) ? 1 : 0; }, }, }, }, rexushen2: { charlotte: true, subSkill: { count: { trigger: { player: "recoverBegin", }, forced: true, silent: true, popup: false, filter: function (event, player) { if (!event.source) return false; if (!player.isDying()) return false; var evt = event.getParent("dying").getParent(2); return evt.name == "rexushen" && evt.player == player; }, content: function () { trigger.rexushen = true; }, sub: true, }, }, group: ["rexushen2_count"], trigger: { player: "recoverAfter", }, filter: function (event, player) { if (player.isDying()) return false; return event.rexushen == true; }, direct: true, silent: true, popup: false, content: function () { "step 0"; player.removeSkill("rexushen2"); player.chooseBool("是否令" + get.translation(trigger.source) + "获得技能〖武圣〗和〖当先〗").ai = function () { return get.attitude(player, trigger.source) > 0; }; "step 1"; if (result.bool) { player.line(trigger.source, "fire"); trigger.source.addSkills(["new_rewusheng", "redangxian"]); } }, }, rezhennan: { audio: "xinfu_zhennan", trigger: { target: "useCardToTargeted" }, filter: function (event, player) { return event.player != player && event.targets && event.targets.length && event.targets.length > event.player.hp; }, direct: true, content: function () { "step 0"; var next = player.chooseToDiscard(get.prompt("rezhennan", trigger.player), "弃置一张牌并对其造成1点伤害", "he"); next.set("logSkill", ["rezhennan", trigger.player]); next.set("ai", function (card) { var player = _status.event.player; var target = _status.event.getTrigger().player; if (get.damageEffect(target, player, player) > 0) return 7 - get.value(card); return -1; }); "step 1"; if (result.bool) trigger.player.damage(); }, }, meiyong: { inherit: "xinfu_wuniang", audio: "xinfu_wuniang", content: function () { "step 0"; player .chooseTarget(get.prompt("meiyong"), "获得一名其他角色的一张牌,然后其摸一张牌。", function (card, player, target) { if (player == target) return false; return target.countGainableCards(player, "he") > 0; }) .set("ai", function (target) { return 10 - get.attitude(_status.event.player, target); }); "step 1"; if (result.bool) { var target = result.targets[0]; event.target = target; player.logSkill("meiyong", target); player.gainPlayerCard(target, "he", true); } else event.finish(); "step 2"; target.draw(); }, }, relianji: { audio: "wylianji", enable: "phaseUse", usable: 1, filter: function (event, player) { return game.players.length > 1; }, filterTarget: lib.filter.notMe, targetprompt: ["打人", "被打"], selectTarget: 2, multitarget: true, content: function () { "step 0"; game.delay(0.5); if (!targets[0].hasEquipableSlot(1)) event.goto(2); "step 1"; var target = targets[0]; var equip1 = get.cardPile2(function (card) { return get.subtype(card) == "equip1" && target.canUse(card, target); }); if (!equip1) { player.popup("连计失败"); game.log("牌堆中无装备"); event.finish(); return; } if (equip1.name == "qinggang" && !lib.inpile.includes("qibaodao")) { equip1.remove(); equip1 = game.createCard("qibaodao", equip1.suit, equip1.number); } target.$draw(equip1); target.chooseUseTarget(equip1, "noanimate", "nopopup", true); "step 2"; game.updateRoundNumber(); var list = ["nanman", "wanjian", "huogong", "juedou", "sha"]; var list2 = game.players.slice(0); list2.remove(player); for (var i = 0; i < list.length; i++) { if (!targets[0].canUse(list[i], targets[1], false)) list.splice(i--, 1); } if (!list.length) return; var name = list.randomGet(); if (name == "nanman" || name == "wanjian") { for (var i = 0; i < list2.length; i++) { if (!targets[0].canUse(name, list2[i], false)) list2.splice(i--, 1); } } else list2 = targets[1]; targets[0].useCard({ name: name, isCard: true }, list2, "noai"); game.delay(0.5); }, ai: { order: 8, result: { target: function (player, target) { if (ui.selected.targets.length == 0) { return 1; } else { return -1; } }, }, expose: 0.4, threaten: 3, }, group: "relianji_count", subSkill: { count: { sub: true, forced: true, popup: false, silent: true, trigger: { global: "damageEnd" }, filter: function (event, player) { var evt = event.getParent(3); return evt && evt.name == "relianji" && evt.player == player; }, content: function () { if (!player.storage.relianji) player.storage.relianji = 0; player.storage.relianji++; event.trigger("remoucheng_awaken"); }, }, }, }, remoucheng: { derivation: "jingong", trigger: { player: "remoucheng_awaken", }, forced: true, filter: function (event, player) { return player.storage.relianji && player.storage.relianji > 2; }, audio: "moucheng", juexingji: true, skillAnimation: true, animationColor: "thunder", content: function () { player.awakenSkill("remoucheng"); player.changeSkills(["jingong", "relianji"]); player.gainMaxHp(); player.recover(); }, ai: { combo: "relianji", }, }, shouye: { audio: 2, group: "shouye_after", trigger: { target: "useCardToTarget" }, filter: function (event, player) { return event.player != player && event.targets.length == 1; }, check: function (event, player) { if (event.player == game.me || event.player.isOnline()) return get.attitude(player, event.player) < 0; return get.effect(player, event.card, event.player, player) < 0; }, usable: 1, logTarget: "player", content: function () { "step 0"; player.line(trigger.player, "green"); player.chooseToDuiben(trigger.player); "step 1"; if (result.bool) { trigger.targets.remove(player); trigger.getParent().triggeredTargets2.remove(player); trigger.getParent().shouyeer = player; } }, subSkill: { after: { sub: true, trigger: { global: "useCardAfter" }, forced: true, silent: true, popup: false, filter: function (event, player) { if (event.shouyeer != player) return false; if (event.cards) { for (var i = 0; i < event.cards.length; i++) { if (event.cards[i].isInPile()) return true; } } return false; }, content: function () { var list = []; for (var i = 0; i < trigger.cards.length; i++) { if (trigger.cards[i].isInPile()) { list.push(trigger.cards[i]); } } player.gain(list, "gain2", "log"); }, }, }, }, liezhi: { audio: 2, group: "liezhi_damage", trigger: { player: "phaseZhunbeiBegin" }, direct: true, filter: function (event, player) { return !player.hasSkill("liezhi_disable"); }, content: function () { "step 0"; player.chooseTarget(get.prompt("liezhi"), "弃置至多两名其他角色区域内的各一张牌", [1, 2], function (card, player, target) { return target != player && target.countDiscardableCards(player, "hej") > 0; }).ai = function (target) { var player = _status.event.player; return get.effect(target, { name: "guohe" }, player, player); }; "step 1"; if (result.bool) { result.targets.sortBySeat(); event.targets = result.targets; player.line(result.targets, "green"); player.logSkill("liezhi", result.targets); } else event.finish(); "step 2"; event.current = targets.shift(); player.discardPlayerCard(event.current, "hej", true); if (targets.length) event.redo(); }, subSkill: { disable: { sub: true, trigger: { player: "phaseAfter" }, forced: true, silent: true, popup: false, charlotte: true, //filter:function(event){return !event.liezhi}, content: function () { player.removeSkill("liezhi_disable"); }, }, damage: { trigger: { player: "damage" }, forced: true, silent: true, popup: false, content: function () { player.addSkill("liezhi_disable"); }, }, }, }, xinzhanyi: { audio: "zhanyi", enable: "phaseUse", usable: 1, filterCard: true, position: "he", check: function (card) { var player = _status.event.player; if (player.hp < 3) return 0; var type = get.type(card, "trick"); if (type == "trick") { return 6 - get.value(card); } else if (type == "equip") { if ( player.hasSha() && game.hasPlayer(function (current) { return player.canUse("sha", current) && get.attitude(player, current) < 0 && get.effect(current, { name: "sha" }, player, player) > 0; }) ) { return 6 - get.value(card); } } return 0; }, content: function () { player.loseHp(); switch (get.type(cards[0], "trick", cards[0].original == "h" ? player : false)) { case "basic": player.addTempSkill("xinzhanyi_basic"); player.addMark("xinzhanyi_basic1", 1, false); break; case "equip": player.addTempSkill("xinzhanyi_equip"); break; case "trick": player.addTempSkill("xinzhanyi_trick"); player.draw(3); break; } }, ai: { order: 9.1, result: { player: 1, }, }, }, xinzhanyi_basic1: { trigger: { player: "useCard" }, filter: function (event, player) { return get.type(event.card, false) == "basic" && player.hasMark("xinzhanyi_basic1"); }, forced: true, silent: true, popup: false, content: function () { if (!trigger.baseDamage) trigger.baseDamage = 1; var num = player.countMark("xinzhanyi_basic1"); trigger.baseDamage += num; player.removeMark("xinzhanyi_basic1", num, false); game.log(trigger.card, "的伤害值/回复值", "#y+" + num); }, }, xinzhanyi_basic: { group: ["xinzhanyi_basic1"], onremove: function (p, s) { delete p.storage[s + 1]; }, hiddenCard: function (player, name) { return get.type(name) == "basic" && player.countCards("h", { type: "basic" }) > 0; }, enable: "chooseToUse", filter: function (event, player) { if ( !player.hasCard(function (card) { return get.type(card) == "basic"; }, "hs") ) return false; for (var name of lib.inpile) { if (get.type(name) != "basic") continue; if (event.filterCard(get.autoViewAs({ name }, "unsure"), player, event)) return true; } return false; }, chooseButton: { dialog: function (event, player) { var list = []; for (var name of lib.inpile) { if (get.type(name) != "basic") continue; if (event.filterCard(get.autoViewAs({ name }, "unsure"), player, event)) list.push(["基本", "", name]); if (name != "sha") continue; for (var j of lib.inpile_nature) { if (event.filterCard({ name: name, nature: j }, player, event)) list.push(["基本", "", "sha", j]); } } return ui.create.dialog("战意", [list, "vcard"], "hidden"); }, check: function (button) { var player = _status.event.player; var card = { name: button.link[2], nature: button.link[3] }; if ( game.hasPlayer(function (current) { return player.canUse(card, current) && get.effect(current, card, player, player) > 0; }) ) { switch (button.link[2]) { case "tao": return 5; case "jiu": { if (player.countCards("hs", { type: "basic" }) >= 2) return 3; return 0; } case "sha": if (button.link[3] == "fire") return 2.95; else if (button.link[3] == "thunder" || button.link[3] == "ice") return 2.92; else return 2.9; } } return 0; }, backup: function (links, player) { return { audio: "zhanyi", filterCard: function (card, player, target) { return get.type(card) == "basic"; }, check: function (card, player, target) { return 9 - get.value(card); }, viewAs: { name: links[0][2], nature: links[0][3] }, position: "hs", popname: true, }; }, prompt: function (links, player) { return "将一张基本牌当做" + get.translation(links[0][3] || "") + get.translation(links[0][2]) + "使用"; }, }, ai: { order: function () { var player = _status.event.player; var event = _status.event; if (event.filterCard({ name: "jiu" }, player, event) && get.effect(player, { name: "jiu" }) > 0 && player.countCards("hs", { type: "basic" }) >= 2) { return 3.3; } return 3.1; }, respondSha: true, skillTagFilter: function (player, tag, arg) { if ( player.hasCard(function (card) { return get.type(card) == "basic"; }, "hs") ) { if (tag == "respondSha") { if (arg != "use") return false; } } else { return false; } }, result: { player: 1, }, }, }, xinzhanyi_equip: { audio: "zhanyi", trigger: { player: "useCardToPlayered" }, forced: true, filter: function (event, player) { return event.card.name == "sha" && event.target.countCards("he") > 0 && event.targets.length == 1; }, check: function (event, player) { return get.attitude(player, event.target) < 0; }, content: function () { "step 0"; trigger.target.chooseToDiscard("he", true, 2); "step 1"; if (result.bool && result.cards && result.cards.length) { const cards = result.cards.filterInD("d"); if (cards.length == 1) { event._result = { bool: true, links: result.cards.slice(0) }; } else if (cards.length > 1) { player.chooseButton(["选择获得其中的一张牌", result.cards.slice(0)], true).set("ai", function (button) { return get.value(button.link); }); } else event.finish(); } else event.finish(); "step 2"; if (result.links) player.gain(result.links, "gain2"); }, }, xinzhanyi_trick: { mod: { wuxieRespondable: function () { return false; }, }, }, xinfu_daigong: { usable: 1, audio: 2, trigger: { player: "damageBegin4", }, filter: function (event, player) { return event.source != undefined && player.countCards("h") > 0; }, content: function () { "step 0"; player.showHandcards(); "step 1"; var cards = player.getCards("h"); var suits = []; for (var i = 0; i < cards.length; i++) { suits.add(get.suit(cards[i])); } trigger.source .chooseCard("he", "交给" + get.translation(player) + "一张满足条件的牌,否则防止此伤害。", function (card) { return !_status.event.suits.includes(get.suit(card)); }) .set("suits", suits).ai = function (card) { var player = _status.event.player; var target = _status.event.getParent("xinfu_daigong").player; if (get.damageEffect(target, player, player) > 0) return 6.5 - get.value(card); return 0; }; "step 2"; if (result.bool) { trigger.source.give(result.cards, player, true); } else trigger.cancel(); }, }, xinfu_zhaoxin: { group: ["zhaoxin_give"], intro: { content: "expansion", markcount: "expansion", }, enable: "phaseUse", usable: 1, audio: 2, filter: function (event, player) { return player.countCards("h") > 0 && player.getExpansions("xinfu_zhaoxin").length < 3; }, filterCard: true, selectCard: function () { var player = _status.event.player; return [1, 3 - player.getExpansions("xinfu_zhaoxin").length]; }, discard: false, lose: false, delay: false, content: function () { player.addToExpansion(player, "give", cards).gaintag.add("xinfu_zhaoxin"); player.draw(cards.length); }, check: function (card) { return 6 - get.value(card); }, onremove: function (player, skill) { var cards = player.getExpansions(skill); if (cards.length) player.loseToDiscardpile(cards); }, ai: { order: 1, result: { player: 1, }, }, }, zhaoxin_give: { trigger: { global: "phaseDrawAfter", }, filter: function (event, player) { if (!player.getExpansions("xinfu_zhaoxin").length) return false; return player == event.player || player.inRange(event.player); }, direct: true, content: function () { "step 0"; player .chooseCardButton(get.prompt("xinfu_zhaoxin", trigger.player), player.getExpansions("xinfu_zhaoxin"), function (button) { return true; }) .set("ai", function (button) { return 1 + Math.random(); }); "step 1"; if (result.bool) { event.card = result.links[0]; player.logSkill("xinfu_zhaoxin", target); player.line(trigger.player, "thunder"); player.showCards(event.card); } else event.finish(); "step 2"; trigger.player.chooseBool("是否获得" + get.translation(event.card) + "?").ai = function () { return get.attitude(trigger.player, player) > 0; }; "step 3"; if (result.bool) { trigger.player.gain(event.card, "give", player, "bySelf"); player.chooseBool("是否对" + get.translation(trigger.player) + "造成1点伤害?").ai = function () { return get.damageEffect(trigger.player, player, player) > 0; }; } else { trigger.player.chat("拒绝"); event.finish(); } "step 4"; if (result.bool) { trigger.player.damage("nocard"); } }, }, xinfu_qianchong: { audio: 3, group: ["qc_weimu", "qc_mingzhe"], subSkill: { effect: { charlotte: true, onremove: true, mod: { cardUsable: function (card, player) { var type = get.type2(card); if (player.getStorage("xinfu_qianchong_effect").includes(type)) return Infinity; }, targetInRange: function (card, player) { var type = get.type2(card); if (player.getStorage("xinfu_qianchong_effect").includes(type)) return true; }, }, }, }, trigger: { player: "phaseUseBegin", }, direct: true, filter: function (event, player) { var es = player.getCards("e"); if (!es.length) return true; var col = get.color(es[0]); for (var i = 0; i < es.length; i++) { if (get.color(es[i]) != col) return true; } return false; }, content: function () { "step 0"; var list = ["basic", "trick", "equip", "cancel2"]; list.removeArray(player.getStorage("xinfu_qianchong_effect")); if (list.length > 1) { player .chooseControl(list) .set("ai", function () { return list[0]; }) .set("prompt", get.prompt("xinfu_qianchong")) .set("prompt2", "你可以选择一种类别的牌,然后你本回合内使用该类别的牌时没有次数和距离限制。"); } else event.finish(); "step 1"; if (result.control && result.control != "cancel2") { player.logSkill("xinfu_qianchong"); var type = result.control; player.addTempSkill("xinfu_qianchong_effect"); player.markAuto("xinfu_qianchong_effect", [type]); var str = get.translation(type) + "牌"; game.log(player, "声明了", "#y" + str); player.popup(str, "thunder"); } }, }, qc_weimu: { audio: "xinfu_qianchong", mod: { targetEnabled: function (card, player, target) { var bool = true; var es = target.getCards("e"); if (!es.length) bool = false; for (var i = 0; i < es.length; i++) { if (get.color(es[i]) != "black") bool = false; } if (bool && (get.type(card) == "trick" || get.type(card) == "delay") && get.color(card) == "black") return false; }, }, }, qc_mingzhe: { audio: "xinfu_qianchong", trigger: { player: ["useCard", "respond", "loseAfter"], global: "loseAsyncAfter", }, frequent: true, filter: function (event, player) { if (player.hasSkill("mingzhe")) return false; if (player == _status.currentPhase) return false; var es = player.getCards("e"); if (!es.length) return false; for (var i = 0; i < es.length; i++) { if (get.color(es[i]) != "red") return false; } if (event.name.indexOf("lose") != 0) return get.color(event.card) == "red"; if (event.type != "discard") return false; var evt = event.getl(player); if (evt.cards2) { for (var i = 0; i < evt.cards2.length; i++) { if (get.color(evt.cards2[i]) == "red") return true; } } return false; }, content: function () { "step 0"; event.count = 1; if (trigger.name.indexOf("lose") == 0) { event.count = 0; var evt = trigger.getl(player); for (var i = 0; i < evt.cards2.length; i++) { if (get.color(evt.cards2[i]) == "red") event.count++; } } "step 1"; player.draw(); event.count--; "step 2"; if (event.count && player.hasSkill(event.name) && !get.is.blocked(event.name, player)) { player.chooseBool(get.prompt2("mingzhe")).set("frequentSkill", event.name); } else event.finish(); "step 3"; if (result.bool) { player.logSkill("qc_mingzhe"); event.goto(1); } }, ai: { threaten: 0.7, }, }, xinfu_shangjian: { trigger: { global: "phaseJieshuBegin", }, audio: 2, filter: function (event, player) { var num = 0; player.getHistory("lose", function (evt) { var evt2 = evt.getParent(); if (evt2.name == "useCard" && evt2.player == player && get.type(evt2.card, null, false) == "equip") return; if (evt.cards2) num += evt.cards2.length; }); return num > 0 && num <= player.hp; }, forced: true, content: function () { "step 0"; var num = 0; player.getHistory("lose", function (evt) { var evt2 = evt.getParent(); if (evt2.name == "useCard" && evt2.player == player && get.type(evt2.card, null, false) == "equip") return; if (evt.cards2) num += evt.cards2.length; }); if (num > 0) { player.draw(num); } }, }, rw_bagua_skill: { inherit: "bagua_skill", audio: true, content: function () { "step 0"; player.judge("rewrite_bagua", function (card) { return get.suit(card) != "spade" ? 1.5 : -0.5; }).judge2 = function (result) { return result.bool; }; "step 1"; if (result.judge > 0) { trigger.untrigger(); trigger.set("responded", true); trigger.result = { bool: true, card: { name: "shan" } }; } }, }, rw_baiyin_skill: { inherit: "baiyin_skill", audio: true, subSkill: { lose: { audio: "rw_baiyin_skill", forced: true, charlotte: true, equipSkill: true, trigger: { player: "loseAfter", global: ["equipAfter", "addJudgeAfter", "gainAfter", "loseAsyncAfter", "addToExpansionAfter"], }, filter: (event, player) => { if (player.hasSkillTag("unequip2")) return false; var evt = event.getl(player); return evt && evt.es.some(card => card.name == "rewrite_baiyin"); }, content: function () { var evt = trigger.getl(player); evt.es.forEach(card => { if (card.name == "rewrite_baiyin") { player.recover(); player.draw(2); } }); }, }, }, }, rw_lanyinjia: { inherit: "lanyinjia", audio: "lanyinjia", }, rw_minguangkai_cancel: { inherit: "minguangkai_cancel", }, rw_minguangkai_link: { inherit: "minguangkai_link", trigger: { player: "linkBefore", }, forced: true, //priority:20, filter: function (event, player) { return !player.isLinked(); }, content: function () { trigger.cancel(); }, ai: { effect: { target_use(card, player, target, current) { if (["tiesuo", "lulitongxin"].includes(card.name)) { return "zerotarget"; } }, }, }, }, rw_renwang_skill: { inherit: "renwang_skill", audio: true, filter: function (event, player) { if (player.hasSkillTag("unequip2")) return false; if ( event.player.hasSkillTag("unequip", false, { name: event.card ? event.card.name : null, target: player, card: event.card, }) ) return false; return event.card.name == "sha" && (get.suit(event.card) == "heart" || get.color(event.card) == "black"); }, ai: { effect: { target_use(card, player, target) { if (typeof card !== "object" || target.hasSkillTag("unequip2")) return; if ( player.hasSkillTag("unequip", false, { name: card ? card.name : null, target: player, card: card, }) || player.hasSkillTag("unequip_ai", false, { name: card ? card.name : null, target: player, card: card, }) ) return; if (card.name == "sha" && ["spade", "club", "heart"].includes(get.suit(card))) return "zeroplayertarget"; }, }, }, }, rw_tengjia1: { inherit: "tengjia1", audio: true, }, rw_tengjia2: { inherit: "tengjia2", audio: true, }, rw_tengjia3: { audio: "rw_tengjia1", inherit: "rw_minguangkai_link", ai: { effect: { target_use(card, player, target, current) { if (["tiesuo", "lulitongxin"].includes(card.name)) { return "zeroplayertarget"; } }, }, }, }, rw_tengjia4: { inherit: "tengjia3", audio: "rw_tengjia1", }, xinfu_pingcai: { subSkill: { backup: {} }, wolong_card: function () { "step 0"; var ingame = game.hasPlayer(function (current) { return ["sp_zhugeliang", "re_sp_zhugeliang", "ol_sp_zhugeliang", "prp_zhugeliang"].includes(current.name) || ["sp_zhugeliang", "re_sp_zhugeliang", "ol_sp_zhugeliang", "prp_zhugeliang"].includes(current.name2); }) ? true : false; var prompt = "请选择"; prompt += ingame ? "至多两名" : "一名"; prompt += "角色,对其造成1点火焰伤害"; var range = ingame ? [1, 2] : [1, 1]; player.chooseTarget(prompt, range).set("ai", function (target) { var player = _status.event.player; return get.damageEffect(target, player, player, "fire"); }); "step 1"; if (result.bool && result.targets.length) { player.line(result.targets, "fire"); result.targets.sortBySeat(); for (var i = 0; i < result.targets.length; i++) { result.targets[i].damage("fire"); } } }, fengchu_card: function () { "step 0"; var ingame = game.hasPlayer(function (current) { return ["re_pangtong", "pangtong", "ol_pangtong"].includes(current.name) || ["re_pangtong", "pangtong", "ol_pangtong"].includes(current.name2); }) ? true : false; var prompt = "请选择"; prompt += ingame ? "至多四名" : "至多三名"; prompt += "要横置的角色"; var range = ingame ? [1, 4] : [1, 3]; player.chooseTarget(prompt, range).set("ai", function (target) { var player = _status.event.player; return get.effect(target, { name: "tiesuo" }, player, player); }); "step 1"; if (result.bool && result.targets.length) { player.line(result.targets, "green"); result.targets.sortBySeat(); for (var i = 0; i < result.targets.length; i++) { result.targets[i].link(); } } }, xuanjian_card: function () { "step 0"; event.ingame = game.hasPlayer(function (current) { return ["re_xushu", "xin_xushu", "xushu", "dc_xushu"].includes(current.name) || ["re_xushu", "xin_xushu", "xushu", "dc_xushu"].includes(current.name2); }) ? true : false; var prompt = "请选择一名角色,令其回复1点体力并摸一张牌"; prompt += event.ingame ? ",然后你摸一张牌。" : "。"; player.chooseTarget(prompt).set("ai", function (target) { var player = _status.event.player; return get.attitude(player, target) * (target.isDamaged() ? 2 : 1); }); "step 1"; if (result.bool && result.targets.length) { var target = result.targets[0]; player.line(target, "thunder"); target.draw(); target.recover(); if (event.ingame) player.draw(); } }, shuijing_card: function () { "step 0"; event.ingame = game.hasPlayer(function (current) { return current.name == "simahui" || current.name2 == "simahui"; }) ? true : false; var prompt = "将一名角色装备区中的"; prompt += event.ingame ? "一张牌" : "防具牌"; prompt += "移动到另一名角色的装备区中"; var next = player.chooseTarget(2, function (card, player, target) { if (ui.selected.targets.length) { if (!_status.event.ingame) { var cards = ui.selected.targets[0].getEquips(2); return cards.some(card => target.canEquip(card)); } var from = ui.selected.targets[0]; if (target.isMin()) return false; var es = from.getCards("e"); for (var i = 0; i < es.length; i++) { if (target.canEquip(es[i])) return true; } return false; } else { if (!event.ingame) { if (target.getEquips(2).length) return true; return false; } return target.countCards("e") > 0; } }); next.set("ingame", event.ingame); next.set("ai", function (target) { var player = _status.event.player; var att = get.attitude(player, target); if (ui.selected.targets.length == 0) { if (att < 0) { if ( game.hasPlayer(function (current) { if (get.attitude(player, current) > 0) { var es = target.getCards("e"); for (var i = 0; i < es.length; i++) { if (current.canEquip(es[i])) return true; } return false; } }) ) return -att; } return 0; } if (att > 0) { var es = ui.selected.targets[0].getCards("e"); var i; for (i = 0; i < es.length; i++) { if (target.canEquip(es[i])) break; } if (i == es.length) return 0; } return -att * get.attitude(player, ui.selected.targets[0]); }); next.set("multitarget", true); next.set("targetprompt", ["被移走", "移动目标"]); next.set("prompt", prompt); "step 1"; if (result.bool) { player.line2(result.targets, "green"); event.targets = result.targets; } else event.finish(); "step 2"; game.delay(); "step 3"; if (targets.length == 2) { if (!event.ingame) { var cards = targets[0].getEquips(2); if (cards.length == 1) event._result = { bool: true, links: cards, }; else { player .choosePlayerCard( "e", true, function (button) { return get.equipValue(button.link); }, targets[0] ) .set("targets0", targets[0]) .set("targets1", targets[1]) .set("filterButton", function (button) { if (!get.subtypes(button.link, false).includes("equip2")) return false; var targets1 = _status.event.targets1; return targets1.canEquip(button.link); }); } } else { player .choosePlayerCard( "e", true, function (button) { return get.equipValue(button.link); }, targets[0] ) .set("targets0", targets[0]) .set("targets1", targets[1]) .set("filterButton", function (button) { var targets1 = _status.event.targets1; return targets1.canEquip(button.link); }); } } else event.finish(); "step 4"; if (result.bool && result.links.length) { var link = result.links[0]; if (get.position(link) == "e") event.targets[1].equip(link); else if (link.viewAs) event.targets[1].addJudge({ name: link.viewAs }, [link]); else event.targets[1].addJudge(link); event.targets[0].$give(link, event.targets[1], false); game.delay(); } }, audio: true, enable: "phaseUse", usable: 1, chooseButton: { dialog: function () { var list = ["wolong", "fengchu", "xuanjian", "shuijing"]; for (var i = 0; i < list.length; i++) { list[i] = ["", "", list[i] + "_card"]; } return ui.create.dialog("评才", [list, "vcard"]); }, check: function (button) { var name = button.link[2]; var player = _status.event.player; if (name == "xuanjian_card") { if ( game.hasPlayer(function (current) { return current.isDamaged() && current.hp < 3 && get.attitude(player, current) > 1; }) ) return 1 + Math.random(); else return 1; } else if (name == "wolong_card") { if ( game.hasPlayer(function (current) { return get.damageEffect(current, player, player, "fire") > 0; }) ) return 1.2 + Math.random(); else return 0.5; } else return 0.6; }, backup: function (links, player) { return { audio: "xinfu_pingcai", filterCard: () => false, selectCard: -1, takara: links[0][2], content: lib.skill.xinfu_pingcai.contentx, }; }, }, contentx: function () { "step 0"; event.pingcai_delayed = true; var name = lib.skill.xinfu_pingcai_backup.takara; event.cardname = name; event.videoId = lib.status.videoId++; if (player.isUnderControl()) { game.swapPlayerAuto(player); } var switchToAuto = function () { game.pause(); game.countChoose(); event.timeout = setTimeout(function () { _status.imchoosing = false; event._result = { bool: true, }; game.resume(); }, 9000); }; var createDialog = function (player, id, name) { if (player == game.me) return; var dialog = ui.create.dialog("forcebutton", "hidden"); var str = get.translation(player) + "正在擦拭宝物上的灰尘…"; var canSkip = !_status.connectMode; if (canSkip) str += "
    (点击宝物可以跳过等待AI操作)"; dialog.textPrompt = dialog.add('
    ' + str + "
    "); dialog.classList.add("fixed"); dialog.classList.add("scroll1"); dialog.classList.add("scroll2"); dialog.classList.add("fullwidth"); dialog.classList.add("fullheight"); dialog.classList.add("noupdate"); dialog.videoId = id; var canvas2 = document.createElement("canvas"); dialog.canvas_viewer = canvas2; dialog.appendChild(canvas2); canvas2.classList.add("grayscale"); canvas2.style.position = "absolute"; canvas2.style.width = "249px"; canvas2.style.height = "249px"; canvas2.style["border-radius"] = "6px"; canvas2.style.left = "calc(50% - 125px)"; canvas2.style.top = "calc(50% - 125px)"; canvas2.width = 249; canvas2.height = 249; canvas2.style.border = "3px solid"; var ctx2 = canvas2.getContext("2d"); var img = new Image(); img.src = lib.assetURL + "image/card/" + name + ".png"; img.onload = function () { ctx2.drawImage(this, 0, 0, this.width, this.height, 0, 0, canvas2.width, canvas2.height); }; if (canSkip) { var skip = function () { if (event.pingcai_delayed) { delete event.pingcai_delayed; clearTimeout(event.timeout); event._result = { bool: true, }; game.resume(); canvas2.removeEventListener(lib.config.touchscreen ? "touchend" : "click", skip); } }; canvas2.addEventListener(lib.config.touchscreen ? "touchend" : "click", skip); } dialog.open(); }; var chooseButton = function (id, name) { var event = _status.event; _status.xinfu_pingcai_finished = false; var dialog = ui.create.dialog("forcebutton", "hidden"); dialog.textPrompt = dialog.add('
    擦拭掉宝物上的灰尘吧!
    '); event.switchToAuto = function () { event._result = { bool: _status.xinfu_pingcai_finished, }; game.resume(); _status.imchoosing = false; _status.xinfu_pingcai_finished = true; }; dialog.classList.add("fixed"); dialog.classList.add("scroll1"); dialog.classList.add("scroll2"); dialog.classList.add("fullwidth"); dialog.classList.add("fullheight"); dialog.classList.add("noupdate"); dialog.videoId = id; var canvas = document.createElement("canvas"); var canvas2 = document.createElement("canvas"); dialog.appendChild(canvas2); dialog.appendChild(canvas); canvas.style.position = "absolute"; canvas.style.width = "249px"; canvas.style.height = "249px"; canvas.style["border-radius"] = "6px"; canvas.style.left = "calc(50% - 125px)"; canvas.style.top = "calc(50% - 125px)"; canvas.width = 249; canvas.height = 249; canvas.style.border = "3px solid"; canvas2.style.position = "absolute"; canvas2.style.width = "249px"; canvas2.style.height = "249px"; canvas2.style["border-radius"] = "6px"; canvas2.style.left = "calc(50% - 125px)"; canvas2.style.top = "calc(50% - 125px)"; canvas2.width = 249; canvas2.height = 249; canvas2.style.border = "3px solid"; var ctx = canvas.getContext("2d"); var ctx2 = canvas2.getContext("2d"); var img = new Image(); img.src = lib.assetURL + "image/card/" + name + ".png"; img.onload = function () { ctx2.drawImage(this, 0, 0, this.width, this.height, 0, 0, canvas2.width, canvas2.height); }; ctx.fillStyle = "lightgray"; ctx.fillRect(0, 0, canvas.width, canvas.height); canvas.onmousedown = function (ev) { //if(_status.xinfu_pingcai_finished) return; canvas.onmousemove = function (e) { if (_status.xinfu_pingcai_finished) return; ctx.beginPath(); ctx.clearRect(e.offsetX - 16, e.offsetY - 16, 32, 32); var data = ctx.getImageData(canvas.width * 0.1, canvas.height * 0.1, canvas.width * 0.8, canvas.height * 0.8).data; var sum = 0; for (var i = 3; i < data.length; i += 4) { if (data[i] == 0) { sum++; } } if (sum >= canvas.width * canvas.height * 0.6) { //ctx.clearRect(0,0,canvas.width,canvas.height); if (!_status.xinfu_pingcai_finished) { _status.xinfu_pingcai_finished = true; event.switchToAuto(); } } }; }; canvas.ontouchstart = function (ev) { //if(_status.xinfu_pingcai_finished) return; canvas.ontouchmove = function (e) { if (_status.xinfu_pingcai_finished) return; ctx.beginPath(); var rect = canvas.getBoundingClientRect(); var X = ((e.touches[0].clientX - rect.left) / rect.width) * canvas.width; var Y = ((e.touches[0].clientY - rect.top) / rect.height) * canvas.height; ctx.clearRect(X - 16, Y - 16, 32, 32); var data = ctx.getImageData(canvas.width * 0.1, canvas.height * 0.1, canvas.width * 0.8, canvas.height * 0.8).data; var sum = 0; for (var i = 3; i < data.length; i += 4) { if (data[i] == 0) { sum++; } } if (sum >= canvas.width * canvas.height * 0.6) { if (!_status.xinfu_pingcai_finished) { _status.xinfu_pingcai_finished = true; event.switchToAuto(); } } }; }; canvas.onmouseup = function (ev) { canvas.onmousemove = null; }; canvas.ontouchend = function (ev) { canvas.ontouchmove = null; }; dialog.open(); game.pause(); game.countChoose(); }; //event.switchToAuto=switchToAuto; game.broadcastAll(createDialog, player, event.videoId, name); if (event.isMine()) { chooseButton(event.videoId, name); } else if (event.isOnline()) { event.player.send(chooseButton, event.videoId, name); event.player.wait(); game.pause(); } else { switchToAuto(); } "step 1"; var result = event.result || result; if (!result) result = { bool: false }; event._result = result; game.broadcastAll( function (id, result, player) { _status.xinfu_pingcai_finished = true; var dialog = get.idDialog(id); if (dialog) { dialog.textPrompt.innerHTML = '
    ' + (get.translation(player) + "擦拭宝物" + (result.bool ? "成功!" : "失败…")) + "
    "; if (result.bool && dialog.canvas_viewer) dialog.canvas_viewer.classList.remove("grayscale"); } if (!_status.connectMode) delete event.pingcai_delayed; }, event.videoId, result, player ); game.delay(2.5); "step 2"; game.broadcastAll("closeDialog", event.videoId); if (result.bool) { player.logSkill("pcaudio_" + event.cardname); event.insert(lib.skill.xinfu_pingcai[event.cardname], { player: player, }); } }, ai: { order: 7, fireAttack: true, threaten: 1.7, result: { player: 1, }, }, }, xinfu_pdgyingshi: { mod: { targetEnabled: function (card, player, target) { if (get.type(card) == "delay") { return false; } }, }, trigger: { player: ["phaseZhunbeiBefore", "phaseJieshuBefore"], }, forced: true, audio: 2, group: "xinfu_pdgyingshi2", content: function () { trigger.cancel(); game.log(player, "跳过了", event.triggername == "phaseZhunbeiBefore" ? "准备阶段" : "结束阶段"); }, }, xinfu_pdgyingshi2: { popup: false, trigger: { player: "phaseJudgeBefore", }, forced: true, content: function () { trigger.cancel(); game.log(player, "跳过了判定阶段"); }, }, pcaudio_wolong_card: { audio: true, }, pcaudio_fengchu_card: { audio: true, }, pcaudio_shuijing_card: { audio: true, }, pcaudio_xuanjian_card: { audio: true, }, yizan_use: { audio: "yizan_respond_shan", intro: { content: "已发动过#次", }, enable: ["chooseToUse", "chooseToRespond"], hiddenCard: function (player, name) { if (get.type(name) != "basic") return false; if (!player.storage.yizan && player.countCards("hes") < 2) return false; return player.hasCard(function (card) { return get.type(card) == "basic"; }, "hs"); }, filter: function (event, player) { if (!player.storage.yizan && player.countCards("hes") < 2) return false; if ( !player.hasCard(function (card) { return get.type(card) == "basic"; }, "hs") ) return false; for (var name of lib.inpile) { if (get.type(name) != "basic") continue; if (event.filterCard(get.autoViewAs({ name }, "unsure"), player, event)) return true; if (name == "sha") { for (var nature of lib.inpile_nature) { if (event.filterCard(get.autoViewAs({ name, nature }, "unsure"), player, event)) return true; } } } return false; }, chooseButton: { dialog: function (event, player) { var list = []; for (var name of lib.inpile) { if (get.type(name) != "basic") continue; if (event.filterCard(get.autoViewAs({ name }, "unsure"), player, event)) { list.push(["基本", "", name]); } if (name == "sha") { for (var nature of lib.inpile_nature) { if (event.filterCard(get.autoViewAs({ name, nature }, "unsure"), player, event)) list.push(["基本", "", "sha", nature]); } } } return ui.create.dialog("翊赞", [list, "vcard"], "hidden"); }, check: function (button) { var player = _status.event.player; var card = { name: button.link[2], nature: button.link[3] }; if ( _status.event.getParent().type != "phase" || game.hasPlayer(function (current) { return player.canUse(card, current) && get.effect(current, card, player, player) > 0; }) ) { switch (button.link[2]) { case "tao": case "shan": return 5; case "jiu": { if (player.storage.yizan && player.countCards("hs", { type: "basic" }) > 2) return 3; return 0; } case "sha": if (button.link[3] == "fire") return 2.95; else if (button.link[3] == "thunder" || button.link[3] == "ice") return 2.92; else return 2.9; } } return 0; }, backup: function (links, player) { return { audio: "yizan_respond_shan", filterCard: function (card, player, target) { if (player.storage.yizan) return get.type(card) == "basic"; else if (ui.selected.cards.length) { if (get.type(ui.selected.cards[0]) == "basic") return true; return get.type(card) == "basic"; } return true; }, complexCard: true, selectCard: function () { var player = _status.event.player; if (player.storage.yizan) return 1; return 2; }, check: function (card, player, target) { if (!ui.selected.cards.length && get.type(card) == "basic") return 6; else return 6 - get.value(card); }, viewAs: { name: links[0][2], nature: links[0][3] }, position: "hes", popname: true, precontent: function () { player.addMark("yizan_use", 1, false); }, }; }, prompt: function (links, player) { var str = player.storage.yizan ? "一张基本牌" : "两张牌(其中至少应有一张基本牌)"; return "将" + str + "当做" + get.translation(links[0][3] || "") + get.translation(links[0][2]) + "使用或打出"; }, }, ai: { order: function () { var player = _status.event.player; var event = _status.event; if (event.filterCard({ name: "jiu" }, player, event) && get.effect(player, { name: "jiu" }) > 0 && player.storage.yizan && player.countCards("hs", { type: "basic" }) > 2) { return 3.3; } return 3.1; }, skillTagFilter: function (player, tag, arg) { if (tag == "fireAttack") return true; if (!player.storage.yizan && player.countCards("hes") < 2) return false; if ( !player.hasCard(function (card) { return get.type(card) == "basic"; }, "hes") ) { return false; } }, result: { player: 1, }, respondSha: true, respondShan: true, fireAttack: true, }, }, yizan_respond_shan: { audio: 2, }, xinfu_longyuan: { audio: 2, forced: true, unique: true, juexingji: true, trigger: { player: "phaseZhunbeiBegin", }, skillAnimation: true, animationColor: "orange", filter: function (event, player) { return player.countMark("yizan_use") >= 3; }, content: function () { player.awakenSkill("xinfu_longyuan"); player.storage.yizan = true; }, derivation: "yizan_rewrite", ai: { combo: "yizan_use", }, }, xinfu_jingxie: { audio: 2, video: function (player, info) { var l2 = player.getCards(info[0] ? "e" : "h"), l1 = info[1]; for (var j = 0; j < l2.length; j++) { if (l2[j].suit == l1[0] && l2[j].number == l1[1] && l2[j].name == l1[2]) { l2[j].init([l2[j].suit, l2[j].number, "rewrite_" + l2[j].name]); break; } } }, }, xinfu_jingxie1: { group: ["xinfu_jingxie2"], position: "he", audio: "xinfu_jingxie", enable: "phaseUse", filter: function (event, player) { var he = player.getCards("he"); for (var i = 0; i < he.length; i++) { if (["bagua", "baiyin", "lanyinjia", "renwang", "tengjia", "zhuge"].includes(he[i].name)) return true; } return false; }, filterCard: function (card) { return ["bagua", "baiyin", "lanyinjia", "renwang", "tengjia", "zhuge"].includes(card.name); }, discard: false, lose: false, delay: false, check: function () { return 1; }, content: function () { "step 0"; player.showCards(cards); "step 1"; var card = cards[0]; var bool = get.position(card) == "e"; if (bool) player.removeEquipTrigger(card); game.addVideo("skill", player, ["xinfu_jingxie", [bool, get.cardInfo(card)]]); game.broadcastAll(function (card) { card.init([card.suit, card.number, "rewrite_" + card.name]); }, card); if (bool) { var info = get.info(card); if (info.skills) { for (var i = 0; i < info.skills.length; i++) { player.addSkillTrigger(info.skills[i]); } } } }, ai: { basic: { order: 10, }, result: { player: 1, }, }, }, xinfu_jingxie2: { prompt: "重铸一张防具牌,然后将体力回复至1点。", audio: "xinfu_jingxie", enable: "chooseToUse", filterCard: (card, player) => get.subtype(card) == "equip2" && player.canRecast(card), filter: (event, player) => { if (event.type != "dying") return false; if (player != event.dying) return false; return player.hasCard(card => lib.skill.xinfu_jingxie2.filterCard(card, player), "he"); }, position: "he", discard: false, lose: false, delay: false, content: function () { "step 0"; player.recast(cards); "step 1"; var num = 1 - player.hp; if (num) player.recover(num); }, ai: { order: 0.5, skillTagFilter: function (player, arg, target) { if (player != target) return false; return player.hasCard(card => (_status.connectMode && get.position(card) == "h") || (get.subtype(card) == "equip2" && player.canRecast(card)), "he"); }, save: true, result: { player: function (player) { return 10; }, }, }, }, xinfu_qiaosi: { enable: "phaseUse", usable: 1, content: function () { "step 0"; if (get.isLuckyStar(player)) { event.num = 6; player.throwDice(6); } else player.throwDice(); "step 1"; event.cards = get.cards(event.num); player.showCards(event.cards); "step 2"; player.gain(event.cards, "gain2"); player .chooseControl() .set("choiceList", ["将" + get.cnNumber(event.num) + "张牌交给一名其他角色", "弃置" + get.cnNumber(event.num) + "张牌"]) .set("ai", function () { if ( game.hasPlayer(function (current) { return current != player && get.attitude(player, current) > 2; }) ) return 0; return 1; }); "step 3"; if (result.index == 0) { player.chooseCardTarget({ position: "he", filterCard: true, selectCard: event.num, filterTarget: function (card, player, target) { return player != target; }, ai1: function (card) { return 1; }, ai2: function (target) { var att = get.attitude(_status.event.player, target); return att; }, prompt: "请选择要送人的卡牌", forced: true, }); } else { player.chooseToDiscard(event.num, true, "he"); event.finish(); } "step 4"; if (result.bool) { var target = result.targets[0]; player.give(result.cards, target); } }, ai: { order: 7.5, result: { player: 1, }, }, }, zhaohuo: { audio: 2, audioname: ["re_taoqian"], trigger: { global: "dying" }, forced: true, //priority:12, filter: function (event, player) { return event.player != player && player.maxHp > 1; }, content: function () { "step 0"; event.num = player.maxHp - 1; player.loseMaxHp(event.num, true); "step 1"; player.draw(event.num); }, ai: { halfneg: true, }, }, yixiang: { audio: 2, audioname: ["re_taoqian"], trigger: { target: "useCardToTargeted" }, frequent: true, filter: function (event, player) { if (event.player.hp <= player.hp) return false; //if(event.targets.length>1) return false; var hs = player.getCards("h"); var names = ["sha", "shan", "tao", "jiu", "du"]; for (var i = 0; i < hs.length; i++) { names.remove(hs[i].name); } if (!names.length) return false; for (var i = 0; i < ui.cardPile.childElementCount; i++) { if (names.includes(ui.cardPile.childNodes[i].name)) { return true; } } return false; }, usable: 1, content: function () { var hs = player.getCards("h"); var list = []; var names = ["sha", "shan", "tao", "jiu", "du"]; for (var i = 0; i < hs.length; i++) { names.remove(hs[i].name); } for (var i = 0; i < ui.cardPile.childElementCount; i++) { if (names.includes(ui.cardPile.childNodes[i].name)) { list.push(ui.cardPile.childNodes[i]); } } if (list.length) { player.gain(list.randomGet(), "draw"); } }, }, yirang: { audio: 2, audioname: ["re_taoqian"], trigger: { player: "phaseUseBegin" }, direct: true, filter: function (event, player) { if ( !player.countCards("he", function (card) { return get.type(card) != "basic"; }) ) { return false; } return game.hasPlayer(function (current) { return current.maxHp > player.maxHp; }); }, content: function () { "step 0"; player .chooseTarget(get.prompt2("yirang"), function (card, player, target) { return target.maxHp > player.maxHp; }) .set("ai", function (target) { return (get.attitude(_status.event.player, target) - 2) * target.maxHp; }); "step 1"; if (result.bool) { var cards = player.getCards("he", function (card) { return get.type(card) != "basic"; }); var target = result.targets[0]; var types = []; for (var i = 0; i < cards.length; i++) { types.add(get.type(cards[i], "trick")); } player.logSkill("yirang", target); player.give(cards, target); player.gainMaxHp(target.maxHp - player.maxHp, true); player.recover(types.length); game.delay(); } }, }, kuangcai: { audio: 2, trigger: { player: "phaseUseBegin" }, filter: function (event, player) { return !event.player.isMad(); }, content: function () { game.broadcastAll(function (player) { player.forceCountChoose = { phaseUse: 5 }; }, player); player.addSkill("kuangcai_use"); player.addSkill("kuangcai_cancel"); //ui.auto.hide(); }, subSkill: { use: { mod: { cardUsable: function (card) { if (get.info(card) && get.info(card).forceUsable) return; return Infinity; }, targetInRange: function () { return true; }, aiOrder: function (player, card, num) { var name = get.name(card); if (name == "tao") return num + 7 + Math.pow(player.getDamagedHp(), 2); if (name == "sha") return num + 6; if (get.subtype(card) == "equip2") return num + get.value(card) / 3; }, }, trigger: { player: "useCard" }, forced: true, charlotte: true, silent: true, popup: false, filter: function (event, player) { if (!player.forceCountChoose || !player.forceCountChoose.phaseUse) { return false; } return true; }, content: function () { player.draw(); if (player.forceCountChoose.phaseUse == 1) { var evt = event.getParent("phaseUse"); if (evt) evt.skipped = true; } else game.broadcastAll(function (player) { player.forceCountChoose.phaseUse--; }, player); }, }, cancel: { trigger: { player: "phaseUseEnd" }, firstDo: true, silent: true, charlotte: true, content: function () { game.broadcastAll(function (player) { delete player.forceCountChoose; }, player); //ui.auto.show(); player.removeSkill("kuangcai_use"); player.removeSkill("kuangcai_cancel"); }, }, }, ai: { threaten: 4.5, }, }, shejian: { audio: 2, trigger: { player: "phaseDiscardEnd" }, direct: true, filter: function (event, player) { var cards = []; player.getHistory("lose", function (evt) { if (evt.type == "discard" && evt.getParent("phaseDiscard") == event) cards.addArray(evt.cards2); }); if (cards) { if (cards.length < 2) return false; var suits = []; for (var i = 0; i < cards.length; i++) { var suit = get.suit(cards[i]); if (suits.includes(suit)) { return false; } else { suits.push(suit); } } return true; } return false; }, content: function () { "step 0"; player.chooseTarget(get.prompt("shejian"), "弃置一名其他角色的一张牌", function (card, player, target) { if (player == target) return false; return target.countDiscardableCards(player, "he") > 0; }).ai = function (target) { return -get.attitude(player, target); }; "step 1"; if (result.bool) { player.logSkill("shejian", result.targets); player.discardPlayerCard(result.targets[0], "he", true); } else { event.finish(); } }, }, shixin: { audio: 2, trigger: { player: "damageBegin4" }, filter: function (event) { return event.hasNature("fire"); }, forced: true, content: function () { trigger.cancel(); }, ai: { nofire: true, effect: { target: function (card, player, target, current) { if (get.tag(card, "fireDamage")) return "zerotarget"; }, }, }, }, fenyin: { locked: false, mod: { aiOrder: function (player, card, num) { if (typeof card == "object" && player == _status.currentPhase) { var evt = player.getLastUsed(); if (evt && evt.card && get.color(evt.card) != "none" && get.color(card) != "none" && get.color(evt.card) != get.color(card)) { return num + 10; } } }, }, audio: 2, trigger: { player: "useCard" }, frequent: true, //usable:3, filter: function (event, player) { if (_status.currentPhase != player) return false; var evt = player.getLastUsed(1); if (!evt) return false; var color1 = get.color(evt.card); var color2 = get.color(event.card); return color1 && color2 && color1 != "none" && color2 != "none" && color1 != color2; }, content: function () { player.draw(); }, ai: { threaten: 3, }, }, dujin: { audio: 2, trigger: { player: "phaseDrawBegin2" }, frequent: true, preHidden: true, filter: function (event, player) { return !event.numFixed; }, content: function () { trigger.num += 1 + Math.ceil(player.countCards("e") / 2); }, }, yingjian: { trigger: { player: "phaseZhunbeiBegin" }, direct: true, audio: "qingyi", content: function () { player.chooseUseTarget("###是否发动【影箭】?###视为使用一张没有距离限制的【杀】", { name: "sha" }, false, "nodistance").logSkill = "yingjian"; }, ai: { threaten: function (player, target) { return 1.6; }, }, }, tunchu: { audio: 2, trigger: { player: "phaseDrawBegin2" }, frequent: true, preHidden: true, locked: false, filter: function (event, player) { if (event.numFixed || player.getExpansions("tunchu").length) return false; return true; }, content: function () { trigger.num += 2; player.addTempSkill("tunchu_choose", "phaseDrawAfter"); }, onremove: function (player, skill) { var cards = player.getExpansions(skill); if (cards.length) player.loseToDiscardpile(cards); }, intro: { content: "expansion", markcount: "expansion", }, mod: { cardEnabled: function (card, player) { if (player.getExpansions("tunchu").length && card.name == "sha") { return false; } }, }, subSkill: { choose: { trigger: { player: "phaseDrawEnd" }, forced: true, popup: false, charlotte: true, content: function () { "step 0"; player.removeSkill("tunchu_choose"); var nh = player.countCards("h"); if (nh) { player.chooseCard("h", [1, nh], "将任意张手牌置于你的武将牌上").set("ai", function (card) { var player = _status.event.player; var count = game.countPlayer(function (current) { return get.attitude(player, current) > 2 && current.hp - current.countCards("h") > 1; }); if (ui.selected.cards.length >= count) return -get.value(card); return 5 - get.value(card); }); } else { event.finish(); } "step 1"; if (result.bool) { player.addToExpansion(result.cards, player, "giveAuto").gaintag.add("tunchu"); } }, }, }, }, shuliang: { audio: 2, trigger: { global: "phaseJieshuBegin" }, direct: true, filter: function (event, player) { return player.getExpansions("tunchu").length > 0 && event.player.countCards("h") < event.player.hp && event.player.isIn(); }, content: function () { "step 0"; var goon = get.attitude(player, trigger.player) > 0; player .chooseCardButton(get.prompt("shuliang", trigger.player), player.getExpansions("tunchu")) .set("ai", function () { if (_status.event.goon) return 1; return 0; }) .set("goon", goon); "step 1"; if (result.bool) { player.logSkill("shuliang", trigger.player); player.loseToDiscardpile(result.links); trigger.player.draw(2); } }, ai: { combo: "tunchu" }, }, choulve: { audio: 2, trigger: { player: "phaseUseBegin" }, filter: function (event, player) { return game.hasPlayer(function (current) { return current != player && current.countCards("he"); }); }, async cost(event, trigger, player){ let str = "令一名其他角色交给你一张牌"; const history = player.getAllHistory("damage", function (evt) { return evt.card && evt.card.name && lib.card[evt.card.name]; }); if (history.length) event.cardname = history[history.length - 1].card.name; if (event.cardname) { str += "。若其如此做,视为你使用【" + get.translation(event.cardname) + "】"; } let goon = true; if (event.cardname) { goon = game.hasPlayer(function (current) { return player.canUse(event.cardname, current) && get.effect(current, { name: event.cardname }, player, player) > 0; }); } const result = await player.chooseTarget(get.prompt("choulve"), str, function (card, player, target) { return target != player && target.countCards("he"); }).set("ai", function (target) { const event = get.event(); if (!event.goon) return 0; var player = event.player; if (get.attitude(player, target) >= 0 && get.attitude(target, player) >= 0) { return Math.sqrt(target.countCards("he")); } return 0; }).set("goon", goon).forResult(); if(result.bool){ result.cost_data = {cardname: event.cardname}; event.result = result; } }, content: function () { "step 0"; event.cardname = event.cost_data.cardname; var target = targets[0]; target.chooseCard("he", "是否交给" + get.translation(player) + "一张牌?", event.cardname ? "若如此做,视为" + get.translation(player) + "使用【" + get.translation(event.cardname) + "】" : null).set("ai", function (card) { if (_status.event.goon) return 7 - get.value(card); return 0; }).set("goon", get.attitude(target, player) > 1); event.target = target; "step 1"; if (result.bool) { event.target.give(result.cards, player); if (event.cardname) { player.chooseUseTarget(event.cardname, true, false); } } }, }, polu: { audio: 2, trigger: { player: "phaseZhunbeiBegin" }, forced: true, filter: function (event, player) { if (!lib.inpile.includes("ly_piliche")) return true; return !!get.cardPile(function (card) { return card.name == "ly_piliche"; }); }, content: function () { var card; if (!lib.inpile.includes("ly_piliche")) { card = game.createCard2("ly_piliche", "diamond", 1); lib.inpile.push("ly_piliche"); } else card = get.cardPile(function (card) { return card.name == "ly_piliche"; }); player.chooseUseTarget(card, true, "nopopup"); }, group: "polu_damage", subSkill: { damage: { trigger: { player: "damageEnd" }, forced: true, filter: function (event, player) { return !player.getEquips("ly_piliche").length; }, content: function () { "step 0"; event.count = trigger.num; "step 1"; event.count--; player.draw(); "step 2"; var card = get.cardPile2(function (card) { return get.subtype(card, false) == "equip1" && player.canUse(card, player); }); if (card) player.chooseUseTarget(card, true, "nopopup"); "step 3"; if (event.count > 0 && !player.getEquips("ly_piliche").length) event.goto(1); }, }, }, }, ly_piliche: { trigger: { source: "damageSource" }, check: function (event, player) { return get.attitude(player, event.player) * get.value(event.player.getDiscardableCards(player, "e"), event.player) <= 0; }, filter: function (event, player) { return player != event.player && event.player.countDiscardableCards(player, "e") > 0; }, logTarget: "player", content: function () { player.discardPlayerCard(trigger.player, "e", true, trigger.player.countCards("e")); }, }, xinzhilve: { enable: "phaseUse", audio: "zhilve", usable: 1, chooseButton: { dialog: function (event, player) { var list = ["移动场上的一张牌", "摸一张牌并视为使用一张【杀】"]; var choiceList = ui.create.dialog("知略:失去1点体力并...", "forcebutton", "hidden"); choiceList.add([ list.map((item, i) => { return [i, item]; }), "textbutton", ]); return choiceList; }, filter: function (button, player) { if (button.link == 0) return player.canMoveCard(); return player.hasUseTarget({ name: "sha", isCard: true }, false); }, check: function (button) { return button.link; }, backup: function (links) { return lib.skill["xinzhilve_" + ["move", "use"][links[0]]]; }, prompt: function () { return "请选择【杀】的目标"; }, }, ai: { order: function (item, player) { return get.order({ name: "sha" }) + 0.1; }, result: { player: function (player) { if (player.hp > 2 && player.hasValueTarget({ name: "sha" })) return 1; return 0; }, }, }, }, xinzhilve_move: { audio: "zhilve", filterCard: function () { return false; }, selectCard: -1, delay: false, content: function () { "step 0"; event.forceDie = true; if (!player.canMoveCard(null, event.nojudge)) { event.finish(); return; } var next = player.chooseTarget(2, function (card, player, target) { if (ui.selected.targets.length) { var from = ui.selected.targets[0]; var js = from.getCards("j"); for (var i = 0; i < js.length; i++) { if (_status.event.nojudge) break; if (target.canAddJudge(js[i])) return true; } if (target.isMin()) return false; var es = from.getCards("e"); for (var i = 0; i < es.length; i++) { if (target.canEquip(es[i])) return true; } return false; } else { var range = "ej"; if (_status.event.nojudge) range = "e"; return target.countCards(range) > 0; } }); next.set("nojudge", event.nojudge || false); next.set("ai", function (target) { var player = _status.event.player; var att = get.attitude(player, target); var sgnatt = get.sgn(att); if (ui.selected.targets.length == 0) { if (att > 0) { if ( !_status.event.nojudge && target.countCards("j", function (card) { return game.hasPlayer(function (current) { return current.canAddJudge(card) && get.attitude(player, current) < 0; }); }) ) return 14; if ( target.countCards("e", function (card) { return ( get.value(card, target) < 0 && game.hasPlayer(function (current) { return current != target && get.attitude(player, current) < 0 && current.canEquip(card); }) ); }) > 0 ) return 9; } else if (att < 0) { if ( game.hasPlayer(function (current) { if (current != target && get.attitude(player, current) > 0) { var es = target.getCards("e"); for (var i = 0; i < es.length; i++) { if (get.value(es[i], target) > 0 && current.canEquip(es[i]) && get.value(es[i], current) > 0) return true; } } }) ) { return -att; } } return 0; } var es = ui.selected.targets[0].getCards("e"); var i; var att2 = get.sgn(get.attitude(player, ui.selected.targets[0])); for (i = 0; i < es.length; i++) { if (sgnatt != 0 && att2 != 0 && get.sgn(get.value(es[i], ui.selected.targets[0])) == -att2 && get.sgn(get.value(es[i], target)) == sgnatt && target.canEquip(es[i])) { return Math.abs(att); } } if ( i == es.length && (_status.event.nojudge || !ui.selected.targets[0].countCards("j", function (card) { return target.canAddJudge(card); })) ) { return 0; } return -att * get.attitude(player, ui.selected.targets[0]); }); next.set("multitarget", true); next.set("targetprompt", _status.event.targetprompt || ["被移走", "移动目标"]); next.set("prompt", event.prompt || "移动场上的一张牌"); if (event.prompt2) next.set("prompt2", event.prompt2); if (event.forced) next.set("forced", true); "step 1"; event.result = result; if (result.bool) { player.line2(result.targets, "green"); event.targets = result.targets; } else { event.finish(); } "step 2"; game.delay(); "step 3"; if (targets.length == 2) { player .choosePlayerCard( "ej", true, function (button) { var player = _status.event.player; var targets0 = _status.event.targets0; var targets1 = _status.event.targets1; if (get.attitude(player, targets0) > 0 && get.attitude(player, targets1) < 0) { if (get.position(button.link) == "j") return 12; if (get.value(button.link, targets0) < 0) return 10; return 0; } else { if (get.position(button.link) == "j") return -10; return get.equipValue(button.link); } }, targets[0] ) .set("nojudge", event.nojudge || false) .set("targets0", targets[0]) .set("targets1", targets[1]) .set("filterButton", function (button) { var targets1 = _status.event.targets1; if (get.position(button.link) == "j") { if (_status.event.nojudge) return false; return targets1.canAddJudge(button.link); } else { return targets1.canEquip(button.link); } }); } else { event.finish(); } "step 4"; if (result.bool && result.links.length) { player.loseHp(); } "step 5"; if (result.bool && result.links.length) { var link = result.links[0]; if (get.position(link) == "e") { event.targets[1].equip(link); } else if (link.viewAs) { event.targets[1].addJudge({ name: link.viewAs }, [link]); } else { event.targets[1].addJudge(link); } event.targets[0].$give(link, event.targets[1]); event.result.card = link; event.result.position = get.position(link); game.delay(); player.addTempSkill("xinzhilve_mark"); player.addMark("xinzhilve_mark", 1, false); } }, }, xinzhilve_use: { audio: "zhilve", filterCard: function () { return false; }, selectCard: -1, filterTarget: function (card, player, target) { return player.canUse({ name: "sha", isCard: true }, target, false); }, content: function () { player.loseHp(); player.draw(); player.useCard({ name: "sha", isCard: true }, false, target).forceDie = true; player.addTempSkill("xinzhilve_mark"); player.addMark("xinzhilve_mark", 1, false); }, ai: { result: { target: function (player, target) { return get.effect(target, { name: "sha" }, player, target); }, }, }, }, xinzhilve_mark: { intro: { content: "本回合手牌上限+#" }, onremove: true, charlotte: true, mod: { maxHandcard: function (player, num) { return num + player.countMark("xinzhilve_mark"); }, }, }, xinxhzhiyan: { audio: "xhzhiyan", enable: "phaseUse", filter: function (event, player) { return (!player.hasSkill("xinxhzhiyan_true") && player.countCards("h") > player.hp) || (!player.hasSkill("xinxhzhiyan_false") && player.countCards("h") < player.maxHp); }, filterCard: true, selectCard: function () { var player = _status.event.player; if (player.hasSkill("xinxhzhiyan_true")) return 0; var num = Math.max(0, player.countCards("h") - player.hp); if (ui.selected.cards.length || player.hasSkill("xinxhzhiyan_false") || player.countCards("h") >= player.maxHp) return [num, num]; return [0, num]; }, filterTarget: lib.filter.notMe, selectTarget: function () { if (ui.selected.cards.length) return [1, 1]; return [0, 0]; }, check: function (card) { var player = _status.event.player; var checkx = function (card) { if ( player.getUseValue(card, null, true) <= 0 && game.hasPlayer(function (current) { return current != player && get.value(card, current) > 0 && get.attitude(player, current) > 0; }) ) return 2; return 1; }; if ( player.countCards("h", function (card) { return checkx(card) > 0; }) < player.countCards("h") - player.hp ) return 0; return checkx(card); }, delay: false, discard: false, lose: false, content: function () { var bool = cards && cards.length > 0; player.addTempSkill("xinxhzhiyan_" + bool, "phaseUseEnd"); if (!bool) { player.draw(player.maxHp - player.countCards("h")); } else { player.give(cards, target); } }, ai: { order: function (obj, player) { if (player.countCards("h") > player.hp) return 10; return 0.5; }, result: { player: function (player, target) { if (!ui.selected.cards.length && player.countCards("h") < player.maxHp) return 1; return 0; }, target: 1, }, }, }, xinxhzhiyan_true: {}, xinxhzhiyan_false: { mod: { playerEnabled: function (card, player, target) { if (player != target && (!get.info(card) || !get.info(card).singleCard || !ui.selected.targets.length)) return false; }, }, mark: true, intro: { content: "不能对其他角色使用牌", }, }, weifeng: { audio: 2, trigger: { player: "useCardAfter" }, forced: true, filter: function (event, player) { if ( !event.targets || !event.targets.filter(function (target) { return target != player && !target.storage.weifeng2; }).length ) return false; var evt = event.getParent("phaseUse"); if (!evt || evt.player != player) return false; if (!get.tag(event.card, "damage")) return false; if (!["basic", "trick"].includes(get.type(event.card))) return false; return ( player .getHistory("useCard", function (ev) { return ev.getParent("phaseUse") == evt && get.tag(ev.card, "damage") && ["basic", "trick"].includes(get.type(ev.card)); }) .indexOf(event) == 0 && game.hasPlayer(function (current) { return current != player && !current.storage.weifeng2 && event.targets.includes(current); }) ); }, content: function () { "step 0"; player .chooseTarget(true, "威风:请选择一个目标,令其获得一个【惧(" + get.translation(trigger.card.name) + ")】标记", function (card, player, target) { return player != target && !target.storage.weifeng2 && _status.event.getTrigger().targets.includes(target); }) .set("ai", function (target) { return -get.attitude(_status.event.player, target); }); "step 1"; if (result.bool) { var target = result.targets[0]; target.storage.weifeng2 = trigger.card.name; player.line(target, "green"); game.log(target, "获得了一个", "#g【惧(" + get.translation(trigger.card.name) + ")】", "标记"); target.markSkill("weifeng2"); player.addSkill("weifeng3"); } }, }, weifeng2: { intro: { content: "当前“惧”标记名称:$", onunmark: function (storage, player) { if (player.storage.weifeng2) { game.log(player, "移去了一个", "#g【惧(" + get.translation(player.storage.weifeng2) + ")】", "标记"); delete player.storage.weifeng2; } }, }, marktext: "惧", }, weifeng3: { trigger: { global: "damageBegin3", player: ["phaseZhunbeiBegin", "dieBegin"], }, forced: true, popup: false, filter: function (event, player) { if (event.name != "damage") return true; return event.player != player && typeof event.player.storage.weifeng2 == "string"; }, content: function () { if (trigger.name == "damage") { player.logSkill("weifeng", trigger.player); if (trigger.card && trigger.card.name == trigger.player.storage.weifeng2) trigger.num++; else if (trigger.player.countGainableCards(player, "he") > 0) player.gainPlayerCard(trigger.player, "he", true); trigger.player.unmarkSkill("weifeng2"); } else { game.countPlayer(function (current) { if (current.storage.weifeng2) current.unmarkSkill("weifeng2"); }); player.removeSkill("weifeng3"); } }, }, gnjinfan: { trigger: { player: "phaseDiscardBegin" }, direct: true, locked: false, audio: 2, filter: function (event, player) { var list = []; player.getCards("s", function (card) { if (card.hasGaintag("gnjinfan")) list.add(get.suit(card)); }); if (list.length >= lib.suit.length) return false; return ( player.countCards("h", function (card) { return _status.connectMode || !list.includes(get.suit(card)); }) > 0 ); }, content: function () { "step 0"; player .chooseCard( "h", get.prompt("gnjinfan"), "将任意张手牌当做“铃”置于武将牌上", [ 1, (function () { var list = []; var list2 = []; player.getCards("s", function (card) { if (card.hasGaintag("gnjinfan")) list.add(get.suit(card)); }); player.getCards("h", function (card) { list2.add(get.suit(card)); }); list2.removeArray(list); return Math.max(1, list2.length); })(), ], function (card, player) { return ( !player.countCards("s", function (cardx) { return cardx.hasGaintag("gnjinfan") && get.suit(cardx, false) == get.suit(card, player); }) && !ui.selected.cards.filter(function (cardx) { return get.suit(cardx, player) == get.suit(card, player); }).length ); } ) .set("ai", function (card) { var player = _status.event.player; if (player.hasUseTarget(card) && !player.hasValueTarget(card)) return 0; if (["sha", "shan", "wuxie", "caochuan"].includes(card.name)) return 2 + Math.random(); return 1 + Math.random(); }) .set("complexCard", true); "step 1"; if (result.bool) { player.logSkill("gnjinfan"); game.log(player, "将", result.cards, "放到了武将牌上"); player.loseToSpecial(result.cards, "gnjinfan").visible = true; } else event.finish(); "step 2"; player.markSkill("gnjinfan"); }, group: ["gnjinfan_gain"], marktext: "铃", intro: { mark: function (dialog, storage, player) { dialog.addAuto( player.getCards("s", function (card) { return card.hasGaintag("gnjinfan"); }) ); }, markcount: function (storage, player) { return player.getCards("s", function (card) { return card.hasGaintag("gnjinfan"); }).length; }, onunmark: function (storage, player) { var cards = player.getCards("s", function (card) { return card.hasGaintag("gnjinfan"); }); if (cards.length) { player.lose(cards, ui.discardPile); player.$throw(cards, 1000); game.log(cards, "进入了弃牌堆"); } }, }, mod: { aiOrder: function (player, card, num) { if (get.itemtype(card) == "card" && card.hasGaintag("gnjinfan")) return num + 0.5; }, }, }, gnjinfan_gain: { audio: "gnjinfan", trigger: { player: "loseAfter" }, forced: true, filter: function (event, player) { if (!event.ss || !event.ss.length) return false; for (var i in event.gaintag_map) { if (event.gaintag_map[i].includes("gnjinfan")) return true; return false; } }, content: function () { "step 0"; var cards = []; for (var i of trigger.ss) { if (!trigger.gaintag_map[i.cardid] || !trigger.gaintag_map[i.cardid].includes("gnjinfan")) continue; var suit = get.suit(i, false); var card = get.cardPile2(function (card) { return !cards.includes(card) && get.suit(card, false) == suit; }); if (card) cards.push(card); } if (cards.length) player.gain(cards, "gain2"); var num = player.getCards("s", function (card) { return card.hasGaintag("gnjinfan"); }).length; if (num) player.markSkill("gnjinfan"); else player.unmarkSkill("gnjinfan"); "step 1"; game.updateRoundNumber(); }, }, gnsheque: { audio: 2, trigger: { global: "phaseZhunbeiBegin" }, direct: true, filter: function (event, player) { return event.player.isIn() && event.player.countCards("e") > 0 && lib.filter.targetEnabled({ name: "sha" }, player, event.player) && (player.hasSha() || (_status.connectMode && player.countCards("h") > 0)); }, content: function () { player .chooseToUse( function (card, player, event) { if (get.name(card) != "sha") return false; return lib.filter.filterCard.apply(this, arguments); }, "射却:是否对" + get.translation(trigger.player) + "使用一张杀?" ) .set("logSkill", "gnsheque") .set("complexSelect", true) .set("filterTarget", function (card, player, target) { if (target != _status.event.sourcex && !ui.selected.targets.includes(_status.event.sourcex)) return false; return lib.filter.targetEnabled.apply(this, arguments); }) .set("sourcex", trigger.player) .set("oncard", function (card) { try { card.gnsheque_tag = true; } catch (e) { alert("发生了一个导致【射却】无法正常触发无视防具效果的错误。请关闭十周年UI/手杀ui等扩展以解决"); } }); }, ai: { unequip: true, unequip_ai: true, skillTagFilter: function (player, tag, arg) { if (tag == "unequip_ai") { if (_status.event.getParent().name != "gnsheque") return false; } else if (!arg || !arg.card || !arg.card.gnsheque_tag) return false; }, }, }, _doublegroup_choice: { trigger: { global: "gameStart", player: "enterGame", }, forced: true, charlotte: true, firstDo: true, popup: false, filter: function (event, player) { return get.mode() != "guozhan" && get.is.double(player.name1) && !player._groupChosen; }, content: function () { "step 0"; player._groupChosen = true; player.chooseControl(get.is.double(player.name1, true)).set("prompt", "请选择你的势力"); "step 1"; player.changeGroup(result.control); }, }, }; export default skills;