import { lib, game, ui, get, ai, _status } from "../../noname.js"; /** @type { importCharacterConfig['skill'] } */ const skills = { //十周年神华佗 jingyu: { audio: 2, trigger: { global: ["useSkill", "logSkillBegin", "useCard", "respond"], }, filter(event, player) { if (["global", "equip"].includes(event.type)) return false; let skill = event.sourceSkill || event.skill; if (!skill || skill === "jingyu") return false; let info = get.info(skill); while (true) { if (!info || info.charlotte || info.equipSkill) return false; if (info && !info.sourceSkill) break; skill = info.sourceSkill; info = get.info(skill); } return !player.getStorage("jingyu_used").includes(skill); }, forced: true, async content(event, trigger, player) { if (!player.storage.jingyu_used) { player .when({ global: "roundStart" }) .assign({ firstDo: true, }) .then(() => delete player.storage.jingyu_used); } let skill = trigger.sourceSkill || trigger.skill, info = get.info(skill); while (true) { if (info && !info.sourceSkill) break; skill = info.sourceSkill; info = get.info(skill); } player.markAuto("jingyu_used", skill); await player.draw(); }, ai: { threaten: 6, }, }, lvxin: { audio: 2, enable: "phaseUse", usable: 1, filterCard: true, filterTarget: lib.filter.notMe, check(card) { const round = game.roundNumber, player = get.player(); let valueFix = 0; if (["sha", "shan"].includes(get.name(card, false))) valueFix += 3; if ( (round <= 2 && player.hasCard(card => { return ["sha", "shan"].includes(get.name(card)) && get.value(card) <= 3; })) || game.hasPlayer(current => { return current !== player && get.attitude(player, current) > 0; }) ) return 6 - get.value(card) + valueFix; return 4.5 - get.value(card) + valueFix; }, delay: false, discard: false, lose: false, async content(event, trigger, player) { const { target, cards } = event, round = Math.min(5, game.roundNumber); const name = get.translation(target); await player.give(cards, target); const result = await player .chooseControl(["摸牌", "弃牌"]) .set("choiceList", [`令${name}摸${get.cnNumber(round)}张牌`, `令${name}随机弃置${get.cnNumber(round)}张手牌`]) .set("prompt", "滤心:请选择一项") .set("ai", () => { return get.event("choice"); }) .set("choice", get.attitude(player, target) > 0 ? "摸牌" : "弃牌") .forResult(); let cards2 = []; const makeDraw = result.index === 0; if (makeDraw) { cards2 = await target.draw(round).forResult(); } else { const cards = target.getCards("h", card => { return lib.filter.cardDiscardable(card, target, "lvxin"); }); if (cards.length > 0) { const evt = await target.discard(cards.randomGets(round)).set("discarder", target); cards2 = evt.done.cards2; } } const cardName = get.name(cards[0], player); if ( cards2.some(card => { return get.name(card, target) === cardName; }) ) { const skillName = `lvxin_${makeDraw ? "recover" : "lose"}`; target.addSkill(skillName); target.addMark(skillName, 1, false); } }, subSkill: { recover: { trigger: { player: ["useSkill", "logSkillBegin", "useCard", "respond"], }, filter(event, player) { if (["global", "equip"].includes(event.type)) return false; const skill = event.sourceSkill || event.skill; const info = get.info(skill); return info && !info.charlotte && !info.equipSkill; }, forced: true, onremove: true, charlotte: true, async content(event, trigger, player) { player.recover(player.countMark("lvxin_recover")); player.removeSkill("lvxin_recover"); }, intro: { content: "下次发动技能时回复#点体力", }, }, lose: { trigger: { player: ["useSkill", "logSkillBegin", "useCard", "respond"], }, filter(event, player) { if (["global", "equip"].includes(event.type)) return false; const skill = event.sourceSkill || event.skill; const info = get.info(skill); return info && !info.charlotte && !info.equipSkill; }, forced: true, onremove: true, charlotte: true, async content(event, trigger, player) { player.loseHp(player.countMark("lvxin_lose")); player.removeSkill("lvxin_lose"); }, intro: { content: "下次发动技能时失去#点体力", }, }, }, ai: { order: 5, result: { target(player, target) { const round = game.roundNumber; if ( round <= 2 && target.countCards("h") > round * 2 && player.getCards("h").some(card => { return ["sha", "shan"].includes(get.name(card)) && get.value(card) <= 3; }) ) return 1; if (get.attitude(player, target) > 0) { return round + Math.sqrt(1 + target.getDamagedHp()); } return -(round + Math.sqrt(Math.max(0, 2 - target.getHp()))); }, }, }, }, huandao: { audio: 2, enable: "phaseUse", usable: 1, limited: true, filterTarget: lib.filter.notMe, skillAnimation: true, animationColor: "metal", async content(event, trigger, player) { player.awakenSkill("huandao"); const { target } = event; await target.turnOver(false); await target.link(false); let names = [target.name1 || target.name]; if (target.name2) names.add(target.name2); names = names.map(name => get.rawName(name)); if (!_status.characterlist) lib.skill.pingjian.initList(); _status.characterlist.randomSort(); let ownedSkills = target.getSkills(null, false, false), ownedSkillsName = ownedSkills.map(skill => get.translation(skill)); let skillToGain = null; outer: for (const name of _status.characterlist) { const info = lib.character[name]; if (!names.includes(get.rawName(name))) continue; const skills = info[3].slice().randomSort(); while (skills.length) { const skill = skills.shift(), skillName = get.translation(skill); if (!ownedSkillsName.includes(skillName)) { skillToGain = skill; break outer; } } } if (!skillToGain) return; player.popup(skillToGain); player.line(target, "green"); let prompt2 = "若你选择是,则你于获得此技能后须失去一个其他技能。

"; if (lib.skill[skillToGain].nobracket) { prompt2 += `
${get.translation(skillToGain)}
${get.skillInfoTranslation(skillToGain)}


`; } else { const translation = lib.translate[skillToGain + "_ab"] || get.translation(skillToGain).slice(0, 2); prompt2 += `
【${translation}】
${get.skillInfoTranslation(skillToGain)}


`; } const bool = await target .chooseBool(`寰道:是否获得技能〖${get.translation(skillToGain)}〗?`, prompt2) .set( "choice", (() => { const rank = get.skillRank(skillToGain, "inout") + 1; return ownedSkills.some(skill => { const info = get.info(skill); if (info) { if (target.awakenedSkills.includes(skill) && (info.limited || info.juexingji || info.dutySkill)) return true; if (info.ai && (info.ai.neg || info.ai.halfneg)) return true; } return get.skillRank(skill, "inout") < rank; }); })() ) .forResultBool(); if (!bool) { target.chat("拒绝"); game.log(target, "拒绝获得技能", `#g【${get.translation(skillToGain)}】`); await game.asyncDelay(); return; } await target.addSkills(skillToGain); ownedSkills = target.getSkills(null, false, false).filter(skill => { if (skill === skillToGain) return false; const info = get.info(skill); if (!info || info.charlotte || !get.skillInfoTranslation(skill, player).length) return false; return true; }); if (!ownedSkills) return; const control = await target .chooseControl(ownedSkills) .set( "choiceList", ownedSkills.map(skill => { return `
【${get.translation(lib.translate[skill + "_ab"] || get.translation(skill).slice(0, 2))}】
${get.skillInfoTranslation(skill, target)}
`; }) ) .set("displayIndex", false) .set("prompt", "寰道:选择失去一个技能") .set("ai", () => { return get.event("choice"); }) .set( "choice", (() => { const uselessSkills = ownedSkills.filter(skill => { const info = get.info(skill); if (!info) return false; if (target.awakenedSkills.includes(skill) && (info.limited || info.juexingji || info.dutySkill)) return true; if (info.ai && (info.ai.neg || info.ai.halfneg)) return true; return false; }); if (uselessSkills.length) return uselessSkills.randomGet(); return ownedSkills.sort((a, b) => { return get.skillRank(a, "inout") - get.skillRank(b, "inout"); })[0]; })() ) .forResultControl(); await target.removeSkills(control); }, ai: { order: 5, result: { target(player, target) { if (game.roundNumber * game.countPlayer() <= (1.5 * game.countPlayer2()) / Math.sqrt(player.getDamagedHp() + 1)) return 0; const ownedSkills = target.getSkills(null, false, false).filter(skill => { const info = get.info(skill); if (!info || info.charlotte || !get.skillInfoTranslation(skill, player).length) return false; return true; }); const uselessSkills = ownedSkills.filter(skill => { const info = get.info(skill); if (!info) return false; if (target.awakenedSkills.includes(skill) && (info.limited || info.juexingji || info.dutySkill)) return true; if (info.ai && (info.ai.neg || info.ai.halfneg)) return true; return false; }); if (uselessSkills.length) return 3; let names = [target.name1 || target.name]; if (target.name2) names.add(target.name2); names = names.map(name => get.rawName(name)); if (_status.characterlist.some(name => names.includes(get.rawName(name)))) return 1; return 0; }, }, }, }, //神许褚 zhengqing: { audio: 2, trigger: { global: "roundStart" }, forced: true, filter() { return ( game.hasPlayer(current => { return current.countMark("zhengqing"); }) || lib.skill.zhengqing.getMostInfoLastRound()[0] > 0 ); }, getMostInfoLastRound() { let max = -1, players = []; const history = game.getAllGlobalHistory(); if (history.length <= 2) return [max, players]; for (let i = history.length - 2; i >= 0; i--) { const evts = history[i]["everything"].filter(evt => { if (evt.name !== "damage") return false; const source = evt.source; return source && source.isIn(); }); if (evts.length) { let curMax = -1, curPlayers = []; const map = {}; for (const evt of evts) { const source = evt.source; const id = source.playerid; if (typeof map[id] !== "number") map[id] = 0; map[id] += evt.num; if (map[id] > curMax) { curMax = map[id]; curPlayers = [source]; } else if (map[id] == curMax) { curPlayers.add(source); } } if (curMax > max) { max = curMax; players = curPlayers.slice(); } else if (curMax === max) { players.addArray(curPlayers); } } if (history[i].isRound) break; } return [max, players]; }, async content(event, trigger, player) { game.countPlayer(current => { if (current.hasMark("zhengqing")) current.clearMark("zhengqing"); }); const [num, players] = lib.skill.zhengqing.getMostInfoLastRound(); player.line(players, "thunder"); const onlyMe = players.length === 1 && players[0] === player; const isMax = (player .getAllHistory("custom", evt => evt && evt.zhengqing_count) .map(evt => evt.zhengqing_count) .sort((a, b) => b - a)[0] || 0) <= num; players.forEach(current => { current.addMark("zhengqing", num); }); if (onlyMe && isMax) { player.draw(Math.min(5, num)); player.getHistory("custom").push({ zhengqing_count: num }); } else { const drawers = [player].concat(players).sortBySeat(trigger.player); for (const drawer of drawers) { await drawer.draw(); } } }, marktext: "擎", intro: { name: "争擎", name2: "擎", content: "mark", }, }, zhuangpo: { audio: 2, enable: "chooseToUse", onChooseToUse(event) { if (!game.online && !event.zhuangpo_cards) { event.set( "zhuangpo_cards", event.player.getCards("hes", card => { if (get.name(card, event.player) == "sha") return true; const str = lib.skill.shencai.getStr(card); return str.includes("【杀】"); }) ); } }, viewAs: { name: "juedou", storage: { zhuangpo: true }, }, viewAsFilter() { return get.event("zhuangpo_cards").length > 0; }, prompt: "将一张牌面信息包含“【杀】”的牌当【决斗】使用", filterCard(card, player) { return get.event("zhuangpo_cards").includes(card); }, position: "hes", precontent() { player.addTempSkill("zhuangpo_effect"); }, subSkill: { effect: { trigger: { player: "useCardToPlayered", }, filter(event, player) { const card = event.card; if (!card || !card.storage || !card.storage.zhuangpo) return false; return player.hasMark("zhengqing"); }, direct: true, charlotte: true, group: "zhuangpo_damage", async content(event, trigger, player) { const target = trigger.target; const list = Array.from({ length: player.countMark("zhengqing") }, (_, i) => { return get.cnNumber(i + 1, true); }); const result = await player .chooseControl(list, "cancel2") .set("prompt", "壮魄:是否移去任意枚“擎”?") .set("prompt2", `若如此做,${get.translation(target)}须弃置等量的牌`) .set("ai", () => get.event("choice")) .set( "choice", (() => { if (get.attitude(player, target) >= 0) return "cancel2"; const markCount = list.length; const cards = target.getCards("he", card => lib.filter.cardDiscardable(card, target)); let allIn = false; if (player.hp < 2 || target.hp + target.countCards("h", card => target.canSaveCard(card, target)) <= 1 + trigger.targets.some(current => current.hasMark("zhengqing"))) allIn = true; if (cards.map(card => get.value(card)).reduce((p, c) => p + c, 0) / cards.length > 5) allIn = true; if ( !player.isPhaseUsing() || !player.hasCard(card => { if (!lib.skill.shencai.getStr(card).includes("【杀】")) return false; return player.hasValueTarget(get.autoViewAs({ name: "juedou" }, [card])); }) ) allIn = true; const maxCount = Math.min(markCount, cards.length); const toRemoveCount = allIn ? maxCount : Math.ceil(Math.random() * maxCount); return get.cnNumber(toRemoveCount, true); })() ) .forResult(); if (result.control === "cancel2") return; const toRemoveCount = result.index + 1; player.logSkill("zhuangpo_effect", target); player.popup(get.cnNumber(toRemoveCount) + "张"); player.removeMark("zhengqing", toRemoveCount); target.chooseToDiscard("he", toRemoveCount, true); }, }, damage: { audio: "zhuangpo", trigger: { source: "damageBegin1" }, filter(event, player) { const card = event.card; if (!card || !card.storage || !card.storage.zhuangpo) return false; const evt = event.getParent(2); return evt.targets && evt.targets.some(current => current.hasMark("zhengqing")); }, charlotte: true, forced: true, async content(event, trigger) { trigger.num++; }, }, }, }, //神鲁肃 dingzhou: { audio: 2, enable: "phaseUse", usable: 1, filter(event, player) { const num = player.countCards("he"); return game.hasPlayer(current => { if (current == player) return false; const total = current.countCards("ej"); return total > 0 && num >= total; }); }, filterCard: true, selectCard() { return [1, Math.max(...game.filterPlayer(i => i != get.player()).map(i => i.countCards("ej")))]; }, check(card) { return 7 - get.value(card); }, filterTarget(card, player, target) { const num = target.countCards("ej"); if (!num) return false; return ui.selected.cards.length == num && player != target; }, filterOk() { return ui.selected.cards.length == ui.selected.targets[0].countCards("ej"); }, position: "he", lose: false, discard: false, delay: false, async content(event, trigger, player) { const target = event.targets[0]; await player.give(event.cards, target); const cards = target.getGainableCards(player, "ej"); if (cards.length) player.gain(cards, "give", target); }, ai: { order: 9, result: { target(player, target) { let eff = 0; if (ui.selected.cards.length) eff = ui.selected.cards.map(card => get.value(card)).reduce((p, c) => p + c, 0); if (player.hasSkill("zhimeng") && (get.mode() == "identity" || player.countCards("h") - target.countCards("h") > 2 * ui.selected.cards.length)) eff *= 1 + get.sgnAttitude(player, target) * 0.15; const es = target.getCards("e"), js = target.getCards("j"); es.forEach(card => { eff -= get.value(card, target); }); js.forEach(card => { eff -= get.effect( target, { name: card.viewAs || card.name, cards: [card], }, target, target ); }); return eff; }, }, }, }, tamo: { audio: 2, trigger: { global: "phaseBefore", player: "enterGame", }, filter(event, player) { return ( (event.name != "phase" || game.phaseNumber == 0) && game.countPlayer(current => { if (get.mode() === "doudizhu") return current.getSeatNum() !== 3; return !current.isZhu2(); }) > 1 ); }, direct: true, changeSeat: true, derivation: "tamo_faq", async content(event, trigger, player) { const toSortPlayers = game.filterPlayer(current => { if (get.mode() === "doudizhu") return current.getSeatNum() !== 3; return !current.isZhu2(); }); toSortPlayers.sortBySeat(game.findPlayer2(current => current.getSeatNum() == 1, true)); const next = player.chooseToMove("榻谟:是否分配" + (get.mode() != "doudizhu" ? (game.hasPlayer(cur => cur.isZhu2()) ? "除主公外" : "") : "除三号位外") + "所有角色的座次?"); next.set("list", [ [ "(以下排列的顺序即为发动技能后角色的座次顺序)", [ toSortPlayers.map(i => `${i.getSeatNum()}|${i.name}`), (item, type, position, noclick, node) => { const info = item.split("|"), _item = item; const seat = parseInt(info[0]); item = info[1]; if (node) { node.classList.add("button"); node.classList.add("character"); node.style.display = ""; } else { node = ui.create.div(".button.character", position); } node._link = item; node.link = item; const func = function (node, item) { const currentPlayer = game.findPlayer(current => current.getSeatNum() == seat); if (currentPlayer.classList.contains("unseen_show")) node.setBackground("hidden_image", "character"); else if (item != "unknown") node.setBackground(item, "character"); if (node.node) { node.node.name.remove(); node.node.hp.remove(); node.node.group.remove(); node.node.intro.remove(); if (node.node.replaceButton) node.node.replaceButton.remove(); } node.node = { name: ui.create.div(".name", node), group: ui.create.div(".identity", node), intro: ui.create.div(".intro", node), }; const infoitem = [currentPlayer.sex, currentPlayer.group, `${currentPlayer.hp}/${currentPlayer.maxHp}/${currentPlayer.hujia}`]; node.node.name.innerHTML = get.slimName(item); if (lib.config.buttoncharacter_style == "default" || lib.config.buttoncharacter_style == "simple") { if (lib.config.buttoncharacter_style == "simple") { node.node.group.style.display = "none"; } node.classList.add("newstyle"); node.node.name.dataset.nature = get.groupnature(get.bordergroup(infoitem)); node.node.group.dataset.nature = get.groupnature(get.bordergroup(infoitem), "raw"); } node.node.name.style.top = "8px"; if (node.node.name.querySelectorAll("br").length >= 4) { node.node.name.classList.add("long"); if (lib.config.buttoncharacter_style == "old") { node.addEventListener("mouseenter", ui.click.buttonnameenter); node.addEventListener("mouseleave", ui.click.buttonnameleave); } } node.node.intro.innerHTML = lib.config.intro; if (!noclick) { lib.setIntro(node); } node.node.group.innerHTML = `
${get.cnNumber(seat, true)}号
`; node.node.group.style.backgroundColor = get.translation(`${get.bordergroup(infoitem)}Color`); }; node.refresh = func; node.refresh(node, item); node.link = _item; node.seatNumber = seat; node._customintro = uiintro => { uiintro.add(`${get.translation(node._link)}(原${get.cnNumber(node.seatNumber, true)}号位)`); }; return node; }, ], ], ]); next.set("processAI", list => { const listx = list[0][1][0]; const me = listx.find(info => parseInt(info.split("|")[0]) == get.player().getSeatNum()); listx.randomSort(); if (me) { listx.remove(me); listx.unshift(me); } return [listx]; }); const { result } = await next; if (!result.bool) return; await player.logSkill("tamo"); const resultList = result.moved[0].map(info => { return parseInt(info.split("|")[0]); }); const toSwapList = []; const cmp = (a, b) => { return resultList.indexOf(a) - resultList.indexOf(b); }; for (let i = 0; i < toSortPlayers.length; i++) { for (let j = 0; j < toSortPlayers.length; j++) { if (cmp(toSortPlayers[i].getSeatNum(), toSortPlayers[j].getSeatNum()) < 0) { toSwapList.push([toSortPlayers[i], toSortPlayers[j]]); [toSortPlayers[i], toSortPlayers[j]] = [toSortPlayers[j], toSortPlayers[i]]; } } } game.broadcastAll(toSwapList => { for (const list of toSwapList) { game.swapSeat(list[0], list[1], false); } }, toSwapList); if (trigger.name === "phase" && !trigger.player.isZhu2() && trigger.player !== toSortPlayers[0] && !trigger._finished) { trigger.finish(); trigger._triggered = 5; const evt = toSortPlayers[0].insertPhase(); delete evt.skill; const evt2 = trigger.getParent(); if (evt2.name == "phaseLoop" && evt2._isStandardLoop) { evt2.player = toSortPlayers[0]; } //跳过新回合的phaseBefore evt.pushHandler("onPhase", (event, option) => { if (event.step === 0 && option.state === "begin") { event.step = 1; } }); } await game.asyncDelay(); }, }, //什么均贫卡 zhimeng: { audio: 2, trigger: { player: "phaseAfter" }, filter(event, player) { return game.hasPlayer(target => { if (target == player || target.countCards("h") + player.countCards("h") == 0) return false; return get.mode() == "identity" || target.countCards("h") <= player.countCards("h") + 1; }); }, direct: true, async content(event, trigger, player) { const { result: { bool, targets }, } = await player .chooseTarget(get.prompt("zhimeng"), "与一名其他角色平分手牌", (card, player, target) => { if (target == player || target.countCards("h") + player.countCards("h") == 0) return false; return get.mode() == "identity" || target.countCards("h") <= player.countCards("h") + 1; }) .set("ai", target => { const player = get.player(); const pvalue = -player .getCards("h") .map(card => get.value(card, player)) .reduce((p, c) => p + c, 0); const tvalue = -target .getCards("h") .map(card => get.value(card, target)) .reduce((p, c) => p + c, 0) * get.sgnAttitude(player, target); return (pvalue + tvalue) / 2; }); if (!bool) return; const target = targets[0]; player.logSkill("zhimeng", target); const lose_list = []; let cards = []; [player, target].forEach(current => { const hs = current.getCards("h"); if (hs.length) { cards.addArray(hs); current.$throw(hs.length, 500); game.log(current, "将", get.cnNumber(hs.length), "张牌置入了处理区"); lose_list.push([current, hs]); } }); await game .loseAsync({ lose_list: lose_list, }) .setContent("chooseToCompareLose"); await game.asyncDelay(); cards = cards.filterInD(); const pcards = cards.randomGets(Math.ceil(cards.length / 2)); const tcards = cards.removeArray(pcards); const list = []; if (pcards.length) { list.push([player, pcards]); game.log(player, "获得了", get.cnNumber(pcards.length), "张牌"); } if (tcards.length) { list.push([target, tcards]); game.log(target, "获得了", get.cnNumber(tcards.length), "张牌"); } game.loseAsync({ gain_list: list, player: player, animate: "draw", }).setContent("gaincardMultiple"); }, ai: { threaten: 4, }, }, //神华佗 wuling: { audio: 2, enable: "phaseUse", filter(event, player) { return game.hasPlayer(target => lib.skill.wuling.filterTarget(null, player, target)); }, filterTarget(card, player, target) { return !target.hasSkill("wuling_wuqinxi"); }, usable: 2, prompt: "选择一名角色,向其传授“五禽戏”", group: "wuling_die", content() { "step 0"; target.addAdditionalSkill(`wuling_${player.playerid}`, "wuling_wuqinxi"); var next = player.chooseToMove(`五灵:调整向${get.translation(target)}传授的“五禽戏”顺序`); next.set("list", [ [ "", [ lib.skill.wuling.wuqinxi, (item, type, position, noclick, node) => { node = ui.create.buttonPresets.vcard(item, type, position, noclick); node._customintro = [node => `五禽戏:${node.link[2]}`, node => lib.skill.wuling.wuqinxiMap[lib.skill.wuling.wuqinxi.indexOf(node.link[2])].slice(2)]; return node; }, ], ], ]); next.set("processAI", () => { const event = get.event().getParent(), player = event.player, target = event.target; const spirits = []; let nextPlayer = player; do { nextPlayer = nextPlayer.getNext(); if (get.attitude(player, nextPlayer) < 0) { spirits.add("熊"); break; } } while (nextPlayer != target); if (!spirits.length) spirits.add("猿"); if ( get.recoverEffect(target, player, player) > 0 || target.hasCard(card => { return ( get.effect( target, { name: card.viewAs || card.name, cards: [card], }, target, target ) < -1 ); }, "j") ) spirits.add("鹿"); const others = lib.skill.wuling.wuqinxi.slice().removeArray(spirits); do { others.randomSort(); } while (others.length > 1 && others[0] == "鹿"); return [spirits.concat(others).map(i => ["", "", i])]; }); "step 1"; var sortedWuqinxi = result.moved[0].map(i => i[2]); game.log(target, "习得的五禽戏顺序为", "#g" + sortedWuqinxi.join("、")); sortedWuqinxi.unshift(sortedWuqinxi[0]); target.storage.wuling_wuqinxi = sortedWuqinxi; lib.skill.wuling.updateMark(target); }, wuqinxi: ["虎", "鹿", "熊", "猿", "鹤"], wuqinxiMap: ["虎:当你使用指定唯一目标的牌对目标角色造成伤害时,此伤害+1。", "鹿:①当你获得此效果时,你回复1点体力并弃置判定区的所有牌。②你不能成为延时锦囊牌的目标。", "熊:每回合限一次,当你受到伤害时,此伤害-1。", "猿:当你获得此效果时,你选择一名其他角色,获得其装备区里的一张牌。", "鹤:当你获得此效果时,你摸三张牌。"], updateMark(player) { var wuqinxi = player.storage.wuling_wuqinxi; if (!wuqinxi) return; var prevMark = wuqinxi.shift(); // wuqinxi.push(prevMark); var curMark = wuqinxi[0]; if (!curMark) { for (var skill in player.additionalSkills) { if (!skill.startsWith("wuling_")) continue; player.removeAdditionalSkill(skill); } game.log(player, "完成了五禽戏的操练"); return; } game.log(player, "获得了", "#g【" + curMark + "】", "标记"); player.markSkill("wuling_wuqinxi"); game.broadcastAll( function (player, curMark) { if (player.marks.wuling_wuqinxi) player.marks.wuling_wuqinxi.firstChild.innerHTML = curMark; }, player, curMark ); var next = game.createEvent("wuling_change"); next.player = player; next.setContent("emptyEvent"); }, ai: { order: 7, threaten: 5, result: { target: 1 }, }, derivation: "wuling_wuqinxi", subSkill: { wuqinxi: { nopop: true, charlotte: true, intro: { markcount: () => 0, mark(dialog, storage) { const wuqinxiMap = lib.skill.wuling.wuqinxiMap; const str = `
  • 当前效果:${storage[0]}
  • ${wuqinxiMap.find(str => storage[0] == str[0]).slice(2)}
    `; dialog.addText(str, false); const str2 = '
    “五禽戏”顺序:
    ' + storage.join(" ") + "
    "; dialog.addText(str2); if (storage.length > 1) { const str3 = `
    [下一效果] ${wuqinxiMap.find(str => storage[1] == str[0])}
    `; dialog.add(str3); } }, }, mod: { targetEnabled(card, player, target) { if (get.type(card) == "delay" && target.storage.wuling_wuqinxi && target.storage.wuling_wuqinxi[0] == "鹿") return false; }, }, trigger: { source: "damageBegin1", player: ["phaseZhunbeiBegin", "damageBegin4", "wuling_change"], }, filter(event, player, name) { const wuqinxi = player.storage.wuling_wuqinxi && player.storage.wuling_wuqinxi[0]; if (!wuqinxi) return false; if (event.name == "phaseZhunbei") return true; switch (name) { case "damageBegin1": if (wuqinxi != "虎" || !event.card) return false; var evt = event.getParent("useCard"); return evt.targets && evt.targets.length == 1 && evt.targets.includes(event.player); case "damageBegin4": return wuqinxi == "熊" && !player.hasSkill("wuling_xiong"); default: switch (wuqinxi) { case "鹿": return player.isDamaged() || player.countCards("j"); case "鹤": return true; case "猿": return game.hasPlayer(target => target != player && target.countGainableCards(player, "e")); default: return false; } } }, forced: true, onremove: true, content() { "step 0"; var wuqinxi = player.storage.wuling_wuqinxi[0]; if (trigger.name == "phaseZhunbei") { lib.skill.wuling.updateMark(player); event.finish(); } else { var name = event.triggername; switch (name) { case "damageBegin1": player.line(trigger.player); trigger.num++; event.finish(); break; case "damageBegin4": player.addTempSkill("wuling_xiong"); trigger.num--; event.finish(); break; default: switch (wuqinxi) { case "鹿": player.recover(); player.discard(player.getCards("j")).discarder = player; event.finish(); break; case "鹤": player.draw(3); event.finish(); break; case "猿": player .chooseTarget("五禽戏:获得一名其他角色装备区里的一张装备牌", function (card, player, target) { return target != player && target.countGainableCards(player, "e"); }) .set("ai", function (target) { var player = _status.event.player; var att = get.attitude(player, target), eff = 0; target.getCards("e", function (card) { var val = get.value(card, target); eff = Math.max(eff, -val * att); }); return eff; }); break; } break; } } "step 1"; if (result.bool) { var target = result.targets[0]; player.line(target, "green"); player.gainPlayerCard(target, "e", true); } }, ai: { effect: { target(card, player, target) { const wuqinxi = target.storage.wuling_wuqinxi; if (!wuqinxi || !wuqinxi.length) return; const curWuqinxi = wuqinxi[0]; const nextWuqinxi = wuqinxi[1]; if (nextWuqinxi == "鹿" && get.type(card) == "delay") return "zerotarget"; if (curWuqinxi != "熊" || player.hasSkill("wuling_xiong")) return; if (player.hasSkillTag("jueqing", false, target)) return; var num = get.tag(card, "damage"); if (num) { if (num > 1) return 0.5; return 0; } }, }, }, }, xiong: { charlotte: true }, die: { trigger: { player: "die" }, filter(event, player) { return game.hasPlayer(current => current.additionalSkills[`wuling_${player.playerid}`]); }, forced: true, locked: false, forceDie: true, content() { var targets = game.filterPlayer(current => { return current.additionalSkills[`wuling_${player.playerid}`]; }); player.line(targets); targets.forEach(current => current.removeAdditionalSkill(`wuling_${player.playerid}`)); }, }, }, }, youyi: { init(player) { player.storage.renku = true; }, audio: 2, enable: "phaseUse", filter(event, player) { return _status.renku.length > 0; }, prompt: "将仁区所有牌置入弃牌堆,令所有角色各回复1点体力", content() { "step 0"; var cards = _status.renku.slice(); game.cardsDiscard(cards).fromRenku = true; _status.renku.removeArray(cards); player.$throw(cards, 1000); game.updateRenku(); game.log(cards, "从仁库进入了弃牌堆"); "step 1"; var targets = game.filterPlayer(); player.line(targets); targets.forEach(target => target.recover()); }, ai: { order(item, player) { return get.order({ name: "taoyuan" }, player); }, result: { player(player) { return Math.max( 0, game.filterPlayer().reduce((num, target) => num + get.recoverEffect(target, player, player), 0) ); }, }, }, group: "youyi_put", subSkill: { put: { audio: "youyi", trigger: { player: "phaseDiscardEnd" }, filter(event, player) { return lib.skill.twlijian.getCards(event).length; }, prompt2(event, player) { return "将" + get.translation(lib.skill.twlijian.getCards(event)) + "置入仁区"; }, content() { var cards = lib.skill.twlijian.getCards(trigger); game.log(player, "将", cards, "置于了仁库"); game.cardsGotoSpecial(cards, "toRenku"); }, }, }, }, //神贾诩 jxlianpo: { audio: 2, init: () => { game.addGlobalSkill("jxlianpo_global"); }, onremove: () => { if (!game.hasPlayer(i => i.hasSkill("jxlianpo"), true)) game.removeGlobalSkill("jxlianpo_global"); }, trigger: { global: "dieAfter" }, filter(event, player) { if (lib.skill.jxlianpo.getMax().length <= 1) return false; return event.source && event.source.isIn(); }, forced: true, logTarget: "source", getMax: () => { const map = { zhu: game.countPlayer(current => { const identity = current.identity; let num = 0; if (identity == "zhu" || identity == "zhong" || identity == "mingzhong") num++; num += current.countMark("jxlianpo_mark_zhong"); return num; }), fan: game.countPlayer(current => { let num = 0; if (current.identity == "fan") num++; num += current.countMark("jxlianpo_mark_fan"); return num; }), nei: game.countPlayer(current => { let num = 0; if (current.identity == "nei") num++; num += current.countMark("jxlianpo_mark_nei"); return num; }), commoner: game.countPlayer(current => { let num = 0; if (current.identity == "commoner") num++; num += current.countMark("jxlianpo_mark_commoner"); return num; }), }; let population = 0, identities = []; for (let i in map) { let curPopulation = map[i]; if (curPopulation >= population) { if (curPopulation > population) identities = []; identities.add(i); population = curPopulation; } } return identities; }, group: "jxlianpo_show", *content(event, map) { var source = map.trigger.source; source.chooseDrawRecover(2, true); }, mark: true, intro: { content: () => `场上最大阵营为${lib.skill.jxlianpo .getMax() .map(i => { if (i == "zhu") return "主忠"; return get.translation(i + "2"); }) .join("、")}`, }, $createButton(item, type, position, noclick, node) { node = ui.create.identityCard(item, position, noclick); node.link = item; return node; }, subSkill: { show: { audio: "jxlianpo", trigger: { global: "roundStart" }, filter(event, player) { var list = lib.config.mode_config.identity.identity.lastItem.slice(); list.removeArray( game.filterPlayer().map(i => { let identity = i.identity; if (identity == "mingzhong") identity = "zhong"; return identity; }) ); return list.length; }, forced: true, content() { "step 0"; var list = lib.config.mode_config.identity.identity.lastItem.slice(); list.removeArray( game.filterPlayer().map(i => { var identity = i.identity; return identity == "mingzhong" ? "zhong" : identity; }) ).unique(); player.chooseButton( [ '###炼魄:请选择一个身份###
    你选择的身份对应的阵营角色数于本轮内视为+1
    ', [ list, function (item, type, position, noclick, node) { return lib.skill.jxlianpo.$createButton(item, type, position, noclick, node); }, ], ], true ); "step 1"; var choice = result.links[0], mark = `jxlianpo_mark_${choice}`; player .when({ global: "roundStart" }) .assign({ firstDo: true, }) .filter(evt => evt != trigger) .then(() => { for (var i in player.storage) { if (i.startsWith("jxlianpo_mark_")) { player.clearMark(i); } } }); player.addMark(mark, 1, false); event.videoId = lib.status.videoId++; var createDialog = function (player, identity, id) { var dialog = ui.create.dialog(`${get.translation(player)}展示了“${get.translation(identity + "2")}”的身份牌
    `, "forcebutton"); dialog.videoId = id; ui.create.spinningIdentityCard(identity, dialog); }; game.broadcastAll(createDialog, player, choice, event.videoId); var color = ""; if (choice == "zhong") color = "#y"; else if (choice == "fan") color = "#g"; else if (choice == "nei") color = "#b"; game.log(player, "展示了", `${color}${get.translation(choice + "2")}`, "的身份牌"); game.delay(3); "step 2"; game.broadcastAll("closeDialog", event.videoId); }, }, global: { mod: { maxHandcard(player, num) { if (!lib.skill.jxlianpo.getMax().includes("fan")) return; return ( num - game.countPlayer(current => { return current != player && current.hasSkill("jxlianpo"); }) ); }, cardUsable(card, player, num) { if (card.name == "sha") { if (!lib.skill.jxlianpo.getMax().includes("fan")) return; return ( num + game.countPlayer(current => { return current.hasSkill("jxlianpo"); }) ); } }, attackRange(player, num) { if (!lib.skill.jxlianpo.getMax().includes("fan")) return; return ( num + game.countPlayer(current => { return current.hasSkill("jxlianpo"); }) ); }, cardSavable(card, player, target) { if (card.name == "tao" && !player.hasSkill("jxlianpo")) { if (!lib.skill.jxlianpo.getMax().includes("zhu")) return; if (player == target) return; return false; } }, playerEnabled(card, player, target) { if (card.name == "tao" && !player.hasSkill("jxlianpo")) { if (!lib.skill.jxlianpo.getMax().includes("zhu")) return; if (player == target) return; return false; } }, }, trigger: { player: "dieAfter" }, filter: () => { return !game.hasPlayer(i => i.hasSkill("jxlianpo"), true); }, silent: true, forceDie: true, content: () => { game.removeGlobalSkill("jxlianpo_global"); }, }, }, }, jxzhaoluan: { audio: 2, trigger: { global: "dieBegin" }, filter(event, player) { return event.getParent().name == "dying" && event.player.isIn(); }, limited: true, skillAnimation: true, animationColor: "metal", logTarget: "player", check(event, player) { if (event.source && event.source.isIn() && get.attitude(player, event.source) > 0 && player.identity == "fan") return false; return get.attitude(player, event.player) > 3.5; }, *content(event, map) { var player = map.player, trigger = map.trigger; var target = trigger.player; player.awakenSkill("jxzhaoluan"); trigger.cancel(); const skills = target.getSkills(null, false, false).filter(skill => { var info = get.info(skill); if (info && !info.charlotte && !get.is.locked(skill)) { return true; } }); if (skills.length) yield target.removeSkills(skills); yield target.gainMaxHp(3); var num = 3 - target.getHp(true); if (num > 0) yield target.recover(num); target.draw(4); player.addSkill("jxzhaoluan_effect"); player.markAuto("jxzhaoluan_effect", target); }, ai: { expose: 0.5, threaten: 3, }, subSkill: { effect: { audio: "jxzhaoluan", enable: "phaseUse", filter(event, player) { return player.getStorage("jxzhaoluan_effect").some(i => i.isIn()); }, filterTarget(card, player, target) { return !player.getStorage("jxzhaoluan_hit").includes(target); }, line: false, locked: true, charlotte: true, promptfunc() { var bodies = _status.event.player.getStorage("jxzhaoluan_effect").filter(i => i.isIn()); return `选择一名角色,你令${get.translation(bodies)}${bodies.length > 1 ? "中的一人" : ""}减1点体力上限,然后你对选择的角色造成1点伤害。`; }, delay: false, content() { "step 0"; var bodies = player.getStorage("jxzhaoluan_effect").filter(i => i.isIn()); if (bodies.length == 1) event._result = { bool: true, targets: bodies }; else { player .chooseTarget("兆乱:请选择被减上限的傀儡", true, (card, player, target) => { return _status.event.targets.includes(target); }) .set("targets", bodies) .set("ai", target => { return 8 - get.attitude(_status.event.player, target); }); } "step 1"; if (result.bool) { var target = result.targets[0]; player.line(target); target.loseMaxHp(); game.delayex(); } else event.finish(); "step 2"; player.line(target); target.damage(); if (!player.storage.jxzhaoluan_hit) { player.when("phaseUseAfter").then(() => { delete player.storage.jxzhaoluan_hit; }); } player.markAuto("jxzhaoluan_hit", target); }, ai: { order: 9, result: { player(player) { var bodies = player.getStorage("jxzhaoluan_effect").filter(i => i.isIn()); var body; if (bodies.length == 1) body = bodies[0]; else body = bodies.sort((a, b) => get.attitude(player, a) - get.attitude(player, b))[0]; if (get.attitude(player, body) > 4 && !body.isDamaged() && body.getHp() <= 2) return -10; return 0; }, target(player, target) { return Math.sign(get.damageEffect(target, player, target)); }, }, }, }, }, }, //神典韦 juanjia: { trigger: { global: "phaseBefore", player: "enterGame", }, forced: true, filter(event, player) { return (event.name != "phase" || game.phaseNumber == 0) && player.hasEnabledSlot(2); }, content() { player.disableEquip(2); player.expandEquip(1); }, }, qiexie: { trigger: { player: "phaseZhunbeiBegin" }, forced: true, filter(event, player) { return player.countEmptySlot(1) > 0; }, content() { "step 0"; if (!_status.characterlist) { lib.skill.pingjian.initList(); } _status.characterlist.randomSort(); var list = []; for (var name of _status.characterlist) { var info = lib.character[name]; if ( info[3].some(function (skill) { var info = get.skillInfoTranslation(skill); if (!info.includes("【杀】")) return false; var list = get.skillCategoriesOf(skill); list.remove("锁定技"); return list.length == 0; }) ) { list.push(name); if (list.length >= 5) break; } } if (!list.length) event.finish(); else { var num = player.countEmptySlot(1); player .chooseButton( [ "挈挟:选择" + (num > 1 ? "至多" : "") + get.cnNumber(num) + "张武将置入武器栏", [ list, function (item, type, position, noclick, node) { return lib.skill.qiexie.$createButton(item, type, position, noclick, node); }, ], ], [1, num], true ) .set("ai", function (button) { var name = button.link; var info = lib.character[name]; var skills = info[3].filter(function (skill) { var info = get.skillInfoTranslation(skill); if (!info.includes("【杀】")) return false; var list = get.skillCategoriesOf(skill); list.remove("锁定技"); return list.length == 0; }); var eff = 0.2; for (var i of skills) { eff += get.skillRank(i, "in"); } return eff; }); } "step 1"; if (result.bool) { var list = result.links; game.addVideo("skill", player, ["qiexie", [list]]); _status.characterlist.removeArray(list); game.broadcastAll( function (player, list) { player.tempname.addArray(list); for (var name of list) lib.skill.qiexie.createCard(name); }, player, list ); var cards = list.map(function (name) { var card = game.createCard("qiexie_" + name, "none", get.infoMaxHp(lib.character[name][2])); return card; }); player.$gain2(cards); game.delayx(); for (var card of cards) player.equip(card); } }, $createButton(item, type, position, noclick, node) { node = ui.create.buttonPresets.character(item, "character", position, noclick); const info = lib.character[item]; const skills = info[3].filter(function (skill) { var info = get.skillInfoTranslation(skill); if (!info.includes("【杀】")) return false; var list = get.skillCategoriesOf(skill); list.remove("锁定技"); return list.length == 0; }); if (skills.length) { const skillstr = skills.map(i => `[${get.translation(i)}]`).join("
    "); const skillnode = ui.create.caption(`
    ${skillstr}
    `, node); skillnode.style.left = "2px"; skillnode.style.bottom = "2px"; } node._customintro = function (uiintro, evt) { const character = node.link, characterInfo = get.character(node.link); let capt = get.translation(character); if (characterInfo) { const infoHp = get.infoMaxHp(characterInfo[2]); capt += `  范围:${infoHp}`; } uiintro.add(capt); if (lib.characterTitle[node.link]) { uiintro.addText(get.colorspan(lib.characterTitle[node.link])); } for (let i = 0; i < skills.length; i++) { if (lib.translate[skills[i] + "_info"]) { let translation = lib.translate[skills[i] + "_ab"] || get.translation(skills[i]).slice(0, 2); if (lib.skill[skills[i]] && lib.skill[skills[i]].nobracket) { uiintro.add('
    ' + get.translation(skills[i]) + "
    " + get.skillInfoTranslation(skills[i]) + "
    "); } else { uiintro.add('
    【' + translation + "】
    " + get.skillInfoTranslation(skills[i]) + "
    "); } if (lib.translate[skills[i] + "_append"]) { uiintro._place_text = uiintro.add('
    ' + lib.translate[skills[i] + "_append"] + "
    "); } } } }; return node; }, video(player, info) { for (var name of info[0]) { lib.skill.qiexie.createCard(name); } }, createCard(name) { if (!_status.postReconnect.qiexie) _status.postReconnect.qiexie = [ function (list) { for (var name of list) lib.skill.qiexie.createCard(name); }, [], ]; _status.postReconnect.qiexie[1].add(name); if (!lib.card["qiexie_" + name]) { if (lib.translate[name + "_ab"]) lib.translate["qiexie_" + name] = lib.translate[name + "_ab"]; else lib.translate["qiexie_" + name] = lib.translate[name]; var info = lib.character[name]; var card = { fullimage: true, image: "character:" + name, type: "equip", subtype: "equip1", enable: true, selectTarget: -1, filterCard(card, player, target) { if (player != target) return false; return target.canEquip(card, true); }, modTarget: true, allowMultiple: false, content: lib.element.content.equipCard, toself: true, ai: {}, skills: ["qiexie_destroy"], }; var maxHp = get.infoMaxHp(info[2]); if (maxHp != 1) card.distance = { attackFrom: 1 - maxHp }; var skills = info[3].filter(function (skill) { var info = get.skillInfoTranslation(skill); if (!info.includes("【杀】")) return false; var list = get.skillCategoriesOf(skill); list.remove("锁定技"); return list.length == 0; }); var str = "锁定技。"; if (skills.length) { card.skills.addArray(skills); str += "你视为拥有技能"; for (var skill of skills) { str += "〖" + get.translation(skill) + "〗"; str += "、"; } str = str.slice(0, str.length - 1); str += ";"; card.ai.equipValue = function (card, player) { let val = maxHp; if (player.hasSkill("qiexie")) val *= 0.4; else val *= 0.6; return (val += skills.length); }; } str += "此牌离开你的装备区后,改为置入剩余武将牌牌堆。"; lib.translate["qiexie_" + name + "_info"] = str; var append = ""; if (skills.length) { for (var skill of skills) { if (lib.skill[skill].nobracket) { append += '
    ' + get.translation(skill) + '
    ' + get.skillInfoTranslation(skill) + "


    "; } else { var translation = lib.translate[skill + "_ab"] || get.translation(skill).slice(0, 2); append += '
    【' + translation + '】
    ' + get.skillInfoTranslation(skill) + "


    "; } } str = str.slice(0, str.length - 8); } lib.translate["qiexie_" + name + "_append"] = append; lib.card["qiexie_" + name] = card; } }, subSkill: { destroy: { trigger: { player: "loseBegin" }, equipSkill: true, forceDie: true, charlotte: true, forced: true, popup: false, filter(event, player) { return event.cards.some(card => card.name.indexOf("qiexie_") == 0); }, content() { for (var card of trigger.cards) { if (card.name.indexOf("qiexie_") == 0) { card._destroy = true; game.log(card, "被放回武将牌堆"); var name = card.name.slice(7); if (player.tempname && player.tempname.includes(name)) { game.broadcastAll( (player, name) => { player.tempname.remove(name); }, player, name ); } if (lib.character[name]) _status.characterlist.add(name); } } }, }, }, }, cuijue: { enable: "phaseUse", filter(event, player) { return player.countCards("he") > 0; //&&game.hasPlayer(target=>lib.skill.cuijue.filterTarget('SB',player,target)); }, filterCard: true, filterTarget(card, player, target) { if (player.getStorage("cuijue_used").includes(target) || !player.inRange(target)) return false; var distance = get.distance(player, target); return !game.hasPlayer(current => current != target && player.inRange(current) && get.distance(player, current) > distance); }, selectTarget: [0, 1], filterOk() { var player = _status.event.player; if (game.hasPlayer(target => lib.skill.cuijue.filterTarget("SB", player, target))) return ui.selected.targets.length > 0; return true; }, position: "he", complexTarget: true, check: card => { var player = _status.event.player, goon = 0; try { ui.selected.cards.add(card); if ( game.hasPlayer(target => { return lib.skill.cuijue.filterTarget("SB", player, target); }) ) { goon = 6; } } catch (e) { console.trace(e); } ui.selected.cards.remove(card); return goon - get.value(card); }, content() { if (target) { player.addTempSkill("cuijue_used", "phaseUseAfter"); player.markAuto("cuijue_used", [target]); target.damage("nocard"); } }, ai: { order: 2, result: { target: -1.5, }, tag: { damage: 1, }, }, subSkill: { used: { onremove: true, charlotte: true, }, }, }, //神邓艾 dctuoyu: { audio: 2, trigger: { player: ["phaseUseBegin", "phaseUseEnd"] }, forced: true, filter(event, player) { return player.countCards("h") > 0 && player.getStorage("dctuoyu").length > 0; }, content() { "step 0"; var hs = player.getCards("h"), tags = ["dctuoyu_fengtian", "dctuoyu_qingqu", "dctuoyu_junshan"]; var storage = player.getStorage("dctuoyu"); var list = [ ["未分配手牌(对话框较长,请下滑操作)", []], ["丰田(伤害/回复值+1)", []], ["清渠(无次数和距离限制)", []], ["峻山(不可被响应)", []], ]; for (var card of hs) { var added = false; for (var i = 0; i < tags.length; i++) { if (card.hasGaintag(tags[i] + "_tag")) { added = true; list[i + 1][1].push(card); break; } } if (!added) list[0][1].push(card); } for (var row of list) { for (var i = 0; i < tags.length; i++) { if (!storage.includes(tags[i])) { list[i + 1][0] = get.translation(tags[i]) + "(尚未激活)"; } } } var next = player.chooseToMove("拓域:请分配你的手牌", true); next.set("list", list); next.set("filterMove", function (from, to, moved) { var storage = _status.event.player.getStorage("dctuoyu"), tags = ["dctuoyu_fengtian", "dctuoyu_qingqu", "dctuoyu_junshan"]; if (typeof to == "number") { if (to == 0) return true; return storage.includes(tags[to - 1]) && moved[to].length < 5; } return true; }); next.set("processAI", function () { var player = _status.event.player; var storage = player.getStorage("dctuoyu"), tags = ["dctuoyu_fengtian", "dctuoyu_qingqu", "dctuoyu_junshan"]; var moved = [[], [], [], []]; var isEmpty = function (to) { return storage.includes(tags[to - 1]) && moved[to].length < 5; }; var hs = player.getCards("h"); var hs2 = hs.slice(0); var usable = player.getCardUsable("sha"); var addTo = function (card, to) { if (isEmpty(to)) { hs2.remove(card); moved[to].push(card); if (get.name(card) == "sha" && to != 2) usable--; } }; var hasRuanshizi = game.hasPlayer(function (target) { return ( target != player && player.canUse("sha", target, null, true) && !target.mayHaveShan( player, "use", target.getCards("h", i => { return i.hasGaintag("sha_notshan"); }) ) && get.attitude(player, target) < 0 && get.effect(target, { name: "sha" }, player, player) > 0 ); }); for (var card of hs) { var name = get.name(card); if (name == "tao" || name == "jiu") { addTo(card, 1); } else if (name == "sha") { if (hasRuanshizi && isEmpty(1) && usable > 0) addTo(card, 1); else if (isEmpty(3) && usable > 0) addTo(card, 3); else addTo(card, 2); } else if (get.type(name) == "trick") { if (isEmpty(1) && get.tag(card, "damage") > 0 && player.hasUseTarget(card)) addTo(card, 1); else addTo(card, 3); } } moved[0].addArray(hs2); return moved; }); "step 1"; if (result.bool) { game.broadcastAll( function (moved, player) { var tags = ["dctuoyu_fengtian", "dctuoyu_qingqu", "dctuoyu_junshan"]; var cards = []; for (var i = 0; i < moved.length; i++) { for (var card of moved[i]) { cards.unshift(card); for (var j = 0; j < tags.length; j++) { if (i == j + 1) { if (!card.hasGaintag(tags[j] + "_tag")) card.addGaintag(tags[j] + "_tag"); } else { if (card.hasGaintag(tags[j] + "_tag")) card.removeGaintag(tags[j] + "_tag"); } } } } if (player == game.me) { game.addVideo("lose", game.me, [get.cardsInfo(cards), [], [], []]); for (var i = 0; i < cards.length; i++) { cards[i].goto(ui.special); } game.me.directgain(cards, false); } }, result.moved, player ); } }, intro: { content: "已激活的副区域:$", }, group: "dctuoyu_effect", subSkill: { effect: { mod: { targetInRange(card, player, target) { if (!card.cards) return; for (var i of card.cards) { if (i.hasGaintag("dctuoyu_qingqu_tag")) return true; } }, cardUsable(card, player, num) { if (!card.cards) return; for (var i of card.cards) { if (i.hasGaintag("dctuoyu_qingqu_tag")) return Infinity; } }, }, trigger: { player: "useCard" }, forced: true, filter(event, player) { var tags = ["dctuoyu_fengtian_tag", "dctuoyu_qingqu_tag", "dctuoyu_junshan_tag"], card = event.card; return player.hasHistory("lose", function (evt) { if (evt.getParent() != event) return false; for (var i in evt.gaintag_map) { for (var tag of evt.gaintag_map[i]) { if (tags.includes(tag)) return true; } } return false; }); }, content() { var tags = ["dctuoyu_fengtian_tag", "dctuoyu_qingqu_tag", "dctuoyu_junshan_tag"], card = trigger.card; player.hasHistory("lose", function (evt) { if (evt.getParent() != trigger) return false; for (var i in evt.gaintag_map) { tags.removeArray(evt.gaintag_map[i]); } return tags.length == 0; }); if (!tags.includes("dctuoyu_fengtian_tag")) { if (get.tag(card, "damage") > 0 || get.tag(card, "recover") > 0) { trigger.baseDamage++; game.log(card, "的伤害值/回复值+1"); } } if (!tags.includes("dctuoyu_qingqu_tag")) { if (trigger.addCount !== false) { trigger.addCount = false; var stat = player.getStat("card"); if (stat[card.name] && stat[card.name] > 0) stat[card.name]--; game.log(card, "不计入次数限制"); } } if (!tags.includes("dctuoyu_junshan_tag")) { game.log(card, "不可被响应"); trigger.directHit.addArray(game.filterPlayer()); } }, }, }, ai: { combo: "dcxianjin", }, }, dcxianjin: { init(player) { var num = game .getAllGlobalHistory("changeHp", evt => { return evt.getParent().name == "damage" && (evt.getParent().player == player || (evt.getParent().source && evt.getParent().source == player)); }) .concat( game.getAllGlobalHistory("changeHp", evt => { return evt.getParent().name == "damage" && evt.getParent().player == player && evt.getParent().source && evt.getParent().source == player; }) ).length; if (num) player.addMark("dcxianjin", num, false); }, onremove: true, audio: 2, trigger: { player: "damageEnd", source: "damageSource", }, filter(event, player) { return player.countMark("dcxianjin") % 2 == 0; }, forced: true, content() { "step 0"; var tags = ["dctuoyu_fengtian", "dctuoyu_qingqu", "dctuoyu_junshan"]; tags.removeArray(player.getStorage("dctuoyu")); if (!tags.length) { player.draw(player.isMaxHandcard() ? 1 : 3); event.finish(); } else if (tags.length == 1) { event._result = { control: tags[0] }; } else player.chooseControl(tags).set("prompt", "险峻:选择激活一个副区域标签"); "step 1"; var control = result.control; game.log(player, "激活了副区域", "#y" + get.translation(control)); player.markAuto("dctuoyu", [control]); player.popup(get.translation(control + "_tag")); if (player.isMaxHandcard()) player.draw(); else player.draw(player.getStorage("dctuoyu").length); }, group: "dcxianjin_mark", intro: { content: "已造成或受到#次伤害" }, subSkill: { mark: { charlotte: true, trigger: { player: "damageEnd", source: "damageSource", }, forced: true, popup: false, firstDo: true, content() { player.addMark("dcxianjin", 1, false); }, }, }, ai: { combo: "dctuoyu", }, }, dcqijing: { derivation: "dccuixin", audio: 2, trigger: { global: "phaseEnd" }, filter(event, player) { return player.getStorage("dctuoyu").length == 3; }, forced: true, juexingji: true, skillAnimation: true, animationColor: "orange", changeSeat: true, content() { "step 0"; player.awakenSkill("dcqijing"); player.loseMaxHp(); player.addSkills("dccuixin"); "step 1"; if (game.countPlayer() > 2) { if (player == trigger.player && !trigger.skill) { var evt = trigger.getParent(); if (evt.name == "phaseLoop" && evt._isStandardLoop) evt.player = player.next; } player .chooseTarget( "请选择一名要更换座次的角色,将自己移动到该角色的上家位置", function (card, player, target) { return target != player && target != player.next; }, true ) .set("ai", function (target) { var player = _status.event.player; var current = _status.currentPhase.next; var max = 20, att = 0; while (max > 0) { max--; if (current == target) return att; att -= get.attitude(player, current); current = current.next; } return att; }); } else event.finish(); "step 2"; if (result.bool) { var target = result.targets[0]; game.broadcastAll( function (target1, target2) { game.swapSeat(target1, target2, null, true); }, player, target ); } else event.finish(); "step 3"; player.insertPhase(); }, ai: { combo: "dctuoyu", }, }, dccuixin: { audio: 2, trigger: { player: "useCardAfter" }, filter(event, player) { if (!event._dccuixin || get.type(event.card, false) == "delay" || get.type(event.card, false) == "equip") return false; var card = { name: event.card.name, nature: event.card.nature, isCard: true, }, list = event._dccuixin; for (var target of list) { var targetx = player[target](); if (lib.filter.targetEnabled2(card, targetx, player)) return true; } return false; }, direct: true, content() { "step 0"; var card = { name: trigger.card.name, nature: trigger.card.nature, isCard: true, }; event.card = card; var list = []; trigger._dccuixin.forEach(target => { var targetx = player[target](); if (lib.filter.targetEnabled2(card, targetx, player)) list.add(targetx); }); if (list.length == 1) { event.target = list[0]; player .chooseBool("摧心:是否视为对" + get.translation(list[0]) + "使用" + get.translation(card) + "?") .set("goon", get.effect(list[0], card, player, player) > 0) .set("ai", () => _status.event.goon); } else { player .chooseTarget("摧心:是否视为对上家或下家使用" + get.translation(card) + "?", "操作提示:从上家或下家中选择一名角色作为使用目标", function (card, player, target) { return (target == player.getNext() || target == player.getPrevious()) && lib.filter.targetEnabled2(_status.event.getParent().card, target, player); }) .set("ai", function (target) { var player = _status.event.player; return get.effect(target, _status.event.getParent().card, player, player); }); } "step 1"; if (result.bool) { var target = event.target || result.targets[0]; player.useCard(card, target, false, "dccuixin"); } }, group: "dccuixin_silent", subSkill: { silent: { trigger: { player: "useCardToPlayered" }, silent: true, forced: true, popup: false, firstDo: true, charlotte: true, filter(event, player) { if (!event.isFirstTarget || event.getParent().skill == "dccuixin") return false; if (event.targets.length == 0) return false; return event.targets.includes(player.getNext()) || event.targets.includes(player.getPrevious()); }, content() { var list = []; if (trigger.targets.includes(player.getNext())) list.push("getPrevious"); if (trigger.targets.includes(player.getPrevious())) list.push("getNext"); trigger.getParent()._dccuixin = list; }, }, }, }, //海外神吕蒙 twshelie: { audio: "shelie", inherit: "shelie", prompt2: () => lib.translate.shelie_info, group: "twshelie_jingce", //什么精策技能啊喂! subSkill: { round: { charlotte: true }, count: { charlotte: true, onremove: true, intro: { markcount(storage) { return storage.length; }, content: "本回合已使用$花色的牌", }, }, jingce: { audio: "shelie", trigger: { player: ["phaseJieshuBegin", "useCard1"] }, filter(event, player) { if (player.hasSkill("twshelie_round") || player != _status.currentPhase) return false; var list = []; player.getHistory("useCard", function (evt) { if (lib.suit.includes(get.suit(evt.card)) && !list.includes(get.suit(evt.card))) list.push(get.suit(evt.card)); }); if (list.length) { player.addTempSkill("twshelie_count"); player.storage.twshelie_count = list.sort(function (a, b) { return lib.suit.indexOf(b) - lib.suit.indexOf(a); }); player.markSkill("twshelie_count"); player.syncStorage("twshelie_count"); } return event.name != "useCard" && list.length >= player.hp; }, forced: true, locked: false, content() { "step 0"; player.addTempSkill("twshelie_round", "roundStart"); player.chooseControl("摸牌阶段", "出牌阶段").set("prompt", "涉猎:请选择要执行的额外阶段"); "step 1"; if (result.index == 0) { var next = player.phaseDraw(); event.next.remove(next); trigger.getParent().next.push(next); } if (result.index == 1) { var next = player.phaseUse(); event.next.remove(next); trigger.getParent().next.push(next); } }, }, }, }, twgongxin: { audio: "gongxin", enable: "phaseUse", filter(event, player) { return game.hasPlayer(function (current) { return current != player && current.countCards("h"); }); }, filterTarget(card, player, target) { return target != player && target.countCards("h") > 0; }, usable: 1, content() { "step 0"; event.num = target.getCards("h").reduce(function (arr, card) { return arr.add(get.suit(card, player)), arr; }, []).length; "step 1"; var cards = target.getCards("h"); player .chooseButton(2, ["攻心", cards, [["弃置此牌", "置于牌堆顶"], "tdnodes"]]) .set("filterButton", function (button) { var type = typeof button.link; if (ui.selected.buttons.length && type == typeof ui.selected.buttons[0].link) return false; return true; }) .set("ai", function (button) { var target = _status.event.target; var type = typeof button.link; if (type == "object") return get.value(button.link, target); }); "step 2"; if (result.bool) { if (typeof result.links[0] != "string") result.links.reverse(); var card = result.links[1], choice = result.links[0]; if (choice == "弃置此牌") target.discard(card); else { player.showCards(card, get.translation(player) + "对" + get.translation(target) + "发动了【攻心】"); target.lose(card, ui.cardPile, "visible", "insert"); game.log(card, "被置于了牌堆顶"); } } "step 3"; if ( event.num == target.getCards("h").reduce(function (arr, card) { return arr.add(get.suit(card, player)), arr; }, []).length ) event.finish(); "step 4"; var num1 = 0; for (var card of target.getCards("h")) { if (get.color(card) == "red") num1++; } var num2 = target.countCards("h") - num1; player .chooseControl(["红色", "黑色", "cancel2"]) .set("prompt", "是否令" + get.translation(target) + "本回合无法使用一种颜色的牌?") .set("ai", function () { return num1 >= num2 ? "红色" : "黑色"; }); "step 5"; if (result.control != "cancel2") { player.line(target); target.addTempSkill("twgongxin2"); target.markAuto("twgongxin2", [result.control == "红色" ? "red" : "black"]); game.log(target, "本回合无法使用" + result.control + "牌"); if (!event.isMine() && !event.isOnline()) game.delayx(); } }, ai: { order: 10, expose: 0.25, result: { target(player, target) { return -target.countCards("h"); }, }, }, }, twgongxin2: { mod: { cardEnabled2(card, player) { const color = get.color(card); if (color != "unsure" && player.getStorage("twgongxin2").includes(color)) return false; }, }, charlotte: true, onremove: true, intro: { content: "本回合内不能使用或打出$牌" }, }, //神张角 yizhao: { audio: 2, trigger: { player: ["useCard", "respond"], }, forced: true, filter(event, player) { return typeof get.number(event.card) == "number"; }, marktext: "黄", intro: { name: "黄(异兆/肆军)", name2: "黄", content: "mark", markcount(storage, player) { return (storage || 0).toString().slice(-2); }, }, content() { "step 0"; event.num = player.countMark("yizhao"); player.addMark("yizhao", get.number(trigger.card)); "step 1"; var num = Math.floor(num / 10) % 10, num2 = Math.floor(player.countMark("yizhao") / 10) % 10; if (num != num2) { var card = get.cardPile2(card => { return get.number(card, false) == num2; }); if (card) player.gain(card, "gain2"); } }, mod: { aiOrder(player, card, num) { if (Math.floor((get.number(card) + (player.countMark("yizhao") % 10)) / 10) == 1) return num + 10; }, }, ai: { threaten: 1.5, effect: { target(card, player, target, current) { if (get.type(card) == "equip" && !get.cardtag(card, "gifts")) return [1, 0.1]; }, }, }, }, sijun: { audio: 2, trigger: { player: "phaseZhunbeiBegin" }, filter(event, player) { return player.countMark("yizhao") > ui.cardPile.childNodes.length; }, check(event, player) { return ui.cardPile.childNodes.length; }, content() { "step 0"; player.removeMark("yizhao", player.countMark("yizhao")); game.washCard(); "step 1"; var pile = Array.from(ui.cardPile.childNodes); if (pile.length < 3) return; var bool = false, max = Math.pow(2, Math.min(100, pile.length)), index; for (var i = 0; i < max; i++) { var num = 0; index = i.toString(2); while (index.length < pile.length) { index = "0" + index; } for (var k = 0; k < index.length; k++) { if (index[k] == "1") num += get.number(pile[k]); if (num > 36) break; } if (num == 36) { bool = true; break; } } if (bool) { var cards = []; for (var k = 0; k < index.length; k++) { if (index[k] == "1") cards.push(pile[k]); } player.gain(cards, "gain2"); } }, ai: { combo: "yizhao", }, }, sanshou: { audio: 2, trigger: { player: "damageBegin4" }, check(event, player) { return get.damageEffect(player, event.source, player, event.nature) <= 0; }, content() { "step 0"; var cards = game.cardsGotoOrdering(get.cards(3)).cards; event.cards = cards; player.showCards(cards, get.translation(player) + "发动了【三首】"); "step 1"; var types = []; types.addArray(game.getGlobalHistory("useCard").map(evt => get.type2(evt.card))); if (cards.filter(card => !types.includes(get.type2(card))).length) { trigger.cancel(); } game.delayx(); }, ai: { effect: { target(card, player, target) { if (card.name == "shandian" || card.name == "fulei") return [0, 0.1]; if (!get.tag(card, "damage")) return; var types = [], bool = 0; types.addArray(game.getGlobalHistory("useCard").map(evt => get.type2(evt.card))); if (!types.includes(get.type2(card))) bool = 1; if (types.length < 2) return Math.min(1, 0.4 + (types.length + bool) * 0.2); }, }, }, }, tianjie: { audio: 2, trigger: { global: "phaseEnd" }, direct: true, filter(event, player) { return game.hasGlobalHistory("cardMove", evt => evt.washCard) && game.hasPlayer(current => current != player); }, skillAnimation: true, animationColor: "metal", content() { "step 0"; player.chooseTarget(get.prompt("tianjie"), "选择至多三名其他角色,依次对这些角色造成X点雷电伤害(X为其手牌中【闪】的数量,至少为1)", [1, 3]).set("ai", target => { var player = _status.event.player; return get.damageEffect(target, player, player, "thunder") * Math.sqrt(Math.max(1, target.countCards("h", "shan"))); }); "step 1"; if (result.bool) { var targets = result.targets; targets.sortBySeat(); player.logSkill("tianjie", targets); for (var target of targets) { var num = Math.max(1, target.countCards("h", "shan")); target.damage(num, "thunder"); } } }, }, shencai: { audio: 2, enable: "phaseUse", usable: 5, filter(event, player) { var count = player.getStat("skill").shencai; if (count && count > player.countMark("shencai")) return false; return true; }, filterTarget: lib.filter.notMe, onremove: true, prompt: "选择一名其他角色进行地狱审判", content() { var next = target.judge(); next.callback = lib.skill.shencai.contentx; }, ai: { order: 8, result: { target: -1 }, }, contentx() { var card = event.judgeResult.card; var player = event.getParent(2).player; var target = event.getParent(2).target; if (get.position(card, true) == "o") player.gain(card, "gain2"); var list = [], str = lib.skill.shencai.getStr(card); for (var i in lib.skill.shencai.filterx) { if (str.indexOf(lib.skill.shencai.filterx[i]) != -1) list.push("shencai_" + i); } if (list.length) { for (var i in lib.skill.shencai.filterx) { var num = target.countMark("shencai_" + i); if (num > 0) { target.removeMark("shencai_" + i, num); target.removeSkill("shencai_" + i); } } if (target.isIn()) { for (var i of list) { target.addSkill(i); target.addMark(i, 1); } } } else if (target.isIn()) { player.gainPlayerCard(target, true, "hej"); target.addMark("shencai_death", 1); target.addSkill("shencai_death"); } }, filterx: { losehp: "体力", weapon: "武器", respond: "打出", distance: "距离", }, getStr(node) { var str = "", name = node.name; if (lib.translate[name + "_info"]) { if (lib.card[name].type && lib.translate[lib.card[name].type]) str += "" + get.translation(lib.card[name].type) + "牌|"; if (get.subtype(name)) { str += "" + get.translation(get.subtype(name)) + "|"; } if (lib.card[name] && lib.card[name].addinfomenu) { str += "" + lib.card[name].addinfomenu + "|"; } if (get.subtype(name) == "equip1") { var added = false; if (lib.card[node.name] && lib.card[node.name].distance) { var dist = lib.card[node.name].distance; if (dist.attackFrom) { added = true; str += "攻击范围:" + (-dist.attackFrom + 1) + "|"; } } if (!added) { str += "攻击范围:1|"; } } } if (lib.card[name].cardPrompt) { str += "" + lib.card[name].cardPrompt(node) + "|"; } else if (lib.translate[name + "_info"]) { str += "" + lib.translate[name + "_info"] + "|"; } if (lib.translate[name + "_append"]) { str += "" + lib.translate[name + "_append"] + "|"; } if (get.is.yingbianConditional(node)) { const yingbianEffects = get.yingbianEffects(node); if (!yingbianEffects.length) { const defaultYingbianEffect = get.defaultYingbianEffect(node); if (lib.yingbian.prompt.has(defaultYingbianEffect)) yingbianEffects.push(defaultYingbianEffect); } if (yingbianEffects.length) str += `应变:${yingbianEffects.map(value => lib.yingbian.prompt.get(value)).join(";")}|`; } return str; }, subSkill: { losehp: { charlotte: true, marktext: "笞", trigger: { player: "damageEnd" }, forced: true, content() { player.loseHp(trigger.num); }, ai: { effect: { target(card, player, target, current) { if (get.tag(card, "damage") && current < 0) return 1.6; }, }, }, intro: { name: "神裁 - 体力", name2: "笞", content: "锁定技。当你受到伤害后,你失去等量的体力。", onunmark: true, }, }, weapon: { charlotte: true, marktext: "杖", trigger: { target: "useCardToTargeted" }, forced: true, filter(event, player) { return event.card.name == "sha"; }, content() { trigger.directHit.add(player); game.log(player, "不可响应", trigger.card); }, intro: { name: "神裁 - 武器", name2: "杖", content: "锁定技。当你成为【杀】的目标后,你不能使用牌响应此【杀】。", onunmark: true, }, global: "shencai_weapon_ai", }, ai: { ai: { directHit_ai: true, skillTagFilter(player, tag, arg) { if (!arg || !arg.card || arg.card.name != "sha") return false; if (!arg.target || !arg.target.hasSkill("shencai_weapon")) return false; return true; }, }, }, respond: { charlotte: true, marktext: "徒", trigger: { player: "loseAfter", global: ["equipAfter", "addJudgeAfter", "gainAfter", "loseAsyncAfter", "addToExpansionAfter"], }, forced: true, filter(event, player) { if ( !player.hasCard(function (card) { return lib.filter.cardDiscardable(card, player, "shencai_respond"); }, "h") ) return false; var evt = event.getParent("shencai_respond"); if (evt && evt.player == player) return false; evt = event.getl(player); return evt && evt.hs && evt.hs.length > 0; }, content() { var cards = player.getCards("h", function (card) { return lib.filter.cardDiscardable(card, player, "shencai_respond"); }); if (cards.length > 0) player.discard(cards.randomGet()); }, intro: { name: "神裁 - 打出", name2: "徒", content: "锁定技。当你失去手牌后,你随机弃置一张手牌(不嵌套触发)。", onunmark: true, }, }, distance: { charlotte: true, marktext: "流", trigger: { player: "phaseJieshuBegin" }, forced: true, content() { player.turnOver(); }, intro: { name: "神裁 - 距离", name2: "流", content: "锁定技。结束阶段开始时,你翻面。", onunmark: true, }, }, death: { charlotte: true, marktext: "死", mod: { maxHandcard(player, num) { return num - player.countMark("shencai_death"); }, }, trigger: { player: "phaseEnd" }, forced: true, filter(event, player) { return player.countMark("shencai_death") > game.countPlayer(); }, content() { player.die(); }, intro: { name: "神裁 - 死", name2: "死", content: "锁定技。你的角色手牌上限-#;回合结束时,若场上存活人数小于#,则你死亡。", onunmark: true, }, }, }, intro: { content: "发动次数上限+#", }, }, xunshi: { audio: 2, mod: { cardname(card) { if (lib.skill.xunshi.isXunshi(card)) return "sha"; }, cardnature(card) { if (lib.skill.xunshi.isXunshi(card)) return false; }, suit(card) { if (lib.skill.xunshi.isXunshi(card)) return "none"; }, targetInRange(card) { const suit = get.color(card); if (suit == "none" || suit == "unsure") return true; }, cardUsable(card) { const suit = get.color(card); if (suit == "none" || suit == "unsure") return Infinity; }, }, isXunshi(card) { var info = lib.card[card.name]; if (!info || (info.type != "trick" && info.type != "delay")) return false; if (info.notarget) return false; if (info.selectTarget != undefined) { if (Array.isArray(info.selectTarget)) { if (info.selectTarget[0] < 0) return !info.toself; return info.selectTarget[0] != 1 || info.selectTarget[1] != 1; } else { if (info.selectTarget < 0) return !info.toself; return info.selectTarget != 1; } } return false; }, trigger: { player: "useCard2" }, forced: true, filter(event, player) { return get.color(event.card) == "none"; }, content() { "step 0"; if (player.countMark("shencai") < 4 && player.hasSkill("shencai", null, null, false)) player.addMark("shencai", 1, false); if (trigger.addCount !== false) { trigger.addCount = false; var stat = player.getStat().card, name = trigger.card.name; if (typeof stat[name] == "number") stat[name]--; } var info = get.info(trigger.card); if (info.allowMultiple == false) event.finish(); else if (trigger.targets && !info.multitarget) { if ( !game.hasPlayer(function (current) { return !trigger.targets.includes(current) && lib.filter.targetEnabled2(trigger.card, player, current); }) ) event.finish(); } else event.finish(); "step 1"; var prompt2 = "为" + get.translation(trigger.card) + "增加任意个目标"; player .chooseTarget( get.prompt("xunshi"), function (card, player, target) { var player = _status.event.player; return !_status.event.targets.includes(target) && lib.filter.targetEnabled2(_status.event.card, player, target); }, [1, Infinity] ) .set("prompt2", prompt2) .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 2"; if (result.bool) { if (!event.isMine() && !event.isOnline()) game.delayx(); event.targets = result.targets; } else { event.finish(); } "step 3"; if (event.targets) { player.line(event.targets, "fire"); trigger.targets.addArray(event.targets); } }, }, twwushen: { mod: { cardname(card, player, name) { if (get.suit(card) == "heart") return "sha"; }, cardnature(card, player) { if (get.suit(card) == "heart") return false; }, targetInRange(card) { if (card.name === "sha") { const suit = get.suit(card); if (suit === "heart" || suit === "unsure") return true; } }, cardUsable(card) { if (card.name === "sha") { const suit = get.suit(card); if (suit === "heart" || suit === "unsure") return Infinity; } }, }, audio: "wushen", trigger: { player: "useCard2" }, forced: true, filter(event, player) { return event.card.name == "sha" && (get.suit(event.card) == "heart" || !player.hasSkill("twwushen_phase", null, null, false)); }, logTarget(event, player) { if (get.suit(event.card) == "heart") { var targets = game.filterPlayer(function (current) { return !event.targets.includes(current) && current.hasMark("twwuhun") && lib.filter.targetEnabled(event.card, player, current); }); if (targets.length) { return targets.sortBySeat(); } } return null; }, content() { if (!player.hasSkill("twwushen_phase", null, null, false)) { trigger.directHit.addArray(game.players); player.addTempSkill("twwushen_phase", ["phaseZhunbeiAfter", "phaseJudgeAfter", "phaseDrawAfter", "phaseUseAfter", "phaseDiscardAfter", "phaseJieshuAfter"]); } if (get.suit(trigger.card) == "heart") { if (trigger.addCount !== false) { trigger.addCount = false; if (player.stat[player.stat.length - 1].card.sha > 0) { player.stat[player.stat.length - 1].card.sha--; } } var targets = game.filterPlayer(function (current) { return !trigger.targets.includes(current) && current.hasMark("twwuhun") && lib.filter.targetEnabled(trigger.card, player, current); }); if (targets.length) { trigger.targets.addArray(targets.sortBySeat()); game.log(targets, "也成为了", trigger.card, "的目标"); } } }, ai: { directHit_ai: true, skillTagFilter(player, tag, arg) { return arg.card.name == "sha" && !player.hasSkill("twwushen_phase", null, null, false); }, }, subSkill: { phase: { charlotte: true } }, shaRelated: true, }, twwuhun: { audio: 2, trigger: { player: "die" }, forceDie: true, skillAnimation: true, animationColor: "soil", locked: true, check(event, player) { return game.hasPlayer(function (current) { return current != player && current.hasMark("twwuhun") && get.attitude(player, current) < 0; }); }, content() { "step 0"; player .judge(function (card) { var name = get.name(card, false); if (name == "tao" || name == "taoyuan") return -25; return 15; }) .set("forceDie", true).judge2 = function (result) { return result.bool; }; "step 1"; var num = game.countPlayer(function (current) { return current != player && current.hasMark("twwuhun"); }); if (result.bool && num > 0) { player .chooseTarget("请选择【武魂】的目标", "选择至少一名拥有“梦魇”标记的角色。令这些角色各自失去X点体力(X为其“梦魇”标记数)", true, [1, num], function (card, player, target) { return target != player && target.hasMark("twwuhun"); }) .set("forceDie", true) .set("ai", function (target) { return -get.attitude(_status.event.player, target); }); } else event.finish(); "step 2"; var targets = result.targets.sortBySeat(); player.line(targets, "fire"); event.targets = targets; "step 3"; var target = targets.shift(); var num = target.countMark("twwuhun"); if (num > 0) target.loseHp(num); if (targets.length > 0) event.redo(); }, marktext: "魇", intro: { name: "梦魇", content: "mark", onunmark: true, }, group: "twwuhun_gain", subSkill: { gain: { audio: "twwuhun", trigger: { player: "damageEnd", source: "damageSource", }, forced: true, filter(event, player, name) { if (event.player == event.source) return false; var target = lib.skill.twwuhun_gain.logTarget(event, player); if (!target || !target.isIn()) return false; return name == "damageEnd" || target.hasMark("twwuhun"); }, logTarget(event, player) { if (player == event.player) return event.source; return event.player; }, content() { var target = lib.skill.twwuhun_gain.logTarget(trigger, player); target.addMark("twwuhun", player == trigger.source ? 1 : trigger.num); game.delayx(); }, }, }, ai: { notemp: true, maixie_defend: true, effect: { target: (card, player, target) => { if (!get.tag(card, "damage") || !target.hasFriend()) return; let die = [], extra = [null, 0], temp; game.filterPlayer(i => { if (!i.hasMark("twwuhun")) return false; temp = get.attitude(target, i); if (temp < 0) die.push(i); else { temp = Math.sqrt(temp) * i.countMark("twwuhun"); if (!extra[0] || temp < extra[1]) extra = [i, temp]; } }); if (extra[0] && !die.length) die.push(extra[0]); if (target.hp + target.hujia > 1 && (!die.length || get.attitude(player, target) <= 0)) die.add(player); if (die.length) return [ 1, 0, 1, die.reduce((num, i) => { return (num -= 2 * get.sgnAttitude(player, i)); }, 0), ]; }, }, }, }, shouli: { audio: 2, mod: { cardUsable(card) { if (card.storage && card.storage.shouli) return Infinity; }, }, enable: ["chooseToUse", "chooseToRespond"], hiddenCard(player, name) { if (player != _status.currentPhase && (name == "sha" || name == "shan")) return true; }, filter(event, player) { if (event.responded || event.shouli || event.type == "wuxie") return false; if ( game.hasPlayer(function (current) { return current.getCards("e", card => get.is.attackingMount(card)).length > 0; }) && event.filterCard( get.autoViewAs( { name: "sha", storage: { shouli: true }, }, "unsure" ), player, event ) ) return true; if ( game.hasPlayer(function (current) { return current.getCards("e", card => get.is.defendingMount(card)).length > 0; }) && event.filterCard( get.autoViewAs( { name: "shan", storage: { shouli: true }, }, "unsure" ), player, event ) ) return true; return false; }, delay: false, locked: false, filterTarget(card, player, target) { var event = _status.event, evt = event; if (event._backup) evt = event._backup; var equip3 = target.getCards("e", card => get.is.defendingMount(card, false)); var equip4 = target.getCards("e", card => get.is.attackingMount(card, false)); if ( equip3.length && equip3.some(card => evt.filterCard( get.autoViewAs( { name: "shan", storage: { shouli: true }, }, [card] ), player, event ) ) ) return true; return equip4.some(card => { var sha = get.autoViewAs( { name: "sha", storage: { shouli: true }, }, [card] ); if (evt.filterCard(sha, player, event)) { if (!evt.filterTarget) return true; return game.hasPlayer(function (current) { return evt.filterTarget(sha, player, current); }); } }); }, prompt: "将场上的一张坐骑牌当做【杀】或【闪】使用或打出", content() { "step 0"; var evt = event.getParent(2); evt.set("shouli", true); var list = []; var equip3 = target.getCards("e", card => get.is.defendingMount(card, false)); var equip4 = target.getCards("e", card => get.is.attackingMount(card, false)); var backupx = _status.event; _status.event = evt; try { if ( equip3.length && equip3.some(card => { var shan = get.autoViewAs( { name: "shan", storage: { shouli: true }, }, [card] ); if (evt.filterCard(shan, player, event)) return true; return false; }) ) { list.push("shan"); } if ( equip4.length && equip4.some(card => { var sha = get.autoViewAs( { name: "sha", storage: { shouli: true }, }, [card] ); if ( evt.filterCard(sha, player, evt) && (!evt.filterTarget || game.hasPlayer(function (current) { return evt.filterTarget(sha, player, current); })) ) return true; return false; }) ) { list.push("sha"); } } catch (e) { game.print(e); } _status.event = backupx; if (list.length == 1) { event.cardName = list[0]; var cards = list[0] == "shan" ? equip3 : equip4; if (cards.length == 1) event._result = { bool: true, links: [cards[0]], }; else player .choosePlayerCard(true, target, "e") .set("filterButton", function (button) { return _status.event.cards.includes(button.link); }) .set("cards", cards); } else player.choosePlayerCard(true, target, "e").set("filterButton", function (button) { var card = button.link; return get.is.attackingMount(card) || get.is.defendingMount(card); }); "step 1"; var evt = event.getParent(2); if (result.bool && result.links && result.links.length) { var name = event.cardName || (get.is.attackingMount(result.links[0]) ? "sha" : "shan"); if (evt.name == "chooseToUse") { game.broadcastAll( function (result, name) { lib.skill.shouli_backup.viewAs = { name: name, cards: [result], storage: { shouli: true }, }; lib.skill.shouli_backup.prompt = "选择" + get.translation(name) + "(" + get.translation(result) + ")的目标"; }, result.links[0], name ); evt.set("_backupevent", "shouli_backup"); evt.backup("shouli_backup"); evt.set("openskilldialog", "选择" + get.translation(name) + "(" + get.translation(result.links[0]) + ")的目标"); evt.set("norestore", true); evt.set("custom", { add: {}, replace: { window() {} }, }); } else { delete evt.result.skill; delete evt.result.used; evt.result.card = get.autoViewAs( { name: name, cards: [result.links[0]], storage: { shouli: true }, }, result.links ); evt.result.cards = [result.links[0]]; target.$give(result.links[0], player, false); if (player != target) target.addTempSkill("fengyin"); target.addTempSkill("shouli_thunder"); player.addTempSkill("shouli_thunder"); evt.redo(); return; } } evt.goto(0); }, ai: { respondSha: true, respondShan: true, skillTagFilter(player, tag) { var func = get.is[tag == "respondSha" ? "attackingMount" : "defendingMount"]; return game.hasPlayer(function (current) { return current.hasCard(card => func(card, false), "e"); }); }, order: 2, result: { player(player, target) { var att = Math.max(8, get.attitude(player, target)); if (_status.event.type != "phase") return 9 - att; if (!player.hasValueTarget({ name: "sha" })) return 0; return 9 - att; }, }, }, group: "shouli_init", subSkill: { thunder: { charlotte: true, trigger: { player: "damageBegin1" }, forced: true, mark: true, content() { trigger.num++; game.setNature(trigger, "thunder"); }, marktext: "⚡", intro: { content: "受到的伤害+1且改为雷属性", }, ai: { effect: { target: (card, player, target) => { if (!get.tag(card, "damage")) return; if (target.hasSkillTag("nodamage") || target.hasSkillTag("nothunder")) return "zeroplayertarget"; if ( target.hasSkillTag("filterDamage", null, { player: player, card: new lib.element.VCard( { name: card.name, nature: "thunder", }, [card] ), }) ) return; return 2; }, }, }, }, init: { audio: "shouli", trigger: { global: "phaseBefore", player: "enterGame", }, forced: true, locked: false, filter(event, player) { return event.name != "phase" || game.phaseNumber == 0; }, logTarget: () => game.filterPlayer(), content() { "step 0"; var targets = game.filterPlayer().sortBySeat(player.getNext()); event.targets = targets; event.num = 0; "step 1"; var target = event.targets[num]; if (target.isIn()) { var card = get.cardPile2(function (card) { if (get.cardtag(card, "gifts")) return false; var type = get.subtype(card); if (type != "equip3" && type != "equip4" && type != "equip6") return false; return target.canUse(card, target); }); if (card) target.chooseUseTarget(card, "nopopup", "noanimate", true); } event.num++; if (event.num < targets.length) event.redo(); }, }, }, }, shouli_backup: { sourceSkill: "shouli", precontent() { "step 0"; delete event.result.skill; var cards = event.result.card.cards; event.result.cards = cards; var owner = get.owner(cards[0]); event.target = owner; owner.$give(cards[0], player, false); player.popup(event.result.card.name, "metal"); game.delayx(); event.getParent().addCount = false; "step 1"; if (player != target) target.addTempSkill("fengyin"); target.addTempSkill("shouli_thunder"); player.addTempSkill("shouli_thunder"); }, filterCard() { return false; }, prompt: "请选择【杀】的目标", selectCard: -1, }, hengwu: { audio: 2, trigger: { player: ["useCard", "respond"] }, frequent: true, filter(event, player) { var suit = get.suit(event.card); if ( !lib.suit.includes(suit) || player.hasCard(function (card) { return get.suit(card, player) == suit; }, "h") ) return false; return game.hasPlayer(function (current) { return current.hasCard(function (card) { return get.suit(card, current) == suit; }, "e"); }); }, content() { var suit = get.suit(trigger.card); player.draw( game.countPlayer(function (current) { return current.countCards("e", function (card) { return get.suit(card, current) == suit; }); }) ); }, ai: { effect: { player: (card, player, target) => { if (typeof card !== "object") return; let suit = get.suit(card); if ( !lib.suit.includes(suit) || player.hasCard(function (i) { return get.suit(i, player) == suit; }, "h") ) return; return [ 1, 0.8 * game.countPlayer(current => { return current.countCards("e", card => { return get.suit(card, current) == suit; }); }), ]; }, target: (card, player, target) => { if ( card.name === "sha" && !player.hasSkillTag( "directHit_ai", true, { target: target, card: card, }, true ) && game.hasPlayer(current => { return current.hasCard(cardx => { return get.subtype(cardx) === "equip3"; }, "e"); }) ) return [0, -0.5]; }, }, }, }, changandajian_equip5: { equipSkill: true, mod: { maxHandcard: (player, num) => num + 2 }, }, changandajian_destroy: { trigger: { player: "loseAfter", global: ["equipAfter", "addJudgeAfter", "gainAfter", "loseAsyncAfter", "addToExpansionAfter"], }, forced: true, charlotte: true, equipSkill: true, filter(event, player) { var evt = event.getl(player); if (!evt || !evt.es || !evt.es.length) return false; for (var i of evt.es) { if (i.name.indexOf("changandajian_equip") == 0) return true; } return false; }, getEffect(player, target) { if (player == target) return 0; var getRaw = function () { var att = get.attitude(player, target); if (att > 0) { if ( target.countCards("j", function (card) { var cardj = card.viewAs ? { name: card.viewAs } : card; return get.effect(target, cardj, target, player) < 0; }) > 0 ) return 3; if (target.getEquip("baiyin") && target.isDamaged() && get.recoverEffect(target, player, player) > 0) { if (target.hp == 1 && !target.hujia) return 1.6; } if ( target.countCards("e", function (card) { if (get.position(card) == "e") return get.value(card, target) < 0; }) > 0 ) return 1; } var es = target.getCards("e"); var noe = es.length == 0 || target.hasSkillTag("noe"); var noe2 = es.filter(function (esx) { return get.value(esx, target) > 0; }).length == 0; if (noe || noe2) return 0; if (att <= 0 && !target.countCards("e")) return 1.5; return -1.5; }; return getRaw() * get.attitude(player, target); }, content() { "step 0"; var num = 0, recover = 0; var evt = trigger.getl(player); for (var i of evt.es) { if (i.name.indexOf("changandajian_equip") == 0) num++; if (i.name == "changandajian_equip2") recover++; } if (recover > 0) player.recover(recover); event.count = num; if ( !game.hasPlayer(function (current) { return current.countCards("ej") > 0; }) ) event.finish(); "step 1"; event.count--; player .chooseTarget(true, "选择一名装备区或判定区有牌的角色", function (card, player, target) { return target.countCards("ej") > 0; }) .set("ai", function (target) { return lib.skill.changandajian_destroy.getEffect(_status.event.player, target); }); "step 2"; if (result.bool) { var target = result.targets[0]; event.target = target; player.line(target, "green"); player.choosePlayerCard(target, true, "ej"); } else event.finish(); "step 3"; if (result.bool) { var card = result.cards[0]; var num = get.number(card); if ([1, 11, 12, 13].includes(num)) { if (lib.filter.canBeGained(card, player, target)) player.gain(card, target, "give", "bySelf"); } else if (lib.filter.canBeDiscarded(card, player, target)) target.discard(card); } else event.finish(); "step 4"; if ( event.count > 0 && game.hasPlayer(function (current) { return current.countCards("ej") > 0; }) ) event.goto(1); }, }, dili: { audio: 2, trigger: { global: "phaseBefore", player: "enterGame", }, forced: true, filter(event, player) { if (player.storage.dili) return false; if (event.name != "phase") return true; if (game.phaseNumber == 0) return true; //让神山识能够获得东吴命运线 return player.name == "key_shiki"; }, content() { player.storage.dili = true; var skill = ["dili_shengzhi", "dili_chigang", "dili_qionglan", "dili_quandao", "dili_jiaohui", "dili_yuanlv"].randomGet(); player.addSkill(skill); game.log(player, '解锁了东吴命运线:', "#g【" + get.translation(skill) + "】"); }, derivation: ["dili_shengzhi", "dili_chigang", "dili_qionglan", "dili_quandao", "dili_jiaohui", "dili_yuanlv", "gzyinghun", "hongde", "rebingyi", "xinfu_guanwei", "bizheng", "xinanguo", "shelie", "wengua", "rebotu", "rezhiheng", "jiexun", "reanxu", "xiashu", "rejieyin", "oldimeng", "xinfu_guanchao", "drlt_jueyan", "lanjiang"], subSkill: { shengzhi: { audio: 2, trigger: { player: "useCard" }, forced: true, filter(event, player) { var num = get.number(event.card); if (typeof num != "number") return false; if (num <= 1) return false; for (var i = 2; i <= Math.sqrt(num); i++) { if (num % i == 0) return false; } if (!player.storage.yuheng) return false; var list = ["gzyinghun", "hongde", "rebingyi"]; for (var i of list) { if (!player.storage.yuheng.includes(i)) return false; } return true; }, content() { trigger.directHit.addArray( game.filterPlayer(function (current) { return current != player; }) ); }, init(player, skill) { player.markAuto("yuheng_current", ["gzyinghun", "hongde", "rebingyi"]); }, mark: true, ai: { directHit_ai: true, skillTagFilter(player, tag, arg) { if (arg && arg.card) { var num = get.number(arg.card); if (typeof num != "number") return false; if (num <= 1) return false; for (var i = 2; i <= Math.sqrt(num); i++) { if (num % i == 0) return false; } return true; } return false; }, }, intro: { name: "命运线:圣质", content(storage, player) { var finished = [], unfinished = ["gzyinghun", "hongde", "rebingyi"]; if (player.storage.yuheng) { for (var i = 0; i < unfinished.length; i++) { if (player.storage.yuheng.includes(unfinished[i])) { finished.push(unfinished[i]); unfinished.splice(i--, 1); } } } var str = ""; if (unfinished.length) str += "
  • 未获得:" + get.translation(unfinished) + "
    "; if (finished.length) str += "
  • 已获得过:" + get.translation(finished) + "
    "; str += "
  • 锁定技。若你因〖驭衡〗获得过〖英魂〗〖弘德〗〖秉壹〗,则当你使用点数为质数的牌时,此牌不可被响应。"; return str; }, }, }, chigang: { audio: 2, trigger: { player: "phaseJudgeBefore" }, forced: true, filter(event, player) { if (!player.storage.yuheng) return false; var list = ["xinfu_guanwei", "bizheng", "xinanguo"]; for (var i of list) { if (!player.storage.yuheng.includes(i)) return false; } return true; }, content() { trigger.cancel(); var next = player.phaseDraw(); event.next.remove(next); trigger.getParent().next.push(next); }, init(player, skill) { player.markAuto("yuheng_current", ["xinfu_guanwei", "bizheng", "xinanguo"]); }, ai: { effect: { target(card) { if (get.type(card) == "delay") return "zerotarget"; }, }, }, mark: true, intro: { name: "命运线:持纲", content(storage, player) { var finished = [], unfinished = ["xinfu_guanwei", "bizheng", "xinanguo"]; if (player.storage.yuheng) { for (var i = 0; i < unfinished.length; i++) { if (player.storage.yuheng.includes(unfinished[i])) { finished.push(unfinished[i]); unfinished.splice(i--, 1); } } } var str = ""; if (unfinished.length) str += "
  • 未获得:" + get.translation(unfinished) + "
    "; if (finished.length) str += "
  • 已获得过:" + get.translation(finished) + "
    "; str += "
  • 锁定技。若你因〖驭衡〗获得过〖观微〗〖弼政〗〖安国〗,则当你的判定阶段开始前,你跳过此阶段并获得一个额外的摸牌阶段。"; return str; }, }, }, qionglan: { audio: 2, init(player, skill) { player.markAuto("yuheng_current", ["shelie", "wengua", "rebotu"]); }, trigger: { player: "useSkillAfter" }, forced: true, limited: true, filter(event, player) { if (!player.storage.yuheng || event.skill != "yuheng") return false; var list = ["shelie", "wengua", "rebotu"]; for (var i of list) { if (!player.storage.yuheng.includes(i)) return false; } return true; }, content() { player.awakenSkill("dili_qionglan"); var list = ["dili_shengzhi", "dili_chigang", "dili_quandao", "dili_jiaohui", "dili_yuanlv"]; var list2 = list.randomRemove(2); if (list2.includes("dili_quandao") && list2.includes("dili_jiaohui")) { list2.randomRemove(1); list2.push(list.randomGet()); } for (var skill of list2) { player.addSkill(skill); game.log(player, '解锁了东吴命运线:', "#g【" + get.translation(skill) + "】"); } }, mark: true, intro: { name: "命运线:穹览", content(storage, player) { var finished = [], unfinished = ["shelie", "wengua", "rebotu"]; if (player.storage.yuheng) { for (var i = 0; i < unfinished.length; i++) { if (player.storage.yuheng.includes(unfinished[i])) { finished.push(unfinished[i]); unfinished.splice(i--, 1); } } } var str = ""; if (unfinished.length) str += "
  • 未获得:" + get.translation(unfinished) + "
    "; if (finished.length) str += "
  • 已获得过:" + get.translation(finished) + "
    "; str += '
  • 锁定技,限定技。若你因〖驭衡〗获得过〖涉猎〗〖问卦〗〖博图〗,则当你发动的〖驭衡〗结算结束后,你随机获得两条其他东吴命运线。'; return str; }, }, }, quandao: { audio: 2, mod: { cardname(card, player) { if (player.storage.yuheng && [1, 11, 12, 13].includes(card.number)) { var list = ["rezhiheng", "jiexun", "reanxu"]; for (var i of list) { if (!player.storage.yuheng.includes(i)) return; } return "tiaojiyanmei"; } }, }, init(player, skill) { player.markAuto("yuheng_current", ["rezhiheng", "jiexun", "reanxu"]); }, mark: true, intro: { name: "命运线:权道", content(storage, player) { var finished = [], unfinished = ["rezhiheng", "jiexun", "reanxu"]; if (player.storage.yuheng) { for (var i = 0; i < unfinished.length; i++) { if (player.storage.yuheng.includes(unfinished[i])) { finished.push(unfinished[i]); unfinished.splice(i--, 1); } } } var str = ""; if (unfinished.length) str += "
  • 未获得:" + get.translation(unfinished) + "
    "; if (finished.length) str += "
  • 已获得过:" + get.translation(finished) + "
    "; str += "
  • 锁定技。若你因〖驭衡〗获得过〖制衡〗〖诫训〗〖安恤〗,则你手牌区内点数为字母的牌的牌名视为【调剂盐梅】。"; return str; }, }, }, jiaohui: { audio: 2, mod: { cardname(card, player) { if (player.countCards("h") == 1 && player.storage.yuheng) { var list = ["xiashu", "rejieyin", "oldimeng"]; for (var i of list) { if (!player.storage.yuheng.includes(i)) return; } return "yuanjiao"; } }, }, init(player, skill) { player.markAuto("yuheng_current", ["xiashu", "rejieyin", "oldimeng"]); }, mark: true, intro: { name: "命运线:交辉", content(storage, player) { var finished = [], unfinished = ["xiashu", "rejieyin", "oldimeng"]; if (player.storage.yuheng) { for (var i = 0; i < unfinished.length; i++) { if (player.storage.yuheng.includes(unfinished[i])) { finished.push(unfinished[i]); unfinished.splice(i--, 1); } } } var str = ""; if (unfinished.length) str += "
  • 未获得:" + get.translation(unfinished) + "
    "; if (finished.length) str += "
  • 已获得过:" + get.translation(finished) + "
    "; str += "
  • 锁定技。若你因〖驭衡〗获得过〖下书〗〖结姻〗〖缔盟〗,且你的手牌数为1,则此牌的牌名视为【远交近攻】。"; return str; }, }, }, yuanlv: { audio: 2, init(player, skill) { player.markAuto("yuheng_current", ["xinfu_guanchao", "drlt_jueyan", "lanjiang"]); }, trigger: { player: "useCardToTargeted" }, forced: true, filter(event, player) { if (get.type(event.card, false) != "equip" || player != event.target || event.card.name.indexOf("changandajian_equip") == 0) return false; if (!player.storage.yuheng) return false; var list = ["xinfu_guanchao", "drlt_jueyan", "lanjiang"]; for (var i of list) { if (!player.storage.yuheng.includes(i)) return false; } var type = get.subtype(event.card); if (lib.card["changandajian_" + type] && player.hasEquipableSlot(type)) return true; return false; }, content() { var cards = trigger.cards.filterInD(); if (cards.length > 0) game.cardsDiscard(cards); var type = get.subtype(trigger.card); var card = game.createCard("changandajian_" + type, Math.random() < 0.5 ? "spade" : "heart", 10); player.useCard(card, player); }, mark: true, intro: { name: "命运线:渊虑", content(storage, player) { var finished = [], unfinished = ["xinfu_guanchao", "drlt_jueyan", "lanjiang"]; if (player.storage.yuheng) { for (var i = 0; i < unfinished.length; i++) { if (player.storage.yuheng.includes(unfinished[i])) { finished.push(unfinished[i]); unfinished.splice(i--, 1); } } } var str = ""; if (unfinished.length) str += "
  • 未获得:" + get.translation(unfinished) + "
    "; if (finished.length) str += "
  • 已获得过:" + get.translation(finished) + "
    "; str += "
  • 锁定技。若你因〖驭衡〗获得过〖观潮〗〖决堰〗〖澜江〗,则当你成为自己使用的装备牌的目标后,你将此牌置于弃牌堆,然后使用一张与此装备牌副类别相同的【长安大舰】。"; return str; }, }, }, }, }, yuheng: { audio: 2, enable: "phaseUse", usable: 1, content() { var skills = player.getSkills(null, false, false).filter(function (i) { if (i == "yuheng") return false; var info = get.info(i); return info && !info.charlotte && !get.is.locked(i); }); if (skills.length) { player.removeSkills(skills); } //初始化技能库 var list1 = ["dili_shengzhi", "dili_chigang", "dili_qionglan", "dili_quandao", "dili_jiaohui", "dili_yuanlv"]; var list2 = ["gzyinghun", "hongde", "rebingyi", "xinfu_guanwei", "bizheng", "xinanguo", "shelie", "wengua", "rebotu", "rezhiheng", "jiexun", "reanxu", "xiashu", "rejieyin", "oldimeng", "xinfu_guanchao", "drlt_jueyan", "lanjiang"]; var list3 = []; if (!player.storage.yuheng_full) player.storage.yuheng_full = list2.slice(0); if (player.getStorage("yuheng_current").length == 0) { for (var i = 0; i < list1.length; i++) { if (player.hasSkill(list1[i])) { for (var j = 0; j < 3; j++) { list3.add(list2[i * 3 + j]); } } } if (!player.storage.yuheng_current) player.storage.yuheng_current = list3.slice(0); } var fullskills, currentskills; //决定抽选技能范围 if (player.storage.yuheng_full && player.storage.yuheng_full.length) fullskills = player.storage.yuheng_full; else fullskills = list2.slice(0); if (player.storage.yuheng_current && player.storage.yuheng_current.length) currentskills = player.storage.yuheng_current; else currentskills = list3.slice(0); var skills = []; //在没有发动过其他非锁定技时抽选技能 var evtx = event.getParent("phaseUse"); if ( currentskills.length > 0 && !player.hasHistory("useSkill", function (evt) { if (evt.skill == "yuheng" || evt.type != "player" || !evt.sourceSkill) return false; var info1 = get.info(evt.skill); if (info1.charlotte) return false; var info = get.info(evt.sourceSkill); if (info.charlotte || get.is.locked(evt.skill)) return false; return evt.event.getParent("phaseUse") == evtx; }) ) { fullskills.randomSort(); currentskills.randomSort(); for (var i = 0; i < fullskills.length; i++) { for (var j = 0; j < currentskills.length; j++) { if (fullskills[i] != currentskills[j] || (i == fullskills.length - 1 && j == currentskills.length - 1)) { skills.add(fullskills.splice(i--, 1)[0]); skills.add(currentskills.splice(j--, 1)[0]); break; } } if (skills.length > 0) break; } } //在已经发动过其他非锁定技时抽选技能 else { skills.add(fullskills.randomRemove(1)[0]); } for (var i of skills) { player.addSkills(i); } player.markAuto("yuheng", skills); }, ai: { order(item, player) { var evtx = _status.event.getParent("phaseUse"); if ( !player.hasHistory("useSkill", function (evt) { if (evt.skill == "yuheng" || evt.type != "player" || !evt.sourceSkill) return false; var info1 = get.info(evt.skill); if (info1.charlotte) return false; var info = get.info(evt.sourceSkill); if (info.charlotte || get.is.locked(evt.skill)) return false; return evt.event.getParent("phaseUse") == evtx; }) ) return 11; return 0.8; }, result: { player: 1 }, }, group: "yuheng_losehp", subSkill: { losehp: { trigger: { player: "phaseUseEnd" }, forced: true, locked: false, filter(event, player) { return !player.hasHistory("useSkill", function (evt) { if (evt.skill != "yuheng") return false; return evt.event.getParent("phaseUse") == event; }); }, content() { player.loseHp(); }, }, }, }, jiufa: { audio: 2, trigger: { player: ["useCardAfter", "respondAfter"] }, frequent: true, filter(event, player) { return event.jiufa_counted && player.getStorage("jiufa").length >= 9; }, content() { "step 0"; player.unmarkSkill("jiufa"); event.cards = get.cards(9); event.cards.sort(function (a, b) { return get.number(b) - get.number(a); }); game.cardsGotoOrdering(event.cards); event.videoId = lib.status.videoId++; game.broadcastAll( function (player, id, cards) { var str; if (player == game.me && !_status.auto) { str = "九伐:选择任意张点数满足条件的牌"; } else { str = "九伐"; } var dialog = ui.create.dialog(str, cards); dialog.videoId = id; }, player, event.videoId, event.cards ); event.time = get.utc(); game.addVideo("showCards", player, ["九伐", get.cardsInfo(event.cards)]); game.addVideo("delay", null, 2); "step 1"; var next = player.chooseButton([0, 9], true); next.set("dialog", event.videoId); next.set("filterButton", function (button) { var num = get.number(button.link), cards = _status.event.getParent().cards; for (var i of ui.selected.buttons) { if (get.number(i.link) == num) return false; } for (var i of cards) { if (i != button.link && get.number(i) == num) return true; } return false; }); next.set("ai", function (button) { return get.value(button.link, _status.event.player); }); "step 2"; if (result.bool && result.links && result.links.length) { event.cards2 = result.links; } var time = 1000 - (get.utc() - event.time); if (time > 0) { game.delay(0, time); } "step 3"; game.broadcastAll("closeDialog", event.videoId); var cards2 = event.cards2; if (cards2 && cards2.length) player.gain(cards2, "log", "gain2"); }, marktext: "⑨", intro: { content: "已记录牌名:$", onunmark: true, }, group: "jiufa_count", subSkill: { count: { trigger: { player: ["useCard1", "respond"] }, forced: true, charlotte: true, popup: false, firstDo: true, filter(event, player) { return !player.getStorage("jiufa").includes(event.card.name); }, content() { trigger.jiufa_counted = true; player.markAuto("jiufa", [trigger.card.name]); }, }, }, }, tianren: { audio: 2, trigger: { global: ["loseAfter", "cardsDiscardAfter", "loseAsyncAfter"] }, forced: true, filter(event, player) { if (event.name.indexOf("lose") == 0) { if (event.getlx === false || event.position != ui.discardPile) return false; } else { var evt = event.getParent(); if (evt.relatedEvent && evt.relatedEvent.name == "useCard") return false; } for (var i of event.cards) { var owner = false; if (event.hs && event.hs.includes(i)) owner = event.player; var type = get.type(i, null, owner); if (type == "basic" || type == "trick") return true; } return false; }, content() { var num = 0; for (var i of trigger.cards) { var owner = false; if (trigger.hs && trigger.hs.includes(i)) owner = trigger.player; var type = get.type(i, null, owner); if (type == "basic" || type == "trick") num++; } player.addMark("tianren", num); }, group: "tianren_maxHp", intro: { content: "mark" }, subSkill: { maxHp: { trigger: { player: ["tianrenAfter", "gainMaxHpAfter", "loseMaxHpAfter"] }, forced: true, filter(event, player) { return player.countMark("tianren") >= player.maxHp; }, content() { player.removeMark("tianren", player.maxHp); player.gainMaxHp(); player.draw(2); }, }, }, }, pingxiang: { audio: 2, enable: "phaseUse", limited: true, skillAnimation: true, animationColor: "ice", filter(event, player) { return player.maxHp > 9; }, content() { "step 0"; player.awakenSkill("pingxiang"); player.loseMaxHp(9); event.num = 0; "step 1"; event.num++; player.chooseUseTarget( { name: "sha", nature: "fire", isCard: true, }, "请选择火【杀】的目标(" + (event.num == 9 ? "⑨" : event.num) + "/9)", false ); "step 2"; if (result.bool && event.num < 9) event.goto(1); else player.removeSkills("jiufa"); "step 3"; player.addSkill("pingxiang_effect"); }, ai: { order() { return get.order({ name: "sha", nature: "fire", isCard: true, }); }, result: { player(player) { if ( player.hasValueTarget({ name: "sha", nature: "fire", isCard: true, }) ) return 1; return 0; }, }, }, subSkill: { effect: { marktext: "襄", intro: { content: "手牌上限基数改为体力上限" }, mod: { maxHandcardBase(player) { return player.maxHp; }, }, }, }, }, yingba: { audio: 2, mod: { aiOrder(player, card, num) { if (num > 0 && _status.event && _status.event.type == "phase" && get.tag(card, "recover")) { if (player.needsToDiscard()) return num / 3; return 0; } }, targetInRange(card, player, target) { if (target.hasMark("yingba_mark")) return true; }, }, enable: "phaseUse", usable: 1, filter: (event, player) => game.hasPlayer(current => current != player && current.maxHp > 1), filterTarget: (card, player, target) => target != player && target.maxHp > 1, content() { "step 0"; target.loseMaxHp(); "step 1"; if (target.isIn()) target.addMark("yingba_mark", 1); player.loseMaxHp(); }, locked: false, //global:'yingba_mark', ai: { combo: "scfuhai", threaten: 3, order: 11, result: { player(player, target) { if (player.maxHp == 1) return -2.5; return -0.25; }, target(player, target) { if (target.isHealthy()) return -2; if (!target.hasMark("yingba_mark")) return -1; return -0.2; }, }, }, subSkill: { mark: { marktext: "定", intro: { name: "平定", content: "mark", onunmark: true, }, mod: { maxHandcard(player, numx) { var num = player.countMark("yingba_mark"); if (num) return ( numx + num * game.countPlayer(function (current) { return current.hasSkill("yingba"); }) ); }, }, }, }, }, scfuhai: { audio: 2, trigger: { player: "useCardToPlayered" }, forced: true, filter(event, player) { return event.target && event.target.hasMark("yingba_mark"); }, logTarget: "target", content() { trigger.directHit.add(trigger.target); if ( player.getHistory("gain", function (evt) { return evt.getParent(2).name == "scfuhai"; }).length < 2 ) player.draw(); }, group: ["scfuhai_die"], ai: { directHit_ai: true, skillTagFilter(player, tag, arg) { return arg && arg.target && arg.target.hasMark("yingba_mark"); }, combo: "yingba", }, subSkill: { usea: { trigger: { player: "useCardAfter" }, forced: true, filter(event, player) { return lib.skill.scfuhai_usea.logTarget(event, player).length > 0; }, logTarget(event, player) { return event.targets.filter(function (i) { return i.hasMark("yingba_mark"); }); }, content() { var num = 0; for (var i of trigger.targets) { var numx = i.countMark("yingba_mark"); if (numx) { num += numx; i.removeMark("yingba_mark", numx); } } if (num) player.gainMaxHp(num); }, }, die: { trigger: { global: "die" }, forced: true, filter(event, player) { return event.player.countMark("yingba_mark") > 0; }, content() { player.gainMaxHp(trigger.player.countMark("yingba_mark")); player.draw(trigger.player.countMark("yingba_mark")); }, }, }, }, pinghe: { audio: 2, mod: { maxHandcardBase(player) { return player.getDamagedHp(); }, }, ai: { effect: { target(card, player, target) { if (get.tag(card, "recover") && _status.event.type == "phase" && !player.needsToDiscard()) return 0.2; }, }, }, trigger: { player: "damageBegin2" }, forced: true, filter(event, player) { return event.source && event.source != player && player.maxHp > 1 && player.countCards("h") > 0; }, content() { "step 0"; player.chooseCardTarget({ prompt: "请选择【冯河】的牌和目标", prompt2: "将一张手牌交给一名其他角色并防止伤害" + (player.hasSkill("yingba") ? ",然后令伤害来源获得一个“平定”标记" : ""), filterCard: true, forced: true, filterTarget: lib.filter.notMe, ai1(card) { if ( get.tag(card, "recover") && !game.hasPlayer(function (current) { return get.attitude(current, player) > 0 && !current.hasSkillTag("nogain"); }) ) return 0; return 1 / Math.max(0.1, get.value(card)); }, ai2(target) { var player = _status.event.player, att = get.attitude(player, target); if (target.hasSkillTag("nogain")) att /= 9; return 4 + att; }, }); "step 1"; if (result.bool) { var target = result.targets[0]; //player.logSkill('pinghe',target); player.line(target, "green"); player.give(result.cards, target); trigger.cancel(); player.loseMaxHp(); if (player.hasSkill("yingba")) { trigger.source.addMark("yingba_mark", 1); } } }, }, tianzuo: { audio: 2, trigger: { global: "phaseBefore", player: "enterGame", }, forced: true, filter(event, player) { return (event.name != "phase" || game.phaseNumber == 0) && !lib.inpile.includes("qizhengxiangsheng"); }, content() { game.addGlobalSkill("tianzuo_global"); var cards = []; for (var i = 2; i < 10; i++) { cards.push(game.createCard2("qizhengxiangsheng", i % 2 ? "club" : "spade", i)); } game.broadcastAll(function () { lib.inpile.add("qizhengxiangsheng"); }); game.cardsGotoPile(cards, () => { return ui.cardPile.childNodes[get.rand(0, ui.cardPile.childNodes.length - 1)]; }); }, group: "tianzuo_remove", subSkill: { remove: { audio: 2, trigger: { target: "useCardToBefore" }, forced: true, priority: 15, filter(event, player) { return event.card && event.card.name == "qizhengxiangsheng"; }, content() { trigger.cancel(); }, ai: { effect: { target(card, player, target) { if (card && card.name == "qizhengxiangsheng") return "zeroplayertarget"; }, }, }, }, global: { trigger: { player: "useCardToPlayered" }, forced: true, popup: false, filter(event, player) { return event.card.name == "qizhengxiangsheng"; }, content() { "step 0"; var target = trigger.target; event.target = target; player .chooseControl("奇兵", "正兵") .set("prompt", "请选择" + get.translation(target) + "的标记") .set( "choice", (function () { var e1 = 1.5 * get.sgn(get.damageEffect(target, player, target)); var e2 = 0; if (target.countGainableCards(player, "h") > 0 && !target.hasSkillTag("noh")) e2 = -1; var es = target.getGainableCards(player, "e"); if (es.length) e2 = Math.min( e2, (function () { var max = 0; for (var i of es) max = Math.max(max, get.value(i, target)); return -max / 4; })() ); if (Math.abs(e1 - e2) <= 0.3) return Math.random() < 0.5 ? "奇兵" : "正兵"; if (e1 < e2) return "奇兵"; return "正兵"; })() ) .set("ai", function () { return _status.event.choice; }); "step 1"; var map = trigger.getParent().customArgs, id = target.playerid; if (!map[id]) map[id] = {}; map[id].qizheng_name = result.control; }, }, rewrite: { audio: "tianzuo", trigger: { global: "useCardToTargeted" }, filter(event, player) { return event.card.name == "qizhengxiangsheng"; }, logTarget: "target", prompt2: "观看其手牌并修改“奇正相生”标记", content() { "step 0"; var target = trigger.target; event.target = target; if (player != target && target.countCards("h") > 0) player.viewHandcards(target); player .chooseControl("奇兵", "正兵") .set("prompt", "请选择" + get.translation(target) + "的标记") .set( "choice", (function () { var shas = target.getCards("h", "sha"), shans = target.getCards("h", "shan"); var e1 = 1.5 * get.sgn(get.damageEffect(target, player, target)); var e2 = 0; if (target.countGainableCards(player, "h") > 0 && !target.hasSkillTag("noh")) e2 = -1; var es = target.getGainableCards(player, "e"); if (es.length) e2 = Math.min( e2, (function () { var max = 0; for (var i of es) max = Math.max(max, get.value(i, target)); return -max / 4; })() ); if (get.attitude(player, target) > 0) { if (shas.length >= Math.max(1, shans.length)) return "奇兵"; if (shans.length > shas.length) return "正兵"; return e1 > e2 ? "奇兵" : "正兵"; } if (shas.length) e1 = -0.5; if (shans.length) e2 = -0.7; if (Math.abs(e1 - e2) <= 0.3) return Math.random() < 0.5 ? "奇兵" : "正兵"; var rand = Math.random(); if (e1 < e2) return rand < 0.1 ? "奇兵" : "正兵"; return rand < 0.1 ? "正兵" : "奇兵"; })() ) .set("ai", () => _status.event.choice); "step 1"; var map = trigger.getParent().customArgs, id = target.playerid; if (!map[id]) map[id] = {}; map[id].qizheng_name = result.control; map[id].qizheng_aibuff = get.attitude(player, target) > 0; }, }, }, }, lingce: { audio: 2, init: player => { game.addGlobalSkill("lingce_global"); }, trigger: { global: "useCard" }, forced: true, filter(event, player) { if (!event.card.isCard || !event.cards || event.cards.length !== 1) return false; return event.card.name == "qizhengxiangsheng" || get.zhinangs().includes(event.card.name) || player.getStorage("dinghan").includes(event.card.name); }, content() { player.draw(); }, subSkill: { global: { ai: { effect: { player: (card, player, target) => { let num = 0, nohave = true; game.countPlayer(i => { if (i.hasSkill("lingce")) { nohave = false; if (i.isIn() && lib.skill.lingce.filter({ card: card }, i)) num += get.sgnAttitude(player, i); } }, true); if (nohave) game.removeGlobalSkill("lingce_global"); else return [1, 0.8 * num]; }, }, }, }, }, }, dinghan: { audio: 2, trigger: { target: "useCardToTarget", player: "addJudgeBefore", }, forced: true, locked: false, filter(event, player) { if (event.name == "useCardToTarget" && get.type(event.card, null, false) != "trick") return false; return !player.getStorage("dinghan").includes(event.card.name); }, content() { player.markAuto("dinghan", [trigger.card.name]); if (trigger.name == "addJudge") { trigger.cancel(); var owner = get.owner(trigger.card); if (owner && owner.getCards("hej").includes(trigger.card)) owner.lose(trigger.card, ui.discardPile); else game.cardsDiscard(trigger.card); game.log(trigger.card, "进入了弃牌堆"); } else { trigger.targets.remove(player); trigger.getParent().triggeredTargets2.remove(player); trigger.untrigger(); } }, onremove: true, intro: { content: "已记录牌名:$" }, group: "dinghan_add", subSkill: { add: { trigger: { player: "phaseBegin" }, direct: true, content() { "step 0"; var dialog = [get.prompt("dinghan")]; (list1 = player.getStorage("dinghan")), (list2 = lib.inpile.filter(function (i) { return get.type2(i, false) == "trick" && !list1.includes(i); })); if (list1.length) { dialog.push('
    已记录
    '); dialog.push([list1, "vcard"]); } if (list2.length) { dialog.push('
    未记录
    '); dialog.push([list2, "vcard"]); } player.chooseButton(dialog).set("ai", function (button) { var player = _status.event.player, name = button.link[2]; if (player.getStorage("dinghan").includes(name)) { return -get.effect(player, { name: name }, player, player); } else { return get.effect(player, { name: name }, player, player) * (1 + player.countCards("hs", name)); } }); "step 1"; if (result.bool) { player.logSkill("dinghan"); var name = result.links[0][2]; if (player.getStorage("dinghan").includes(name)) { player.unmarkAuto("dinghan", [name]); game.log(player, "从定汉记录中移除了", "#y" + get.translation(name)); } else { player.markAuto("dinghan", [name]); game.log(player, "向定汉记录中添加了", "#y" + get.translation(name)); } game.delayx(); } }, }, }, }, dulie: { audio: 2, trigger: { target: "useCardToTarget" }, forced: true, logTarget: "player", filter(event, player) { return event.card.name == "sha" && event.player.hp > player.hp; }, content() { "step 0"; player.judge(function (result) { if (get.suit(result) == "heart") return 2; return -1; }).judge2 = function (result) { return result.bool; }; "step 1"; if (result.bool) { trigger.targets.remove(player); trigger.getParent().triggeredTargets2.remove(player); trigger.untrigger(); } }, ai: { effect: { target(card, player, target, current, isLink) { if (card.name == "sha" && !isLink && player.hp > target.hp) return 0.5; }, }, }, marktext: "围", intro: { name: "破围(围)", name2: "围", content: "mark", }, }, tspowei: { audio: 3, dutySkill: true, derivation: "shenzhu", group: ["tspowei_init", "tspowei_move", "tspowei_achieve", "tspowei_fail", "tspowei_use", "tspowei_remove"], subSkill: { remove: { audio: "tspowei3", trigger: { global: "damageEnd" }, filter(event, player) { return event.player && event.player.isIn() && event.player.hasMark("dulie"); }, forced: true, logTarget: "player", content() { trigger.player.removeMark("dulie", trigger.player.countMark("dulie")); }, }, use: { audio: "tspowei3", trigger: { global: "phaseBegin" }, direct: true, filter(event, player) { return event.player != player && event.player.hasMark("dulie") && (player.countCards("h") > 0 || (player.hp >= event.player.hp && event.player.countCards("h") > 0)); }, content() { "step 0"; var list = [], target = trigger.player, choiceList = ["弃置一张牌并对其造成1点伤害", "获得其一张手牌"]; event.target = target; if ( player.hasCard(function (card) { return lib.filter.cardDiscardable(card, player, "tspowei_use"); }, "h") ) list.push("选项一"); else choiceList[0] = '' + choiceList[0] + ""; if (player.hp >= target.hp && target.countCards("h") > 0) list.push("选项二"); else choiceList[1] = '' + choiceList[1] + ""; player .chooseControl(list, "cancel2") .set("prompt", get.prompt("tspowei", target)) .set("choiceList", choiceList) .set("ai", function () { var evt = _status.event.getParent(); if ( evt.player.hasCard(function (card) { return lib.filter.cardDiscardable(card, evt.player, "tspowei_use") && get.value(card, evt.player) < 7; }, "h") && get.damageEffect(evt.target, evt.player, evt.player) > 0 ) return "选项一"; if (evt.player.hp >= evt.target.hp && evt.target.countCards("h") > 0 && get.attitude(evt.player, evt.target) <= 0 && !evt.target.hasSkillTag("noh")) return "选项二"; return "cancel2"; }); "step 1"; if (result.control != "cancel2") { if (result.control == "选项二") { player.logSkill("tspowei_use", target); player.gainPlayerCard(target, "h", true); event.goto(3); } } else event.finish(); "step 2"; player.chooseToDiscard("h", true).logSkill = ["tspowei_use", target]; if (get.mode() != "identity" || player.identity != "nei") player.addExpose(0.2); target.damage(); "step 3"; player.addTempSkill("tspowei_inRange"); }, ai: { expose: 0.2 }, }, inRange: { charlotte: true, mod: { inRangeOf(from, to) { if (from == _status.currentPhase) return true; }, }, }, init: { audio: "tspowei3", trigger: { global: "phaseBefore", player: "enterGame", }, forced: true, filter(event, player) { return event.name != "phase" || game.phaseNumber == 0; }, logTarget(event, player) { return game.filterPlayer(current => current != player && !current.hasMark("dulie")); }, content() { var list = game.filterPlayer(current => current != player && !current.hasMark("dulie")).sortBySeat(); for (var i of list) i.addMark("dulie", 1, false); }, }, move: { audio: "tspowei3", trigger: { player: "phaseBegin" }, forced: true, filter(event, player) { return game.hasPlayer(current => current != player && current.hasMark("dulie")); }, content() { var list = game.filterPlayer(current => current != player && current.hasMark("dulie")).sortBySeat(); var map = {}; for (var i of list) { var num = i.countMark("dulie"); i.removeMark("dulie", num); map[i.playerid] = num; } for (var i of list) { var next = i.next; if (next == player) next = next.next; next.addMark("dulie", map[i.playerid]); } }, }, achieve: { audio: "tspowei1", trigger: { player: "phaseBegin" }, forced: true, skillAnimation: true, animationColor: "metal", filter(event, player) { return !game.hasPlayer(function (current) { return current.hasMark("dulie"); }); }, content() { game.log(player, "成功完成使命"); player.awakenSkill("tspowei"); player.addSkills("shenzhu"); }, }, fail: { audio: "tspowei2", trigger: { player: "dying" }, forced: true, content() { "step 0"; game.log(player, "使命失败"); player.awakenSkill("tspowei"); if (player.hp < 1) player.recover(1 - player.hp); "step 1"; var num = player.countCards("e"); if (num > 0) player.chooseToDiscard("e", true, num); }, }, }, }, tspowei1: { audio: true }, tspowei2: { audio: true }, tspowei3: { audio: true }, shenzhu: { audio: 2, trigger: { player: "useCardAfter" }, forced: true, filter(event, player) { return event.card.name == "sha" && event.card.isCard && event.cards.length == 1; }, content() { "step 0"; player .chooseControl() .set("choiceList", ["摸一张牌,且本回合使用【杀】的次数上限+1", "摸三张牌,且本回合不能再使用【杀】"]) .set("ai", () => (_status.event.player.hasSha() ? 0 : 1)); "step 1"; if (result.index == 0) { player.draw(); player.addTempSkill("shenzhu_more"); player.addMark("shenzhu_more", 1, false); } else { player.draw(3); player.addTempSkill("shenzhu_less"); } }, subSkill: { more: { charlotte: true, onremove: true, mod: { cardUsable(card, player, num) { if (card.name == "sha") return num + player.countMark("shenzhu_more"); }, }, }, less: { charlotte: true, mod: { cardEnabled(card) { if (card.name == "sha") return false; }, }, }, }, }, dangmo: { audio: 2, trigger: { player: "useCard2" }, direct: true, filter(event, player) { if (event.card.name != "sha" || player.hp <= 1) return false; var evt = event.getParent("phaseUse"); return ( evt && evt.player == player && player.getHistory("useCard", function (evtx) { return evtx.card.name == "sha" && evtx.getParent("phaseUse") == evt; })[0] == event && game.hasPlayer(function (current) { return !event.targets.includes(current) && lib.filter.filterTarget(event.card, player, current); }) ); }, content() { "step 0"; var num = Math.min( player.hp - 1, game.countPlayer(function (current) { return !trigger.targets.includes(current) && lib.filter.filterTarget(trigger.card, player, current); }) ); player .chooseTarget(get.prompt("dangmo"), "为" + get.translation(trigger.card) + "增加至多" + get.translation(num) + "个目标", [1, num], function (card, player, target) { var evt = _status.event.getTrigger(); return !evt.targets.includes(target) && lib.filter.filterTarget(evt.card, player, target); }) .set("ai", function (target) { var evt = _status.event.getTrigger(), eff = get.effect(target, evt.card, evt.player, evt.player); if (player.hasSkill("tspowei") && target.hasMark("dulie")) return 4 * eff; return eff; }); "step 1"; if (result.bool) { if (player != game.me && !player.isOnline()) game.delayx(); event.targets = result.targets; } else event.finish(); "step 2"; player.logSkill("dangmo", targets); trigger.targets.addArray(targets); }, }, reshuishi: { audio: "shuishi", enable: "phaseUse", usable: 1, frequent: true, filter(event, player) { return player.maxHp < 10; }, content() { "step 0"; event.cards = []; event.suits = []; "step 1"; player .judge(function (result) { var evt = _status.event.getParent("reshuishi"); if (evt && evt.suits && evt.suits.includes(get.suit(result))) return 0; return 1; }) .set("callback", lib.skill.reshuishi.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, att = get.attitude(player, target); if (att <= 0) return att; if (target.countCards("h") + _status.event.num >= _status.event.max) att /= 3; if (target.hasSkillTag("nogain")) att /= 10; return att; }) .set("num", cards.length) .set( "max", game.filterPlayer().reduce((num, i) => { return Math.max(num, i.countCards("h")); }, 0) ); 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(); "step 4"; if (target.isMaxHandcard()) player.loseMaxHp(); }, callback() { "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 && player.maxHp < 10) { evt.suits.push(event.getParent().result.suit); player.gainMaxHp(); player.chooseBool("是否继续发动【慧识】?").set("frequentSkill", "reshuishi"); } else event._result = { bool: false }; "step 1"; if (result.bool) event.getParent(2).redo(); }, ai: { order: 9, result: { player: 1, }, }, }, shuishi: { audio: 2, enable: "phaseUse", usable: 1, filter(event, player) { return player.maxHp < 10; }, filterTarget: true, content() { "step 0"; target.draw(); "step 1"; if (!result || !Array.isArray(result) || result.length != 1 || get.itemtype(result[0]) != "card") { event.finish(); return; } var suit = get.suit(result[0]), hs = target.getCards("h"); for (var i of hs) { if (i != result[0] && get.suit(i, target) == suit) { player.loseMaxHp(); target.showHandcards(); event.finish(); return; } } player.gainMaxHp(); "step 2"; if (player.maxHp < 10) { player.chooseBool("是否继续发动【慧识】?"); } else event.finish(); "step 3"; if (result.bool) event.goto(0); }, ai: { order: 0.5, result: { target: 0.2, player(player, target) { var list = [], hs = target.getCards("h"); for (var i of hs) list.add(get.suit(i, target)); if (list.length == 0) return 0; if (list.length == 1) return player.maxHp > 2 ? 0 : -2; if (list.length == 2) return player.maxHp > 3 ? 0 : -2; return -2; }, }, }, }, stianyi: { audio: 2, trigger: { player: "phaseZhunbeiBegin" }, forced: true, juexingji: true, skillAnimation: true, animationColor: "gray", filter(event, player) { return !game.hasPlayer(function (current) { return current.getAllHistory("damage").length == 0; }); }, content() { "step 0"; player.awakenSkill("stianyi"); player.gainMaxHp(2); player.recover(); "step 1"; player.chooseTarget(true, "令一名角色获得技能〖佐幸〗").set("ai", function (target) { return get.attitude(_status.event.player, target); }); "step 2"; if (result.bool) { var target = result.targets[0]; player.line(target, "green"); target.storage.zuoxing = player; target.addSkills("zuoxing"); } }, derivation: "zuoxing", }, zuoxing: { audio: 3, enable: "phaseUse", usable: 1, filter(event, player) { var target = player.storage.zuoxing; if (!target || !target.isIn() || target.maxHp < 2) return false; for (var i of lib.inpile) { if (get.type(i) == "trick" && event.filterCard({ name: i, isCard: true }, player, event)) return true; } return false; }, chooseButton: { dialog(event, player) { var list = []; for (var i of lib.inpile) { if (get.type(i) == "trick" && event.filterCard({ name: i, isCard: true }, player, event)) list.push(["锦囊", "", i]); } return ui.create.dialog("佐幸", [list, "vcard"]); }, check(button) { return _status.event.player.getUseValue({ name: button.link[2], isCard: true }); }, backup(links, player) { return { viewAs: { name: links[0][2], isCard: true, }, filterCard: () => false, selectCard: -1, popname: true, precontent() { player.logSkill("zuoxing"); var target = player.storage.zuoxing; target.loseMaxHp(); //delete event.result.skill; }, }; }, prompt(links, player) { return "请选择" + get.translation(links[0][2]) + "的目标"; }, }, ai: { order: 1, result: { player: 1 } }, }, resghuishi: { audio: "sghuishi", inherit: "sghuishi", filterTarget: true, prompt() { var player = _status.event.player; if (player.maxHp >= game.players.length) return "选择一名角色。若其拥有未发动过的觉醒技,则你解除其中一个觉醒技的发动限制;否则其摸四张牌。然后你减2点体力上限。"; return "令一名角色摸四张牌,然后你减2点体力上限。"; }, content() { "step 0"; player.awakenSkill("resghuishi"); var list = target.getSkills(null, false, false).filter(function (skill) { var info = lib.skill[skill]; return info && info.juexingji && !target.awakenedSkills.includes(skill); }); if (player.maxHp >= game.players.length && list.length > 0) { if (list.length == 1) event._result = { control: list[0] }; else player.chooseControl(list).set("prompt", "选择一个觉醒技,令" + get.translation(target) + "可无视条件发动该技能"); } else { target.draw(4); event.goto(2); } "step 1"; target.storage.resghuishi_mark = result.control; target.markSkill("resghuishi_mark"); var info = lib.skill[result.control]; if (info.filter && !info.charlotte && !info.resghuishi_filter) { info.resghuishi_filter = info.filter; info.filter = function (event, player) { if (player.storage.resghuishi_mark) return true; return this.resghuishi_filter.apply(this, arguments); }; } "step 2"; player.loseMaxHp(2); }, intro: { content: "未发动" }, ai: { order: 0.1, expose: 0.2, result: { target(player, target) { if ((target != player && player.hasUnknown()) || player.maxHp < (player.getDamagedHp() > 1 ? 5 : 6)) return 0; if ( target == player && player.hasSkill("resghuishi") && game.hasPlayer(function (current) { return current.getAllHistory("damage").length == 0; }) ) return 4; var list = target.getSkills(null, false, false).filter(function (skill) { var info = lib.skill[skill]; return info && info.juexingji && !target.awakenedSkills.includes(skill); }); if (list.length || target.hasJudge("lebu") || target.hasSkillTag("nogain")) return 0; return 4; }, }, }, subSkill: { mark: { intro: { content: "发动【$】时无视条件" } } }, }, sghuishi: { audio: 2, enable: "phaseUse", limited: true, skillAnimation: true, animationColor: "water", filterTarget: lib.filter.notMe, content() { "step 0"; player.awakenSkill("sghuishi"); var list = target.getSkills(null, false, false).filter(function (skill) { var info = lib.skill[skill]; return info && info.juexingji; }); if (list.length) { target.addMark("sghuishi", 1, false); for (var i of list) { var info = lib.skill[i]; if (info.filter && !info.charlotte && !info.sghuishi_filter) { info.sghuishi_filter = info.filter; info.filter = function (event, player) { if (player.hasMark("sghuishi")) return true; return this.sghuishi_filter.apply(this, arguments); }; } } } else target.draw(4); player.loseMaxHp(2); }, intro: { content: "发动非Charlotte觉醒技时无视条件" }, ai: { order: 0.1, expose: 0.2, result: { target(player, target) { if (player.hasUnknown() || player.maxHp < 5) return 0; var list = target.getSkills(null, false, false).filter(function (skill) { var info = lib.skill[skill]; return info && info.juexingji; }); if (list.length || target.hasJudge("lebu") || target.hasSkillTag("nogain")) return 0; return 4; }, }, }, }, zhanjiang: { trigger: { player: "phaseZhunbeiBegin" }, filter(event, player) { var players = game.filterPlayer(); for (var i = 0; i < players.length; i++) { if (players[i] != player && players[i].getEquips("qinggang").length > 0) { return true; } } }, content() { var players = game.filterPlayer(); for (var i = 0; i < players.length; i++) { if (players[i] != player) { var e = players[i].getEquips("qinggang"); if (e.length > 0) { player.line(players[i], "green"); player.gain(e, players[i], "give", "bySelf"); } } } }, }, boss_juejing: { audio: "juejing", audioname2: { dc_zhaoyun: "dcjuejing", }, trigger: { player: "phaseDrawBefore" }, forced: true, content() { trigger.cancel(); }, ai: { noh: true, nogain: true, }, group: "boss_juejing2", }, boss_juejing2: { audio: "juejing", audioname2: { dc_zhaoyun: "dcjuejing", }, trigger: { player: "loseAfter", global: ["equipAfter", "addJudgeAfter", "gainAfter", "loseAsyncAfter", "addToExpansionAfter"], }, forced: true, filter(event, player) { if (event.name == "gain" && event.player == player) return player.countCards("h") > 4; var evt = event.getl(player); if (!evt || !evt.hs || evt.hs.length == 0 || player.countCards("h") >= 4) return false; var evt = event; for (var i = 0; i < 4; i++) { evt = evt.getParent("boss_juejing2"); if (evt.name != "boss_juejing2") return true; } return false; }, content() { var num = 4 - player.countCards("h"); if (num > 0) player.draw(num); else player.chooseToDiscard("h", true, -num); }, }, dcjuejing: { audio: 2 }, meihun: { audio: 2, trigger: { player: "phaseJieshuBegin", target: "useCardToTargeted", }, direct: true, filter(event, player) { if (event.name != "phaseJieshu" && event.card.name != "sha") return false; return game.hasPlayer(function (current) { return current != player && current.countCards("h"); }); }, content() { "step 0"; player .chooseTarget(get.prompt2("meihun"), function (card, player, target) { return target != player && target.countCards("h") > 0; }) .set("ai", function (target) { var player = _status.event.player; var att = get.attitude(player, target); if (att > 0) return 0; return 0.1 - att / target.countCards("h"); }); "step 1"; if (result.bool) { var target = result.targets[0]; player.logSkill("meihun", target); event.target = target; player .chooseControl(lib.suit) .set("prompt", "请选择一种花色") .set("ai", function () { return lib.suit.randomGet(); }); } else event.finish(); "step 2"; var suit = result.control; player.chat(get.translation(suit + 2)); game.log(player, "选择了", "#y" + get.translation(suit + 2)); if (target.countCards("h", { suit: suit })) { target .chooseCard("h", "交给" + get.translation(player) + "一张" + get.translation(suit) + "花色的手牌", true, function (card, player) { return get.suit(card, player) == _status.event.suit; }) .set("suit", suit); } else { player.discardPlayerCard(target, true, "h", "visible"); event.finish(); } "step 3"; if (result.bool && result.cards && result.cards.length) target.give(result.cards, player, "give"); }, }, //Connect Mode support after Angel Beats! -2nd beat- huoxin: { audio: 2, enable: "phaseUse", usable: 1, filter(event, player) { if (game.countPlayer() < 3) return false; for (var i of lib.suit) { if (player.countCards("h", { suit: i }) > 1) return true; } return false; }, complexCard: true, position: "h", filterCard(card, player) { if (!ui.selected.cards.length) { var suit = get.suit(card); return ( player.countCards("h", function (card2) { return card != card2 && get.suit(card2, player) == suit; }) > 0 ); } return get.suit(card, player) == get.suit(ui.selected.cards[0], player); }, selectCard: 2, selectTarget: 2, filterTarget: lib.filter.notMe, multitarget: true, multiline: true, delay: false, discard: false, lose: false, check(card) { return 6 - get.value(card); }, targetprompt: ["拼点发起人", "拼点目标"], content() { "step 0"; var list = []; for (var i = 0; i < targets.length; i++) { list.push([targets[i], cards[i]]); } game.loseAsync({ gain_list: list, player: player, cards: cards, giver: player, animate: "giveAuto", }).setContent("gaincardMultiple"); "step 1"; game.delayx(); if (targets[0].canCompare(targets[1])) { targets[0].chooseToCompare(targets[1]); } else event.finish(); "step 2"; if (result.winner !== targets[0]) targets[0].addMark("huoxin", 1); if (result.winner !== targets[1]) targets[1].addMark("huoxin", 1); }, marktext: "魅", intro: { name: "魅惑", name2: "魅惑", content: "mark", }, group: "huoxin_control", ai: { order: 1, result: { target(player, target) { if (target.hasMark("huoxin")) return -2; return -1; }, }, }, }, huoxin_control: { audio: "huoxin", forced: true, trigger: { global: "phaseBeginStart" }, filter(event, player) { return player != event.player && !event.player._trueMe && event.player.countMark("huoxin") > 1; }, logTarget: "player", skillAnimation: true, animationColor: "key", content() { trigger.player.removeMark("huoxin", trigger.player.countMark("huoxin")); trigger.player._trueMe = player; game.addGlobalSkill("autoswap"); if (trigger.player == game.me) { game.notMe = true; if (!_status.auto) ui.click.auto(); } trigger.player.addSkill("huoxin2"); }, }, huoxin2: { trigger: { player: ["phaseAfter", "dieAfter"], global: "phaseBeforeStart", }, lastDo: true, charlotte: true, forceDie: true, forced: true, silent: true, content() { player.removeSkill("huoxin2"); }, onremove(player) { if (player == game.me) { if (!game.notMe) game.swapPlayerAuto(player._trueMe); else delete game.notMe; if (_status.auto) ui.click.auto(); } delete player._trueMe; }, }, caopi_xingdong: { audio: "olfangquan", audioname: ["shen_caopi"], subSkill: { mark: { mark: true, marktext: "令", intro: { content: "跳过下个回合的判定阶段和摸牌阶段", }, }, }, enable: "phaseUse", usable: 1, filter(event, player) { return player.countCards("h", lib.skill.caopi_xingdong.filterCard) > 0; }, filterCard(card) { return card.name == "sha" || get.type(card) == "trick"; }, check(card) { return 1; }, filterTarget: lib.filter.notMe, discard: false, lose: false, delay: 0, content() { "step 0"; player.give(cards, target); "step 1"; if (!target.getCards("h").includes(cards[0])) event._result = { bool: false }; else target.chooseUseTarget( cards[0], game.filterPlayer(function (current) { return current != player; }), "请使用得到的牌,或者跳过下回合的判定阶段和摸牌阶段" ); "step 2"; if (result.bool) game.asyncDraw([player, target]); else { target.addTempSkill("caopi_xingdong_mark", "phaseJudgeSkipped"); target.skip("phaseJudge"); target.skip("phaseDraw"); event.finish(); } "step 3"; game.delay(); }, ai: { order: 12, result: { target(player, target) { var card = ui.selected.cards[0]; if (target.hasSkill("pingkou")) return 1; if (!card) return 0; var info = get.info(card); if (info.selectTarget == -1) { var eff = 0; game.countPlayer(function (current) { if (current != player && target.canUse(card, current)) eff += get.effect(current, card, target, target) > 0; }); if (eff > 0 || get.value(card) < 3) return eff; return 0; } else if ( game.hasPlayer(function (current) { return current != player && target.canUse(card, current) && get.effect(current, card, target, target) > 0; }) ) return 1.5; else if (get.value(card) < 3) return -1; return 0; }, }, }, }, shenfu: { audio: 2, trigger: { player: "phaseEnd" }, direct: true, content() { "step 0"; event.logged = false; event.targets = []; event.goto(player.countCards("h") % 2 == 1 ? 1 : 4); "step 1"; player .chooseTarget(get.prompt("shenfu"), "对一名其他角色造成1点雷属性伤害", function (card, player, target) { return target != player && !_status.event.getParent().targets.includes(target); }) .set("ai", function (target) { var player = _status.event.player; return get.damageEffect(target, player, player, "thunder") * (target.hp == 1 ? 2 : 1); }); "step 2"; if (result.bool) { var target = result.targets[0]; event.target = target; if (!event.logged) { event.logged = true; player.logSkill("shenfu", target, "thunder"); } else player.line(target, "thunder"); event.targets.push(target); target.damage("thunder"); } else event.finish(); "step 3"; if ( target.getHistory("damage", function (evt) { return evt.getParent("shenfu") == event && evt._dyinged; }).length ) event.goto(1); else event.finish(); "step 4"; player .chooseTarget(get.prompt("shenfu"), "令一名角色摸一张牌或弃置其一张手牌", function (card, player, target) { return !_status.event.getParent().targets.includes(target); }) .set("ai", function (target) { var att = get.attitude(_status.event.player, target); var delta = target.hp - target.countCards("h"); if (Math.abs(delta) == 1 && get.sgn(delta) == get.sgn(att)) return 3 * Math.abs(att); if (att > 0 || target.countCards("h") > 0) return Math.abs(att); return 0; }); "step 5"; if (result.bool) { var target = result.targets[0]; event.target = target; if (!event.logged) { event.logged = true; player.logSkill("shenfu", target); } else player.line(target, "green"); event.targets.push(target); if (target.countCards("h") == 0) event._result = { index: 0 }; else player .chooseControl("摸一张牌", "弃置一张手牌") .set("prompt", "选择一项令" + get.translation(target) + "执行…") .set("goon", get.attitude(player, target) > 0 ? 0 : 1) .set("ai", () => _status.event.goon); //else player.discardPlayerCard(target,'h','弃置'+get.translation(target)+'一张手牌,或点【取消】令其摸一张牌。'); } else event.finish(); "step 6"; if (result.index == 0) target.draw(); else target.chooseToDiscard("h", true); "step 7"; if (target.hp == target.countCards("h")) event.goto(4); }, ai: { expose: 0.25 }, }, qixian: { mod: { maxHandcardBase(player, num) { return 7; }, }, }, chuyuan: { audio: 2, trigger: { global: "damageEnd" }, filter(event, player) { return event.player.isIn() && player.getExpansions("chuyuan").length < player.maxHp; }, logTarget: "player", locked: false, content() { "step 0"; trigger.player.draw(); "step 1"; if (!trigger.player.countCards("h")) event.finish(); else trigger.player.chooseCard("h", true, "选择一张牌置于" + get.translation(player) + "的武将牌上作为「储」"); "step 2"; player.addToExpansion(result.cards, trigger.player, "give").gaintag.add("chuyuan"); }, intro: { content: "expansion", markcount: "expansion", }, onremove(player, skill) { var cards = player.getExpansions(skill); if (cards.length) player.loseToDiscardpile(cards); }, ai: { combo: "dengji" }, }, dengji: { audio: 2, derivation: ["tianxing", "new_rejianxiong", "rerende", "rezhiheng", "olluanji", "caopi_xingdong"], trigger: { player: "phaseZhunbeiBegin" }, forced: true, unique: true, juexingji: true, skillAnimation: true, animationColor: "water", filter(event, player) { return player.getExpansions("chuyuan").length >= 3; }, content() { player.awakenSkill(event.name); player.addSkills(["tianxing", "new_rejianxiong"]); player.loseMaxHp(); player.gain(player.getExpansions("chuyuan"), "gain2", "fromStorage"); }, ai: { combo: "chuyuan", }, }, tianxing: { audio: 2, trigger: { player: "phaseZhunbeiBegin" }, forced: true, unique: true, juexingji: true, skillAnimation: true, animationColor: "thunder", filter(event, player) { return player.getExpansions("chuyuan").length >= 3; }, content() { "step 0"; player.awakenSkill(event.name); player.loseMaxHp(); player.gain(player.getExpansions("chuyuan"), "gain2", "fromStorage"); "step 1"; player.removeSkills("chuyuan"); player .chooseControl("rerende", "rezhiheng", "olluanji", "caopi_xingdong") .set("prompt", "选择获得一个技能") .set("ai", function () { var player = _status.event.player; if (!player.hasSkill("luanji") && !player.hasSkill("olluanji") && player.getUseValue({ name: "wanjian" }) > 4) return "olluanji"; if (!player.hasSkill("rezhiheng")) return "rezhiheng"; if (!player.hasSkill("caopi_xingdong")) return "caopi_xingdong"; return "rerende"; }); "step 2"; player.addSkills(result.control); }, ai: { combo: "chuyuan", }, }, olzhiti: { audio: "drlt_zhiti", global: "olzhiti2", mod: { maxHandcard(player, num) { if ( game.hasPlayer(function (current) { return current.isDamaged(); }) ) return num + 1; }, }, trigger: { player: ["phaseDrawBegin2", "phaseEnd"] }, forced: true, filter(event, player) { var num = event.name == "phase" ? 5 : 3; if ( num == 3 ? event.numFixed : !game.hasPlayer(function (current) { return current.hasEnabledSlot(); }) ) return false; return ( game.countPlayer(function (current) { return current.isDamaged(); }) >= num ); }, direct: true, content() { "step 0"; if (trigger.name == "phaseDraw") { player.logSkill("olzhiti"); trigger.num++; event.finish(); } else { player .chooseTarget(get.prompt("olzhiti"), "废除一名角色的一个随机装备栏", function (card, player, target) { return target.hasEnabledSlot(); }) .set("ai", function (target) { return -get.attitude(_status.event.player, target) * (target.countCards("e") + 1); }); } "step 1"; if (result.bool) { var target = result.targets[0]; player.logSkill("olzhiti", target); var list = []; for (var i = 1; i < 6; i++) { if (target.hasEnabledSlot(i)) list.add(i == 3 || i == 4 ? 6 : i); } var num = list.randomGet(); if (num != 6) target.disableEquip(num); else { target.disableEquip(3, 4); } } }, }, olzhiti2: { mod: { maxHandcard(player, num) { if (player.isDamaged()) return ( num - game.countPlayer(function (current) { return current.hasSkill("olzhiti") && current.inRange(player); }) ); }, }, }, olduorui: { audio: "drlt_duorui", trigger: { source: "damageSource", }, filter(event, player) { if (!player.isPhaseUsing() || event.player.isDead()) return false; for (var i in event.player.disabledSkills) { if (event.player.disabledSkills[i].includes("olduorui2")) return false; } var list = []; var listm = []; var listv = []; if (event.player.name1 != undefined) listm = lib.character[event.player.name1][3]; else listm = lib.character[event.player.name][3]; if (event.player.name2 != undefined) listv = lib.character[event.player.name2][3]; listm = listm.concat(listv); var func = function (skill) { var info = get.info(skill); if (!info || info.charlotte) return false; return true; }; for (var i = 0; i < listm.length; i++) { if (func(listm[i])) list.add(listm[i]); } return list.length > 0; }, check(event, player) { if (get.attitude(_status.event.player, event.player) >= 0) return false; if (event.getParent("phaseUse").skipped) return true; var nd = player.needsToDiscard(); return ( player.countCards("h", function (card) { return player.getUseValue(card, null, true) > 0 && (nd ? true : get.tag(card, "damage") > 0); }) == 0 ); }, logTarget: "player", content() { "step 0"; var list = []; var listm = []; var listv = []; if (trigger.player.name1 != undefined) listm = lib.character[trigger.player.name1][3]; else listm = lib.character[trigger.player.name][3]; if (trigger.player.name2 != undefined) listv = lib.character[trigger.player.name2][3]; listm = listm.concat(listv); var func = function (skill) { var info = get.info(skill); if (!info || info.charlotte) return false; return true; }; for (var i = 0; i < listm.length; i++) { if (func(listm[i])) list.add(listm[i]); } event.skills = list; player.chooseControl(list).set("prompt", "选择" + get.translation(trigger.player) + "武将牌上的一个技能并令其失效"); "step 1"; trigger.player.disableSkill("olduorui2", result.control); trigger.player.addTempSkill("olduorui2", { player: "phaseAfter" }); game.log(player, "选择了", trigger.player, "的技能", "#g【" + get.translation(result.control) + "】"); event.getParent("phaseUse").skipped = true; }, }, olduorui2: { onremove(player, skill) { player.enableSkill(skill); }, locked: true, mark: true, charlotte: true, intro: { content(storage, player, skill) { var list = []; for (var i in player.disabledSkills) { if (player.disabledSkills[i].includes(skill)) list.push(i); } if (list.length) { var str = "失效技能:"; for (var i = 0; i < list.length; i++) { if (lib.translate[list[i] + "_info"]) str += get.translation(list[i]) + "、"; } return str.slice(0, str.length - 1); } }, }, }, wuhun2: { audio: 2 }, new_wuhun: { audio: "wuhun2", trigger: { player: "damageEnd" }, filter(event, player) { return event.source && event.source.isIn(); }, forced: true, logTarget: "source", content() { trigger.source.addMark("new_wuhun", trigger.num); }, group: "new_wuhun_die", ai: { notemp: true, effect: { target: (card, player, target) => { if (!get.tag(card, "damage") || !target.hasFriend()) return; if (player.hasSkillTag("jueqing", null, target)) return 1.7; let die = [null, 1], temp; game.filterPlayer(i => { temp = i.countMark("new_wuhun"); if (i === player && target.hp + target.hujia > 1) temp++; if (temp >= die[1]) { if (!die[0]) die = [i, temp]; else { let att = get.attitude(player, i); if (att < die[1]) die = [i, temp]; } } }); if (die[0]) return [1, 0, 1, (-6 * get.sgnAttitude(player, die[0])) / Math.max(1, target.hp)]; }, }, }, marktext: "魇", intro: { name: "梦魇", content: "mark", onunmark: true, }, subSkill: { die: { audio: "wuhun2", trigger: { player: "die" }, filter(event, player) { return game.hasPlayer(function (current) { return current != player && current.hasMark("new_wuhun"); }); }, forced: true, direct: true, forceDie: true, skillAnimation: true, animationColor: "soil", content() { "step 0"; var num = 0; for (var i = 0; i < game.players.length; i++) { var current = game.players[i]; if (current != player && current.countMark("new_wuhun") > num) { num = current.countMark("new_wuhun"); } } player .chooseTarget(true, "请选择【武魂】的目标", "令其进行判定,若判定结果不为【桃】或【桃园结义】,则其死亡", function (card, player, target) { return target != player && target.countMark("new_wuhun") == _status.event.num; }) .set("ai", function (target) { return -get.attitude(_status.event.player, target); }) .set("forceDie", true) .set("num", num); "step 1"; if (result.bool) { var target = result.targets[0]; event.target = target; player.logSkill("new_wuhun_die", target); player.line(target, { color: [255, 255, 0] }); game.delay(2); } "step 2"; target.judge(function (card) { if (["tao", "taoyuan"].includes(card.name)) return 10; return -10; }).judge2 = function (result) { return result.bool == false ? true : false; }; "step 3"; if (!result.bool) target.die(); }, }, }, }, new_guixin: { audio: "guixin", trigger: { player: "damageEnd", }, check(event, player) { if (player.isTurnedOver() || event.num > 1) return true; var num = game.countPlayer(function (current) { if (current.countCards("he") && current != player && get.attitude(player, current) <= 0) { return true; } if (current.countCards("j") && current != player && get.attitude(player, current) > 0) { return true; } }); return num >= 2; }, content() { "step 0"; var targets = game.filterPlayer(); targets.remove(player); targets.sort(lib.sort.seat); event.targets = targets; event.count = trigger.num; "step 1"; event.num = 0; player.line(targets, "green"); player .chooseControl("手牌区", "装备区", "判定区") .set("ai", function () { if ( game.hasPlayer(function (current) { return current.countCards("j") && current != player && get.attitude(player, current) > 0; }) ) return 2; return Math.floor(Math.random() * 3); }) .set("prompt", "请选择优先获得的区域"); "step 2"; event.range = { 手牌区: ["h", "e", "j"], 装备区: ["e", "h", "j"], 判定区: ["j", "h", "e"], }[result.control || "手牌区"]; "step 3"; if (num < event.targets.length) { var target = event.targets[num]; var range = event.range; for (var i = 0; i < range.length; i++) { var cards = target.getCards(range[i]); if (cards.length) { var card = cards.randomGet(); player.gain(card, target, "giveAuto", "bySelf"); break; } } event.num++; } "step 4"; if (num < event.targets.length) event.goto(3); "step 5"; player.turnOver(); "step 6"; event.count--; if (event.count && player.hasSkill("new_guixin")) { player.chooseBool(get.prompt2("new_guixin")).ai = function () { return lib.skill.new_guixin.check({ num: event.count }, player); }; } else { event.finish(); } "step 7"; if (event.count && result.bool) { player.logSkill("new_guixin"); event.goto(1); } }, ai: { maixie: true, maixie_hp: true, threaten(player, target) { if (target.hp == 1) return 2.5; return 1; }, effect: { target(card, player, target) { if ( !target._new_guixin_eff && get.tag(card, "damage") && target.hp > (player.hasSkillTag("damageBonus", true, { card: card, target: target, }) ? 2 : 1) ) { if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; target._new_guixin_eff = true; let gain = game.countPlayer(function (current) { if (target == current) return 0; if (get.attitude(target, current) > 0) { if (current.hasCard(cardx => lib.filter.canBeGained(cardx, target, current, "new_guixin") && get.effect(current, cardx, current, current) < 0, "j")) return 1.3; return 0; } if (current.hasCard(cardx => lib.filter.canBeGained(cardx, target, current, "new_guixin") && get.effect(current, cardx, current, current) > 0, "e")) return 1.1; if (current.hasCard(cardx => lib.filter.canBeGained(cardx, target, current, "new_guixin"), "h")) return 0.9; return 0; }); if (target.isTurnedOver()) gain += 2.3; else gain -= 2.3; delete target._new_guixin_eff; return [1, Math.max(0, gain)]; } }, }, }, }, ol_shenfen: { audio: 2, enable: "phaseUse", filter(event, player) { return player.countMark("baonu") >= 6; }, usable: 1, skillAnimation: true, animationColor: "metal", content() { "step 0"; event.delay = false; player.removeMark("baonu", 6); event.targets = game.filterPlayer(); event.targets.remove(player); event.targets.sort(lib.sort.seat); player.line(event.targets, "green"); event.targets2 = event.targets.slice(0); event.targets3 = event.targets.slice(0); "step 1"; if (event.targets2.length) { event.targets2.shift().damage("nocard"); event.redo(); } "step 2"; if (event.targets.length) { event.current = event.targets.shift(); if (event.current.countCards("e")) event.delay = true; event.current.discard(event.current.getCards("e")).delay = false; } "step 3"; if (event.delay) game.delay(0.5); event.delay = false; if (event.targets.length) event.goto(2); "step 4"; if (event.targets3.length) { var target = event.targets3.shift(); target.chooseToDiscard(4, "h", true).delay = false; if (target.countCards("h")) event.delay = true; } "step 5"; if (event.delay) game.delay(0.5); event.delay = false; if (event.targets3.length) event.goto(4); "step 6"; player.turnOver(); }, ai: { combo: "baonu", order: 10, result: { player(player) { return game.countPlayer(function (current) { if (current != player) { return get.sgn(get.damageEffect(current, player, player)); } }); }, }, }, }, ol_wuqian: { audio: 2, enable: "phaseUse", derivation: "wushuang", filter(event, player) { return player.countMark("baonu") >= 2 && game.hasPlayer(target => lib.skill.ol_wuqian.filterTarget(null, player, target)); }, filterTarget(card, player, target) { return target != player && !target.hasSkill("ol_wuqian_targeted"); }, content() { player.removeMark("baonu", 2); player.addTempSkills("wushuang"); player.popup("无双"); // game.log(player,'获得了技能','#g【无双】'); target.addTempSkill("ol_wuqian_targeted"); }, ai: { order: 9, result: { target(player, target) { if ( player.countCards("hs", card => { if (!player.getCardUsable({ name: card.name })) return false; if (!player.canUse(card, target)) return false; var eff1 = get.effect(target, card, player, player); _status.baonuCheck = true; var eff2 = get.effect(target, card, player, player); delete _status.baonuCheck; return eff2 > Math.max(0, eff1); }) ) return -1; return 0; }, }, combo: "baonu", }, global: "ol_wuqian_ai", subSkill: { targeted: { charlotte: true, ai: { unequip2: true }, }, ai: { ai: { unequip2: true, skillTagFilter(player) { if (!_status.baonuCheck) return false; }, }, }, }, }, wumou: { audio: 2, trigger: { player: "useCard" }, forced: true, filter(event) { return get.type(event.card) == "trick"; }, content() { "step 0"; if (player.hasMark("baonu")) { player.chooseControlList(["移去一枚【暴怒】标记", "失去1点体力"], true).set("ai", function (event, player) { if (get.effect(player, { name: "losehp" }, player, player) >= 0) return 1; if (player.storage.baonu > 6) return 0; if (player.hp + player.num("h", "tao") > 3) return 1; return 0; }); } else { player.loseHp(); event.finish(); } "step 1"; if (result.index == 0) { player.removeMark("baonu", 1); } else { player.loseHp(); } }, ai: { effect: { player_use(card, player) { if (get.type(card) == "trick" && get.value(card) < 6) { return [0, -2]; } }, }, neg: true, }, }, qinyin: { audio: 2, trigger: { player: "phaseDiscardEnd" }, direct: true, filter(event, player) { var cards = []; player.getHistory("lose", function (evt) { if (evt.type == "discard" && evt.getParent("phaseDiscard") == event) cards.addArray(evt.cards2); }); return cards.length > 1; }, content() { "step 0"; event.forceDie = true; if (typeof event.count != "number") { // event.count=trigger.cards.length-1; event.count = 1; } var recover = 0, lose = 0, players = game.filterPlayer(); for (var i = 0; i < players.length; i++) { if (players[i].hp < players[i].maxHp) { if (get.attitude(player, players[i]) > 0) { if (players[i].hp < 2) { lose--; recover += 0.5; } lose--; recover++; } else if (get.attitude(player, players[i]) < 0) { if (players[i].hp < 2) { lose++; recover -= 0.5; } lose++; recover--; } } else { if (get.attitude(player, players[i]) > 0) { lose--; } else if (get.attitude(player, players[i]) < 0) { lose++; } } } var prompt = get.prompt("qinyin") + "(剩余" + get.cnNumber(event.count) + "次)"; player.chooseControl("失去体力", "回复体力", "cancel2", ui.create.dialog(get.prompt("qinyin"), "hidden")).ai = function () { if (lose > recover && lose > 0) return 0; if (lose < recover && recover > 0) return 1; return 2; }; "step 1"; if (result.control == "cancel2") { event.finish(); } else { player.logSkill("qinyin"); event.bool = result.control == "回复体力"; event.num = 0; event.players = game.filterPlayer(); } "step 2"; if (event.num < event.players.length) { var target = event.players[event.num]; if (event.bool) { target.recover(); } else { target.loseHp(); } event.num++; event.redo(); } "step 3"; if (event.count > 1) { event.count--; event.goto(0); } }, ai: { expose: 0.1, threaten: 2, }, }, lianpo: { audio: 2, trigger: { global: "phaseAfter" }, frequent: true, filter(event, player) { return player.getStat("kill") > 0; }, content() { player.insertPhase(); }, }, baonu: { audio: 2, marktext: "暴", unique: true, trigger: { source: "damageSource", player: ["damageEnd", "enterGame"], global: "phaseBefore", }, forced: true, filter(event) { return (event.name != "damage" && (event.name != "phase" || game.phaseNumber == 0)) || event.num > 0; }, content() { player.addMark("baonu", trigger.name == "damage" ? trigger.num : 2); }, intro: { name: "暴怒", content: "mark", }, ai: { combo: "ol_shenfen", maixie: true, maixie_hp: true, }, }, shenfen: { audio: 2, unique: true, enable: "phaseUse", filter(event, player) { return player.storage.baonu >= 6; }, skillAnimation: true, animationColor: "metal", limited: true, content() { "step 0"; player.awakenSkill("shenfen"); player.storage.baonu -= 6; player.markSkill("baonu"); player.syncStorage("baonu"); event.targets = game.filterPlayer(); event.targets.remove(player); event.targets.sort(lib.sort.seat); event.targets2 = event.targets.slice(0); player.line(event.targets, "green"); "step 1"; if (event.targets.length) { event.targets.shift().damage(); event.redo(); } "step 2"; if (event.targets2.length) { var cur = event.targets2.shift(); if (cur && cur.countCards("he")) { cur.chooseToDiscard("he", true, 4); } event.redo(); } }, ai: { order: 10, result: { player(player) { return game.countPlayer(function (current) { if (current != player) { return get.sgn(get.damageEffect(current, player, player)); } }); }, }, combo: "baonu", }, }, wuqian: { audio: 2, enable: "phaseUse", derivation: "wushuang", filter(event, player) { return player.storage.baonu >= 2 && !player.hasSkill("wushuang"); }, content() { player.storage.baonu -= 2; player.addTempSkill("wushuang"); }, ai: { order: 5, result: { player(player) { if (!player.storage.shenfen) return 0; var cards = player.getCards("h", "sha"); if (cards.length) { if ( game.hasPlayer(function (current) { return player.canUse("sha", current) && get.effect(current, cards[0], player, player) > 0 && current.hasShan(); }) ) { return 1; } } return 0; }, }, combo: "baonu", }, }, renjie: { audio: "renjie2", trigger: { player: "damageEnd" }, forced: true, group: "renjie2", notemp: true, //mark:true, filter(event) { return event.num > 0; }, content() { player.addMark("renjie", trigger.num); }, intro: { name2: "忍", content: "mark", }, ai: { maixie: true, maixie_hp: true, combo: "sbaiyin", effect: { target(card, player, target) { if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; if (get.tag(card, "damage")) { if (target.hp == target.maxHp) { if (!target.hasSkill("jilue")) { return [0, 1]; } return [0.7, 1]; } return 0.7; } }, }, }, }, renjie2: { audio: 2, mod: { aiOrder: (player, card, num) => { if (num <= 0 || typeof card !== "object" || !player.isPhaseUsing()) return num; if (player.hasSkill("sbaiyin")) { if (player.countMark("renjie") < 4 && player.getUseValue(card) < Math.min(4, (player.hp * player.hp) / 4)) return 0; } else if (player.hasSkill("jilue")) { if (player.countMark("renjie") < 3 && player.getUseValue(card) < Math.min(1.8, 0.18 * player.hp * player.hp)) return 0; } }, }, trigger: { player: "loseAfter", global: "loseAsyncAfter", }, forced: true, filter(event, player) { if (event.type != "discard" || event.getlx === false) return false; var evt = event.getParent("phaseDiscard"), evt2 = event.getl(player); return evt && evt2 && evt.name == "phaseDiscard" && evt.player == player && evt2.cards2 && evt2.cards2.length > 0; }, content() { player.addMark("renjie", trigger.getl(player).cards2.length); }, }, sbaiyin: { skillAnimation: "epic", animationColor: "thunder", juexingji: true, trigger: { player: "phaseZhunbeiBegin" }, forced: true, unique: true, audio: 2, filter(event, player) { return player.countMark("renjie") >= 4; }, content() { player.awakenSkill("sbaiyin"); player.loseMaxHp(); player.addSkills("jilue"); }, derivation: ["jilue", "reguicai", "fangzhu", "rejizhi", "rezhiheng", "rewansha"], ai: { combo: "renjie", }, }, jilue: { unique: true, group: ["jilue_guicai", "jilue_fangzhu", "jilue_wansha", "jilue_zhiheng", "jilue_jizhi"], ai: { combo: "renjie", }, }, jilue_guicai: { audio: 1, trigger: { global: "judge" }, direct: true, filter(event, player) { return player.countCards("hes") > 0 && player.hasMark("renjie"); }, content() { "step 0"; player.chooseCard("是否弃置一枚“忍”,并发动〖鬼才〗?", "hes", function (card) { 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; }).ai = function (card) { var trigger = _status.event.parent._trigger; var player = _status.event.player; var result = trigger.judge(card) - trigger.judge(trigger.player.judging[0]); var attitude = get.attitude(player, trigger.player); if (attitude == 0 || result == 0) return 0; if (attitude > 0) { return result - get.value(card) / 2; } else { return -result - get.value(card) / 2; } }; "step 1"; if (result.bool) { player.respond(result.cards, "highlight", "jilue_guicai", "noOrdering"); } else { event.finish(); } "step 2"; if (result.bool) { player.removeMark("renjie", 1); if (trigger.player.judging[0].clone) { trigger.player.judging[0].clone.delete(); game.addVideo("deletenode", player, get.cardsInfo([trigger.player.judging[0].clone])); } game.cardsDiscard(trigger.player.judging[0]); trigger.player.judging[0] = result.cards[0]; trigger.orderingCards.addArray(result.cards); game.log(trigger.player, "的判定牌改为", result.cards[0]); game.delay(2); } }, ai: { rejudge: true, tag: { rejudge: 1, }, }, }, jilue_fangzhu: { audio: 1, trigger: { player: "damageEnd" }, direct: true, //priority:-1, filter(event, player) { return player.hasMark("renjie"); }, content() { "step 0"; player .chooseTarget("是否弃置一枚“忍”,并发动【放逐】?", function (card, player, target) { return player != target; }) .set("ai", target => { if (target.hasSkillTag("noturn")) return 0; var player = _status.event.player; var current = _status.currentPhase; var dis = current ? get.distance(current, target, "absolute") : 1; var draw = player.getDamagedHp(); var att = get.attitude(player, target); if (att == 0) return target.hasJudge("lebu") ? Math.random() / 3 : Math.sqrt(get.threaten(target)) / 5 + Math.random() / 2; if (att > 0) { if (target.isTurnedOver()) return att + draw; if (draw < 4) return -1; if (current && target.getSeatNum() > current.getSeatNum()) return att + draw / 3; return (10 * Math.sqrt(Math.max(0.01, get.threaten(target)))) / (3.5 - draw) + dis / (2 * game.countPlayer()); } else { if (target.isTurnedOver()) return att - draw; if (draw >= 5) return -1; if (current && target.getSeatNum() <= current.getSeatNum()) return -att + draw / 3; return (4.25 - draw) * 10 * Math.sqrt(Math.max(0.01, get.threaten(target))) + (2 * game.countPlayer()) / dis; } }); "step 1"; if (result.bool) { player.removeMark("renjie", 1); player.logSkill("jilue_fangzhu", result.targets); result.targets[0].draw(player.maxHp - player.hp); result.targets[0].turnOver(); } }, }, jilue_wansha: { audio: "wansha", audioname: ["shen_simayi"], enable: "phaseUse", usable: 1, filter(event, player) { return player.hasMark("renjie"); }, content() { player.removeMark("renjie", 1); player.addTempSkill("rewansha"); }, ai: { order: () => { let player = _status.event.player; if ( game.hasPlayer(current => { if (player === current || current.hp > 1 || get.attitude(player, current) >= 0) return false; return (player.inRange(current) && player.countCards("hs", "sha") && player.getCardUsable("sha")) || player.countCards("hs", card => get.name(card) !== "sha" && get.tag(card, "damage")) > 1; }) ) return 9.2; return 0; }, result: { player: 1, }, effect: { player(card, player, target) { if (target && player.hasSkill("rewansha") && target.hp <= 1 && get.tag(card, "damage")) return [1, 0, 1.5, -1.5]; }, }, }, }, jilue_zhiheng: { audio: 1, mod: { aiOrder(player, card, num) { if (num <= 0 || get.itemtype(card) != "card" || get.type(card) != "equip") return num; let eq = player.getEquip(get.subtype(card)); if (eq && get.equipValue(card) - get.equipValue(eq) < Math.max(1.2, 6 - player.hp)) return 0; }, }, enable: "phaseUse", usable: 1, filter(event, player) { return player.hasMark("renjie"); }, position: "he", filterCard: lib.filter.cardDiscardable, discard: false, lose: false, delay: false, selectCard: [1, Infinity], prompt: "弃置一枚“忍”,然后弃置任意张牌并摸等量的牌。若弃置了所有的手牌,则可以多摸一张牌。", check(card) { var player = _status.event.player; if ( get.position(card) == "h" && !player.countCards("h", function (card) { return get.value(card) >= 8; }) ) { return 8 - get.value(card); } return 6 - get.value(card); }, content() { "step 0"; player.removeMark("renjie", 1); player.discard(cards); event.num = 1; var hs = player.getCards("h"); if (!hs.length) event.num = 0; for (var i = 0; i < hs.length; i++) { if (!cards.includes(hs[i])) { event.num = 0; break; } } "step 1"; player.draw(event.num + cards.length); }, ai: { order(item, player) { if (player.hasCard(i => get.value(i) > Math.max(6, 9 - player.hp), "he")) return 1; return 10; }, result: { player(player) { var num = 0; var cards = player.getCards("he"); for (var i = 0; i < cards.length; i++) { if (get.value(cards[i]) < 6) { num++; } } if (cards.length > 2) return 1; if (cards.length == 2 && player.storage.jilue > 1); return 0; }, }, nokeep: true, skillTagFilter(player, tag, arg) { if (tag === "nokeep") return player.isPhaseUsing() && !player.getStat().skill.jilue_zhiheng && player.hasCard(card => get.name(card) !== "tao", "h"); }, }, }, jilue_jizhi: { audio: 1, trigger: { player: "useCard" }, filter(event, player) { return get.type(event.card, "trick") == "trick" && event.card.isCard && player.hasMark("renjie"); }, content() { "step 0"; player.removeMark("renjie", 1); player.draw(); "step 1"; event.card = result[0]; if (get.type(event.card) == "basic") { player .chooseBool("是否弃置" + get.translation(event.card) + "并令本回合手牌上限+1?") .set("ai", function (evt, player) { return _status.currentPhase == player && player.needsToDiscard(-3) && _status.event.value < 6; }) .set("value", get.value(event.card, player)); } "step 2"; if (result.bool) { player.discard(event.card); player.addTempSkill("jilue_jizhi_clear"); player.addMark("jilue_jizhi_clear", 1, false); } }, subSkill: { clear: { charlotte: true, onremove: true, mod: { maxHandcard(player, num) { return num + player.countMark("jilue_jizhi_clear"); }, }, intro: { content: "手牌上限+#" }, }, }, }, wushen: { mod: { cardname(card, player, name) { if (get.suit(card) == "heart") return "sha"; }, cardnature(card, player) { if (get.suit(card) == "heart") return false; }, targetInRange(card) { if (card.name === "sha") { const suit = get.suit(card); if (suit === "heart" || suit === "unsure") return true; } }, cardUsable(card) { if (card.name === "sha") { const suit = get.suit(card); if (suit === "heart" || suit === "unsure") return Infinity; } }, }, audio: 2, trigger: { player: "useCard" }, forced: true, filter(event, player) { return event.card.name == "sha" && get.suit(event.card) == "heart"; }, content() { trigger.directHit.addArray(game.players); if (trigger.addCount !== false) { trigger.addCount = false; if (player.stat[player.stat.length - 1].card.sha > 0) { player.stat[player.stat.length - 1].card.sha--; } } }, ai: { effect: { target(card, player, target, current) { if (get.tag(card, "respondSha") && current < 0) return 0.6; }, }, directHit_ai: true, skillTagFilter(player, tag, arg) { return arg.card.name == "sha" && get.suit(arg.card) == "heart"; }, }, }, wuhun: { audio: "wuhun2", trigger: { player: "die" }, filter(event) { return event.source && event.source.isIn(); }, forced: true, forceDie: true, skillAnimation: true, animationColor: "soil", logTarget: "source", content() { var num = trigger.source.getHp(); if (num > 0) trigger.source.loseHp(num); }, ai: { threaten(player, target) { if (target.hp == 1) { if (player.getHp() <= 0) return 100; return 0.2; } return 0.8; }, effect: { target(card, player, target, current) { if (player.getHp() <= 0) return; if (!target.hasFriend()) return; if (target.hp <= 1 && get.tag(card, "damage")) return [1, 0, 0, -2]; }, }, }, }, guixin: { audio: 2, trigger: { player: "damageEnd" }, check(event, player) { if (player.isTurnedOver() || event.num > 1) return true; var num = game.countPlayer(function (current) { if (current.countCards("he") && current != player && get.attitude(player, current) <= 0) { return true; } if (current.countCards("j") && current != player && get.attitude(player, current) > 0) { return true; } }); return num >= 2; }, content() { "step 0"; event.count = trigger.num; "step 1"; var targets = game.filterPlayer(current => current != player).sortBySeat(); player.line(targets); player.gainMultiple(targets, "hej"); "step 2"; player.turnOver(); "step 3"; event.count--; if (event.count && player.hasSkill("guixin")) { player.chooseBool(get.prompt2("guixin")); } else event.finish(); "step 4"; if (event.count && result.bool) event.goto(1); }, ai: { maixie: true, maixie_hp: true, threaten(player, target) { if (target.hp == 1) return 2.5; return 0.5; }, effect: { target(card, player, target) { if ( !target._guixin_eff && get.tag(card, "damage") && target.hp > (player.hasSkillTag("damageBonus", true, { card: card, target: target, }) ? 2 : 1) ) { if (player.hasSkillTag("jueqing", false, target)) return [1, -2]; target._guixin_eff = true; let gain = game.countPlayer(function (current) { if (target == current) return 0; if (get.attitude(target, current) > 0) { if (current.hasCard(cardx => lib.filter.canBeGained(cardx, target, current, "guixin") && get.effect(current, cardx, current, current) < 0, "ej")) return 1.3; return 0; } if (current.hasCard(cardx => lib.filter.canBeGained(cardx, target, current, "guixin") && get.effect(current, cardx, current, current) > 0, "ej")) return 1.1; if (current.hasCard(cardx => lib.filter.canBeGained(cardx, target, current, "guixin"), "h")) return 0.9; return 0; }); if (target.isTurnedOver()) gain += 2.3; else gain -= 2.3; delete target._guixin_eff; return [1, Math.max(0, gain)]; } }, }, }, }, qixing: { audio: 2, unique: true, trigger: { global: "phaseBefore", player: "enterGame", }, forced: true, locked: false, filter(event, player) { return event.name != "phase" || game.phaseNumber == 0; }, content() { "step 0"; player.addToExpansion(get.cards(7), "draw").gaintag.add("qixing"); "step 1"; var cards = player.getExpansions("qixing"); if (!cards.length || !player.countCards("h")) { event.finish(); return; } var next = player.chooseToMove("七星:是否交换“星”和手牌?"); next.set("list", [ [get.translation(player) + "(你)的星", cards], ["手牌区", player.getCards("h")], ]); next.set("filterMove", function (from, to) { return typeof to != "number"; }); next.set("processAI", function (list) { var player = _status.event.player, cards = list[0][1].concat(list[1][1]).sort(function (a, b) { return get.useful(a) - get.useful(b); }), cards2 = cards.splice(0, player.getExpansions("qixing").length); return [cards2, cards]; }); "step 2"; if (result.bool) { var pushs = result.moved[0], gains = result.moved[1]; pushs.removeArray(player.getExpansions("qixing")); gains.removeArray(player.getCards("h")); if (!pushs.length || pushs.length != gains.length) return; player.addToExpansion(pushs, player, "giveAuto").gaintag.add("qixing"); //game.log(player,'将',pushs,'作为“星”置于武将牌上'); player.gain(gains, "draw"); } }, intro: { markcount: "expansion", mark(dialog, content, player) { var content = player.getExpansions("qixing"); if (content && content.length) { if (player == game.me || player.isUnderControl()) { dialog.addAuto(content); } else { return "共有" + get.cnNumber(content.length) + "张星"; } } }, content(content, player) { var content = player.getExpansions("qixing"); if (content && content.length) { if (player == game.me || player.isUnderControl()) { return get.translation(content); } return "共有" + get.cnNumber(content.length) + "张星"; } }, }, group: ["qixing2"], ai: { combo: "dawu" }, }, qixing2: { trigger: { player: "phaseDrawAfter" }, direct: true, filter(event, player) { return player.getExpansions("qixing").length > 0 && player.countCards("h") > 0; }, content() { "step 0"; var cards = player.getExpansions("qixing"); if (!cards.length || !player.countCards("h")) { event.finish(); return; } var next = player.chooseToMove("七星:是否交换“星”和手牌?"); next.set("list", [ [get.translation(player) + "(你)的星", cards], ["手牌区", player.getCards("h")], ]); next.set("filterMove", function (from, to) { return typeof to != "number"; }); next.set("processAI", function (list) { var player = _status.event.player, cards = list[0][1].concat(list[1][1]).sort(function (a, b) { return get.value(a) - get.value(b); }), cards2 = cards.splice(0, player.getExpansions("qixing").length); return [cards2, cards]; }); "step 1"; if (result.bool) { var pushs = result.moved[0], gains = result.moved[1]; pushs.removeArray(player.getExpansions("qixing")); gains.removeArray(player.getCards("h")); if (!pushs.length || pushs.length != gains.length) return; player.logSkill("qixing2"); player.addToExpansion(pushs, player, "giveAuto").gaintag.add("qixing"); game.log(player, "将", pushs, "作为“星”置于武将牌上"); player.gain(gains, "draw"); } }, }, dawu: { trigger: { player: "phaseJieshuBegin" }, direct: true, filter(event, player) { return player.getExpansions("qixing").length; }, audio: 2, content() { "step 0"; var num = Math.min(game.countPlayer(), player.getExpansions("qixing").length); player .chooseTarget(get.prompt("dawu"), "令至多" + get.cnNumber(num) + "名角色获得“大雾”标记", [1, num]) .set("ai", function (target) { if (target.isMin()) return 0; if (target.hasSkill("biantian2") || target.hasSkill("dawu2")) return 0; var att = get.attitude(player, target); if (att >= 4) { if (target.hp > 2 && (target.isHealthy() || target.hasSkillTag("maixie"))) return 0; if (_status.event.allUse) return att; if (target.hp == 1) return att; if (target.hp == 2 && target.countCards("he") <= 2) return att * 0.7; return 0; } return -1; }) .set( "allUse", player.getExpansions("qixing").length >= game.countPlayer(function (current) { return get.attitude(player, current) > 4; }) * 2 ); "step 1"; if (result.bool) { var targets = result.targets.sortBySeat(); player.logSkill("dawu", targets, "thunder"); var length = targets.length; targets.forEach(target => { target.addAdditionalSkill(`dawu_${player.playerid}`, "dawu2"); target.markAuto("dawu2", [player]); }); player.addTempSkill("dawu3", { player: "phaseBeginStart" }); player.chooseCardButton("选择弃置" + get.cnNumber(length) + "张“星”", length, player.getExpansions("qixing"), true); } else { event.finish(); } "step 2"; player.loseToDiscardpile(result.links); }, ai: { combo: "qixing" }, }, dawu2: { charlotte: true, ai: { nofire: true, nodamage: true, effect: { target(card, player, target, current) { if (get.tag(card, "damage") && !get.tag(card, "thunderDamage")) return "zeroplayertarget"; }, }, }, intro: { content(storage) { return `共有${storage.length}枚标记`; }, }, }, dawu3: { trigger: { global: "damageBegin4" }, filter(event, player) { return !event.hasNature("thunder") && event.player.getStorage("dawu2").includes(player); }, forced: true, charlotte: true, logTarget: "player", content() { trigger.cancel(); }, onremove(player) { game.countPlayer2(current => { if (current.getStorage("dawu2").includes(player)) { current.unmarkAuto("dawu2", [player]); current.removeAdditionalSkill(`dawu_${player.playerid}`); } }, true); }, }, kuangfeng: { unique: true, audio: 2, trigger: { player: "phaseJieshuBegin" }, direct: true, filter(event, player) { return player.getExpansions("qixing").length; }, content() { "step 0"; player.chooseTarget(get.prompt("kuangfeng"), "令一名角色获得“狂风”标记").ai = function (target) { return -1; }; "step 1"; if (result.bool) { var targets = result.targets.sortBySeat(); player.logSkill("kuangfeng", targets, "fire"); var length = targets.length; targets.forEach(target => { target.addAdditionalSkill(`kuangfeng_${player.playerid}`, "kuangfeng2"); target.markAuto("kuangfeng2", [player]); }); player.addTempSkill("kuangfeng3", { player: "phaseBeginStart" }); player.chooseCardButton("选择弃置" + get.cnNumber(length) + "张“星”", length, player.getExpansions("qixing"), true); } else { event.finish(); } "step 2"; player.loseToDiscardpile(result.links); }, ai: { combo: "qixing" }, }, kuangfeng2: { charlotte: true, intro: { content(storage) { return `共有${storage.length}枚标记`; }, }, ai: { effect: { target(card, player, target, current) { if (get.tag(card, "fireDamage") && current < 0) return 1.5; }, }, }, }, kuangfeng3: { trigger: { global: "damageBegin3" }, filter(event, player) { return event.hasNature("fire") && event.player.getStorage("kuangfeng2").includes(player); }, charlotte: true, forced: true, logTarget: "player", content() { trigger.num++; }, onremove(player) { game.countPlayer2(current => { if (current.getStorage("kuangfeng2").includes(player)) { current.unmarkAuto("kuangfeng2", player); current.removeAdditionalSkill(`kuangfeng_${player.playerid}`); } }, true); }, }, yeyan: { unique: true, limited: true, audio: 2, enable: "phaseUse", filterCard(card, player) { return !ui.selected.cards.some(cardx => get.suit(cardx, player) == get.suit(card, player)); }, selectCard: [0, 4], filterTarget(card, player, target) { var length = ui.selected.cards.length; return length == 0 || length == 4; }, selectTarget() { if (ui.selected.cards.length == 4) return [1, 2]; if (ui.selected.cards.length == 0) return [1, 3]; game.uncheck("target"); return [1, 3]; }, complexCard: true, complexSelect: true, line: "fire", forceDie: true, animationColor: "metal", skillAnimation: "legend", check(card) { if (!lib.skill.yeyan.getBigFire(get.event("player"))) return -1; return 1 / (get.value(card) || 0.5); }, multitarget: true, multiline: true, contentBefore() { player.awakenSkill("yeyan"); }, content() { "step 0"; event.num = 0; targets.sortBySeat(); "step 1"; if (cards.length == 4) event.goto(2); else { if (event.num < targets.length) { targets[event.num].damage("fire", 1, "nocard"); event.num++; } if (event.num == targets.length) event.finish(); else event.redo(); } "step 2"; player.loseHp(3); if (targets.length == 1) event.goto(4); else { player .chooseTarget("请选择受到2点伤害的角色", true, function (card, player, target) { return _status.event.targets.includes(target); }) .set("ai", function (target) { return 1; }) .set("forceDie", true) .set("targets", targets); } "step 3"; if (event.num < targets.length) { var dnum = 1; if (result.bool && result.targets && targets[event.num] == result.targets[0]) dnum = 2; targets[event.num].damage("fire", dnum, "nocard"); event.num++; } if (event.num == targets.length) event.finish(); else event.redo(); "step 4"; player .chooseControl("2点", "3点") .set("prompt", "请选择伤害点数") .set("ai", function () { return "3点"; }) .set("forceDie", true); "step 5"; targets[0].damage("fire", result.control == "2点" ? 2 : 3, "nocard"); }, ai: { order(item, player) { return lib.skill.yeyan.getBigFire(player) ? 10 : 1; }, fireAttack: true, result: { target(player, target) { if (player.hasUnknown()) return 0; const att = get.sgn(get.attitude(player, target)); const targets = game.filterPlayer(target => get.damageEffect(target, player, player, "fire") && (!lib.skill.yeyan.getBigFire(player) || (target.hp <= 3 && !target.hasSkillTag("filterDamage", null, { player: player })))); if (!targets.includes(target)) return 0; if (lib.skill.yeyan.getBigFire(player)) { if (ui.selected.targets.length) return 0; if (!(targets.length == 1 || (att < 0 && target.identity && target.identity.indexOf("zhu") != -1))) return 0; } return att * get.damageEffect(target, player, player, "fire"); }, }, }, getBigFire(player) { if (player.getDiscardableCards(player, "h").reduce((list, card) => list.add(get.suit(card, player)), []).length < 4) return false; const targets = game.filterPlayer(target => get.damageEffect(target, player, player, "fire") && target.hp <= 3 && !target.hasSkillTag("filterDamage", null, { player: player })); if (!targets.length) return false; if (targets.length == 1 || targets.some(target => get.attitude(player, target) < 0 && target.identity && target.identity.indexOf("zhu") != -1)) { let suits = player.getDiscardableCards(player, "h").reduce((map, card) => { const suit = get.suit(card, player); if (!map[suit]) map[suit] = []; return map; }, {}), cards = []; Object.keys(suits).forEach(i => { suits[i].addArray(player.getDiscardableCards(player, "h").filter(card => get.suit(card) == i)); cards.add(suits[i].sort((a, b) => get.value(a) - get.value(b))[0]); }); return player.hp + player.countCards("h", card => !cards.includes(card) && player.canSaveCard(card, player)) - 3 > 0; } return false; }, }, longhun: { audio: 4, group: ["longhun1", "longhun2", "longhun3", "longhun4"], ai: { fireAttack: true, skillTagFilter(player, tag) { switch (tag) { case "respondSha": { if (player.countCards("he", { suit: "diamond" }) < Math.max(1, player.hp)) return false; break; } case "respondShan": { if (player.countCards("he", { suit: "club" }) < Math.max(1, player.hp)) return false; break; } case "save": { if (player.countCards("he", { suit: "heart" }) < Math.max(1, player.hp)) return false; break; } default: return true; } }, maixie: true, respondSha: true, respondShan: true, effect: { target(card, player, target) { if (get.tag(card, "recover") && target.hp >= 1) return [0, 0]; if (!target.hasFriend()) return; if ((get.tag(card, "damage") == 1 || get.tag(card, "loseHp")) && target.hp > 1) return [0, 1]; }, }, threaten(player, target) { if (target.hp == 1) return 2; return 0.5; }, }, }, longhun1: { audio: true, enable: ["chooseToUse", "chooseToRespond"], prompt() { return "将" + get.cnNumber(Math.max(1, _status.event.player.hp)) + "张红桃牌当作桃使用"; }, position: "hes", check(card, event) { if (_status.event.player.hp > 1) return 0; return 10 - get.value(card); }, selectCard() { return Math.max(1, _status.event.player.hp); }, viewAs: { name: "tao" }, viewAsFilter(player) { return player.countCards("hes", { suit: "heart" }) >= player.hp; }, filterCard(card) { return get.suit(card) == "heart"; }, }, longhun2: { audio: true, enable: ["chooseToUse", "chooseToRespond"], prompt() { return "将" + get.cnNumber(Math.max(1, _status.event.player.hp)) + "张方片当作火杀使用或打出"; }, position: "hes", check(card, event) { if (_status.event.player.hp > 1) return 0; return 10 - get.value(card); }, selectCard() { return Math.max(1, _status.event.player.hp); }, viewAs: { name: "sha", nature: "fire" }, viewAsFilter(player) { return player.countCards("hes", { suit: "diamond" }) >= player.hp; }, filterCard(card) { return get.suit(card) == "diamond"; }, }, longhun3: { audio: true, enable: ["chooseToUse", "chooseToRespond"], prompt() { return "将" + get.cnNumber(Math.max(1, _status.event.player.hp)) + "张黑桃牌当作无懈可击使用"; }, position: "hes", check(card, event) { if (_status.event.player.hp > 1) return 0; return 7 - get.value(card); }, selectCard() { return Math.max(1, _status.event.player.hp); }, viewAs: { name: "wuxie" }, viewAsFilter(player) { return player.countCards("hes", { suit: "spade" }) >= player.hp; }, filterCard(card) { return get.suit(card) == "spade"; }, }, longhun4: { audio: true, enable: ["chooseToUse", "chooseToRespond"], prompt() { return "将" + get.cnNumber(Math.max(1, _status.event.player.hp)) + "张梅花牌当作闪使用或打出"; }, position: "hes", check(card, event) { if (_status.event.player.hp > 1) return 0; return 10 - get.value(card); }, selectCard() { return Math.max(1, _status.event.player.hp); }, viewAsFilter(player) { return player.countCards("hes", { suit: "club" }) >= player.hp; }, viewAs: { name: "shan" }, filterCard(card) { return get.suit(card) == "club"; }, }, juejing: { mod: { maxHandcard(player, num) { return 2 + num; }, }, audio: true, trigger: { player: "phaseDrawBegin2" }, //priority:-5, filter(event, player) { return !event.numFixed && player.hp < player.maxHp; }, forced: true, content() { trigger.num += player.getDamagedHp(); }, }, relonghun: { audio: 2, //技能发动时机 enable: ["chooseToUse", "chooseToRespond"], //发动时提示的技能描述 prompt: "将♦牌当做杀,♥牌当做桃,♣牌当做闪,♠牌当做无懈可击使用或打出", //动态的viewAs viewAs(cards, player) { if (cards.length) { var name = false, 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; }, //AI选牌思路 check(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(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(get.autoViewAs({ name: "shan" }, "unsure"), player, event)) return true; //如果这张牌是方片并且当前时机能够使用/打出火杀 那么这张牌可以选择 if (name == "diamond" && filter(get.autoViewAs({ name: "sha", nature: "fire" }, "unsure"), player, event)) return true; //如果这张牌是黑桃并且当前时机能够使用/打出无懈 那么这张牌可以选择 if (name == "spade" && filter(get.autoViewAs({ name: "wuxie" }, "unsure"), player, event)) return true; //如果这张牌是红桃并且当前时机能够使用/打出桃 那么这张牌可以选择 if (name == "heart" && filter(get.autoViewAs({ name: "tao" }, "unsure"), player, event)) return true; //上述条件都不满足 那么就不能选择这张牌 return false; }, //判断当前时机能否发动技能 filter(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; }, ai: { respondSha: true, respondShan: true, //让系统知道角色“有杀”“有闪” skillTagFilter(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; }, //AI牌序 order(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(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; }, group: ["relonghun_num", "relonghun_discard"], subSkill: { num: { trigger: { player: "useCard" }, forced: true, popup: false, filter(event) { var evt = event; return ["sha", "tao"].includes(evt.card.name) && evt.skill == "relonghun" && evt.cards && evt.cards.length == 2; }, content() { trigger.baseDamage++; }, }, discard: { trigger: { player: ["useCardAfter", "respondAfter"] }, forced: true, popup: false, logTarget() { return _status.currentPhase; }, autodelay(event) { return event.name == "respond" ? 0.5 : false; }, filter(evt, player) { return ["shan", "wuxie"].includes(evt.card.name) && evt.skill == "relonghun" && evt.cards && evt.cards.length == 2 && _status.currentPhase && _status.currentPhase != player && _status.currentPhase.countDiscardableCards(player, "he"); }, content() { //game.log(trigger.card) //game.log(trigger.cards) player.line(_status.currentPhase, "green"); player.discardPlayerCard(_status.currentPhase, "he", true); }, }, }, }, xinlonghun: { audio: "longhun", enable: ["chooseToUse", "chooseToRespond"], prompt: "将♦手牌当做火【杀】,♥手牌当做【桃】,♣手牌当做【闪】,♠手牌当做【无懈可击】使用或打出", viewAs(cards, player) { if (cards.length) { var name = false, 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(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("hs", 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: "hs", filterCard(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(event, player) { var filter = event.filterCard; if (filter(get.autoViewAs({ name: "sha", nature: "fire" }, "unsure"), player, event) && player.countCards("hs", { suit: "diamond" })) return true; if (filter(get.autoViewAs({ name: "shan" }, "unsure"), player, event) && player.countCards("hs", { suit: "club" })) return true; if (filter(get.autoViewAs({ name: "tao" }, "unsure"), player, event) && player.countCards("hs", { suit: "heart" })) return true; if (filter(get.autoViewAs({ name: "wuxie" }, "unsure"), player, event) && player.countCards("hs", { suit: "spade" })) return true; return false; }, precontent() { delete event.result.skill; player.logSkill("longhun" + (4 - lib.suit.indexOf(get.suit(event.result.cards[0], player)))); }, ai: { respondSha: true, respondShan: true, skillTagFilter(player, tag) { var name; switch (tag) { case "respondSha": name = "diamond"; break; case "respondShan": name = "club"; break; case "save": name = "heart"; break; } if (!player.countCards("hs", { suit: name })) return false; }, order(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("hs", 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(player, name) { if (name == "wuxie" && _status.connectMode && player.countCards("hs") > 0) return true; if (name == "wuxie") return player.countCards("hs", { suit: "spade" }) > 0; if (name == "tao") return player.countCards("hs", { suit: "heart" }) > 0; }, }, xinjuejing: { mod: { maxHandcard(player, num) { return 2 + num; }, }, audio: 2, trigger: { player: ["dying", "dyingAfter"] }, forced: true, content() { player.draw(); }, }, shelie: { audio: 2, trigger: { player: "phaseDrawBegin1" }, filter(event, player) { return !event.numFixed; }, content() { "step 0"; trigger.changeToZero(); event.cards = get.cards(5); game.cardsGotoOrdering(event.cards); event.videoId = lib.status.videoId++; game.broadcastAll( function (player, id, cards) { var str; if (player == game.me && !_status.auto) { str = "涉猎:获取花色各不相同的牌"; } else { str = "涉猎"; } var dialog = ui.create.dialog(str, cards); dialog.videoId = id; }, player, event.videoId, event.cards ); event.time = get.utc(); game.addVideo("showCards", player, ["涉猎", get.cardsInfo(event.cards)]); game.addVideo("delay", null, 2); "step 1"; var list = []; for (var i of cards) list.add(get.suit(i, false)); var next = player.chooseButton(list.length, true); next.set("dialog", event.videoId); next.set("filterButton", function (button) { for (var i = 0; i < ui.selected.buttons.length; i++) { if (get.suit(ui.selected.buttons[i].link) == get.suit(button.link)) return false; } return true; }); next.set("ai", function (button) { return get.value(button.link, _status.event.player); }); "step 2"; if (result.bool && result.links) { event.cards2 = result.links; } else { event.finish(); } var time = 1000 - (get.utc() - event.time); if (time > 0) { game.delay(0, time); } "step 3"; game.broadcastAll("closeDialog", event.videoId); var cards2 = event.cards2; player.gain(cards2, "log", "gain2"); }, ai: { threaten: 1.2, }, }, gongxin: { audio: 2, audioname: ["re_lvmeng", "gexuan"], enable: "phaseUse", usable: 1, filterTarget(card, player, target) { return target != player && target.countCards("h"); }, content() { "step 0"; var cards = target.getCards("h"); player.chooseButton(2, ["攻心", cards, [["弃置此牌", "置于牌堆顶"], "tdnodes"]]).set("filterButton", function (button) { var type = typeof button.link; if (ui.selected.buttons.length && type == typeof ui.selected.buttons[0].link) return false; return type == "string" || get.suit(button.link) == "heart"; }); "step 1"; if (result.bool) { if (typeof result.links[0] != "string") result.links.reverse(); var card = result.links[1], choice = result.links[0]; if (choice == "弃置此牌") target.discard(card); else { player.showCards(card, get.translation(player) + "对" + get.translation(target) + "发动了【攻心】"); target.lose(card, ui.cardPile, "visible", "insert"); } } }, ai: { threaten: 1.5, result: { target(player, target) { return -target.countCards("h"); }, }, order: 10, expose: 0.4, }, }, nzry_longnu: { mark: true, locked: true, zhuanhuanji: true, marktext: "☯", intro: { content(storage, player, skill) { if (player.storage.nzry_longnu == true) return "锁定技,出牌阶段开始时,你减1点体力上限并摸一张牌,然后本阶段内你的锦囊牌均视为雷杀且无使用次数限制"; return "锁定技,出牌阶段开始时,你失去1点体力并摸一张牌,然后本阶段内你的红色手牌均视为火杀且无距离限制"; }, }, audio: 2, trigger: { player: "phaseUseBegin", }, forced: true, content() { "step 0"; player.changeZhuanhuanji("nzry_longnu"); if (player.storage.nzry_longnu != true) { player.loseMaxHp(); } else { player.loseHp(); } player.draw(); "step 1"; if (player.storage.nzry_longnu != true) { player.addTempSkill("nzry_longnu_2", "phaseUseAfter"); } else { player.addTempSkill("nzry_longnu_1", "phaseUseAfter"); } }, subSkill: { 1: { mod: { cardname(card, player) { if (get.color(card) == "red") return "sha"; }, cardnature(card, player) { if (get.color(card) == "red") return "fire"; }, targetInRange(card) { if (get.color(card) == "red") return true; }, }, ai: { effect: { target(card, player, target, current) { if (get.tag(card, "respondSha") && current < 0) return 0.6; }, }, respondSha: true, }, }, 2: { mod: { cardname(card, player) { if (["trick", "delay"].includes(lib.card[card.name].type)) return "sha"; }, cardnature(card, player) { if (["trick", "delay"].includes(lib.card[card.name].type)) return "thunder"; }, cardUsable(card, player) { if (card.name == "sha" && game.hasNature(card, "thunder")) return Infinity; }, }, ai: { effect: { target(card, player, target, current) { if (get.tag(card, "respondSha") && current < 0) return 0.6; }, }, respondSha: true, }, }, }, ai: { fireAttack: true, halfneg: true, threaten: 1.05, }, }, nzry_jieying: { audio: 2, locked: true, global: "g_nzry_jieying", ai: { effect: { target(card) { if (card.name == "tiesuo") return "zeroplayertarget"; }, }, }, group: ["nzry_jieying_1", "nzry_jieying_2"], subSkill: { 1: { audio: "nzry_jieying", trigger: { player: ["linkBefore", "enterGame"], global: "phaseBefore", }, forced: true, filter(event, player) { if (event.name == "link") return player.isLinked(); return (event.name != "phase" || game.phaseNumber == 0) && !player.isLinked(); }, content() { if (trigger.name != "link") player.link(true); else trigger.cancel(); }, }, 2: { audio: "nzry_jieying", trigger: { player: "phaseJieshuBegin", }, direct: true, filter(event, player) { return game.hasPlayer(function (current) { return current != player && !current.isLinked(); }); }, content() { "step 0"; player.chooseTarget(true, "请选择【结营】的目标", function (card, player, target) { return target != player && !target.isLinked(); }).ai = function (target) { return 1 + Math.random(); }; "step 1"; if (result.bool) { player.line(result.targets); player.logSkill("nzry_jieying"); result.targets[0].link(true); } else { event.finish(); } }, }, }, }, g_nzry_jieying: { mod: { maxHandcard(player, num) { if ( game.countPlayer(function (current) { return current.hasSkill("nzry_jieying"); }) > 0 && player.isLinked() ) return num + 2; }, }, }, nzry_junlve: { audio: 2, //marktext:"军", intro: { content: "当前有#个标记", }, //mark:true, trigger: { player: "damageAfter", source: "damageSource", }, forced: true, content() { player.addMark("nzry_junlve", trigger.num); }, ai: { combo: "nzry_cuike", }, }, nzry_cuike: { audio: 2, trigger: { player: "phaseUseBegin", }, direct: true, content() { "step 0"; if (player.countMark("nzry_junlve") % 2 == 1) { player.chooseTarget("是否发动【摧克】,对一名角色造成1点伤害?").ai = function (target) { return -get.attitude(player, target); }; } else { player.chooseTarget("是否发动【摧克】,横置一名角色并弃置其区域内的一张牌?").ai = function (target) { return -get.attitude(player, target); }; } "step 1"; if (result.bool) { player.logSkill("nzry_cuike", result.targets); if (player.countMark("nzry_junlve") % 2 == 1) { result.targets[0].damage(); } else { result.targets[0].link(true); player.discardPlayerCard(result.targets[0], 1, "hej", true); } } "step 2"; if (player.countMark("nzry_junlve") > 7) { player .chooseBool() .set("ai", function () { return true; }) .set("prompt", "是否弃置所有“军略”标记并对所有其他角色造成1点伤害?"); } else { event.finish(); } "step 3"; if (result.bool) { var players = game.players.slice(0).sortBySeat(); player.line(players); player.removeMark("nzry_junlve", player.countMark("nzry_junlve")); for (var i = 0; i < players.length; i++) { if (players[i] != player) players[i].damage(); } } }, ai: { combo: "nzry_junlve", }, }, nzry_dinghuo: { audio: 2, limited: true, init(player) { player.storage.nzry_dinghuo = false; }, intro: { content: "limited", }, unique: true, mark: true, skillAnimation: true, animationColor: "metal", enable: "phaseUse", filter(event, player) { return !player.storage.nzry_dinghuo && player.countMark("nzry_junlve") > 0; }, check(event, player) { var num = game.countPlayer(function (current) { return get.attitude(player, current) < 0 && current.isLinked(); }); return ( player.storage.nzry_junlve >= num && num == game.countPlayer(function (current) { return get.attitude(player, current) < 0; }) ); }, filterTarget(card, player, target) { return target.isLinked(); }, selectTarget() { return [1, _status.event.player.countMark("nzry_junlve")]; }, multiline: true, multitarget: true, content() { "step 0"; player.awakenSkill("nzry_dinghuo"); player.storage.nzry_dinghuo = true; "step 1"; player.removeMark("nzry_junlve", player.countMark("nzry_junlve")); for (var i = 0; i < targets.length; i++) { targets[i].discard(targets[i].getCards("e")); } player .chooseTarget(true, "对一名目标角色造成1点火焰伤害", function (card, player, target) { return _status.event.targets.includes(target); }) .set("targets", targets).ai = function () { return 1; }; "step 2"; if (result.bool) { result.targets[0].damage("fire", "nocard"); } }, ai: { order: 1, fireAttack: true, combo: "nzry_junlve", result: { target(player, target) { if (target.hasSkillTag("nofire")) return 0; if (lib.config.mode == "versus") return -1; if (player.hasUnknown()) return 0; return get.damageEffect(target, player) - target.countCards("e"); }, }, }, }, drlt_duorui: { audio: 2, init(player, skill) { if (!player.storage.drlt_duorui) player.storage.drlt_duorui = []; }, trigger: { source: "damageSource", }, filter(event, player) { if (player.storage.drlt_duorui.length) return false; return event.player.isIn() && _status.currentPhase == player; }, check(event, player) { if (get.attitude(_status.event.player, event.player) >= 0) return false; if (player.hasEnabledSlot() && !player.hasEnabledSlot(5)) return false; return true; }, bannedList: ["bifa", "buqu", "gzbuqu", "songci", "funan", "xinfu_guhuo", "reguhuo", "huashen", "rehuashen", "old_guhuo", "shouxi", "xinpojun", "taoluan", "xintaoluan", "yinbing", "xinfu_yingshi", "zhenwei", "zhengnan", "xinzhengnan", "zhoufu"], logTarget: "player", content() { "step 0"; var list = []; var listm = []; var listv = []; if (trigger.player.name1 != undefined) listm = lib.character[trigger.player.name1][3]; else listm = lib.character[trigger.player.name][3]; if (trigger.player.name2 != undefined) listv = lib.character[trigger.player.name2][3]; listm = listm.concat(listv); var func = function (skill) { var info = get.info(skill); if (!info || info.charlotte || info.hiddenSkill || info.zhuSkill || info.juexingji || info.limited || info.dutySkill || (info.unique && !info.gainable) || lib.skill.drlt_duorui.bannedList.includes(skill)) return false; return true; }; for (var i = 0; i < listm.length; i++) { if (func(listm[i])) list.add(listm[i]); } event.skills = list; if (player.hasEnabledSlot()) { player.chooseToDisable().ai = function (event, player, list) { if (list.includes("equip5")) return "equip5"; return list.randomGet(); }; } "step 1"; if (event.skills.length > 0) { player .chooseControl(event.skills) .set("prompt", "请选择要获得的技能") .set("ai", function () { return event.skills.randomGet(); }); } else event.finish(); "step 2"; player.addTempSkills(result.control, { player: "dieAfter" }); // player.popup(result.control,'thunder'); player.storage.drlt_duorui = [result.control]; player.storage.drlt_duorui_player = trigger.player; trigger.player.storage.drlt_duorui = [result.control]; trigger.player.addTempSkill("drlt_duorui1", { player: "phaseAfter" }); // game.log(player,'获得了技能','#g【'+get.translation(result.control)+'】') }, group: ["duorui_clear"], }, duorui_clear: { trigger: { global: ["phaseAfter", "dieAfter"] }, filter(event, player) { if (!player.storage.drlt_duorui_player || !player.storage.drlt_duorui) return false; return player.storage.drlt_duorui_player == event.player && player.storage.drlt_duorui.length; }, silent: true, forced: true, popup: false, content() { player.removeSkills(player.storage.drlt_duorui[0]); delete player.storage.drlt_duorui_player; player.storage.drlt_duorui = []; }, }, drlt_duorui1: { init(player, skill) { player.disableSkill(skill, player.storage.drlt_duorui); }, onremove(player, skill) { player.enableSkill(skill); }, locked: true, mark: true, charlotte: true, intro: { content(storage, player, skill) { var list = []; for (var i in player.disabledSkills) { if (player.disabledSkills[i].includes(skill)) list.push(i); } if (list.length) { var str = "失效技能:"; for (var i = 0; i < list.length; i++) { if (lib.translate[list[i] + "_info"]) str += get.translation(list[i]) + "、"; } return str.slice(0, str.length - 1); } }, }, }, drlt_zhiti: { audio: 2, locked: true, group: ["drlt_zhiti_damage", "drlt_zhiti_compare", "drlt_zhiti_juedou"], global: "g_drlt_zhiti", subSkill: { juedou: { audio: "drlt_zhiti", trigger: { player: "juedouAfter", target: "juedouAfter", }, forced: true, filter(event, player) { if (event.turn === player || !player.hasDisabledSlot()) return false; const opposite = event.player === player ? event.target : event.player; return opposite && opposite.isIn() && opposite.inRangeOf(player); }, content() { player.chooseToEnable(); }, }, compare: { audio: "drlt_zhiti", trigger: { player: ["chooseToCompareAfter", "compareMultipleAfter"], target: ["chooseToCompareAfter", "compareMultipleAfter"], }, filter(event, player) { if (event.preserve || !player.hasDisabledSlot()) return false; let opposite; if (player === event.player) { if (event.num1 > event.num2) { opposite = event.target; } else { return false; } } else { if (event.num1 < event.num2) { opposite = event.player; } else { return false; } } return opposite && opposite.isIn() && opposite.inRangeOf(player); }, forced: true, content() { player.chooseToEnable(); }, }, damage: { audio: "drlt_zhiti", trigger: { player: "damageEnd" }, forced: true, filter(event, player) { if (!player.hasDisabledSlot()) return false; const opposite = event.source; return opposite && opposite.isIn() && opposite.inRangeOf(player); }, content() { player.chooseToEnable(); }, }, }, }, g_drlt_zhiti: { mod: { maxHandcard(player, num) { if (player.isDamaged()) return ( num - game.countPlayer(function (current) { return current != player && current.hasSkill("drlt_zhiti") && current.inRange(player); }) ); }, }, }, drlt_poxi: { audio: 2, enable: "phaseUse", usable: 1, filterTarget(card, player, target) { return target != player && target.countCards("h") > 0; //return target!=player; }, content() { "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) { if (ts.length > 1) return 0; if (ts.length == 0 || player.hp > 3) return val; 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); } "step 2"; if (event.list1.length + event.list2.length == 4) { if (event.list1.length == 0) player.loseMaxHp(); if (event.list1.length == 1) { var evt = _status.event; for (var i = 0; i < 10; i++) { if (evt && evt.getParent) evt = evt.getParent(); if (evt.name == "phaseUse") { evt.skipped = true; break; } } player.addTempSkill("drlt_poxi1", { player: "phaseAfter" }); } if (event.list1.length == 3) player.recover(); if (event.list1.length == 4) player.draw(4); } }, ai: { order: 13, result: { target(target, player) { return -1; }, }, }, }, drlt_poxi1: { mod: { maxHandcard(player, num) { return num - 1; }, }, }, drlt_jieying_mark: { marktext: "营", intro: { name: "营", content: "mark", }, mod: { cardUsable(card, player, num) { if (player.hasMark("drlt_jieying_mark") && card.name == "sha") return ( num + game.countPlayer(function (current) { return current.hasSkill("drlt_jieying"); }) ); }, maxHandcard(player, num) { if (player.hasMark("drlt_jieying_mark")) return ( num + game.countPlayer(function (current) { return current.hasSkill("drlt_jieying"); }) ); }, aiOrder(player, card, num) { if ( player.hasMark("drlt_jieying_mark") && game.hasPlayer(current => { return current.hasSkill("drlt_jieying") && get.attitude(player, current) <= 0; }) ) return Math.max(num, 0) + 1; }, }, audio: "drlt_jieying", trigger: { player: "phaseDrawBegin2", }, forced: true, filter(event, player) { return ( !event.numFixed && player.hasMark("drlt_jieying_mark") && game.hasPlayer(function (current) { return current.hasSkill("drlt_jieying"); }) ); }, content() { trigger.num += game.countPlayer(function (current) { return current.hasSkill("drlt_jieying"); }); }, ai: { nokeep: true, skillTagFilter(player) { return ( player.hasMark("drlt_jieying_mark") && game.hasPlayer(current => { return current.hasSkill("drlt_jieying") && get.attitude(player, current) <= 0; }) ); }, }, }, drlt_jieying: { audio: 2, locked: false, global: "drlt_jieying_mark", group: ["drlt_jieying_1", "drlt_jieying_2", "drlt_jieying_3"], subSkill: { 1: { audio: "drlt_jieying", trigger: { player: "phaseBegin", }, forced: true, filter(event, player) { return !game.hasPlayer(function (current) { return current.hasMark("drlt_jieying_mark"); }); }, content() { player.addMark("drlt_jieying_mark", 1); }, }, 2: { audio: "drlt_jieying", trigger: { player: "phaseJieshuBegin", }, direct: true, filter(event, player) { return player.hasMark("drlt_jieying_mark"); }, content() { "step 0"; player.chooseTarget(get.prompt("drlt_jieying"), "将“营”交给一名角色;其摸牌阶段多摸一张牌,出牌阶段使用【杀】的次数上限+1且手牌上限+1。该角色回合结束后,其移去“营”标记,然后你获得其所有手牌。", function (card, player, target) { return target != player; }).ai = function (target) { let th = target.countCards("h"), att = get.attitude(_status.event.player, target); for (let i in target.skills) { let info = get.info(i); if (info && info.shaRelated) return Math.abs(att); } if (att > 0) { if (th > 3 && target.hp > 2) return 0.6 * th; } if (att < 1) { if (target.countCards("j", { name: "lebu" })) return 1 + Math.min((1.5 + th) * 0.8, target.getHandcardLimit() * 0.7); if (!th || target.getEquip("zhangba") || target.getEquip("guanshi")) return 0; if (!target.inRange(player) || player.countCards("hs", { name: "shan" }) > 1) return Math.min((1 + th) * 0.3, target.getHandcardLimit() * 0.2); } return 0; }; "step 1"; if (result.bool) { var target = result.targets[0]; player.line(target); player.logSkill("drlt_jieying", target); var mark = player.countMark("drlt_jieying_mark"); player.removeMark("drlt_jieying_mark", mark); target.addMark("drlt_jieying_mark", mark); } }, ai: { effect: { player(card, player, target) { if (get.name(card) === "lebu" && get.attitude(player, target) < 0) return 1 + Math.min((target.countCards("h") + 1.5) * 0.8, target.getHandcardLimit() * 0.7); }, }, }, }, 3: { audio: "drlt_jieying", trigger: { global: "phaseEnd", }, forced: true, filter(event, player) { return player != event.player && event.player.hasMark("drlt_jieying_mark") && event.player.isIn(); }, logTarget: "player", content() { if (trigger.player.countCards("h") > 0) { trigger.player.give(trigger.player.getCards("h"), player); } trigger.player.removeMark("drlt_jieying_mark", trigger.player.countMark("drlt_jieying_mark")); }, }, }, }, }; export default skills;