noname/character/tw/skill.js

17130 lines
529 KiB
JavaScript
Raw Normal View History

import { lib, game, ui, get, ai, _status } from "../../noname.js";
/** @type { importCharacterConfig['skill'] } */
const skills = {
//颜良文丑,但是颜良+文丑
twduwang: {
audio: 3,
dutySkill: true,
derivation: ["twxiayong", "twylyanshix"],
global: "twduwang_global",
group: ["twduwang_effect", "twduwang_achieve", "twduwang_fail"],
onremove: ["twduwang", "twduwang_fail"],
subSkill: {
effect: {
audio: "twduwang1.mp3",
trigger: { player: "phaseUseBegin" },
filter(event, player) {
return game.hasPlayer(target => {
return (
target != player &&
target.hasCard(card => {
if (get.position(card) == "h") return true;
return target.canUse(get.autoViewAs({ name: "juedou" }, [card]), player, false);
}, "he")
);
});
},
async cost(event, trigger, player) {
let { result } = await player
.chooseTarget([1, 3], (_, player, target) => {
return (
target != player &&
target.hasCard(card => {
if (get.position(card) == "h") return true;
return target.canUse(get.autoViewAs({ name: "juedou" }, [card]), player, false);
}, "he")
);
})
.set("prompt", get.prompt("twduwang"))
.set("ai", target => {
const player = get.event("player");
const num = game.countPlayer(current => {
return (
current != player &&
current.hasCard(card => {
if (get.position(card) == "h") return true;
return current.canUse(get.autoViewAs({ name: "juedou" }, [card]), player, false);
}, "he") &&
get.effect(current, { name: "guohe_copy2" }, current, player) + get.effect(player, { name: "juedou" }, current, player) > 0
);
});
return (Math.min(num, 3) + 1) * get.effect(player, { name: "draw" }, player, player) + get.effect(target, { name: "guohe_copy2" }, target, player) + get.effect(player, { name: "juedou" }, target, player);
})
.set("prompt2", "选择至多三名其他角色并摸选择角色数+1的牌然后这些角色须将一张牌当作【决斗】对你使用");
if (result.bool) result.targets.sortBySeat();
event.result = result;
},
async content(event, trigger, player) {
const targets = event.targets;
await player.draw(targets.length + 1);
await game.asyncDelayx();
for (const target of targets) {
if (
!target.hasCard(card => {
return target.canUse(get.autoViewAs({ name: "juedou" }, [card]), player, false);
}, "he")
)
continue;
await target
.chooseToUse()
.set("forced", true)
.set("openskilldialog", "独往:将一张牌当作【决斗】对" + get.translation(player) + "使用")
.set("norestore", true)
.set("_backupevent", "twduwang_backup")
.set("targetRequired", true)
.set("complexSelect", true)
.set("custom", {
add: {},
replace: { window: function () {} },
})
.backup("twduwang_backup")
.set("filterTarget", function (card, player, target) {
if (target != _status.event.sourcex && !ui.selected.targets.includes(_status.event.sourcex)) return false;
return lib.filter.targetEnabled.apply(this, arguments);
})
.set("sourcex", player)
.set("addCount", false);
await game.asyncDelayx();
}
},
},
backup: {
viewAs: { name: "juedou" },
position: "he",
filterCard(card, player) {
const cardx = get.autoViewAs({ name: "juedou" }, [card]);
return lib.filter.targetEnabledx(cardx, player, get.event("sourcex"));
},
check(card) {
if (get.name(card) == "sha") return 5 - get.value(card);
return 8 - get.value(card);
},
precontent() {
delete event.result.skill;
},
},
achieve: {
audio: "twduwang2.mp3",
trigger: { player: "phaseZhunbeiBegin" },
filter(event, player) {
if (player.storage.twduwang_fail) return false;
const history = player.actionHistory;
if (history.length < 2) return false;
for (let i = history.length - 2; i >= 0; i--) {
if (history[i].isMe && !history[i].isSkipped) {
let num = history[i].useCard.filter(evt => {
return evt.card.name == "juedou";
}).length,
targets = game.players.slice().concat(game.dead.slice());
for (const target of targets) {
num += target.actionHistory[i].useCard.filter(evt => {
return evt.card.name == "juedou" && evt.targets && evt.targets.includes(player);
}).length;
}
return num >= (targets.length < 4 ? 3 : 4);
}
}
return false;
},
forced: true,
skillAnimation: true,
animationColor: "metal",
async content(event, trigger, player) {
player.awakenSkill("twduwang");
game.log(player, "完成使命");
if (player.awakenedSkills.includes("twduwang")) {
player.restoreSkill("twduwang");
game.log(player, "重置了技能", "#g【独往】");
}
if (!player.storage.twduwang_fail) {
player.storage.twduwang_fail = true;
game.log(player, "修改了技能", "#g【独往】");
}
let result,
bool1 = player.hasSkill("twxiayong", null, false, false),
bool2 = !player.awakenedSkills.includes("twylyanshi") && player.storage.twduwang_ylyanshi;
if (bool1 && bool2) result = { index: 2 };
else if (bool1) result = { index: 1 };
else if (bool2) result = { index: 0 };
else
result = await player
.chooseControl()
.set("choiceList", ["获得〖狭勇〗", "重置〖延势〗并为其添加历战效果"])
.set("prompt", "独往:请选择一项")
.set("ai", () => {
const player = get.event("player"),
num = game.countPlayer(current => {
return (
current != player &&
current.hasCard(card => {
if (get.position(card) == "h") return true;
return current.canUse(get.autoViewAs({ name: "juedou" }, [card]), player, false);
}, "he") &&
get.effect(current, { name: "guohe_copy2" }, current, player) / 2.5 + get.effect(player, { name: "juedou" }, current, player) > 0
);
});
return num >= 2 ? 0 : 1;
})
.forResult();
if (result.index == 0) await player.addSkills("twxiayong");
if (result.index == 1) {
player.popup("twylyanshi");
if (player.awakenedSkills.includes("twylyanshi")) {
player.restoreSkill("twylyanshi");
game.log(player, "重置了技能", "#g【延势】");
}
if (!player.storage.twduwang_ylyanshi) {
player.storage.twduwang_ylyanshi = true;
game.log(player, "修改了技能", "#g【延势】");
}
}
},
},
fail: {
audio: "twduwang3.mp3",
trigger: { player: "die" },
forceDie: true,
filter(event, player) {
return !player.storage.twduwang_fail;
},
forced: true,
content() {
player.awakenSkill("twduwang");
game.log(player, "使命失败");
},
},
global: {
mod: {
cardSavable(card, player, target) {
if (card.name == "tao" && target != player && target.hasSkill("twduwang") && !target.storage.twduwang_fail) return false;
},
},
audio: "twduwang3.mp3",
trigger: { player: "dying" },
filter(event, player) {
return player.hasSkill("twduwang") && !player.storage.twduwang_fail;
},
forced: true,
content() {},
},
},
},
twylyanshi: {
audio: 2,
enable: ["chooseToUse", "chooseToRespond"],
filter(event, player) {
return ["juedou", "binglinchengxiax"].concat(get.zhinangs()).some(name => {
const info = { name: name };
return (
get.info(info) &&
player.hasCard(card => {
return get.name(card) == "sha" && event.filterCard({ name: name, cards: [card] }, player, event);
}, "hs")
);
});
},
limited: true,
skillAnimation: true,
animationColor: "fire",
onremove: ["twylyanshi", "twduwang_ylyanshi"],
chooseButton: {
dialog(event, player) {
const list = ["juedou", "binglinchengxiax"]
.concat(get.zhinangs())
.filter(name => {
const info = { name: name };
return (
get.info(info) &&
player.hasCard(card => {
return get.name(card) == "sha" && event.filterCard({ name: name, cards: [card] }, player, event);
}, "hs")
);
})
.map(name => [get.translation(get.type(name)), "", name]);
return ui.create.dialog("延势", [list, "vcard"]);
},
check(button) {
return get.event("player").getUseValue({ name: button.link[2] });
},
backup(links, player) {
return {
audio: "twylyanshi",
filterCard(card, player) {
return get.name(card) == "sha";
},
popname: true,
check(card) {
return 5 - get.value(card);
},
position: "hs",
viewAs: { name: links[0][2] },
precontent() {
delete event.result.skill;
player.logSkill("twylyanshi");
player.awakenSkill("twylyanshi");
if (player.storage.twduwang_ylyanshi) {
player.when({ global: "phaseEnd" }).then(() => {
if (player.awakenedSkills.includes("twylyanshi")) {
player.popup("历战");
player.restoreSkill("twylyanshi");
game.log(player, "触发了", "#g【延势】", "的", "#y历战", "效果");
}
});
}
},
};
},
prompt(links, player) {
return "将一张【杀】当作" + "【" + get.translation(links[0][2]) + "】使用";
},
},
subSkill: { backup: {} },
hiddenCard(player, name) {
if (player.awakenedSkills.includes("twylyanshi") || !player.countCards("hs", card => _status.connectMode || get.name(card) == "sha")) return false;
return ["juedou", "binglinchengxiax"].concat(get.zhinangs()).includes(name);
},
ai: {
order(item, player) {
if (!player || _status.event.type != "phase") return 0.001;
let max = 0,
names = ["juedou", "binglinchengxiax"].concat(get.zhinangs()).filter(name => {
const info = { name: name };
return (
get.info(info) &&
player.hasCard(card => {
return get.name(card) == "sha" && player.hasValueTarget(get.autoViewAs(info, [card]), true, true);
}, "hs")
);
});
if (!names.length) return 0;
names = names.map(namex => {
return { name: namex };
});
names.forEach(card => {
if (player.getUseValue(card) > 0) {
let temp = get.order(card);
if (temp > max) max = temp;
}
});
if (max > 0) max += 0.3;
return max;
},
result: { player: 1 },
},
},
twjuexing: {
audio: 2,
enable: "phaseUse",
filter(event, player) {
return game.hasPlayer(target => get.info("twjuexing").filterTarget(null, player, target));
},
filterTarget(_, player, target) {
const card = new lib.element.VCard({ name: "juedou" });
return target != player && player.canUse(card, target);
},
usable: 1,
onremove: "twjuexing_lizhan",
async content(event, trigger, player) {
player.when({ global: "phaseEnd" }).then(() => {
player.popup("历战");
player.addSkill("twjuexing_lizhan");
player.addMark("twjuexing_lizhan", 1, false);
game.log(player, "触发了", "#g【绝行】", "的", "#y历战", "效果");
});
const target = event.target;
const card = new lib.element.VCard({ name: "juedou" });
player.addTempSkill("twjuexing_effect");
player
.when({ global: "useCardAfter" })
.filter(evtx => evtx.getParent() == event)
.then(() => {
let list = [];
var targets = [player].concat(trigger.targets);
for (const i of targets) {
if (i.isIn() && i.hasCard(card => card.hasGaintag("twjuexing"), "h")) {
list.push([i, i.getCards("h", card => card.hasGaintag("twjuexing"))]);
}
}
if (list.length) {
game.loseAsync({ lose_list: list }).setContent("discardMultiple");
}
})
.then(() => {
let listx = [];
var targets = [player].concat(trigger.targets);
for (const i of targets) {
if (i.isIn() && i.getExpansions("twjuexing_buff").length) {
listx.push([i, i.getExpansions("twjuexing_buff")]);
}
}
if (listx.length) {
game.loseAsync({ gain_list: listx, animate: "draw" }).setContent("gaincardMultiple");
}
})
.then(() => {
var targets = [player].concat(trigger.targets);
targets.forEach(current => {
current.removeSkill("twjuexing_buff");
});
game.delay();
});
await player.useCard(card, target, false);
},
ai: {
order: 1,
result: {
target(player, target) {
return get.sgn(get.attitude(player, target)) * get.effect(target, { name: "juedou" }, player, player) * ((player.getHp() + 1) / (target.getHp() + 1));
},
},
},
subSkill: {
effect: {
trigger: { global: "useCardToBegin" },
forced: true,
popup: false,
charlotte: true,
filter(event, player) {
return event.getParent(2).name === "twjuexing";
},
async content(event, trigger, player) {
const target = trigger.target;
player.addSkill("twjuexing_buff");
target.addSkill("twjuexing_buff");
let list = [];
for (const i of [player, target]) {
if (i.isIn() && i.countCards("h")) {
list.push([i, i.getCards("h")]);
}
}
if (list.length) {
await game
.loseAsync({
lose_list: list,
log: true,
animate: "giveAuto",
gaintag: ["twjuexing_buff"],
})
.setContent(get.info("sbquhu").addToExpansionMultiple);
}
if (player.getHp() > 0) await player.draw(player.getHp(), target.getHp() > 0 ? "nodelay" : "").set("gaintag", ["twjuexing"]);
if (target.getHp() > 0) await target.draw(target.getHp()).set("gaintag", ["twjuexing"]);
await game.asyncDelay();
},
},
lizhan: {
charlotte: true,
onremove: true,
marktext: "战",
intro: { content: "因【绝行】摸牌时,摸牌数+#" },
trigger: { player: "drawBegin" },
filter(event, player) {
if (!player.hasMark("twjuexing_lizhan")) return false;
return (event.gaintag || []).includes("twjuexing");
},
forced: true,
popup: false,
content() {
player.popup("历战");
game.log(player, "触发了", "#g【绝行】", "的", "#y历战", "效果");
trigger.num += player.countMark("twjuexing_lizhan");
},
},
buff: {
charlotte: true,
onremove(player, skill) {
const cards = player.getExpansions(skill);
if (cards.length) player.gain(cards, "gain2");
},
intro: {
markcount: "expansion",
mark(dialog, _, player) {
var cards = player.getExpansions("twjuexing_buff");
if (player.isUnderControl(true)) dialog.addAuto(cards);
else return "共有" + get.cnNumber(cards.length) + "张牌";
},
},
},
},
},
twxiayong: {
audio: 2,
audioname: ["tw_yanliang"],
locked: true,
group: "twxiayong_effect",
subSkill: {
effect: {
trigger: { global: "damageBegin1" },
filter(event, player) {
if (event.getParent().type != "card" || event.card.name != "juedou" || !event.player.isIn()) return false;
2024-05-05 10:58:14 +00:00
const evt = event.getParent()
if (evt && evt.targets && (event.player != player || player.countCards("h") > 0)) {
return (evt.player === player || evt.targets.includes(player));
}
return false;
},
forced: true,
popup: false,
async content(event, trigger, player) {
2024-05-05 10:58:14 +00:00
player.logSkill("twxiayong" + (trigger.player === player ? "1" : "2"), trigger.player);
if (trigger.player === player) {
const cards = player.getCards("h", card => {
return lib.filter.cardDiscardable(card, player, "twxiayong");
});
if (cards.length > 0) player.discard(cards.randomGet());
} else {
trigger.increase("num");
}
},
},
},
},
twxiayong1: {
audio: true,
audioname: ["tw_yanliang"],
sourceSkill: "twxiayong",
},
twxiayong2: {
inherit: "twxiayong1",
},
//袁谭
twqiaosi: {
audio: 2,
trigger: { player: "phaseJieshuBegin" },
filter(event, player) {
return get.info("twqiaosi").getCards(player).length;
},
check(event, player) {
const cards = get.info("twqiaosi").getCards(player);
if (cards.reduce((sum, card) => sum + get.value(card), 0)) return false;
if (cards.length >= player.getHp() || cards.some(card => get.name(card, player) == "tao" || get.name(card, player) == "jiu")) return true;
return player.getHp() > 2 && cards.length > 1;
},
prompt2(event, player) {
const cards = get.info("twqiaosi").getCards(player);
let str = "获得" + get.translation(cards);
if (cards.length < player.getHp()) str += "然后你失去1点体力";
return str;
},
async content(event, trigger, player) {
const cards = get.info("twqiaosi").getCards(player);
await player.gain(cards, "gain2");
if (cards.length < player.getHp()) await player.loseHp();
},
getCards(player) {
let cards = [],
targets = game.players.slice().concat(game.dead.slice());
for (const target of targets) {
if (target == player) continue;
const history = target.getHistory("lose", evt => evt.position == ui.discardPile);
if (history.length) {
for (const evt of history) cards.addArray(evt.cards2.filterInD("d"));
}
}
const historyx = game.getGlobalHistory("cardMove", evt => {
if (evt.name != "cardsDiscard") return false;
const evtx = evt.getParent();
if (evtx.name != "orderingDiscard") return false;
const evt2 = evtx.relatedEvent || evtx.getParent();
const current = evt2.player;
if (evt2.name == "phaseJudge" || current == player) return false;
return current.hasHistory("lose", evtx3 => {
const evtx4 = evtx3.relatedEvent || evtx3.getParent();
if (evt2 != evtx4) return false;
return evtx3.getl(current).cards2.length > 0;
});
});
if (historyx.length) {
for (const evtx of historyx) cards.addArray(evtx.cards.filterInD("d"));
}
return cards;
},
},
twbaizu: {
audio: 2,
trigger: { player: "phaseJieshuBegin" },
filter(event, player) {
return (
player.isDamaged() &&
player.countCards("h") &&
game.hasPlayer(target => {
return target != player && target.countCards("h");
}) &&
player.getHp() + player.countMark("twbaizu_lizhan")
);
},
locked: true,
async cost(event, trigger, player) {
const sum = player.getHp() + player.countMark("twbaizu_lizhan"),
filterTarget = (_, player, target) => {
return target != player && target.countCards("h");
};
let targets = game.filterPlayer(target => filterTarget(null, player, target));
if (targets.length > sum) {
targets = await player
.chooseTarget("请选择【败族】的目标", "令你和这些角色同时弃置一张手牌然后你对与你弃置牌类别相同的其他角色各造成1点伤害", filterTarget, sum, true)
.set("ai", target => {
const player = get.event("player");
return get.effect(target, { name: "guohe_copy2" }, target, player) + get.damageEffect(target, player, player);
})
.forResultTargets();
}
event.result = { bool: true, targets };
},
async content(event, trigger, player) {
const targets = event.targets.slice().sortBySeat();
player.line(targets);
let list = [player].concat(targets).filter(target => target.countDiscardableCards(target, "h"));
if (list.length) {
let discards = [];
const { result } = await player
.chooseCardOL(
list,
"败族:请弃置一张手牌",
(card, player) => {
return lib.filter.cardDiscardable(card, player);
},
true
)
.set("ai", get.unuseful);
if (result) {
for (let i = 0; i < result.length; i++) {
discards.push([list[i], result[i].cards]);
}
await game.loseAsync({ lose_list: discards }).setContent("discardMultiple");
list = list.filter(i => get.type2(result[0].cards[0]) == get.type2(result[list.indexOf(i)].cards[0]));
if (list.length) {
for (const i of list) {
if (i === player) continue;
player.line(i);
await i.damage();
}
}
}
}
player.when({ global: "phaseEnd" }).then(() => {
player.popup("历战");
player.addMark("twbaizu_lizhan", 1, false);
game.log(player, "触发了", "#g【败族】", "的", "#y历战", "效果");
});
},
subSkill: {
lizhan: {
charlotte: true,
onremove: true,
marktext: "战",
intro: { content: "【败族】目标选择数+#" },
},
},
},
//玉真子
twhuajing: {
audio: 2,
getSkills(player) {
return player
.getCards("e", card => get.subtype(card) == "equip1")
.reduce((list, card) => {
const info = get.info(card);
if (info && info.skills) return list.addArray(info.skills);
return list;
}, []);
},
trigger: { global: "phaseBefore", player: "enterGame" },
filter(event, player) {
return event.name != "phase" || game.phaseNumber == 0;
},
forced: true,
locked: false,
async content(event, trigger, player) {
const skills = lib.skill.twhuajing.derivation;
for (const eff of skills) {
player.addMark(eff, 1);
player.unmarkSkill(eff);
}
player.markSkill("twhuajing");
},
global: "twhuajing_global",
group: "twhuajing_use",
derivation: ["twhuajing_jian", "twhuajing_dao", "twhuajing_fu", "twhuajing_qiang", "twhuajing_ji", "twhuajing_gong"],
marktext: "武",
intro: {
markcount(storage, player) {
return lib.skill.twhuajing.derivation.filter(skill => player.hasMark(skill)).length;
},
content(storage, player) {
const skills = lib.skill.twhuajing.derivation.filter(skill => player.hasMark(skill));
if (!skills.length) return "功力已消耗殆尽";
let str = "当前武功:";
for (const eff of skills) {
str += "<br><li>";
str += lib.translate[eff];
str += "";
str += lib.translate[eff + "_info"];
}
return str;
},
},
subSkill: {
global: {
mod: {
attackRange(player, num) {
const skills = lib.skill.twhuajing.derivation.filter(skill => player.hasMark(skill) || player.hasSkill(skill));
if (skills.length) return num + skills.length * game.countPlayer(target => target.hasSkill("twhuajing"));
},
},
},
use: {
audio: "twhuajing",
enable: "phaseUse",
filter(event, player) {
return lib.skill.twhuajing.derivation.some(skill => player.hasMark(skill));
},
filterCard: true,
selectCard: [1, 4],
position: "h",
complexCard: true,
discard: false,
lose: false,
delay: false,
check(card) {
const player = get.event("player"),
skills = lib.skill.twhuajing.derivation.filter(skill => player.hasMark(skill));
if (ui.selected.cards.some(cardx => get.suit(cardx, player) == get.suit(card, player))) return 0;
return skills.length - ui.selected.cards.length;
},
usable: 1,
prompt: "展示至多四张手牌,然后根据这些牌含有的花色数于本回合获得等量你拥有的“武”标记的效果",
async content(event, trigger, player) {
await player.showCards(event.cards, get.translation(player) + "发动了【化境】");
const skills = lib.skill.twhuajing.derivation.filter(skill => player.hasMark(skill));
const gainSkills = skills.randomGets(Math.min(skills.length, event.cards.reduce((list, cardx) => list.add(get.suit(cardx, player)), []).length));
for (const eff of gainSkills) player.popup(eff);
player.addTempSkill(gainSkills);
player.addTempSkill("twhuajing_blocker");
player.getHistory("custom").push({ twhuajing_skills: gainSkills });
},
ai: {
order: 12,
result: {
player(player) {
return player.countCards("hs", card => {
return get.name(card) == "sha" && player.hasValueTarget(card, false, true);
});
},
},
},
},
jian: {
charlotte: true,
mark: true,
marktext: "剑",
intro: {
name: "化境·剑",
name2: "剑",
markcount: () => 0,
content: () => lib.translate.twhuajing_jian_info,
},
nopop: true,
trigger: { player: "useCardToPlayered" },
filter(event, player) {
return event.card.name == "sha" && event.target.countCards("he");
},
forced: true,
logTarget: "target",
async content(event, trigger, player) {
const target = trigger.target;
const cards = target.getDiscardableCards(player, "he");
target.discard(cards.randomGets(Math.min(2, cards.length))).discarder = player;
},
},
dao: {
charlotte: true,
mark: true,
marktext: "刀",
intro: {
name: "化境·刀",
name2: "刀",
markcount: () => 0,
content: () => lib.translate.twhuajing_dao_info,
},
nopop: true,
inherit: "guding_skill",
equipSkill: false,
},
fu: {
charlotte: true,
mark: true,
marktext: "斧",
intro: {
name: "化境·斧",
name2: "斧",
markcount: () => 0,
content: () => lib.translate.twhuajing_fu_info,
},
nopop: true,
trigger: { player: "shaMiss" },
forced: true,
logTarget: "target",
async content(event, trigger, player) {
trigger.target.damage();
},
ai: {
directHit_ai: true,
skillTagFilter(player, tag, arg) {
if (!arg || !arg.card || arg.card.name != "sha" || !arg.baseDamage || arg.baseDamage <= 1) return false;
return true;
},
},
},
qiang: {
charlotte: true,
mark: true,
marktext: "枪",
intro: {
name: "化境·枪",
name2: "枪",
markcount: () => 0,
content: () => lib.translate.twhuajing_qiang_info,
},
nopop: true,
trigger: { player: "useCardAfter" },
filter(event, player) {
return event.card.name == "sha" && get.color(event.card) == "black";
},
forced: true,
async content(event, trigger, player) {
const card = get.cardPile(card => card.name == "shan");
if (card) player.gain(card, "gain2");
},
},
ji: {
charlotte: true,
mark: true,
marktext: "戟",
intro: {
name: "化境·戟",
name2: "戟",
markcount: () => 0,
content: () => lib.translate.twhuajing_ji_info,
},
nopop: true,
trigger: { source: "damageBegin3" },
filter(event, player) {
return event.card && event.card.name == "sha";
},
forced: true,
async content(event, trigger, player) {
player.draw(trigger.num);
},
},
gong: {
charlotte: true,
mark: true,
marktext: "弓",
intro: {
name: "化境·弓",
name2: "弓",
markcount: () => 0,
content: () => lib.translate.twhuajing_gong_info,
},
nopop: true,
trigger: { source: "damageSource" },
filter(event, player) {
return event.card && event.card.name == "sha" && event.player.countDiscardableCards(player, "e");
},
forced: true,
logTarget: "player",
async content(event, trigger, player) {
trigger.player.discard(trigger.player.getDiscardableCards(player, "e").randomGets(1)).discarder = player;
},
},
blocker: {
charlotte: true,
init(player, skill) {
player.disableSkill(skill, lib.skill.twhuajing.getSkills(player));
},
onremove(player, skill) {
player.enableSkill(skill);
},
mod: {
attackRange(player, num) {
return num - player.getEquipRange();
},
},
trigger: {
player: "loseAfter",
global: ["equipAfter", "addJudgeAfter", "gainAfter", "loseAsyncAfter", "addToExpansionAfter", "phaseBefore"],
},
filter(event, player) {
if (event.name == "phase") return true;
if (event.name == "equip" && event.player == player && get.subtype(event.card) == "equip1") return true;
const evt = event.getl(player);
return evt && evt.player == player && evt.es && evt.es.some(card => get.subtype(card) == "equip1");
},
forced: true,
popup: false,
firstDo: true,
async content(event, trigger, player) {
player.enableSkill("twhuajing_blocker");
player.disableSkill("twhuajing_blocker", lib.skill.twhuajing.getSkills(player));
},
ai: { unequip_equip1: true },
},
},
},
twtianshou: {
audio: 2,
trigger: { player: "phaseEnd" },
filter(event, player) {
return (
player.getHistory("sourceDamage", evt => {
return evt.card && evt.card.name == "sha";
}).length &&
player
.getHistory("custom", evt => {
return evt.twhuajing_skills;
})
.reduce((list, evt) => list.addArray(evt.twhuajing_skills), [])
.some(skill => player.hasMark(skill))
);
},
forced: true,
async content(event, trigger, player) {
const {
result: { bool, targets },
} = await player
.chooseTarget(lib.filter.notMe, true)
.set("prompt", "天授令一名其他角色获得1枚“武”并获得此标记的效果")
.set("ai", target => {
const player = get.event("player"),
att = get.attitude(player, target);
const card = new lib.element.VCard({ name: "sha" });
if (att > 0)
return (
game.countPlayer(aim => {
return target.canUse(card, target) && get.effect(aim, card, target, player) > 0 && get.effect(aim, card, target, target) > 0;
}) + 10
);
if (att == 0) return 1.5 + Math.random();
return 0.1 + Math.random();
});
if (bool) {
const target = targets[0];
const skills = player
.getHistory("custom", evt => {
return evt.twhuajing_skills;
})
.reduce((list, evt) => list.addArray(evt.twhuajing_skills), [])
.filter(skill => player.hasMark(skill));
let choiceList = skills.map(i => {
return '<div class="skill">【' + get.translation(lib.translate[i + "_ab"] || get.translation(i).slice(0, 2)) + "】</div>" + "<div>" + get.skillInfoTranslation(i, player) + "</div>";
});
const {
result: { control },
} = await player
.chooseControl(skills)
.set("prompt", "选择令" + get.translation(target) + "获得的“武”")
.set("choiceList", choiceList)
.set("displayIndex", false)
.set("ai", () => get.event("controls").randomGet());
if (control) {
player.removeMark(control, 1);
player.markSkill("twhuajing");
player.popup(control, "metal");
target.addTempSkill(control, { player: "phaseAfter" });
target.addTempSkill("twhuajing_blocker", { player: "phaseAfter" });
target.getHistory("custom").push({ twhuajing_skills: [control] });
await player.draw(2);
}
}
},
ai: { combo: "twhuajing" },
},
//史阿
twdengjian: {
audio: 2,
trigger: { global: "phaseDiscardEnd" },
filter(event, player) {
if (player.hasSkill("twdengjian_ban")) return false;
return event.player != player && lib.skill.twdengjian.getCards(player, event.player).length;
},
getCards(player, target) {
let cards = target
.getHistory("useCard", evt => {
return (
evt.cards &&
evt.cards.filterInD("d").some(card => get.name(card, false) == "sha") &&
target.getHistory("sourceDamage", evtx => {
return evtx.card && evtx.card == evt.card;
}).length
);
})
.reduce((list, evt) => list.addArray(evt.cards.filterInD("d").filter(card => get.name(card, false) == "sha")), []);
if (cards.length) {
const history = player.actionHistory;
for (let i = history.length - 1; i >= 0; i--) {
for (let evt of history[i].gain) {
if (evt.getParent().name == "twdengjian") {
const card = evt.cards[0];
cards = cards.filter(cardx => get.color(cardx) != get.color(card));
if (!cards.length) break;
}
}
if (history[i].isRound) break;
}
}
return cards;
},
//direct:true,
frequent: true,
async content(event, trigger, player) {
const cards = lib.skill.twdengjian.getCards(player, trigger.player);
/*const {result:{bool}}=await player.chooseToDiscard(get.prompt('twdengjian'),'he')
.set('prompt2','弃置一张牌并随机获得本回合所有造成伤害的牌对应的实体牌的其中一张与你本轮以此法获得的牌的颜色均不同的【杀】')
.set('ai',card=>7-get.value(card))
.set('logSkill','twdengjian');
if(bool) */ await player.gain(cards.randomGet(), "gain2").gaintag.add("twdengjianx");
},
group: "twdengjian_buff",
subSkill: {
ban: { charlotte: true },
buff: {
mod: {
aiOrder(player, card, num) {
if (get.itemtype(card) == "card" && card.hasGaintag("twdengjianx")) return num + 0.1;
},
},
audio: "twdengjian",
trigger: { player: "useCard1" },
filter(event, player) {
return (
event.cards &&
event.cards.length == 1 &&
player.getHistory("lose", evt => {
if (evt.getParent() != event) return false;
for (var i in evt.gaintag_map) {
if (evt.gaintag_map[i].includes("twdengjianx")) return true;
}
return false;
}).length &&
event.addCount !== false
);
},
forced: true,
locked: false,
async content(event, trigger, player) {
trigger.addCount = false;
if (player.stat[player.stat.length - 1].card.sha > 0) player.stat[player.stat.length - 1].card.sha--;
game.log(trigger.card, "不计入次数限制");
},
},
},
},
twdengjianx: {},
twxinshou: {
audio: 2,
trigger: { player: "useCard" },
filter(event, player) {
if (event.card.name != "sha") return false;
const goon =
!player.getHistory("useCard", evt => {
return evt != event && evt.card.name == "sha" && get.color(evt.card) == get.color(event.card);
}).length && player.isPhaseUsing();
if (!player.hasSkill("twxinshou_0")) return goon;
if (!player.hasSkill("twxinshou_1")) return goon && game.hasPlayer(target => target != player);
return (
!player.hasSkill("twdengjian_ban") &&
game.hasPlayer(target => {
if (target == player) return false;
return !target.hasSkill("twdengjian", null, null, false);
}) &&
player.hasSkill("twdengjian", null, null, false)
);
},
direct: true,
async content(event, trigger, player) {
if (player.hasSkill("twxinshou_0") && player.hasSkill("twxinshou_1")) {
const {
result: { bool, targets },
} = await player
.chooseTarget((card, player, target) => {
return target != player && !target.hasSkill("twdengjian", null, null, false);
})
.set("ai", target => {
const player = get.event("player");
if (get.attitude(player, target) > 0) {
if (target.isTurnedOver()) return 0;
const card = new lib.element.VCard({ name: "sha" });
if (
game.hasPlayer(aim => {
return target.canUse(card, target) && get.effect(aim, card, target, player) > 0 && get.effect(aim, card, target, target) > 0;
})
)
return target.countCards("h") - 3;
return 0;
}
return 0;
})
.set("prompt", get.prompt("twxinshou"))
.set("prompt2", "令【登剑】失效并令一名其他角色获得【登剑】,你的下个回合开始时,其失去【登剑】,若其这期间使用【杀】造成过伤害,则你结束【登剑】的失效状态");
if (bool) {
const target = targets[0];
player.logSkill("twxinshou", target);
player.addSkill("twdengjian_ban");
target.addAdditionalSkills("twxinshou_" + player.playerid, "twdengjian");
player.popup("登剑");
target.popup("登剑");
game.log(player, "将", "#g【登剑】", "传授给了", target);
game.log(player, "的", "#g【登剑】", "被失效了");
player
.when("phaseBegin")
.then(() => {
target.removeAdditionalSkills("twxinshou_" + player.playerid);
})
.then(() => {
const history = game.getAllGlobalHistory("everything");
for (let i = history.length - 1; i >= 0; i--) {
const evt = history[i];
if (evt.name == "damage" && evt.card && evt.source && evt.card.name == "sha" && evt.source == target) {
player.popup("洗具");
player.removeSkill("twdengjian_ban");
game.log(player, "结束了", "#g【登剑】", "的失效状态");
return;
}
if (evt == evtx) break;
}
player.popup("杯具");
player.chat("剑法废掉了...");
})
.vars({ target: target, evtx: event });
}
} else {
let choice = [],
choiceList = ["摸一张牌", "交给一名其他角色一张牌"];
if (!player.hasSkill("twxinshou_0")) choice.push("摸牌");
else choiceList[0] = '<span style="opacity:0.5">' + choiceList[0] + "</span>";
if (!player.hasSkill("twxinshou_1") && game.hasPlayer(target => target != player)) choice.push("给牌");
else choiceList[1] = '<span style="opacity:0.5">' + choiceList[1] + "</span>";
const {
result: { control },
} = await player
.chooseControl(choice, "cancel2")
.set("prompt", get.prompt("twxinshou"))
.set("choiceList", choiceList)
.set("ai", () => {
if (get.event("controls").includes("摸牌")) return "摸牌";
const player = get.event("player");
return game.hasPlayer(target => {
if (target == player) return false;
if (player.countCards("he", card => card.name == "du") && get.attitude(player, target) <= 0) return true;
if (player.countCards("he", card => get.value(card, player) < 0 && get.attitude(player, target) * get.value(card, target) > 0)) return true;
return get.attitude(player, target) > 0;
}) && get.event("controls").includes("给牌")
? "给牌"
: "cancel2";
});
if (control == "cancel2") return;
player.logSkill("twxinshou");
if (control == "摸牌") {
player.addTempSkill("twxinshou_0");
await player.draw();
}
if (control == "给牌") {
player.addTempSkill("twxinshou_1");
const {
result: { bool, targets },
} = await player.chooseTarget("交给一名其他角色一张牌", lib.filter.notMe, true).set("ai", target => {
const player = get.event("player"),
att = get.attitude(player, target);
if (player.countCards("he", card => card.name == "du")) return -att;
let cards = player.getCards("he", card => get.value(card, player) < 0);
if (cards.length) {
cards.sort((a, b) => get.value(a, player) - get.value(b, player));
return get.value(cards[0], target) * att;
}
return att;
});
if (bool) {
const target = targets[0];
player.line(target);
await player.chooseToGive(target, "he", true);
}
}
}
},
subSkill: {
0: { charlotte: true },
1: { charlotte: true },
},
},
//石韬
twjieqiu: {
audio: 2,
enable: "phaseUse",
filter(event, player) {
return game.hasPlayer(target => lib.skill.twjieqiu.filterTarget(null, player, target));
},
filterTarget(card, player, target) {
return target != player && !target.hasDisabledSlot();
},
usable: 1,
async content(event, trigger, player) {
const target = event.target,
num = target.countCards("e");
let disables = [];
for (let i = 1; i <= 5; i++) {
for (let j = 0; j < target.countEnabledSlot(i); j++) {
disables.push(i);
}
}
target.disableEquip(disables);
if (num) await target.draw(num);
target.addSkill("twjieqiu_buff");
target.markAuto("twjieqiu_buff", [player]);
target
.when("enableEquipEnd")
.filter((e, p) => !p.hasDisabledSlot())
.then(() => player.removeSkill("twjieqiu_buff"));
},
ai: {
order: 7,
result: {
target(player, target) {
return -target.countCards("e") - (get.attitude(player, target) < 0 ? 1 : 0);
},
},
},
subSkill: {
used: { charlotte: true },
buff: {
charlotte: true,
onremove: true,
trigger: { player: "phaseDiscardEnd" },
filter(event, player) {
return player.hasDisabledSlot() && event.cards && event.cards.length;
},
forced: true,
popup: false,
async content(event, trigger, player) {
const num = trigger.cards.length;
let list = [],
map = {};
for (let i = 1; i < 6; i++) {
map[get.translation("equip" + i)] = "equip" + i;
if (player.hasDisabledSlot(i)) {
for (let j = 0; j < player.countDisabledSlot(i); j++) {
list.push("equip" + i);
}
}
}
let result;
const transList = list.map(i => get.translation(i));
if (transList.length <= num) result = { bool: true, links: transList };
else
result = await player
.chooseButton(["劫囚:请选择你要恢复的装备栏", [transList, "tdnodes"]], Math.min(transList.length, num), true)
.set("map", map)
.set("ai", button => ["equip5", "equip4", "equip1", "equip3", "equip2"].indexOf(get.event("map")[button.link]) + 2)
.forResult();
if (result.bool) await player.enableEquip(result.links.slice().map(i => map[i]));
},
group: ["twjieqiu_end"],
},
end: {
charlotte: true,
trigger: { player: "phaseEnd" },
filter(event, player) {
return (
player.hasDisabledSlot() &&
player.getStorage("twjieqiu_buff").some(target => {
return target.isIn() && !target.hasSkill("twjieqiu_used");
})
);
},
forced: true,
popup: false,
async content(event, trigger, player) {
const targets = player
.getStorage("twjieqiu_buff")
.filter(target => {
return target.isIn() && !target.hasSkill("twjieqiu_used");
})
.sortBySeat();
for (const target of targets) {
target.popup("劫囚");
target.addTempSkill("twjieqiu_used", "roundStart");
target.insertPhase();
}
},
},
},
},
twenchou: {
audio: 2,
enable: "phaseUse",
filter(event, player) {
return game.hasPlayer(current => lib.skill.twenchou.filterTarget(null, player, current));
},
position: "he",
filterTarget(card, player, target) {
return target != player && target.countCards("h") && target.hasDisabledSlot();
},
usable: 1,
async content(event, trigger, player) {
const target = event.target;
await player.gainPlayerCard(target, "h", true, "visible");
let list = [],
map = {};
for (let i = 1; i < 6; i++) {
map[get.translation("equip" + i)] = "equip" + i;
if (target.hasDisabledSlot(i)) {
list.push("equip" + i);
}
}
let result;
const transList = list.map(i => get.translation(i));
if (transList.length == 1) result = { bool: true, links: transList };
else
result = await player
.chooseButton(["恩仇:请选择" + get.translation(target) + "要恢复的装备栏", [transList, "tdnodes"]], true)
.set("map", map)
.set("ai", button => 1 / (["equip5", "equip4", "equip1", "equip3", "equip2"].indexOf(get.event("map")[button.link]) + 2))
.forResult();
if (result.bool) await target.enableEquip(result.links.slice().map(i => map[i]));
},
ai: {
order: 9,
result: { target: -1 },
},
},
//侠关羽
twzhongyi: {
mod: {
targetInRange(card) {
if (card.name == "sha") return true;
},
},
audio: 2,
trigger: { player: "useCardAfter" },
filter(event, player) {
if (event.card.name != "sha") return false;
return player.getHistory("sourceDamage", evt => evt.card && evt.card == event.card).length;
},
forced: true,
async content(event, trigger, player) {
//const num=player.getHistory('sourceDamage',evt=>evt.card&&evt.card==trigger.card).reduce((sum,evt)=>sum+evt.num,0);
const num = game.countPlayer2(target => {
return target.hasHistory("damage", evt => {
return evt.card && evt.card == trigger.card;
});
});
const num2 = 1 + player.getAllHistory("custom", evt => evt.twzhongyi).length;
let choice = ["摸牌"],
choiceList = ["摸" + get.cnNumber(num) + "张牌"];
if (player.isDamaged()) {
choice.addArray(["回血", "背水!"]);
choiceList.addArray(["回复" + num + "点体力", "失去" + num2 + "点体力,依次执行以上所有项"]);
}
const {
result: { control },
} = await player
.chooseControl(choice)
.set("prompt", "忠义:请选择一项")
.set("choiceList", choiceList)
.set("ai", () => {
const player = get.event("player");
const num = get.event("num"),
num2 = get.event("num2");
if (player.isHealthy()) return "摸牌";
return player.hp + player.countCards("hs", card => player.canSaveCard(card, player)) - num2 > 0 && num > num2 ? "背水!" : "回血";
})
.set("num", num)
.set("num2", num2);
if (control != "cancel2") {
if (control == "背水!") {
await player.loseHp(num2);
player.getHistory("custom").push({ twzhongyi: true });
}
if (control != "回血") await player.draw(num);
if (control != "摸牌") await player.recover(num);
}
},
},
twchue: {
audio: 2,
trigger: { player: "useCardToPlayer" },
filter(event, player) {
return event.card.name == "sha" && event.isFirstTarget && event.targets.length == 1 && game.hasPlayer(target => !event.targets.includes(target) && player.canUse(event.card, target));
},
prompt2: "失去1点体力额外指定至多等同于你体力值的目标",
check(event, player) {
return player.hp + player.countCards("hs", card => player.canSaveCard(card, player)) - 1 > 0;
},
async content(event, trigger, player) {
await player.loseHp();
const targetx = trigger.targets.slice(),
num = player.getHp();
if (!num) return;
const {
result: { bool, targets },
} = await player
.chooseTarget("额外指定至多" + get.cnNumber(num) + "名目标", [1, num], (card, player, target) => {
const trigger = _status.event.getTrigger();
return !trigger.targets.includes(target) && player.canUse(trigger.card, target);
})
.set("ai", target => {
const player = get.event("player"),
trigger = _status.event.getTrigger();
return get.effect(target, trigger.card, player, player);
});
if (!bool) return;
player.line(targets);
trigger.targets.addArray(targets);
},
group: ["twchue_gain", "twchue_effect"],
marktext: "勇",
intro: {
name: "勇",
content: "mark",
},
subSkill: {
gain: {
audio: "twchue",
trigger: { player: ["damageEnd", "loseHpEnd"] },
forced: true,
locked: false,
async content(event, trigger, player) {
await player.draw();
player.addMark("twchue", 1);
},
},
effect: {
audio: "twchue",
trigger: { global: "phaseEnd" },
filter(event, player) {
const card = new lib.element.VCard({ name: "sha" });
return (
player.hasUseTarget(card) &&
/*player.getHistory('useSkill',evt=>{
return evt.skill=='twchue_gain';
}).length&&player.getHp()&&*/ player.countMark("twchue") >= player.getHp()
);
},
check(event, player) {
return player.hasValueTarget(new lib.element.VCard({ name: "sha" }));
},
prompt2(event, player) {
const num = player.getHp();
return "失去" + num + "个“勇”标记,视为使用一张造成的伤害+1且可以额外指定" + num + "个目标的【杀】";
},
async content(event, trigger, player) {
const num = player.getHp();
player.removeMark("twchue", num);
const card = new lib.element.VCard({ name: "sha" });
player
.when("useCard2")
.filter(evt => evt.getParent(2) == event && game.hasPlayer(target => !evt.targets.includes(target) && player.canUse(evt.card, target)))
.assign({
firstDo: true,
})
.then(() => {
trigger.baseDamage++;
player
.chooseTarget("额外指定至多" + get.cnNumber(num) + "名目标", [1, num], (card, player, target) => {
const trigger = _status.event.getTrigger();
return !trigger.targets.includes(target) && player.canUse(trigger.card, target);
})
.set("ai", target => {
const player = get.event("player"),
trigger = _status.event.getTrigger();
return get.effect(target, trigger.card, player, player);
});
})
.then(() => {
if (result.bool) {
const targets = result.targets;
player.line(targets);
trigger.targets.addArray(targets);
}
})
.vars({ num: num });
player.chooseUseTarget("视为使用造成的伤害+1且可以额外指定" + num + "个目标的【杀】", card, false, true);
},
},
},
},
//夏侯惇
twdanlie: {
audio: 2,
enable: "phaseUse",
filter: function (event, player) {
return game.hasPlayer(target => player.canCompare(target));
},
filterTarget: function (card, player, target) {
return player.canCompare(target);
},
usable: 1,
selectTarget: [1, 3],
multitarget: true,
multiline: true,
group: "twdanlie_add",
content: function () {
"step 0";
player.chooseToCompare(targets).setContent("chooseToCompareMeanwhile");
"step 1";
if (result.winner && result.winner == player) {
player.line(targets);
targets.forEach(target => target.damage());
} else player.loseHp();
},
ai: {
order: 10,
result: {
target: function (player, target) {
var att = get.attitude(player, target);
if (att >= 0) return 0;
if (player.getHp() > 2) return -get.damageEffect(target, player, player) - 10 / target.countCards("h");
var hs = player.getCards("h").sort((a, b) => b.number - a.number);
var ts = target.getCards("h").sort((a, b) => b.number - a.number);
if (!hs.length || !ts.length) return 0;
if (Math.min(13, hs[0].number + player.getDamagedHp()) > ts[0].number) return -get.damageEffect(target, player, player);
return 0;
},
},
},
subSkill: {
add: {
audio: "twdanlie",
trigger: { player: "compare", target: "compare" },
filter: function (event, player) {
if (!player.isDamaged()) return false;
if (player != event.target && event.iwhile) return false;
return true;
},
forced: true,
locked: false,
content: function () {
var num = player.getDamagedHp();
if (player == trigger.player) {
trigger.num1 += num;
if (trigger.num1 > 13) trigger.num1 = 13;
} else {
trigger.num2 += num;
if (trigger.num2 > 13) trigger.num2 = 13;
}
game.log(player, "的拼点牌点数+", num);
},
},
},
},
//张葳
twhuzhong: {
audio: 2,
trigger: { player: "useCardToPlayer" },
filter: function (event, player) {
return event.card.name == "sha" && !game.hasNature(event.card, "linked") && event.targets.length == 1 && player.isPhaseUsing() && (game.hasPlayer(target => !event.targets.includes(target) && player.canUse(event.card, target)) || event.target.countCards("h") > 0);
},
direct: true,
content: function () {
"step 0";
var target = trigger.target;
event.target = target;
var list = ["cancel2"];
var choiceList = ["令此【杀】可以额外指定一个目标", "弃置" + get.translation(target) + "一张手牌,若此【杀】造成伤害,则你摸一张牌且本阶段可以额外使用一张【杀】"];
if (target.countCards("h")) list.unshift("其弃置");
else choiceList[1] = '<span style="opacity:0.5">' + choiceList[1] + "</span>";
if (game.hasPlayer(targetx => !trigger.targets.includes(targetx) && player.canUse(trigger.card, targetx))) list.unshift("多指");
else choiceList[0] = '<span style="opacity:0.5">' + choiceList[0] + "</span>";
player
.chooseControl(list)
.set("choiceList", choiceList)
.set("ai", () => {
var controls = _status.event.controls;
var trigger = _status.event.getTrigger();
var player = trigger.player;
var target = trigger.target;
if (controls.includes("其弃置") && _status.event.goon) return "其弃置";
if (controls.includes("多指")) {
if (game.hasPlayer(targetx => !trigger.targets.includes(targetx) && player.canUse(trigger.card, targetx) && get.effect(targetx, trigger.card, player, player) > 0)) return "你弃置";
}
return "cancel2";
})
.set(
"goon",
(function () {
var d1 = true;
if (player.hasSkill("jueqing") || player.hasSkill("gangzhi")) d1 = false;
if (
!target.mayHaveShan(
player,
"use",
target.getCards("h", i => {
return i.hasGaintag("sha_notshan");
})
) ||
player.hasSkillTag(
"directHit_ai",
true,
{
target: target,
card: trigger.card,
},
true
)
) {
if (!target.hasSkill("gangzhi")) d1 = false;
if (
!target.hasSkillTag("filterDamage", null, {
player: player,
card: trigger.card,
}) &&
get.attitude(player, target) < 0
)
return true;
}
if (d1) return get.damageEffect(player, player, player) > 0;
return false;
})()
)
.set("prompt", "护众:是否摸一张牌并执行其中一项?");
"step 1";
if (result.control != "cancel2") {
player.logSkill("twhuzhong", target);
player.draw();
if (result.control == "其弃置") {
player.discardPlayerCard(target, "h", true);
player
.when("useCardAfter")
.filter(evt => evt == trigger.getParent())
.then(() => {
if (player.getHistory("sourceDamage", evt => evt.card == trigger.card).length) {
player.draw();
player.addTempSkill("twhuzhong_sha", "phaseUseAfter");
player.addMark("twhuzhong_sha", 1, false);
}
});
event.finish();
}
} else event.finish();
"step 2";
player
.chooseTarget("请选择" + get.translation(trigger.card) + "的额外目标", function (card, player, target) {
var trigger = _status.event.getTrigger();
return !trigger.targets.includes(target) && player.canUse(trigger.card, target);
})
.set("ai", function (target) {
var player = _status.event.player;
var trigger = _status.event.getTrigger();
return get.effect(target, trigger.card, player, player);
});
"step 3";
if (result.bool) {
player.line(result.targets);
trigger.getParent().targets.addArray(result.targets);
game.log(result.targets, "成为了", trigger.card, "的额外目标");
}
},
subSkill: {
sha: {
charlotte: true,
onremove: true,
mod: {
cardUsable: function (card, player, num) {
if (card.name == "sha") return num + player.countMark("twhuzhong_sha");
},
},
},
},
},
twfenwang: {
audio: 2,
trigger: { source: "damageBegin2", player: "damageBegin4" },
filter: function (event, player, name) {
if (name == "damageBegin2") {
return !event.hasNature() && player.countCards("h") >= event.player.countCards("h");
}
return event.hasNature();
},
forced: true,
content: function () {
"step 0";
if (event.triggername == "damageBegin2") {
player.line(trigger.player);
trigger.num++;
event.finish();
} else
player.chooseToDiscard("h", "弃置一张手牌,或令此伤害+1").set("ai", function (card) {
return 8 - get.value(card);
});
"step 1";
if (!result.bool) trigger.num++;
},
},
//夏侯子萼
//差点和夏侯紫萼搞混
twchengxi: {
audio: 2,
enable: "phaseUse",
filter: function (event, player) {
return game.hasPlayer(target => lib.skill.twchengxi.filterTarget(null, player, target));
},
filterTarget: function (card, player, target) {
if (player.getStorage("twchengxi_used").includes(target) || target == player) return false;
return !player.hasSkillTag("noCompareSource") && target.countCards("h") > 0 && !target.hasSkillTag("noCompareTarget");
},
content: function () {
"step 0";
if (!player.storage.twchengxi_used) {
player.when("phaseUseAfter").then(() => delete player.storage.twchengxi_used);
}
player.markAuto("twchengxi_used", [target]);
player.draw();
"step 1";
if (player.canCompare(target)) player.chooseToCompare(target);
else event.finish();
"step 2";
if (result.bool) {
player.addSkill("twchengxi_effect");
} else {
var card = { name: "sha", isCard: true };
if (target.canUse(card, player, false)) target.useCard(card, player, false);
}
},
ai: {
order: 8,
result: {
target: function (player, target) {
if (player.hasSkill("twchengxi_effect")) return 0;
var hs = player.getCards("h").sort((a, b) => b.number - a.number);
var ts = target.getCards("h").sort((a, b) => b.number - a.number);
if (!hs.length || !ts.length) return 0;
if (hs[0].number > ts[0].number) return -3;
if (!target.canUse({ name: "sha", isCard: true }, player, false)) return -1;
return 0;
},
},
},
subSkill: {
effect: {
charlotte: true,
trigger: { player: "useCard1" },
filter: function (event, player) {
return get.type(event.card) == "basic" || get.type(event.card) == "trick";
},
forced: true,
popup: false,
content: function () {
player.removeSkill("twchengxi_effect");
player
.when("useCardAfter")
.filter(evt => evt == trigger)
.then(() => {
if (trigger.targets) {
var card = {
name: trigger.card.name,
isCard: true,
};
var targets = trigger.targets.filter(i => i.isIn() && player.canUse(card, i, false));
if (targets.length) player.useCard(card, targets, false);
}
});
},
mark: true,
marktext: "袭",
intro: {
content: "使用的下一张基本牌或非延时锦囊牌结算完毕后视为对相同目标再使用一张无次数限制的同名牌",
},
},
},
},
//侠刘备
twshenyi: {
audio: 2,
trigger: { global: "damageEnd" },
filter: function (event, player) {
if (!event.player.isIn()) return false;
if (event.player.getHistory("damage").indexOf(event) != 0) return false;
return event.player == player || player.inRange(event.player);
},
usable: 1,
direct: true,
content: function* (event, map) {
var player = map.player,
trigger = map.trigger;
var list = get.inpileVCardList(info => {
return ["basic", "trick", "delay"].includes(info[0]) && !player.getStorage("twshenyi").includes(info[2]);
});
var dialog = [`###${get.prompt("twshenyi", trigger.player)}###<div class="text center">从牌堆中将一张牌作为“侠义”置于武将牌上${player != trigger.player && player.countCards("h") ? ",然后将任意张手牌交给其" : ""}</div>`, [list, "vcard"]];
var result = yield player.chooseButton(dialog).set("ai", function (button) {
var trigger = _status.event.getTrigger();
var player = _status.event.player,
name = button.link[2];
if (!get.cardPile2(card => card.name == name)) return 0;
var value = get.value({ name: name });
if (["tao", "jiu", "caochuan", "wuxie"].includes(name) && get.event().getRand() > 0.4) return value * 2;
return value;
});
if (result.bool) {
var name = result.links[0][2],
nature = result.links[0][3];
var cardx = { name: name, nature: nature };
player.logSkill("twshenyi", trigger.player);
player.popup(cardx);
player.markAuto("twshenyi", [name]);
game.log(player, "声明了", `#y${get.translation(cardx)}`);
var card = get.cardPile2(card => get.name(card, false) == name && get.nature(card, false) == nature);
if (card) player.addToExpansion([card], "gain2").gaintag.add("twshenyi");
else {
var card = get.cardPile2(card => get.type2(card) == get.type2(name));
if (card) player.addToExpansion([card], "gain2").gaintag.add("twshenyi");
else player.chat("无牌可得?!");
}
if (trigger.player != player && player.countCards("h")) {
game.delayex();
var skill = "twshenyi_" + player.playerid;
game.broadcastAll(lib.skill.twshenyi.createGainTag, skill, player.name);
game.addVideo("skill", player, ["twshenyi", [skill, player.name]]);
var result2 = yield player
.chooseCard("伸义:是否将任意张牌交给" + get.translation(trigger.player) + "?", [1, player.countCards("h")])
.set("ai", card => {
if (!_status.event.goon) return 0;
return 7 - get.value(card);
})
.set("goon", get.attitude(player, trigger.player) > 0);
if (result2.bool) {
player.give(result2.cards, trigger.player).gaintag.add(skill);
player.addSkill("twshenyi_draw");
}
}
} else player.storage.counttrigger.twshenyi--;
},
video: (player, info) => lib.skill.twshenyi.createGainTag(info[0], info[1]),
createGainTag: function (skill, name) {
if (!lib.skill[skill]) {
lib.skill[skill] = { charlotte: true };
lib.translate[skill] = "义·" + get.translation(name);
}
if (!_status.postReconnect.twshenyi) {
_status.postReconnect.twshenyi = [lib.skill.twshenyi.createGainTag, [], []];
}
_status.postReconnect.twshenyi[1].add(skill);
_status.postReconnect.twshenyi[2].add(name);
},
marktext: "义",
intro: {
name: "侠义",
content: "expansion",
markcount: "expansion",
},
onremove: function (player, skill) {
delete player.storage[skill];
//var cards=player.getExpansions(skill);
//if(cards.length) player.loseToDiscardpile(cards);
},
subSkill: {
draw: {
charlotte: true,
audio: "twshenyi",
trigger: {
global: ["loseAfter", "equipAfter", "addJudgeAfter", "gainAfter", "loseAsyncAfter", "addToExpansionAfter"],
},
filter: function (event, player) {
var skill = "twshenyi_" + player.playerid;
return game.hasPlayer(target => {
var evt = event.getl(target);
if (!evt || !evt.hs || !evt.hs.length) return false;
for (let i in evt.gaintag_map) {
if (evt.gaintag_map[i].includes(skill)) return true;
}
return false;
});
},
forced: true,
direct: true,
content: function () {
var skill = "twshenyi_" + player.playerid;
var num = 0;
var targets = game.filterPlayer(target => {
var evt = trigger.getl(target);
var numx = 0;
if (!evt || !evt.hs || !evt.hs.length) return false;
for (var i in evt.gaintag_map) {
if (evt.gaintag_map[i].includes(skill)) numx++;
}
if (numx > 0) return (num += numx);
return false;
});
if (num > 0) {
player.logSkill("twshenyi_draw", targets);
player.draw(num);
}
},
},
},
},
twxinghan: {
audio: 2,
trigger: { player: "phaseZhunbeiBegin" },
filter: function (event, player) {
return player.getExpansions("twshenyi").length > game.countPlayer();
},
check: function (event, player) {
if (player.hp >= 3 || (player.countCards("h") >= 4 && player.getExpansions("twshenyi").every(card => !player.hasValueTarget(card) || !get.tag(card, "damage") || !lib.skill.xunshi.isXunshi(card)))) return false;
return player.getExpansions("twshenyi").some(card => player.hasValueTarget(card));
},
direct: true,
content: function* (event, map) {
var player = map.player;
var result = yield player
.chooseBool()
.set("createDialog", [
get.prompt("twxinghan"),
`<div class="text center">按顺序使用以下“侠义”牌。但是回合结束时你须弃置所有手牌并失去X点体力X为你的体力值-1且X至少为1</div>`,
player
.getExpansions("twshenyi")
.filter(card => player.hasUseTarget(card))
.reverse(),
"hidden",
])
.set("choice", lib.skill.twxinghan.check(null, player));
if (!result.bool) {
event.finish();
return;
}
while (true) {
var cards = player
.getExpansions("twshenyi")
.filter(card => player.hasUseTarget(card))
.reverse();
if (!cards.length) break;
yield player.chooseUseTarget(true, cards[0], false);
}
player.when("phaseEnd").then(() => {
if (player.countCards("h")) player.chooseToDiscard(player.countCards("h"), true);
var num = Math.max(1, player.getHp() - 1);
player.loseHp(num);
});
},
group: "twxinghan_init",
subSkill: {
init: {
audio: "twxinghan",
trigger: {
player: ["loseEnd", "dying", "phaseBefore", "phaseAfter", "dyingAfter", "die"],
global: ["equipEnd", "addJudgeEnd", "gainEnd", "loseAsyncEnd", "addToExpansionEnd"],
},
filter: function (event, player) {
return (player.getExpansions("twshenyi").length && event.name != "die" && (_status.currentPhase != player || player.isDying())) ^ player.hasSkill("twxinghan_in");
},
forced: true,
firstDo: true,
silent: true,
forceDie: true,
content: function () {
if (player.getExpansions("twshenyi").length && trigger.name != "die" && (_status.currentPhase != player || player.isDying())) {
var cards = player.getExpansions("twshenyi");
var cardsx = cards.map(card => {
var cardx = ui.create.card();
cardx.init(get.cardInfo(card));
cardx._cardid = card.cardid;
return cardx;
});
player.directgains(cardsx, null, "twxinghan_tag");
player.addSkill("twxinghan_in");
} else player.removeSkill("twxinghan_in");
},
},
in: {
charlotte: true,
audio: "twxinghan",
trigger: { player: "addToExpansionEnd" },
filter: function (event, player) {
return event.gaintag.includes("twshenyi");
},
forced: true,
locked: false,
silent: true,
content: function () {
"step 0";
var cards2 = player.getCards("s", card => card.hasGaintag("twxinghan_tag"));
if (player.isOnline2()) {
player.send(
function (cards, player) {
cards.forEach(i => i.delete());
if (player == game.me) ui.updatehl();
},
cards2,
player
);
}
cards2.forEach(i => i.delete());
if (player == game.me) ui.updatehl();
"step 1";
var cards = player.getExpansions("twshenyi");
var cardsx = cards.map(card => {
var cardx = ui.create.card();
cardx.init(get.cardInfo(card));
cardx._cardid = card.cardid;
return cardx;
});
player.directgains(cardsx, null, "twxinghan_tag");
},
onremove: function (player) {
var cards2 = player.getCards("s", card => card.hasGaintag("twxinghan_tag"));
if (player.isOnline2()) {
player.send(
function (cards, player) {
cards.forEach(i => i.delete());
if (player == game.me) ui.updatehl();
},
cards2,
player
);
}
cards2.forEach(i => i.delete());
if (player == game.me) ui.updatehl();
},
group: "twxinghan_use",
},
use: {
charlotte: true,
trigger: { player: ["useCardBefore", "respondBefore"] },
filter: function (event, player) {
var cards = player.getCards("s", card => card.hasGaintag("twxinghan_tag") && card._cardid);
return (
event.cards &&
event.cards.some(card => {
return cards.includes(card);
})
);
},
forced: true,
popup: false,
firstDo: true,
content: function () {
var idList = player.getCards("s", card => card.hasGaintag("twxinghan_tag")).map(i => i._cardid);
var cards = player.getExpansions("twshenyi");
var cards2 = [];
for (var card of trigger.cards) {
var cardx = cards.find(cardx => cardx.cardid == card._cardid);
if (cardx) cards2.push(cardx);
}
var cards3 = trigger.cards.slice();
trigger.cards = cards2;
trigger.card.cards = cards2;
if (player.isOnline2()) {
player.send(
function (cards, player) {
cards.forEach(i => i.delete());
if (player == game.me) ui.updatehl();
},
cards3,
player
);
}
cards3.forEach(i => i.delete());
if (player == game.me) ui.updatehl();
},
},
},
ai: {
combo: "twshenyi",
},
},
//张纮
twquanqian: {
audio: 2,
sunbenSkill: true,
enable: "phaseUse",
filter: function (event, player) {
return !player.hasSkill("twquanqian_sunben") && player.countCards("h") && game.countPlayer() > 1;
},
filterCard: function (card, player) {
return !ui.selected.cards.some(cardx => get.suit(cardx, player) == get.suit(card, player));
},
selectCard: [1, 4],
check: function (card) {
return 1 / (get.value(card) || 0.5);
},
position: "h",
complexCard: true,
discard: false,
lose: false,
delay: false,
filterTarget: lib.filter.notMe,
usable: 1,
content: function () {
"step 0";
player.addSkill("twquanqian_sunben");
player.give(cards, target);
if (cards.length < 2) event.finish();
"step 1";
var card = get.cardPile2(card => get.type(card) == "equip");
if (card) player.gain(card, "gain2");
"step 2";
if (player.countCards("h") >= target.countCards("h")) {
if (target.countCards("h")) event._result = { index: 1 };
else event.finish();
} else {
var str = get.translation(target);
player
.chooseControl()
.set("choiceList", ["将手牌数摸至与" + str + "相同", "观看" + str + "的手牌并获得其一种花色的所有手牌"])
.set("ai", () => {
var player = _status.event.player;
var target = _status.event.target;
if (target.countCards("h") - player.countCards("h") > target.countCards("h") / 4 || get.attitude(player, target) > 0) return 0;
return 1;
})
.set("target", target);
}
"step 3";
if (result.index == 0) {
player.drawTo(target.countCards("h"));
event.finish();
return;
}
var list = [];
var dialog = ["劝迁:获得" + get.translation(target) + "一种花色的所有牌"];
for (var suit of lib.suit.concat("none")) {
if (target.countCards("h", { suit: suit })) {
dialog.push('<div class="text center">' + get.translation(suit + "2") + "牌</div>");
dialog.push(target.getCards("h", { suit: suit }));
list.push(suit);
}
}
if (!list.length) {
event.finish();
return;
}
player
.chooseControl(list)
.set("dialog", dialog)
.set("ai", () => {
return _status.event.control;
})
.set(
"control",
(() => {
var getv = cards => cards.map(i => get.value(i)).reduce((p, c) => p + c, 0);
return list.sort((a, b) => {
return getv(target.getCards("h", { suit: b })) - getv(target.getCards("h", { suit: a }));
})[0];
})()
);
"step 4";
if (result.control) player.gain(target.getCards("h", { suit: result.control }), target, "give");
},
ai: {
order: 7,
result: {
target: function (player, target) {
return target.countCards("h");
},
},
},
subSkill: {
sunben: {
charlotte: true,
init: function (player) {
player.storage.twquanqian_sunben = 0;
},
onremove: true,
mark: true,
intro: {
markcount: function (num) {
return (num || 0).toString();
},
content: "弃牌进度:#/6",
},
trigger: {
player: "loseAfter",
global: "loseAsyncAfter",
},
filter: function (event, player) {
if (event.type != "discard") return false;
var evt = event.getl(player);
return evt && evt.hs && evt.hs.length;
},
forced: true,
popup: false,
firstDo: true,
content: function () {
"step 0";
player.addMark("twquanqian_sunben", trigger.getl(player).hs.length, false);
"step 1";
if (player.countMark("twquanqian_sunben") >= 6) {
player.removeSkill("twquanqian_sunben");
player.popup("劝迁");
game.log(player, "恢复了技能", "#g【劝迁】");
}
},
},
},
},
twrouke: {
audio: 2,
trigger: {
player: "gainAfter",
global: "loseAsyncAfter",
},
filter: function (event, player) {
var evt = event.getParent("phaseDraw");
if (evt && evt.player == player) return false;
return event.getg(player).length > 1;
},
forced: true,
content: function () {
player.draw();
},
},
//张昭
twlijian: {
getCards: function (event) {
var cards = [];
game.countPlayer2(function (current) {
current.checkHistory("lose", function (evt) {
if (evt.position == ui.discardPile && evt.getParent("phaseDiscard") == event) cards.addArray(evt.cards);
});
});
game.checkGlobalHistory("cardMove", function (evt) {
if (evt.name == "cardsDiscard" && evt.getParent("phaseDiscard") == event) cards.addArray(evt.cards);
});
return cards.filterInD("d");
},
audio: 2,
sunbenSkill: true,
trigger: { global: "phaseDiscardEnd" },
filter: function (event, player) {
if (player.hasSkill("twlijian_sunben")) return false;
if (event.player != player && event.player.isIn()) {
return lib.skill.twlijian.getCards(event).length;
}
return false;
},
prompt2: () => "选择任意张本阶段进入弃牌堆的牌令其获得然后你获得剩余的牌若其获得的牌数大于你则你可以对其造成1点伤害",
logTarget: "player",
content: function () {
"step 0";
player.addSkill("twlijian_sunben");
var cards = lib.skill.twlijian.getCards(trigger),
target = trigger.player;
event.cards = cards;
event.target = target;
player
.chooseToMove("力荐:请分配" + get.translation(target) + "和你获得的牌", true)
.set("list", [[get.translation(target) + "获得的牌", cards], ["你获得的牌"]])
.set("processAI", function (list) {
var player = _status.event.player;
var target = _status.event.getTrigger().player;
var att = get.attitude(player, target);
var cards = _status.event.cards;
var cardx = cards.filter(card => card.name == "du");
var cardy = cards.removeArray(cardx);
switch (get.sgn(att)) {
case 1:
return [cards, []];
case 0:
return [cardx, cardy];
case -1:
var num = Math.ceil(cards.length / 2) + (cards.length % 2 == 0 ? 1 : 0);
if (num > 1 && player.hasSkill("twchungang")) num--;
if (get.damageEffect(target, player, player) <= 0 || num > 2 || cardx.length > cardy.length) return [cardx, cardy];
var num2 = cardy.length - cardx.length;
num2 = Math.ceil(num2 / 2) + (num2 % 2 == 0 ? 1 : 0);
cardy.sort((a, b) => get.value(b) - get.value(a));
cardx.addArray(cardy.slice(num, cardy.length));
return [cardx, cardy.slice(0, num)];
}
})
.set("cards", cards);
"step 1";
if (result.bool) {
target.gain(result.moved[0], "gain2");
player.gain(result.moved[1], "gain2");
if (result.moved[0].length > result.moved[1].length) {
player.chooseBool("是否对" + get.translation(target) + "造成1点伤害").set("choice", get.damageEffect(target, player, player) > 0);
} else event.finish();
} else event.finish();
"step 2";
if (result.bool) {
player.line(target);
target.damage();
}
},
subSkill: {
sunben: {
charlotte: true,
init: function (player) {
player.storage.twlijian_sunben = 0;
},
onremove: true,
mark: true,
intro: {
markcount: function (num) {
return (num || 0).toString();
},
content: "弃牌堆进入牌进度:#/8",
},
trigger: {
global: ["loseAfter", "cardsDiscardAfter", "loseAsyncAfter", "equipAfter"],
},
filter: function (event, player) {
var cards = event.getd();
if (!cards.length) return false;
var list = cards.slice();
game.checkGlobalHistory(
"cardMove",
function (evt) {
if (evt == event || evt.getParent() == event || (evt.name != "lose" && evt.name != "cardsDiscard")) return false;
if (evt.name == "lose" && evt.position != ui.discardPile) return false;
list.removeArray(evt.cards);
},
event
);
return list.length > 0;
},
forced: true,
popup: false,
firstDo: true,
content: function () {
"step 0";
var cards = trigger.getd().slice();
game.checkGlobalHistory(
"cardMove",
function (evt) {
if (evt == trigger || evt.getParent() == trigger || (evt.name != "lose" && evt.name != "cardsDiscard")) return false;
if (evt.name == "lose" && evt.position != ui.discardPile) return false;
cards.removeArray(evt.cards);
},
trigger
);
player.addMark("twlijian_sunben", cards.length, false);
"step 1";
if (player.countMark("twlijian_sunben") >= 8) {
player.removeSkill("twlijian_sunben");
player.popup("力荐");
game.log(player, "恢复了技能", "#g【力荐】");
}
},
},
},
},
twchungang: {
audio: 2,
init: () => {
game.addGlobalSkill("twchungang_global");
},
onremove: player => {
if (
!game.hasPlayer(i => {
return player !== i && i.hasSkill("twchungang");
}, true)
)
game.removeGlobalSkill("twchungang_global");
},
trigger: { global: ["gainAfter", "loseAsyncAfter"] },
filter: function (event, player) {
var evt = event.getParent("phaseDraw");
return game.hasPlayer(target => {
if (target == player || (evt && evt.player == target)) return false;
return event.getg(target).length > 1 && target.countCards("he");
});
},
forced: true,
logTarget: function (event, player) {
var evt = event.getParent("phaseDraw");
return game.filterPlayer(target => {
if (target == player || (evt && evt.player == target)) return false;
return event.getg(target).length > 1 && target.countCards("he");
});
},
content: function () {
for (var i of lib.skill.twchungang.logTarget(trigger, player)) {
i.chooseToDiscard("he", true);
}
},
subSkill: {
global: {
trigger: {
player: "dieAfter",
},
filter(event, player) {
return !game.hasPlayer(i => i.hasSkill("twchungang"), true);
},
silent: true,
forceDie: true,
charlotte: true,
content() {
game.removeGlobalSkill("twchungang_global");
},
ai: {
effect: {
target(card, player, target) {
if ((get.tag(card, "gain") || 0) < 2 && (get.tag(card, "draw") || 0) < 2) return;
let evt = _status.event.getParent("phaseDraw"),
dis = game.countPlayer(i => {
return target !== i && i.hasSkill("twchungang");
});
if (!dis || (evt && evt.player === target)) return;
return [1, -dis];
},
},
},
},
},
},
//海外主公技
//张鲁
twshijun: {
unique: true,
global: "twshijun_global",
audio: 2,
zhuSkill: true,
ai: { combo: "yishe" },
subSkill: {
global: {
audio: "twshijun",
usable: 1,
enable: "phaseUse",
forceaudio: true,
filter: function (event, player) {
return (
player.group == "qun" &&
game.hasPlayer(function (current) {
return current != player && current.hasZhuSkill("twshijun", player) && !current.getExpansions("yishe").length;
})
);
},
filterTarget: function (card, player, target) {
return target != player && target.hasZhuSkill("twshijun", player) && !target.getExpansions("yishe").length;
},
prompt: "摸一张牌然后将一张牌作为“米”置于主公的武将牌上",
content: function () {
"step 0";
player.draw();
if (player.countCards("he")) player.chooseCard("将一张牌置于" + get.translation(target) + "的武将牌上", "he", true);
else event.finish();
"step 1";
if (result.bool) target.addToExpansion(result.cards, player, "give").gaintag.add("yishe");
},
ai: {
order: 7,
result: {
target: 1,
},
},
},
},
},
//张绣
twjuxiang: {
unique: true,
global: "twjuxiang_global",
audio: 2,
zhuSkill: true,
subSkill: {
global: {
audio: "twjuxiang",
usable: 1,
enable: "phaseUse",
forceaudio: true,
filter: function (event, player) {
return (
player.countCards("e") &&
player.group == "qun" &&
game.hasPlayer(function (target) {
return target != player && target.hasZhuSkill("twjuxiang", player) && player.countCards("e", card => target.hasEmptySlot(get.subtype(card)) || target.hasDisabledSlot(get.subtype(card)));
})
);
},
filterTarget: function (card, player, target) {
return target != player && target.hasZhuSkill("twjuxiang", player) && (target.hasEmptySlot(get.subtype(ui.selected.cards[0])) || target.hasDisabledSlot(get.subtype(ui.selected.cards[0])));
},
filterCard: { type: "equip" },
position: "e",
check: function (card) {
return get.value(card);
},
prompt: "将装备区中的一张牌置入主公的装备区中或恢复主公的对应装备栏",
discard: false,
lose: false,
content: function () {
if (target.hasEmptySlot(get.subtype(cards[0]))) {
player.$give(cards[0], target, false);
target.equip(cards[0]);
} else {
target.gain(cards[0], player, "give");
target.enableEquip(get.subtype(cards[0]));
}
},
ai: {
order: 7,
result: {
target: 1,
},
},
},
},
},
//孙坚
twpolu: {
unique: true,
audio: "repolu",
trigger: { global: ["dieAfter", "die"] },
forceDie: true,
zhuSkill: true,
filter: function (event, player, name) {
if (!player.hasZhuSkill("twpolu")) return false;
if (name == "dieAfter" && event.source && event.source.group == "wu") return true;
if (name == "die" && event.player.group == "wu") return true;
return false;
},
direct: true,
content: function () {
"step 0";
if (!player.storage.twpolu) player.storage.twpolu = 0;
event.num = player.storage.twpolu + 1;
player.chooseTarget([1, Infinity], get.prompt("twpolu"), "令任意名角色摸" + get.cnNumber(event.num) + "张牌").set("forceDie", true).ai = function (target) {
return get.attitude(_status.event.player, target);
};
"step 1";
if (result.bool) {
player.storage.twpolu++;
result.targets.sortBySeat();
player.logSkill("repolu", result.targets);
game.asyncDraw(result.targets, num);
} else event.finish();
"step 2";
game.delay();
},
},
//孟获
twqiushou: {
unique: true,
audio: 2,
trigger: { global: "useCardAfter" },
filter: function (event, player) {
if (event.card.name != "nanman") return false;
var num = 0,
bool = false;
for (var i of event.targets) {
if (!i.isAlive()) bool = true;
i.getHistory("damage", function (evt) {
if (evt.getParent(2) == event) num += evt.num;
});
}
return player.hasZhuSkill("twqiushou") && (bool || num > 3);
},
zhuSkill: true,
forced: true,
logTarget: function (event, player) {
return game.filterPlayer(function (target) {
return ["shu", "qun"].includes(target.group);
});
},
content: function () {
"step 0";
game.asyncDraw(lib.skill.twqiushou.logTarget(trigger.player));
"step 1";
game.delayx();
},
},
//刘协
twzhuiting: {
unique: true,
zhuSkill: true,
audio: 2,
global: "twzhuiting_global",
subSkill: {
global: {
hiddenWuxie: function (player, info) {
if (player.group != "wei" && player.group != "qun") return false;
const target = info.target,
card = info.card;
if (!target || target == player || !target.hasZhuSkill("twzhuiting")) return false;
if (_status.connectMode && player.countCards("hs") > 0) return true;
const color = get.color(card, false);
if (color == "none") return false;
return player.hasCard(card => get.color(card) == color, "hes");
},
audio: "twzhuiting",
forceaudio: true,
enable: "chooseToUse",
filter: function (event, player) {
if (event.type != "wuxie" || (player.group != "wei" && player.group != "qun")) return false;
const info = event.info_map,
target = info.target,
card = info.card;
if (!target || target == player || !target.hasZhuSkill("twzhuiting")) return false;
const color = get.color(card, false);
if (color == "none") return false;
return player.hasCard(card => get.color(card) == color, "hes");
},
filterCard: function (card) {
const info = _status.event.info_map;
return info && get.color(card) == get.color(info.card, false);
},
viewAs: { name: "wuxie" },
position: "hes",
prompt: function () {
const info = _status.event.info_map;
return "将一张" + get.translation(get.color(info.card)) + "牌当作【无懈可击】对" + get.translation(info.target) + "使用";
},
check: function (card) {
return 8 - get.value(card);
},
},
},
},
//刘繇
twniju: {
audio: 2,
zhuSkill: true,
trigger: {
global: "compare",
},
priority: 1,
filter(event, player) {
if (!player.hasZhuSkill("twniju")) return false;
if (event.iwhile || (event.target && event.compareMeanwhile)) return false;
const participant = [event.player];
if (event.targets) participant.addArray(event.targets);
else participant.add(event.target);
return participant.includes(player);
},
direct: true,
async content(event, trigger, player) {
const num = game.countPlayer(current => current.group === "qun");
const dialog = [
get.prompt("twniju"),
`<div class="text center">令一张拼点牌的点数+${num}或-${num}</div>`,
[
[
["addNumber", "增加"],
["subtractNumber", "减少"],
],
"tdnodes",
],
];
const lose_list = trigger.lose_list.slice().sort((a, b) => lib.sort.seat(a[0], b[0]));
dialog.push(
`<div class="text center">${lose_list
.map(list => {
return get.translation(list[0]);
})
.join("  /  ")}</div>`
);
const cards = lose_list.map(list => list[1]).flat();
dialog.push(cards);
const result = await player
.chooseButton(dialog, 2)
.set("filterButton", button => {
const type = typeof button.link;
if (ui.selected.buttons.length && type === typeof ui.selected.buttons[0].link) return false;
return true;
})
.forResult();
if (!result.bool) return;
const { links } = result;
if (typeof links[0] !== "string") links.reverse();
let [fn, card] = links;
const selectedPlayer = lose_list.find(item => {
if (Array.isArray(item[1])) return item[1].includes(card);
return item[1] == card;
})[0];
player.logSkill("twniju", selectedPlayer);
selectedPlayer.addTempSkill("twniju_change");
if (!selectedPlayer.storage.twniju_change) selectedPlayer.storage.twniju_change = [];
selectedPlayer.storage.twniju_change.push([fn, num, card]);
player
.when("chooseToCompareAfter")
.filter(evt => evt === trigger)
.vars({
toDraw: num,
})
.then(() => {
const num1 = trigger.result.num1,
num2 = trigger.result.num2;
let bool = false;
if (typeof num1 === "number" && typeof num2 === "number") {
if (num1 === num2) {
bool = true;
}
} else {
const num1List = num1.toUniqued();
const totalList = num1List.concat(num2).toUniqued();
if (totalList.length < num1List.length + num2.length) {
bool = true;
}
}
if (bool) player.draw(toDraw);
});
},
subSkill: {
change: {
trigger: { global: "compare" },
filter(event, player) {
const storage = player.getStorage("twniju_change");
if (!storage.length) return false;
if ((player !== event.player || event.iwhile) && player !== event.target) return false;
return event.lose_list.some(list => {
const cards = Array.isArray(list[1]) ? list[1] : [list[1]];
return list[0] === player && storage.some(s => cards.includes(s[2]));
});
},
charlotte: true,
forced: true,
silent: true,
async content(event, trigger, player) {
const [fn, num] = player.getStorage("twniju_change").find(s => {
return trigger.lose_list.some(list => {
const cards = Array.isArray(list[1]) ? list[1] : [list[1]];
return list[0] === player && cards.includes(s[2]);
});
});
const numId = player === trigger.player ? "num1" : "num2";
trigger[fn](numId, num);
if (trigger[numId] > 13) trigger[numId] = 13;
else if (trigger[numId] < 1) trigger[numId] = 1;
game.log(player, "的拼点牌点数", fn === "addNumber" ? "+" : "-", num);
},
},
},
},
//刘虞
twchongwang: {
init: function (player) {
player.storage.twchongwang = [];
player.storage.twchongwangx = [];
},
mod: {
playerEnabled: function (card, player, target) {
if (!player.hasZhuSkill("twchongwang")) return;
if (get.tag(card, "damage") > 0 && player.storage.twchongwangx.includes(target)) return false;
},
targetEnabled: function (card, player, target) {
if (!target.hasZhuSkill("twchongwang")) return;
if (get.tag(card, "damage") > 0 && target.storage.twchongwangx.includes(player)) return false;
},
},
locked: false,
unique: true,
onremove: true,
global: "twchongwang_global",
group: "twchongwang_clear",
audio: 2,
zhuSkill: true,
subSkill: {
clear: {
charlotte: true,
trigger: { player: "phaseAfter" },
direct: true,
content: function () {
player.storage.twchongwangx = [];
},
},
global: {
trigger: { player: "phaseUseBegin" },
filter: function (event, player) {
return (
player.group == "qun" &&
game.hasPlayer(function (current) {
return current != player && current.hasZhuSkill("twchongwang", player) && !current.storage.twchongwang.includes(player);
})
);
},
direct: true,
content: function () {
"step 0";
player.chooseCardTarget({
prompt: "崇望:是否将一张牌交给主公并获得双重庇护?",
selectCard: 1,
filterCard: true,
filterTarget: function (card, player, target) {
return target != player && target.hasZhuSkill("twchongwang", player) && !target.storage.twchongwang.includes(player);
},
position: "he",
ai1: function (card) {
if (card.name == "du") return 10;
else if (ui.selected.cards.length && ui.selected.cards[0].name == "du") return 0;
var player = _status.event.player;
if (
ui.selected.cards.length > 4 ||
!game.hasPlayer(function (current) {
return get.attitude(player, current) > 0 && !current.hasSkillTag("nogain");
})
)
return 0;
return 1 / Math.max(0.1, get.value(card));
},
ai2: function (target) {
var player = _status.event.player,
att = get.attitude(player, target);
if (ui.selected.cards[0].name == "du") return -att;
if (target.hasSkillTag("nogain")) att /= 6;
return att;
},
});
"step 1";
if (result.bool) {
player.logSkill("twchongwang", result.targets[0]);
result.targets[0].gain(result.cards, player, "giveAuto");
result.targets[0].storage.twchongwang.push(player);
result.targets[0].storage.twchongwangx.push(player);
}
},
},
},
},
//公孙范
twhuiyuan: {
audio: 2,
trigger: { player: "useCardAfter" },
filter: function (event, player) {
var evt = event.getParent("phaseUse");
if (!evt || evt.player != player) return false;
var type = get.type2(event.card);
return !player.hasHistory("gain", evtx => {
if (evtx.getParent("phaseUse") != evt) return false;
return evtx.cards.some(card => get.type2(card) == type);
});
},
direct: true,
content: function () {
"step 0";
var prompt2 = "展示一名角色的一张手牌。若展示牌为" + get.translation(get.type2(trigger.card)) + "牌则你获得之否则其弃置之并摸一张牌。然后若其在你的攻击范围内且你不在其攻击范围内你对其造成1点伤害";
player
.chooseTarget(get.prompt("twhuiyuan"), prompt2, (card, player, target) => {
return target.countCards("h");
})
.set("ai", target => {
var player = _status.event.player;
var att = get.attitude(player, target);
return -att + (player.inRange(target) && !target.inRange(player) ? get.damageEffect(target, player, player) / 3 : 0);
});
"step 1";
if (result.bool) {
var target = result.targets[0];
event.target = target;
player.logSkill("twhuiyuan", target);
player.choosePlayerCard(target, "h", true, "回援:展示" + get.translation(target) + "一张手牌");
} else event.finish();
"step 2";
if (result.bool) {
var card = result.cards[0];
target.showCards([card], get.translation(target) + "【回援】展示");
if (get.type2(card) == get.type2(trigger.card)) {
if (lib.filter.canBeGained(card, target, player)) {
player.gain(card, target, "giveAuto", "bySelf");
}
} else {
if (lib.filter.canBeDiscarded(card, target, player)) {
target.discard(card, "notBySelf");
target.draw();
}
}
} else event.finish();
"step 3";
if (player.inRange(target) && !target.inRange(player)) {
game.log(player, "触发了", "#y搏击", "效果");
player.line(target);
target.damage();
}
},
ai: {
expose: 0.2,
threaten: 3,
},
},
twshoushou: {
audio: 2,
trigger: {
player: "gainAfter",
global: "loseAsyncAfter",
},
filter: function (event, player) {
var cards = event.getg(player);
if (!cards.length) return false;
return (
game.hasPlayer(current => {
return event.getl(current).cards2.length;
}) &&
game.hasPlayer(current => {
return current.inRange(player);
})
);
},
forced: true,
locked: false,
group: "twshoushou_damage",
onremove: function (player) {
if (player.countMark("twshoushou_plus") - player.countMark("twshoushou_minus") == 0) {
player.removeSkill("twshoushou_distance");
}
},
content: function () {
player.addSkill("twshoushou_distance");
player.addMark("twshoushou_plus", 1, false);
},
ai: {
halfneg: true,
},
subSkill: {
damage: {
trigger: {
player: "damageEnd",
source: "damageSource",
},
filter: function (event, player) {
return game.hasPlayer(current => {
return current != player && !current.inRange(player);
});
},
forced: true,
locked: false,
content: function () {
player.addSkill("twshoushou_distance");
player.addMark("twshoushou_minus", 1, false);
},
},
distance: {
mark: true,
marktext: "绶",
intro: {
markcount: function (storage, player) {
return player.countMark("twshoushou_plus") - player.countMark("twshoushou_minus");
},
content: function (storage, player) {
var dis = player.countMark("twshoushou_plus") - player.countMark("twshoushou_minus");
return "其他角色至你的距离" + (dis >= 0 ? "+" : "") + dis;
},
},
mod: {
globalTo: function (from, to, distance) {
return distance + to.countMark("twshoushou_plus") - to.countMark("twshoushou_minus");
},
},
},
},
},
//严纲
twzhiqu: {
audio: 2,
trigger: { player: "phaseJieshuBegin" },
direct: true,
content: function () {
"step 0";
var count = get.cnNumber(
game.countPlayer(current => {
return get.distance(player, current) <= 1;
})
);
player.chooseTarget(get.prompt("twzhiqu"), "选择一名其他角色并视为使用牌堆顶" + count + "张牌中的【杀】。若你与其均在对方的攻击范围内,你改为依次对其使用牌堆顶" + count + "张牌中的【杀】或锦囊牌。", lib.filter.notMe).set("ai", target => {
var player = _status.event.player;
return get.effect(target, { name: "sha" }, player, player) * (get.distance(player, target) == 1 ? 2 : 1);
});
"step 1";
if (result.bool) {
var target = result.targets[0];
event.target = target;
player.logSkill("twzhiqu", target);
event.fight = player.inRange(target) && target.inRange(player);
if (event.fight) game.log(player, "触发了", "#y搏击", "效果");
event.cards = game
.cardsGotoOrdering(
get.cards(
game.countPlayer(current => {
return get.distance(player, current) <= 1;
})
)
)
.cards.slice();
} else event.finish();
"step 2";
if (player.isIn() && target.isIn() && cards.length) {
do var card = cards.shift();
while (get.name(card) != "sha" && (!event.fight || get.type2(card) != "trick") && cards.length);
if (get.name(card) != "sha" && (!event.fight || get.type2(card) != "trick")) return;
player.showCards([card], get.translation(player) + "发动了【直取】");
player
.chooseUseTarget(card, true, false, "nodistance")
.set("filterTarget", function (card, player, target) {
var evt = _status.event;
if (_status.event.name == "chooseTarget") evt = evt.getParent();
if (target != player && target != evt.twzhiqu_target) return false;
return lib.filter.targetEnabledx(card, player, target);
})
.set("twzhiqu_target", target);
event.redo();
}
},
},
twxianfeng: {
audio: 2,
trigger: { source: "damageSource" },
filter: function (event, player) {
if (!player.isPhaseUsing()) return false;
if (player == event.player) return false;
if (!event.player.isIn()) return false;
if (!event.card) return false;
return event.card.name == "sha" || (get.type(event.card) == "trick" && get.tag(event.card, "damage"));
},
logTarget: "player",
check: function (event, player) {
let att = get.attitude(player, event.player);
if (att > 0) return true;
if (!player.hasSkill("twzhiqu")) return false;
let cnt = game.countPlayer(current => get.distance(player, current) === 2);
if (cnt > 2 || (cnt === 2 && Math.abs(att) < 2) || (cnt && Math.abs(att) < 1)) return true;
return false;
},
content: function () {
"step 0";
var target = trigger.player;
event.target = target;
target
.chooseControl()
.set("choiceList", ["你摸一张牌,然后直到" + get.translation(player) + "下个回合开始时,其至其他角色的距离-1", get.translation(player) + "摸一张牌,然后直到其下个回合开始时,你至其的距离-1"])
.set("prompt", "先锋:请选择一项")
.set("ai", () => {
return _status.event.choice;
})
.set(
"choice",
(function () {
var att = get.attitude(target, player);
if (att === 0) return 0;
if (player.hasSkill("twzhiqu")) {
var cnt = game.countPlayer(current => get.distance(player, current) === 2);
if (att > 0) {
if (cnt || player.needsToDiscard(1)) return 0;
return 1;
}
if (!cnt) return 0;
if (cnt >= 2 || get.distance(target, player, "attack") === 2 || get.distance(target, player) === 2) return 1;
return 0;
}
if (
att < 0 ||
(player.needsToDiscard(1) &&
game.hasPlayer(function (current) {
return current !== player && current !== target && !player.inRange(current);
}))
)
return 0;
return [0, 1].randomGet();
})()
);
"step 1";
if (result.index == 0) {
target.draw();
player.addTempSkill("twxianfeng_me", { player: "phaseBegin" });
player.addMark("twxianfeng_me", 1, false);
} else {
player.draw();
target.addSkill("twxianfeng_others");
if (!target.storage.twxianfeng_others) target.storage.twxianfeng_others = {};
if (typeof target.storage.twxianfeng_others[player.playerid] != "number") target.storage.twxianfeng_others[player.playerid] = 0;
target.storage.twxianfeng_others[player.playerid]++;
}
},
subSkill: {
me: {
charlotte: true,
mark: true,
intro: { content: "至其他角色的距离-#" },
mod: {
globalFrom: function (from, to, distance) {
return distance - from.countMark("twxianfeng_me");
},
},
},
others: {
trigger: { global: ["phaseBegin", "die"] },
filter: function (event, player) {
return player.storage.twxianfeng_others && player.storage.twxianfeng_others[event.player.playerid];
},
charlotte: true,
mark: true,
forced: true,
intro: {
markcount: function (storage, player) {
var max = 0;
for (var id in storage) {
if (storage[id] > max) max = storage[id];
}
return max;
},
content: function (storage, player) {
if (!storage) return "";
var str = "";
var map = _status.connectMode ? lib.playerOL : game.playerMap;
for (var id in storage) {
str += "至" + get.translation(map[id]) + "的距离-" + storage[id] + "、";
}
return str.slice(0, -1);
},
},
content: function () {
delete player.storage.twxianfeng_others[trigger.player.playerid];
if (get.is.empty(player.storage.twxianfeng_others)) player.removeSkill("twxianfeng_others");
},
mod: {
globalFrom: function (from, to, distance) {
if (from.storage.twxianfeng_others && typeof from.storage.twxianfeng_others[to.playerid] == "number") return distance - from.storage.twxianfeng_others[to.playerid];
},
},
},
},
},
//夏侯紫萼
twxuechang: {
audio: 2,
enable: "phaseUse",
usable: 1,
filterTarget: function (card, player, target) {
return player.canCompare(target);
},
content: function () {
"step 0";
player.chooseToCompare(target);
"step 1";
if (result.bool) {
if (!target.countGainableCards(player, "he")) event.finish();
else player.gainPlayerCard(target, "he", true);
} else {
player.damage(target);
player.addSkill("twxuechang_add");
if (!player.storage.twxuechang_add) player.storage.twxuechang_add = {};
if (!player.storage.twxuechang_add[target.playerid]) player.storage.twxuechang_add[target.playerid] = 0;
player.storage.twxuechang_add[target.playerid]++;
player.markSkill("twxuechang_add");
event.finish();
}
"step 2";
var card = result.cards[0];
if (get.type(card) == "equip") {
var card = { name: "sha", isCard: true };
if (player.canUse(card, target, false)) player.useCard(card, target, "noai", false);
}
},
ai: {
order: 6.5,
result: {
target: function (player, target) {
var hs = player.getCards("h").sort(function (a, b) {
return get.number(b) - get.number(a);
});
var ts = target.getCards("h").sort(function (a, b) {
return get.number(b) - get.number(a);
});
if (!hs.length || !ts.length) return 0;
if (get.number(hs[0]) > get.number(ts[0]) || get.number(hs[0]) - ts.length >= 9 + Math.min(2, player.hp / 2)) return get.sgnAttitude(player, target) * get.effect(target, { name: "shunshou_copy2" }, player, player);
return 0;
},
},
},
subSkill: {
add: {
audio: "twxuechang",
trigger: { source: "damageBegin1" },
filter: function (event, player) {
return player.storage.twxuechang_add && player.storage.twxuechang_add[event.player.playerid];
},
forced: true,
charlotte: true,
content: function () {
trigger.num += player.storage.twxuechang_add[trigger.player.playerid];
delete player.storage.twxuechang_add[trigger.player.playerid];
if (get.is.empty(player.storage.twxuechang_add)) player.removeSkill("twxuechang_add");
else player.markSkill("twxuechang_add");
},
marktext: "偿",
intro: {
content: function (storage, player) {
if (!storage) return "";
var str = "";
var map = _status.connectMode ? lib.playerOL : game.playerMap;
for (var i in storage) {
str += "<li>下次对" + get.translation(map[i]) + "造成的伤害+" + storage[i];
}
return str;
},
},
},
},
},
twduoren: {
audio: 2,
trigger: { source: "dieAfter" },
check: function (event, player) {
if (player.hp < 3 && !player.isDamaged()) return false;
var skills = event.player.getSkills(null, false, false).filter(skill => {
if (player.hasSkill(skill, null, false, false)) return false;
var info = get.info(skill);
return info && !info.hiddenSkill && !info.zhuSkill && !info.charlotte;
});
return skills.length > 0;
},
group: "twduoren_remove",
prompt2: function (event, player) {
var skills = event.player.getSkills(null, false, false).filter(skill => {
if (player.hasSkill(skill, null, false, false)) return false;
var info = get.info(skill);
return info && !info.hiddenSkill && !info.zhuSkill && !info.charlotte;
});
var str = "";
for (var i of skills) {
str += "〖" + get.translation(i) + "〗、";
}
str = str.slice(0, str.length - 1);
return "减1点体力上限然后" + (str.length ? "获得" + str : "听一句技能配音");
},
logTarget: "player",
content: function () {
"step 0";
player.loseMaxHp();
"step 1";
var skills = trigger.player.getSkills(null, false, false).filter(skill => {
if (player.hasSkill(skill, null, false, false)) return false;
var info = get.info(skill);
return info && !info.hiddenSkill && !info.zhuSkill && !info.charlotte;
});
if (skills.length) {
//for(var i of skills) player.addSkillLog(i);
player.addSkills(skills);
player.markAuto("twduoren", skills);
game.broadcastAll(function (list) {
game.expandSkills(list);
for (var i of list) {
var info = lib.skill[i];
if (!info) continue;
if (!info.audioname2) info.audioname2 = {};
info.audioname2.xia_xiahouzie = "twduoren";
}
}, skills);
}
},
subSkill: {
remove: {
trigger: { source: "dying" },
filter: function (event, player) {
return (
event.player != player &&
player.getStorage("twduoren").some(skill => {
return player.hasSkill(skill, null, false, false);
})
);
},
forced: true,
locked: false,
content: function () {
player.removeSkills(player.getStorage("twduoren"));
delete player.storage.twduoren;
},
},
},
},
//赵娥
twyanshi: {
audio: 2,
trigger: { global: "phaseBefore", player: "enterGame" },
forced: true,
locked: false,
direct: true,
onremove: true,
intro: {
content: "players",
},
filter: function (event, player) {
return game.hasPlayer(current => current != player) && (event.name != "phase" || game.phaseNumber == 0);
},
group: ["twyanshi_hurt", "twyanshi_damage"],
content: function () {
"step 0";
player.chooseTarget("言誓:选择一名其他角色", lib.filter.notMe, true).set("ai", target => get.attitude(_status.event.player, target));
"step 1";
if (result.bool) {
var target = result.targets[0];
player.logSkill("twyanshi", target);
player.markAuto("twyanshi", [target]);
}
},
mod: {
targetInRange: function (card, player, target) {
if (target.hasMark("twyanshi_mark")) return true;
},
},
subSkill: {
hurt: {
audio: "twyanshi",
trigger: {
global: "damageEnd",
},
forced: true,
locked: false,
filter: function (event, player) {
if (!event.source || !event.source.isIn()) return false;
return (player == event.player && !player.getStorage("twyanshi").includes(event.source)) || (player != event.source && player.getStorage("twyanshi").includes(event.player));
},
content: function () {
trigger.source.addMark("twyanshi_mark", 1);
},
},
damage: {
audio: "twyanshi",
trigger: {
source: ["damageBegin1", "damageSource"],
},
forced: true,
locked: false,
filter: function (event, player) {
return event.player.hasMark("twyanshi_mark");
},
content: function () {
"step 0";
if (event.triggername == "damageBegin1") {
trigger.num++;
} else {
player.draw(trigger.num);
trigger.player.removeMark("twyanshi_mark", trigger.player.countMark("twyanshi_mark"));
}
},
},
mark: {
marktext: "誓",
intro: {
name: "誓",
name2: "誓",
content: "mark",
},
},
},
},
twrenchou: {
audio: 2,
trigger: { global: "die" },
forced: true,
forceDie: true,
filter: function (event, player) {
if (!event.source || !event.source.isIn()) return false;
if (event.player == player) {
return player.getStorage("twyanshi").some(i => i.isIn() && i.hp > 0);
}
if (player.getStorage("twyanshi").includes(event.player)) {
return player.isIn() && player.hp > 0;
}
return false;
},
logTarget: "source",
line: false,
skillAnimation: true,
animationColor: "water",
global: "twrenchou_ai",
content: function () {
"step 0";
var avengers = [];
if (trigger.player == player) {
avengers = player.getStorage("twyanshi").filter(i => i.isIn() && i.hp > 0);
}
if (player.getStorage("twyanshi").includes(trigger.player)) {
avengers = [player];
}
event.avengers = avengers;
"step 1";
var avenger = event.avengers.shift();
avenger.line(trigger.source, "fire");
trigger.source.damage(avenger, avenger.hp);
"step 2";
if (event.avengers.length && trigger.source.isIn()) event.goto(1);
},
ai: {
combo: "twyanshi",
},
subSkill: {
ai: {
ai: {
effect: {
target: function (card, player, target) {
if (!get.tag(card, "damage")) return;
if (target.hp > 1) return;
var num = 0;
game.filterPlayer(current => {
if (current.getStorage("twyanshi").some(i => target == i)) {
num += current.hp;
}
});
var targets = target.getStorage("twyanshi").filter(i => i.isIn());
for (var targetx of targets) {
num += targetx.hp;
}
if (num >= player.hp) return 0;
if (num > 0) return [1, 0, 0, 0.5 - 1.5 * num];
},
},
},
},
},
},
//侠典韦
twliexi: {
audio: 2,
trigger: { player: "phaseZhunbeiBegin" },
filter: function (event, player) {
return player.countCards("he");
},
direct: true,
content: function () {
"step 0";
var list = [[], []];
for (var current of game.players) {
if (current == player) continue;
var cards = [];
var weapon = false;
for (var card of player.getCards("he")) {
if (!lib.filter.cardDiscardable(card, player)) continue;
if (get.subtype(card) == "equip1" && !ui.selected.cards.some(i => get.subtype(i) == "equip1")) {
if (16 - get.value(card) > 0) {
cards.push(card);
weapon = true;
}
}
if (7 - get.value(card) > 0) cards.push(card);
}
if (cards.length > current.hp) {
var val = 0;
for (var card of cards) {
if (get.subtype(card) != "equip1") val += get.value(card);
}
if (val < 30) list[0].push(current);
}
if ((weapon && player.hp > 2) || get.damageEffect(player, current, player) > 10) list[1].push(current);
}
list[0].sort((a, b) => {
return get.damageEffect(b, player, player) - get.damageEffect(a, player, player);
});
player.chooseCardTarget({
filterCard: lib.filter.cardDiscardable,
selectCard: [1, Infinity],
position: "he",
filterTarget: lib.filter.notMe,
prompt: get.prompt2("twliexi"),
targetsx: [list[0][0], list[1][0]],
ai1: function (card) {
var targetx = _status.event.targetsx[0];
var hasWeapon = ui.selected.cards.some(i => get.subtype(i) == "equip1");
if (!targetx) {
var targetx = _status.event.targetsx[1];
if (get.subtype(card) == "equip1" && !hasWeapon) return 30 - get.value(card);
return -get.value(card);
}
if (ui.selected.cards.length > targetx.hp) return 0;
if (get.subtype(card) == "equip1" && !hasWeapon) return 30 - get.value(card);
return 7 - get.value(card);
},
ai2: function (target) {
var targetx = _status.event.targetsx[0] || _status.event.targetsx[1];
if (targetx == target) return 10;
return 0;
},
});
"step 1";
if (result.bool) {
var target = result.targets[0];
event.target = target;
var cards = result.cards;
player.logSkill("twliexi", target);
player.discard(cards);
if (cards.length > target.hp) target.damage();
else player.damage(target);
var goon = false;
for (var card of cards) {
if (get.subtype(card) == "equip1") {
goon = true;
break;
}
}
if (!goon) event.finish();
} else event.finish();
"step 2";
game.delayx();
target.damage();
},
},
twshezhong: {
audio: 2,
trigger: { player: "phaseJieshuBegin" },
direct: true,
content: function () {
"step 0";
var damage = player.getHistory("sourceDamage").length;
if (damage) {
player.chooseTarget(get.prompt("twshezhong"), "令至多" + get.cnNumber(damage) + "名其他角色下个摸牌阶段的摸牌数-1", [1, damage], lib.filter.notMe).set("ai", target => {
return -get.attitude(_status.event.player, target);
});
} else event.goto(2);
"step 1";
if (result.bool) {
var targets = result.targets;
player.logSkill("twshezhong", targets);
for (var target of targets) {
target.addSkill("twshezhong_minus");
target.addMark("twshezhong_minus", 1, false);
}
}
"step 2";
var targets = [];
for (var evt of player.getHistory("damage")) {
if (evt.source && evt.source.isIn()) targets.add(evt.source);
}
if (targets.length) {
player
.chooseTarget(get.prompt("twshezhong"), "将手牌摸至一名与一名本回合对你造成过伤害的角色的体力值相同,且至多摸至五张", (card, player, target) => {
return _status.event.targets.includes(target);
})
.set("ai", target => {
return Math.max(0.1, target.hp - _status.event.player.countCards("h"));
})
.set("targets", targets);
} else event.finish();
"step 3";
if (result.bool) {
var target = result.targets[0];
player.logSkill("twshezhong", target);
var num = Math.min(target.hp, 5) - player.countCards("h");
if (num > 0) player.draw(num);
}
},
subSkill: {
minus: {
trigger: { player: "phaseDrawBegin" },
forced: true,
onremove: true,
content: function () {
var num = player.countMark("twshezhong_minus");
trigger.num -= num;
game.log(player, "的额定摸牌数", "#g-" + num);
player.removeSkill("twshezhong_minus");
},
mark: true,
intro: {
content: "额定摸牌数-#",
},
},
},
},
//侠鲁肃
twkaizeng: {
audio: 2,
global: "twkaizeng_want",
refuseInfo: ["不给", "拒绝"],
subSkill: {
want: {
audio: "twkaizeng",
forceaudio: true,
enable: "phaseUse",
usable: 1,
charlotte: true,
filter: function (event, player) {
return game.hasPlayer(current => {
return current != player && current.hasSkill("twkaizeng");
});
},
chooseButton: {
dialog: function (event, player) {
var targets = game.filterPlayer(current => {
return current != player && current.hasSkill("twkaizeng");
});
return ui.create.dialog("###慨赠###" + "选择一种基本牌的牌名或非基本牌的类型,然后令" + get.translation(targets) + (targets.length > 1 ? "中的一人" : "") + "选择是否交给你任意张牌");
},
chooseControl: function () {
var list = [];
var basic = [];
for (var i = 0; i < lib.inpile.length; i++) {
var name = lib.inpile[i];
var type = get.type(name, "trick");
if (type == "basic") {
list.push(name);
basic.push(name);
} else list.add(type);
}
list.push("cancel2");
return list;
},
check: function (event, player) {
if (Math.random() < 0.4) {
var list = _status.event.controls.slice();
list.remove("du");
return list.randomGet();
}
var targets = game.filterPlayer(current => current != player && current.hasSkill("twkaizeng"));
targets.sort((a, b) => get.attitude(player, b) - get.attitude(player, a));
var cards = targets[0].getCards("h");
var list = [];
for (var card of cards) {
var type = get.type2(card);
if (type == "basic") list.add(get.name(card));
else list.add(type);
}
var need = ["trick", "equip"].randomSort();
need.addArray(["sha", "jiu"].randomSort());
for (var type of need) {
if (list.includes(type)) return type;
}
return list.randomGet();
},
backup: function (result, player) {
return {
audio: "twkaizeng",
type: result.control,
log: false,
delay: false,
filterTarget: function (card, player, target) {
return target.hasSkill("twkaizeng");
},
selectTarget: function () {
var player = _status.event.player;
var targets = game.filterPlayer(function (current) {
return current != player && current.hasSkill("twkaizeng");
});
return targets.length > 1 ? 1 : -1;
},
prepare: function (cards, player, targets) {
targets[0].logSkill("twkaizeng_want", player);
},
content: function () {
"step 0";
var type = lib.skill.twkaizeng_want_backup.type;
var isbasic = lib.card[type];
target
.chooseCard("慨赠:是否交给" + get.translation(player) + "任意张手牌?", "若你以此法:交给其至少两张牌,你摸一张牌;交给其的牌包含其选择的牌名或类型,你获得一张不为此牌名或类型的牌", [1, Infinity])
.set("ai", card => {
if (!_status.event.goon) return -get.value(card);
var player = _status.event.player,
target = _status.event.getParent().player;
if (ui.selected.cards.length > player.countCards("h") / 2 && ui.selected.cards.length >= 2) return 0;
var type = _status.event.type;
var isbasic = lib.card[type];
var add = 0;
if (!ui.selected.cards.some(i => get[isbasic ? "name" : "type2"](i, target) == type)) add += 3;
if (ui.selected.cards.length < 2) add += 3;
return get.value(card, target) - get.value(card, player) + add;
})
.set("type", type)
.set("goon", get.attitude(target, player) > 0);
"step 1";
if (result.bool) {
var cards = result.cards;
event.cards = cards;
target.give(cards, player);
} else {
var refuseInfo = lib.skill.twkaizeng.refuseInfo.slice();
if (get.attitude(target, player) < 0) refuseInfo.push("没门");
target.chat(refuseInfo.randomGet());
event.finish();
}
"step 2";
if (cards.length > 1) target.draw();
"step 3";
var type = lib.skill.twkaizeng_want_backup.type;
var isbasic = lib.card[type];
var fn = isbasic ? "name" : "type2";
if (cards.some(card => get[fn](card, player) == type)) {
var card = get.cardPile(cardx => {
return get[fn](cardx, target) != type;
});
if (card) target.gain(card, "gain2");
}
"step 4";
game.delayx();
},
ai: {
result: {
target: 1,
},
},
};
},
prompt: () => "请选择一名有【慨赠】的角色",
},
ai: {
order: 10,
result: {
player: function (player) {
var targets = game.filterPlayer(current => {
return current != player && current.hasSkill("twkaizeng");
});
for (var i of targets) if (get.attitude(player, i) > 0) return 1;
return 0;
},
},
},
},
want_backup: {},
},
ai: {
threaten: 3,
},
},
twyangming: {
audio: 2,
trigger: {
player: "phaseUseEnd",
},
frequent: true,
filter: function (event, player) {
return player.hasHistory("useCard", evt => evt.getParent("phaseUse") == event);
},
content: function () {
var types = [];
var history = player.getHistory("useCard", evt => evt.getParent("phaseUse") == trigger);
for (var evt of history) {
types.add(get.type2(evt.card));
}
var num = types.length;
player.draw(num);
player.addTempSkill("twyangming_limit");
player.addMark("twyangming_limit", num, false);
game.log(player, "本回合的手牌上限", "#g+" + num);
},
subSkill: {
limit: {
charlotte: true,
onremove: true,
mod: {
maxHandcard: function (player, num) {
return num + player.countMark("twyangming_limit");
},
},
},
},
},
//邴原
twbingde: {
audio: 2,
enable: "phaseUse",
usable: 1,
filter: function (event, player) {
return player.countCards("he") && player.getStorage("twbingde_clear").length < 4;
},
onChooseToUse: function (event) {
if (event.type == "phase" && !game.online) {
var map = {};
event.player.getHistory("useCard", evt => {
var evtx = evt.getParent("phaseUse"),
suit = get.suit(evt.card);
if (!lib.suit.includes(suit)) return;
if (evtx != event.getParent("phaseUse")) return;
if (typeof map[suit] != "number") map[suit] = 0;
map[suit]++;
});
event.set("twbingde_map", map);
}
},
chooseButton: {
dialog: function (event, player) {
var str = get.translation("twbingde_info"),
str2 = "";
if (event.twbingde_map) {
str2 = '<div class="text center">本回合使用牌对应花色数:</div>';
str2 += '<div class="text center">';
for (var suit of lib.suit) {
str2 += get.translation(suit) + "" + get.cnNumber(event.twbingde_map[suit] || 0) + "张;";
}
str2 = str2.slice(0, str2.length - 1) + "</div>";
}
return ui.create.dialog("###秉德###" + str, str2);
},
chooseControl: function (event, player) {
var list = lib.suit.slice();
list.removeArray(player.getStorage("twbingde_clear"));
list.push("cancel2");
return list;
},
check: function (event, player) {
var map = event.twbingde_map;
var suit = lib.suit
.filter(i => !player.getStorage("twbingde_clear").includes(i))
.sort((a, b) => {
return map[b] - map[a];
})[0];
if (map[suit] == 0) return "cancel2";
return suit;
},
backup: function (result, player) {
return {
audio: "twbingde",
filterCard: true,
selectCard: 1,
position: "he",
suit: result.control,
check: function (card) {
var suit = lib.skill.twbingde.suit;
if (get.suit(card) == suit) return 10 - get.value(card);
return 6 - get.value(card);
},
content: function () {
"step 0";
var suit = lib.skill.twbingde_backup.suit,
num = 0;
player.popup(suit + 2);
game.log(player, "选择了", "#y" + suit + 2);
player.addTempSkill("twbingde_clear", "phaseUseAfter");
player.markAuto("twbingde_clear", [suit]);
player.getHistory("useCard", evt => {
var evtx = evt.getParent("phaseUse"),
suitx = get.suit(evt.card);
if (!evtx || evtx != event.getParent("phaseUse") || suit != suitx) return false;
num++;
});
if (num > 0) player.draw(num);
"step 1";
if (get.suit(cards[0], player) == lib.skill.twbingde_backup.suit) {
delete player.getStat("skill").twbingde;
}
},
ai: {
result: {
player: 1,
},
},
};
},
prompt: () => "秉德:弃置一张牌",
},
ai: {
order: 2,
result: { player: 1 },
},
subSkill: {
backup: {},
clear: {
charlotte: true,
onremove: true,
},
},
},
twqingtao: {
audio: 2,
trigger: { player: "phaseDrawEnd" },
filter: function (event, player) {
return player.countCards("he");
},
direct: true,
group: "twqingtao_jieshu",
content: function () {
"step 0";
player.chooseCard(get.prompt2("twqingtao"), "he", lib.filter.cardRecastable).set("ai", function (card) {
if (card.name == "jiu" || get.type(card) != "basic") return 10 - get.value(card);
return 6 - get.value(card);
});
"step 1";
if (result.bool) {
player.logSkill("twqingtao");
player.recast(result.cards);
if (get.name(result.cards[0]) == "jiu" || get.type(result.cards[0], false, player) != "basic") player.draw();
}
},
subSkill: {
jieshu: {
audio: "twqingtao",
trigger: { player: "phaseJieshuBegin" },
filter: function (event, player) {
return player.countCards("he") > 0 && !player.hasHistory("useSkill", evt => evt.skill == "twqingtao");
},
direct: true,
content: function () {
var next = game.createEvent("twqingtao");
next.player = player;
next.setContent(lib.skill.twqingtao.content);
},
},
},
},
//牛董
twjuntun: {
audio: 2,
trigger: {
global: ["phaseBefore", "dieAfter"],
player: "enterGame",
},
init: function (player) {
lib.skill.baonvezhi.change(player, 0);
},
direct: true,
derivation: ["twxiongjun", "baonvezhi_faq"],
group: "twjuntun_extra",
filter: function (event, player) {
return (
(event.name != "phase" || game.phaseNumber == 0) &&
game.hasPlayer(current => {
return !current.hasSkill("twxiongjun");
})
);
},
content: function () {
"step 0";
player
.chooseTarget(get.prompt("twjuntun"), "令一名角色获得〖凶军〗", (card, player, target) => {
return !target.hasSkill("twxiongjun");
})
.set("ai", target => get.attitude(player, target) - 2);
"step 1";
if (result.bool) {
var target = result.targets[0];
player.logSkill("twjuntun", target);
target.addSkills("twxiongjun");
if (target != player) player.addExpose(0.25);
}
},
subSkill: {
extra: {
audio: 2,
trigger: { global: "damageSource" },
forced: true,
locked: false,
filter: function (event, player) {
return event.source && event.source.hasSkill("twxiongjun") && event.source != player;
},
logTarget: "source",
content: function () {
lib.skill.baonvezhi.change(player, trigger.num);
},
},
},
},
baonvezhi: {
audio: 2,
trigger: {
player: "damageEnd",
source: "damageSource",
},
silent: true,
forced: true,
charlotte: true,
baonvezhi_max: 5,
change: function (player, num) {
var baonvezhi_max = lib.skill.baonvezhi.baonvezhi_max;
player.addSkill("baonvezhi");
var tmp = player.countMark("baonvezhi");
if (tmp + num > baonvezhi_max) num = baonvezhi_max - tmp;
else if (tmp + num < 0) num = -tmp;
if (num === 0) return;
player[num > 0 ? "addMark" : "removeMark"]("baonvezhi", Math.abs(num), false);
game.log(player, num >= 0 ? "获得了" : "失去了", get.cnNumber(Math.abs(num)) + '点<span class="firetext">暴虐值</span>');
player[player.countMark("baonvezhi") > 0 ? "markSkill" : "unmarkSkill"]("baonvezhi");
},
filter: function (event, player) {
return player.countMark("baonvezhi") < lib.skill.baonvezhi.baonvezhi_max;
},
content: function () {
lib.skill.baonvezhi.change(player, trigger.num);
},
marktext: "暴",
intro: {
name: "暴虐值",
content: function (storage, player) {
return get.translation(player) + "的暴虐值为" + (player.storage.baonvezhi || 0);
},
},
},
baonvezhi_faq: {},
twxiongjun: {
init: function (player) {
lib.skill.baonvezhi.change(player, 0);
},
trigger: { source: "damageSource" },
forced: true,
usable: 1,
content: function () {
var targets = game.filterPlayer(current => current.hasSkill("twxiongjun")).sortBySeat();
player.line(targets, "green");
game.asyncDraw(targets);
},
},
twxiongxi: {
audio: 2,
enable: "phaseUse",
usable: 1,
init: function (player) {
lib.skill.baonvezhi.change(player, 0);
},
filterCard: () => true,
selectCard: function () {
return (lib.skill.baonvezhi.baonvezhi_max || 5) - _status.event.player.countMark("baonvezhi");
},
check: function (card) {
return 6 - get.value(card);
},
position: "he",
filterTarget: function (card, player, target) {
return target != player;
},
content: function () {
target.damage();
},
ai: {
expose: 0.25,
order: 8,
result: {
target: function (player, target) {
return get.damageEffect(target, player, player);
},
},
},
},
twxiafeng: {
audio: 2,
trigger: { player: "phaseUseBegin" },
filter: function (event, player) {
return player.countMark("baonvezhi") > 0;
},
init: function (player) {
lib.skill.baonvezhi.change(player, 0);
},
direct: true,
content: function () {
"step 0";
player
.chooseButton(["黠凤:选择要消耗的暴虐值", [["tw_bn_1", "tw_bn_2", "tw_bn_3"], "vcard"]], button => {
var num = player.countCards("hs", card => get.tag(card, "damage") && game.hasPlayer(current => get.effect(current, card, player, player) > 0));
if (num <= 0) return 0;
if (num >= 3) num = 3;
if (button.link[2] == "tw_bn_" + num) return 10;
return 1;
})
.set("filterButton", button => {
var player = _status.event.player;
var link = button.link[2];
if (link[link.length - 1] * 1 > player.storage.baonvezhi) return false;
return true;
});
"step 1";
if (result.bool) {
player.logSkill("twxiafeng");
var link = result.links[0][2],
num = link[link.length - 1] * 1;
player.addTempSkill("twxiafeng_effect");
player.storage.twxiafeng_effect = num;
lib.skill.baonvezhi.change(player, -num);
}
},
subSkill: {
effect: {
trigger: { player: "useCard" },
filter: function (event, player) {
return !player.storage.twxiafeng_effect2;
},
forced: true,
content: function () {
var count = player.getHistory("useCard", evt => evt.getParent("phaseUse").player == player).length;
if (count == player.storage.twxiafeng_effect) {
player.storage.twxiafeng_effect2 = true;
}
if (count <= player.storage.twxiafeng_effect) {
trigger.directHit.addArray(game.players);
if (trigger.addCount !== false) {
trigger.addCount = false;
var stat = player.getStat().card,
name = trigger.card.name;
if (typeof stat[name] == "number") stat[name]--;
}
}
},
onremove: function (player) {
delete player.storage.twxiafeng_effect;
delete player.storage.twxiafeng_effect2;
},
mod: {
targetInRange: function (card, player, target, now) {
if (!player.storage.twxiafeng_effect2) return true;
},
cardUsableTarget: function (card, player, target) {
if (!player.storage.twxiafeng_effect2) return true;
},
maxHandcard: function (player, num) {
return num + (player.storage.twxiafeng_effect || 0);
},
},
},
},
},
//蒋济
twjichou: {
audio: 2,
enable: "chooseToUse",
group: ["twjichou_ban", "twjichou_give"],
filter: function (event, player) {
if (player.hasSkill("twjichou_used") && player.hasSkill("twjichou_given")) return false;
if (!player.hasSkill("twjichou_used")) {
var record = player.getStorage("twjichou");
for (var i of lib.inpile) {
var type = get.type(i);
if (type == "trick" && !record.includes(i) && event.filterCard({ name: i, isCard: true }, player, event)) return true;
}
}
return false;
},
chooseButton: {
dialog: function (event, player) {
var dialog = ui.create.dialog("急筹");
if (
!player.hasSkill("twjichou_used") &&
!player.hasSkill("twjichou_given") &&
event.type == "phase" &&
player.countCards("h", card => {
return player.getStorage("twjichou").includes(get.name(card));
})
) {
dialog._chosenOpt = [];
var table = document.createElement("div");
table.classList.add("add-setting");
table.style.margin = "0";
table.style.width = "100%";
table.style.position = "relative";
var list = ["视为使用牌", "交出锦囊牌"];
for (var i of list) {
var td = ui.create.div(".shadowed.reduce_radius.pointerdiv.tdnode");
td.innerHTML = "<span>" + i + "</span>";
td.link = i;
if (i == list[0]) {
td.classList.add("bluebg");
dialog._chosenOpt.add(td);
}
td.addEventListener(lib.config.touchscreen ? "touchend" : "click", function () {
if (_status.dragged) return;
if (_status.clicked) return;
if (_status.justdragged) return;
_status.tempNoButton = true;
_status.clicked = true;
setTimeout(function () {
_status.tempNoButton = false;
}, 500);
var link = this.link;
if (link == "交出锦囊牌") game.uncheck();
var current = this.parentNode.querySelector(".bluebg");
if (current) {
current.classList.remove("bluebg");
dialog._chosenOpt.remove(current);
}
dialog._chosenOpt.add(this);
this.classList.add("bluebg");
game.check();
});
table.appendChild(td);
dialog.buttons.add(td);
}
dialog.content.appendChild(table);
}
var list = [],
record = player.getStorage("twjichou");
for (var name of lib.inpile) {
if (get.type(name) == "trick" && !record.includes(name) && event.filterCard({ name: name, isCard: true }, player, event)) list.push(["锦囊", "", name]);
}
dialog.add([list, "vcard"]);
return dialog;
},
filter: function (button) {
if (_status.event.dialog) {
var opts = _status.event.dialog._chosenOpt;
if (opts && opts.length && opts[0].link == "交出锦囊牌" && typeof button.link != typeof opts[0].link) {
return false;
}
return true;
}
return false;
},
select: function () {
if (_status.event.dialog) {
var opts = _status.event.dialog._chosenOpt;
return opts && opts.length && opts[0].link == "交出锦囊牌" ? 0 : 1;
}
return 0;
},
check: function (button) {
if (_status.event.getParent().type != "phase") return 1;
var player = _status.event.player;
if (["wugu", "zhulu_card", "yiyi", "lulitongxin", "lianjunshengyan", "diaohulishan"].includes(button.link[2])) return 0.1;
return player.getUseValue({ name: button.link[2] });
},
backup: function (links, player) {
var isUse = links.length == 1;
var backup = get.copy(lib.skill["twjichou_" + (isUse ? "use" : "give")]);
if (isUse) backup.viewAs = { name: links[0][2], isCard: true };
return backup;
},
prompt: function (links, player) {
var isUse = links.length == 1;
return "急筹:" + (isUse ? "视为使用" + get.translation(links[0][2]) + "" : "选择要交出的牌和要交给的目标");
},
},
hiddenCard: function (player, name) {
if (player.hasSkill("twjichou_used")) return false;
var type = get.type(name);
return type == "trick" && !player.getStorage("twjichou").includes(name);
},
marktext: "筹",
intro: {
markcount: function (storage, player) {
if (storage && storage.length) return storage.length;
return 0;
},
content: "已记录牌名:$",
},
ai: {
order: 1,
result: {
player: function (player) {
if (_status.event.dying) return get.attitude(player, _status.event.dying);
return 1;
},
},
},
subSkill: {
backup: {},
used: { charlotte: true },
given: { charlotte: true },
ban: {
trigger: { global: "useCard1" },
filter: function (event, player) {
return player.getStorage("twjichou").includes(event.card.name);
},
forced: true,
locked: false,
silent: true,
content: function () {
trigger.directHit.add(player);
},
mod: {
cardEnabled: function (card, player) {
if (player.getStorage("twjichou").includes(card.name) && (get.position(card) == "h" || (card.cards && card.cards.some(i => get.position(i) == "h")))) return false;
},
cardSavable: function (card, player) {
if (player.getStorage("twjichou").includes(card.name) && (get.position(card) == "h" || (card.cards && card.cards.some(i => get.position(i) == "h")))) return false;
},
aiValue: function (player, card) {
if (get.type(card) != "trick" || _status.twjichou_give_aiCheck) return;
if (!player.getFriends().length && player.getStorage("twjichou").includes(get.name(card))) return 0;
},
aiUseful: function () {
return lib.skill.twjichou_ban.mod.aiValue.apply(this, arguments);
},
},
},
use: {
filterCard: () => false,
selectCard: -1,
audio: "twjichou",
popname: true,
onuse: function (links, player) {
player.markAuto("twjichou", [links.card.name]);
player.syncStorage("twjichou");
player.addTempSkill("twjichou_used");
},
},
give: {
audio: "twjichou",
enable: "phaseUse",
filter: function (event, player) {
return player.hasSkill("twjichou_used") && !player.hasSkill("twjichou_given") && player.countCards("h", i => player.getStorage("twjichou").includes(get.name(i)));
},
filterTarget: function (card, player, target) {
return target != player;
},
filterCard: function (card, player) {
return player.getStorage("twjichou").includes(get.name(card));
},
check: function (card) {
_status.twjichou_give_aiCheck = true;
var val = get.value(card);
delete _status.twjichou_give_aiCheck;
return val;
},
prompt: () => "选择要交出的牌和要交给的目标",
selectCard: [1, Infinity],
discard: false,
lose: false,
delay: false,
content: function () {
player.give(cards, target);
player.addTempSkill("twjichou_given", "phaseUseAfter");
},
ai: {
order: 0.9,
result: {
target: function (player, target) {
if (target.hasSkillTag("nogain")) return 0;
if (target.hasJudge("lebu")) return 0;
return target.getCards("h", card => player.getStorage("twjichou").includes(get.name(card))).reduce((p, c) => p + (target.getUseValue(c) || 1), 0);
},
},
},
},
},
},
twjilun: {
audio: 2,
trigger: { player: "damageEnd" },
direct: true,
content: function () {
"step 0";
var num = Math.min(Math.max(1, player.getStorage("twjichou").length), 5);
event.num = num;
var choices = ["选项一"];
var choiceList = ["摸" + get.cnNumber(num) + "张牌", "视为使用一张在〖急筹〗记录内且不在〖机论〗记录内的普通锦囊牌"];
if (
!player.getStorage("twjichou").length ||
player.getStorage("twjichou").filter(name => {
return !player.getStorage("twjilun").includes(name) && player.hasUseTarget({ name: name });
}).length == 0
)
choiceList[1] = '<span style="opacity:0.5">' + choiceList[1] + "</span>";
else choices.push("选项二");
player
.chooseControl(choices, "cancel2")
.set("choiceList", choiceList)
.set("prompt", get.prompt("twjilun"))
.set("ai", () => {
if (_status.event.choiceList.length == 1 || !player.getStorage("twjichou").length) return 0;
var val = _status.event.num > 3 ? Math.min(1.5, 1 + (_status.event.num - 3) * 0.1) : 1;
for (var name of player.getStorage("twjichou")) {
if (player.getStorage("twjilun").includes(name)) continue;
if (player.getUseValue({ name: name }) > 4 * val) return 1;
}
return 0;
})
.set("num", num);
"step 1";
if (result.control != "cancel2") {
if (result.control == "选项一") {
player.logSkill("twjilun");
player.draw(num);
event.finish();
} else {
var list = [];
for (var name of player.getStorage("twjichou")) {
if (!player.getStorage("twjilun").includes(name)) {
list.push(["锦囊", "", name]);
}
}
player
.chooseButton(['###机论###<div class="text center">是否视为使用一张〖急筹〗已记录的普通锦囊牌?</div>', [list, "vcard"]])
.set("filterButton", button => {
return _status.event.player.hasUseTarget({ name: button.link[2] });
})
.set("ai", button => {
return _status.event.getParent().player.getUseValue({ name: button.link[2] }, null, true);
});
}
} else event.finish();
"step 2";
if (result.bool) {
var card = { name: result.links[0][2], isCard: true };
player.chooseUseTarget(card, true).set("logSkill", "twjilun");
player.markAuto("twjilun", [card.name]);
player.syncStorage("twjilun");
} else event.goto(0);
},
marktext: "论",
intro: {
markcount: function (storage, player) {
if (storage && storage.length) return storage.length;
return 0;
},
content: "已记录牌名:$",
},
ai: {
maixie: true,
maixie_defend: true,
threaten: 0.7,
},
},
//蹇硕
twkunsi: {
audio: 2,
enable: "phaseUse",
onremove: true,
derivation: "twlinglu",
filter: function (event, player) {
return game.hasPlayer(function (current) {
return player.canUse({ name: "sha", isCard: true }, current, false) && current != player && !player.getStorage("twkunsi").includes(current);
});
},
filterTarget: function (card, player, target) {
return player.canUse({ name: "sha", isCard: true }, target, false) && target != player && !player.getStorage("twkunsi").includes(target);
},
content: function () {
"step 0";
player.markAuto("twkunsi", [target]);
player.storage.twkunsi.sortBySeat();
player.markSkill("twkunsi");
player.useCard({ name: "sha", isCard: true }, target, false).animate = false;
"step 1";
if (
!player.hasHistory("sourceDamage", function (evt) {
var card = evt.card;
if (!card || card.name != "sha") return false;
var evtx = evt.getParent("useCard");
return evtx.card == card && evtx.getParent() == event;
})
) {
player.line(target);
target.markAuto("twlinglu", [player]);
target.addAdditionalSkills("twkunsi_temp", "twlinglu");
player.markAuto("twkunsi_clear", [target]);
player.addTempSkill("twkunsi_clear", { player: "phaseBegin" });
}
},
intro: { content: "已对$发动过〖困兕〗" },
ai: {
order: function () {
return get.order({ name: "sha" }) - 0.1;
},
expose: 0.2,
result: {
target: function (player, target) {
if (
target.countCards("h") <= target.hp &&
!target.mayHaveShan(
player,
"use",
target.getCards("h", i => {
return i.hasGaintag("sha_notshan");
})
) &&
get.effect(target, { name: "sha", isCard: true }, player, player) > 0
)
return -1;
else if (target.countCards("h") > target.hp && target.hp > 2 && target.hasShan()) return 1;
return 0;
},
},
},
subSkill: {
clear: {
forced: true,
onremove: function (player, skill) {
var targets = player.getStorage(skill);
for (var target of targets) {
if (target.isIn()) {
target.removeAdditionalSkill("twkunsi_temp");
}
}
},
},
},
},
twlinglu: {
audio: 2,
trigger: { player: "phaseUseBegin" },
filter: function (event, player) {
return game.hasPlayer(function (current) {
return current != player;
});
},
direct: true,
content: function () {
"step 0";
player
.chooseTarget(get.prompt2("twlinglu"), function (card, player, target) {
return target != player;
})
.set("ai", function (target) {
var player = _status.event.player,
att = get.attitude(player, target);
if (target.countCards("hs") > 4 && target.hp >= 3) return att;
if (player.getStorage("twlinglu").includes(target)) return -2 * att;
return -att;
});
"step 1";
if (result.bool) {
var target = result.targets[0];
event.target = target;
player.logSkill("twlinglu", target);
target.addTempSkill("twlinglu_order", { player: "phaseAfter" });
if (!target.storage.twlinglu_settle) target.storage.twlinglu_settle = [];
target.storage.twlinglu_settle.unshift([player, 1]);
if (player.getStorage("twlinglu").includes(target))
player.chooseBool("是否令" + get.translation(target) + "于〖令戮〗失败时进行两次结算?").set("ai", function () {
return true;
});
else event.finish();
} else event.finish();
"step 2";
if (result.bool) {
target.storage.twlinglu_settle[0][1]++;
game.log(target, "于本次强令失败时进行两次结算");
}
},
ai: { expose: 0.2 },
subSkill: {
order: {
audio: 2,
trigger: { source: "damageSource" },
group: "twlinglu_settle",
silent: true,
charlotte: true,
onremove: true,
mark: true,
marktext: "令",
intro: {
content: function (storage, player) {
return "<li>任务目标于你下回合结束前造成的伤害不小于2点<br><li>已造成" + player.countMark("twlinglu_order") + "点伤害";
},
},
content: function () {
player.addMark("twlinglu_order", trigger.num, false);
},
},
settle: {
audio: "twlinglu_order",
trigger: { player: "phaseEnd" },
charlotte: true,
silent: true,
onremove: true,
filter: function (event, player) {
return player.getStorage("twlinglu_settle").length > 0;
},
content: function () {
"step 0";
var list = player.getStorage("twlinglu_settle").shift();
var target = list[0],
count = list[1] || 1;
event.target = target;
event.count = count;
"step 1";
if (player.countMark("twlinglu_order") >= 2) {
game.log(player, "成功完成了", target, "发布的", "#g【令戮】", "强令");
player.popup("强令成功", "wood");
player.draw(2);
event.finish();
} else {
game.log(player, "未完成", target, "发布的", "#g【令戮】", "强令");
player.popup("强令失败", "fire");
}
"step 2";
if (player.countMark("twlinglu_order") >= 2) {
game.delayx();
} else {
event.count--;
player.loseHp();
}
"step 3";
if (event.count > 0) event.goto(2);
"step 4";
if (player.getStorage("twlinglu_settle").length > 0) {
event.goto(0);
game.delayx();
}
},
},
},
},
//马腾
twxiongzheng: {
audio: 2,
onremove: true,
trigger: { global: "roundStart" },
direct: true,
content: function () {
"step 0";
var target = player.storage.twxiongzheng_target;
delete player.storage.twxiongzheng_target;
if (!target) {
event.goto(4);
return;
}
event.target = target;
var list = [],
list2 = [];
var history = target.actionHistory;
if (history.length < 2) {
event.goto(4);
return;
}
for (var i = history.length - 2; i >= 0; i--) {
for (var evt of history[i].damage) {
if (evt.source) list.add(evt.source);
}
if (history[i].isRound) break;
}
var list2 = game.filterPlayer(i => i != player).removeArray(list);
event.list = list;
event.list2 = list2;
var choiceList = ["视为对任意名上一轮未对" + get.translation(target) + "造成过伤害的角色使用一张【杀】", "令任意名上一轮对" + get.translation(target) + "造成过伤害的角色摸两张牌"];
var choices = [];
if (list2.length) {
choices.push("选项一");
choiceList[0] += "" + get.translation(list2) + "";
} else choiceList[0] = '<span style="opacity:0.5">' + choiceList[0] + "</span>";
if (list.length) {
choices.push("选项二");
choiceList[1] += "" + get.translation(list) + "";
} else choiceList[1] = '<span style="opacity:0.5">' + choiceList[1] + "</span>";
choices.push("cancel2");
player
.chooseControl(choices)
.set("prompt", "雄争:是否选择一项?")
.set("choiceList", choiceList)
.set("ai", function () {
var player = _status.event.player;
var list = _status.event.getParent().list,
list2 = _status.event.getParent().list2;
var eff = list
.map(target => {
if (target == player) return 0;
return get.effect(target, { name: "sha" }, player, player);
})
.reduce((p, c) => p + c, 0),
eff2 = list2.map(target => 2 * get.effect(target, { name: "draw" }, player, player)).reduce((p, c) => p + c, 0);
if (_status.event.controls.includes("选项二") && eff2 > eff) return "选项二";
if (eff > 0) return 0;
return "cancel2";
});
"step 1";
if (result.control == "选项一") {
event.bool = true;
if (event.list2.length)
player
.chooseTarget("雄争:请选择任意名满足条件的角色,你视为依次对这些角色使用一张杀", [1, Infinity], true, function (card, player, target) {
return player.canUse("sha", target, false, false) && _status.event.getParent().list2.includes(target);
})
.set("ai", function (target) {
var player = _status.event.player;
return get.effect(target, { name: "sha" }, player, player);
});
else event.finish();
} else if (result.control == "选项二") {
event.bool = false;
if (event.list.length)
player
.chooseTarget("雄争:请选择任意名满足条件的角色,这些角色摸两张牌", [1, Infinity], true, function (card, player, target) {
return _status.event.getParent().list.includes(target);
})
.set("ai", function (target) {
var player = _status.event.player;
return get.effect(target, { name: "draw" }, player, player);
});
else event.finish();
} else event.goto(3);
"step 2";
result.targets.sortBySeat();
player.logSkill("twxiongzheng", result.targets);
if (event.bool) {
for (var i of result.targets) player.useCard({ name: "sha", isCard: true }, i, false);
} else game.asyncDraw(result.targets, 2);
"step 3";
if (
!game.hasPlayer(function (current) {
return !player.getStorage("twxiongzheng").includes(current);
})
)
event.finish();
else game.delayx();
"step 4";
player
.chooseTarget(get.prompt("twxiongzheng"), "选择一名未选择过的角色,称为“雄争”角色", function (card, player, target) {
return !player.getStorage("twxiongzheng").includes(target);
})
.set("ai", function (target) {
var player = _status.event.player,
att = get.attitude(player, target);
if (game.roundNumber <= 1 && player.hasUnknown()) return 0;
return -att;
});
"step 5";
if (result.bool) {
var target = result.targets[0];
player.logSkill("twxiongzheng", target);
player.markAuto("twxiongzheng", [target]);
player.storage.twxiongzheng_target = target;
player.addTempSkill("twxiongzheng_mark", "roundStart");
target.addTempSkill("twxiongzheng_threaten", "roundStart");
game.delayx();
}
},
subSkill: {
mark: {
intro: {
content: "$参与了〖雄争〗的争斗",
onunmark: true,
},
charlotte: true,
onremove: true,
trigger: { global: "damage" },
firstDo: true,
direct: true,
filter: function (event, player) {
return event.player == player.storage.twxiongzheng_target && get.itemtype(event.source) == "player";
},
content: function () {
player.markAuto("twxiongzheng_mark", [trigger.source]);
},
},
threaten: {
mark: true,
intro: { content: "本轮〖雄争〗目标" },
ai: { threaten: 10 },
},
},
},
twluannian: {
audio: 2,
global: "twluannian_global",
unique: true,
zhuSkill: true,
subSkill: {
global: {
audio: "twluannian",
enable: "phaseUse",
usable: 1,
forceaudio: true,
onChooseToUse: function (event) {
if (!game.online) {
var num = 1;
game.countPlayer2(current => {
var history = current.actionHistory;
for (var i = history.length - 1; i >= 0; i--) {
for (var evt of history[i].useSkill) {
if (evt.skill == "twluannian_global") num++;
}
if (history[i].isRound) break;
}
});
event.set("twluannian_num", num);
}
},
filter: function (event, player) {
if (!event.twluannian_num) return false;
return (
player.group == "qun" &&
player.countCards("he") >= event.twluannian_num &&
game.hasPlayer(function (current) {
var target = current.storage.twxiongzheng_target;
return target && target.isIn() && current != player && current.hasZhuSkill("twluannian", player);
})
);
},
filterCard: true,
position: "he",
prompt: function () {
var player = _status.event.player;
var num = _status.event.twluannian_num;
var list = game
.filterPlayer(function (current) {
return current.hasZhuSkill("twluannian", player);
})
.map(i => i.storage.twxiongzheng_target)
.sortBySeat();
return "弃置" + get.cnNumber(num) + "张牌,对" + get.translation(list) + (list.length > 1 ? "中的一人" : "") + "造成1点伤害";
},
selectCard: function () {
return _status.event.twluannian_num;
},
complexSelect: true,
complexCard: true,
filterTarget: function (card, player, target) {
return game
.filterPlayer(function (current) {
return current.hasZhuSkill("twluannian", player);
})
.map(i => i.storage.twxiongzheng_target)
.includes(target);
},
selectTarget: function () {
return game
.filterPlayer(function (current) {
return current.hasZhuSkill("twluannian", _status.event.player);
})
.map(i => i.storage.twxiongzheng_target)
.filter(i => i && i.isIn()).length > 1
? 1
: -1;
},
check: function (card) {
return 6 - get.value(card);
},
content: function () {
target.damage();
},
ai: {
order: 7,
result: {
target: function (player, target) {
return get.damageEffect(target, player, target);
},
},
expose: 0.25,
},
},
},
ai: {
combo: "twxiongzheng",
},
},
//鲍信
twmutao: {
audio: 2,
enable: "phaseUse",
usable: 1,
filterTarget: function (card, player, target) {
return target.countCards("h");
},
content: function () {
"step 0";
event.togive = target.getNext();
var cards = target.getCards("h", { name: "sha" });
if (!cards.length) {
game.log("但", target, "没有", "#y杀", "");
event.finish();
}
"step 1";
var cards = target.getCards("h", { name: "sha" }),
card = cards.randomRemove(1)[0];
target.give(card, event.togive);
if (cards.length) {
event.togive = event.togive.getNext();
event.redo();
}
"step 2";
target.line(event.togive);
event.togive.damage(Math.min(2, event.togive.countCards("h", { name: "sha" })), target);
},
ai: {
order: 10,
result: {
target: function (player, target) {
var num = 0,
numx = target.countCards("h", { name: "sha" }),
targetx = target;
for (var i = 0; i < numx; i++) {
targetx = targetx.next;
if (targetx == player) targetx = targetx.next;
}
var att1 = get.attitude(player, target),
att2 = get.attitude(player, targetx);
if (att1 > 0 && att2 < 0) num = 0.25;
if (att1 < 0 && att2 < 0) num = 4;
return att1 * num * numx * (targetx.countCards("h", { name: "sha" }) + 1);
},
},
},
},
twyimou: {
audio: 2,
trigger: { global: "damageEnd" },
filter: function (event, player) {
return event.player.isIn() && get.distance(player, event.player) <= 1;
},
logTarget: "player",
check: function (event, player) {
return get.attitude(player, event.player) > 0;
},
content: function () {
"step 0";
if (trigger.player != player) player.addExpose(0.3);
var target = get.translation(trigger.player);
var choiceList = ["令" + target + "获得牌堆里的一张【杀】", "令" + target + "将一张牌交给另一名角色,然后" + target + "摸两张牌", "背水!" + (trigger.player != player ? "将所有手牌交给" + target + ",然后" : "") + "依次执行以上所有选项"];
var list = ["选项一"];
if (trigger.player.countCards("h")) list.push("选项二");
else choiceList[1] = '<span style="opacity:0.5">' + choiceList[1] + "</span>";
if (player.countCards("h")) list.push("背水!");
else choiceList[2] = '<span style="opacity:0.5">' + choiceList[2] + "</span>";
player
.chooseControl(list)
.set("prompt", "毅谋:请选择一项")
.set("choiceList", choiceList)
.set("ai", function () {
var evt = _status.event.getTrigger(),
list = _status.event.list;
var player = _status.event.player;
var target = evt.player;
if ((target.hp >= target.countCards("h") + 2 || target == player) && list.includes("背水!")) return "背水!";
if (target.countCards("h") && list.includes("选项二")) return "选项二";
return "选项一";
})
.set("list", list);
"step 1";
event.choice = result.control;
if (event.choice == "背水!" && player != trigger.player) player.give(player.getCards("h"), trigger.player);
"step 2";
if (event.choice != "选项二") {
var card = get.cardPile2(function (card) {
return card.name == "sha";
});
if (card) trigger.player.gain(card, "gain2");
else game.log("但牌堆里已经没有", "#y杀", "了!");
if (event.choice == "选项一") event.finish();
}
"step 3";
if (event.choice != "选项一") {
if (trigger.player.countCards("h"))
trigger.player.chooseCardTarget({
prompt: "将一张手牌交给另一名其他角色并摸两张牌",
filterCard: true,
forced: true,
filterTarget: lib.filter.notMe,
ai1: function (card) {
return 1 / Math.max(0.1, get.value(card));
},
ai2: function (target) {
var player = _status.event.player,
att = get.attitude(player, target);
if (target.hasSkillTag("nogain")) att /= 9;
return 4 + att;
},
});
else event.finish();
}
"step 4";
var target = result.targets[0];
trigger.player.line(target);
trigger.player.give(result.cards, target);
trigger.player.draw(2);
},
ai: {
threaten: 2.5,
},
},
//刘夫人
twzhuidu: {
audio: 2,
enable: "phaseUse",
usable: 1,
filter: function (event, player) {
return game.hasPlayer(function (current) {
return current != player && current.isDamaged();
});
},
filterTarget: function (card, player, target) {
if (player == target) return false;
return target.isDamaged();
},
chooseButton: {
dialog: function (event, player) {
var name = get.translation(event.result.targets[0]);
var dialog = ui.create.dialog("追妒:选择一项", "hidden");
dialog.add([
[
["damage", "对" + name + "造成1点伤害"],
["discard", "弃置" + name + "装备区里的一张牌"],
["both", "背水!若该角色为女性,弃置一张牌,然后依次执行以上所有选项"],
],
"textbutton",
]);
return dialog;
},
filter: function (button, player) {
var target = _status.event.getParent().result.targets[0];
var link = button.link;
if (link == "damage") return true;
if (link == "discard") return target.countCards("e");
return target.hasSex("female") && player.countDiscardableCards(player, "he") > 0;
},
check: function (button) {
switch (button.link) {
case "damage":
return 10;
case "discard":
return 1;
case "both":
return 15;
}
},
backup: function (links) {
var backup = {
audio: "twzhuidu",
target: _status.event.result.targets[0],
choice: links[0],
filterTarget: function (card, player, target) {
return target == lib.skill.twzhuidu_backup.target;
},
selectTarget: -1,
content: function () {
var target = lib.skill.twzhuidu_backup.target;
var choice = lib.skill.twzhuidu_backup.choice;
if (choice != "discard") target.damage();
if (choice != "damage") player.discardPlayerCard(target, "e", true);
},
};
if (links[0] == "both") {
backup.filterCard = true;
backup.position = "he";
}
return backup;
},
prompt: function (links) {
var name = get.translation(_status.event.result.targets[0]);
switch (links[0]) {
case "damage":
return "对" + name + "造成1点伤害";
case "discard":
return "弃置" + name + "装备区里的一张牌";
case "both":
return "背水!弃置一张牌,然后对" + name + "造成1点伤害并弃置其装备区里的一张牌";
}
},
},
subSkill: {
backup: {},
},
ai: {
order: 7,
result: {
target: function (player, target) {
if (target.hasSex("female") && target.countCards("e") && player.countCards("he")) return -2;
return -1;
},
},
},
},
twshigong: {
audio: 2,
trigger: { player: "dying" },
filter: function (event, player) {
var target = _status.currentPhase;
return player.hp <= 0 && target && target.isIn() && target != player;
},
skillAnimation: true,
animationColor: "gray",
limited: true,
logTarget: function (event, player) {
return _status.currentPhase;
},
content: function () {
"step 0";
player.awakenSkill("twshigong");
var target = _status.currentPhase;
if (target.hp <= 0) event._result = { bool: false };
else
target
.chooseToDiscard("h", target.hp, get.translation(player) + "对你发动了【示恭】,是否弃置" + get.cnNumber(target.hp) + "张手牌?", "若如此做其将体力回复至1点或者点击“取消”加1点体力上限并回复1点体力摸一张牌然后其将体力回复至体力上限")
.set("ai", card => {
if (!_status.event.goon) return 0;
return 7 - get.value(card);
})
.set("goon", get.attitude(target, player) >= 0);
"step 1";
var target = _status.currentPhase;
if (result.bool) {
var num = 1 - player.hp;
if (num > 0) player.recover(num);
event.finish();
} else {
target.gainMaxHp();
target.recover();
target.draw();
}
"step 2";
var num = player.maxHp - player.hp;
if (num > 0) player.recover(num);
},
},
//王淩
twmibei: {
audio: "mibei",
trigger: { player: "useCardAfter" },
group: ["twmibei_mark", "twmibei_fail"],
forced: true,
locked: false,
direct: true,
dutySkill: true,
derivation: "twmouli",
filter: function (event, player) {
var map = { basic: 0, trick: 0, equip: 0 };
for (var name of player.getStorage("twmibei")) {
var type = get.type2(name);
if (typeof map[type] == "number") map[type]++;
}
for (var i in map) {
if (map[i] < 2) return false;
}
return true;
},
content: function () {
player.awakenSkill("twmibei");
player.logSkill("twmibei_achieve");
game.log(player, "成功完成使命");
player.addSkills("twmouli");
},
intro: { content: "已使用牌名:$" },
subSkill: {
achieve: {
audio: "mibei1",
skillAnimation: true,
animationColor: "water",
},
mark: {
trigger: { player: "useCard1" },
filter: function (event, player) {
return !player.getStorage("twmibei").includes(event.card.name);
},
charlotte: true,
forced: true,
silent: true,
dutySkill: true,
content: function () {
player.markAuto("twmibei", [trigger.card.name]);
},
},
fail: {
audio: "mibei2",
trigger: { player: "phaseUseEnd" },
forced: true,
filter: function (event, player) {
return !player.getHistory("useCard").length;
},
content: function () {
game.log(player, "使命失败");
delete player.storage.twmibei;
player.addTempSkill("twmibei_less");
player.addMark("twmibei_less", 1, false);
},
},
less: {
charlotte: true,
marktext: "缚",
intro: { content: "本回合手牌上限-#" },
mod: {
maxHandcard: function (player, num) {
return num - player.countMark("twmibei_less");
},
},
},
},
},
twxingqi: {
audio: "xingqi",
trigger: { player: "phaseZhunbeiBegin" },
filter: function (event, player) {
var num = 0;
game.countPlayer(function (current) {
num += current.countCards("ej");
});
return num > player.hp;
},
forced: true,
juexingji: true,
skillAnimation: true,
animationColor: "thunder",
content: function () {
player.awakenSkill("twxingqi");
player.recover();
if (!player.awakenedSkills.includes("twmibei")) {
var list = ["basic", "equip", "trick"],
cards = [];
for (var i of list) {
var card = get.cardPile2(function (card) {
return get.type(card) == i;
});
if (card) cards.push(card);
}
if (cards.length) player.gain(cards, "gain2");
} else player.addSkill("twxingqi_range");
},
subSkill: {
range: {
charlotte: true,
mark: true,
marktext: "启",
mod: {
targetInRange: () => true,
},
intro: { content: "使用牌无距离限制" },
},
},
},
twmouli: {
audio: "mouli",
enable: "chooseToUse",
filter: function (event, player) {
if (event.type == "wuxie") return false;
if (player.hasSkill("twmouli_used")) return false;
if (!Array.isArray(event.twmouli)) return false;
for (var card of event.twmouli) {
if (event.filterCard(card, player, event)) return true;
}
return false;
},
onChooseToUse: function (event) {
if (game.online || !event.player.hasSkill("twmouli")) return;
var cards = [];
for (var i = 0; i < ui.cardPile.childNodes.length; i++) {
var card = ui.cardPile.childNodes[i];
if (get.type(card) == "basic") cards.push(card);
}
event.set("twmouli", cards);
},
chooseButton: {
dialog: function (event, player) {
var dialog = ui.create.dialog("谋立", "hidden");
if (event.twmouli && event.twmouli.length) dialog.add(event.twmouli);
else dialog.addText("牌堆里没有基本牌");
return dialog;
},
filter: function (button, player) {
var evt = _status.event.getParent(),
card = button.link;
if (evt && evt.filterCard) return evt.filterCard(card, player, evt);
return false;
},
check: function (button) {
var player = _status.event.player,
card = button.link;
if (_status.event.type != "phase") return 1;
if (_status.event.dying) return get.attitude(player, _status.event.dying);
if (card.name == "jiu") return player.getUseValue(card);
return player.getUseValue(card) / 4;
},
backup: function (links, player) {
return {
audio: "mouli",
filterCard: () => false,
selectCard: -1,
viewAs: { name: links[0].name, isCard: true, cards: [links[0]] },
popname: true,
precontent: function () {
player.logSkill("twmouli");
player.addTempSkill("twmouli_used");
delete event.result.skill;
var name = event.result.card.name;
event.result.cards = event.result.card.cards;
event.result.card = get.autoViewAs(event.result.cards[0]);
event.result.card.name = name;
var next = game.createEvent("twmouli_update");
event.next.remove(next);
event.getParent().after.push(next);
next.setContent(function () {
game.updateRoundNumber();
});
},
};
},
prompt: function (links, player) {
return "使用牌堆中的" + get.translation(links);
},
},
hiddenCard: function (player, name) {
return get.type(name) == "basic" && !player.getStat("skill").twmouli;
},
subSkill: {
used: { charlotte: true },
},
ai: {
effect: {
target: function (card, player, target, effect) {
if (get.tag(card, "respondShan")) return 0.7;
if (get.tag(card, "respondSha")) return 0.7;
},
},
order: 11,
respondSha: true,
respondShan: true,
fireAttack: true,
skillTagFilter: function (player, tag, arg) {
if (arg == "respond") return false;
var list = [];
for (var i = 0; i < ui.cardPile.childNodes.length; i++) {
var card = ui.cardPile.childNodes[i];
if (get.type(card, player) == "basic" && !list.includes(card.name)) list.push(card.name);
}
if (tag == "respondSha") return list.includes("sha");
if (tag == "respondShan") return list.includes("shan");
return !player.getStat("skill").twmouli;
},
result: {
player: function (player) {
if (_status.event.dying) return get.attitude(player, _status.event.dying);
return 1;
},
},
},
},
//诸葛果
twqirang: {
audio: "qirang",
trigger: { player: "equipEnd" },
frequent: true,
content: function () {
var card = get.cardPile(function (card) {
return get.type2(card) == "trick";
});
if (card) {
player.gain(card, "gain2").gaintag.add("twqirang");
player.addTempSkill("twqirang_use");
player.addTempSkill("twqirang_clear", ["phaseZhunbeiAfter", "phaseDrawAfter", "phaseUseAfter", "phaseDiscardAfter", "phaseJieshuAfter", "phaseAfter"]);
}
},
ai: {
effect: {
target: function (card, player, target, current) {
if (get.type(card) == "equip" && !get.cardtag(card, "gifts")) return [1, 3];
},
},
},
subSkill: {
clear: {
charlotte: true,
onremove: function (player) {
player.removeGaintag("twqirang");
},
},
use: {
audio: "qirang",
trigger: { player: "useCard2" },
forced: true,
filter: function (event, player) {
if (get.type2(event.card) != "trick") return false;
if (
!player.hasHistory("lose", function (evt) {
if (evt.getParent() != event) return false;
for (var i in evt.gaintag_map) {
if (evt.gaintag_map[i].includes("twqirang")) return true;
}
return false;
})
)
return false;
return true;
},
content: function () {
"step 0";
game.log(trigger.card, "不可被响应");
trigger.directHit.addArray(game.players);
var info = get.info(trigger.card);
if (info.allowMultiple == false) event.finish();
else if (trigger.targets) {
if (
!info.multitarget &&
!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("twqirang"), function (card, player, target) {
var player = _status.event.player;
if (_status.event.targets.includes(target)) return true;
return lib.filter.targetEnabled2(_status.event.card, player, target);
})
.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) * (_status.event.targets.includes(target) ? -1 : 1);
})
.set("targets", trigger.targets)
.set("card", trigger.card);
"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);
if (trigger.targets.includes(event.targets[0])) trigger.targets.removeArray(event.targets);
else trigger.targets.addArray(event.targets);
}
},
mod: {
targetInRange: function (card, player, target) {
if (!card.cards) return;
for (var i of card.cards) {
if (i.hasGaintag("twqirang")) return true;
}
},
},
},
},
},
twyuhua: {
audio: "yuhua",
frequent: true,
trigger: {
player: "loseAfter",
global: ["equipAfter", "addJudgeAfter", "gainAfter", "loseAsyncAfter", "addToExpansionAfter"],
},
filter: function (event, player) {
if (player == _status.currentPhase) return false;
if (event.name == "gain" && player == event.player) return false;
var evt = event.getl(player);
if (!evt || !evt.cards2 || !evt.cards2.length) return false;
for (var i of evt.cards2) {
if (get.type(i, player) != "basic") return true;
}
return false;
},
content: function () {
"step 0";
var num = 0,
evt = trigger.getl(player);
for (var i of evt.cards2) {
if (get.type(i, player) != "basic" && num < 5) num++;
}
player.chooseToGuanxing(num);
player.chooseBool("羽化:是否摸" + get.cnNumber(num) + "张牌?").set("frequentSkill", "twyuhua");
event.num = num;
"step 1";
if (result.bool) player.draw(num);
},
mod: {
ignoredHandcard: function (card, player) {
if (get.type(card) != "basic") return true;
},
cardDiscardable: function (card, player, name) {
if (name == "phaseDiscard" && get.type(card) != "basic") return false;
},
},
},
//樊稠
twxingluan: {
audio: "xinfu_xingluan",
trigger: { player: "phaseJieshuBegin" },
frequent: true,
content: function () {
"step 0";
event.cards = game.cardsGotoOrdering(get.cards(6)).cards;
event.list = [];
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 = ["basic", "trick", "equip"].filter(type => cards.some(card => get.type2(card) == type));
let fs = game
.filterPlayer(i => get.attitude(_status.event.player, i) > 0)
.sort((a, b) => {
if (a === player) {
//尽量把player往前放
if (a.hp < b.hp) return 1;
return -1;
}
if (b === player) {
if (b.hp < a.hp) return -1;
return 1;
}
return b.hp - a.hp;
}),
es = game.filterPlayer(i => get.attitude(_status.event.player, i) < 0).sort((a, b) => a.hp - b.hp),
types = list
.map(type => {
let num = 0;
for (let i of event.cards) {
if (get.type2(i) == type) num++;
}
return [type, num];
})
.sort((a, b) => b[1] - a[1]);
event.tempCache = {
max: -Infinity,
tars: [],
};
for (let idx = 0; idx < types.length; idx++) {
let f,
e,
temp = 0,
tars = [],
type = types[idx][1];
if (es.length * 3 >= type) {
//都分给敌人
e = -type;
while (temp < es.length && temp < type) {
e += 10 / (2 + es[temp].hp);
tars.push(es[temp]);
temp++;
}
if (e > event.tempCache.max) {
event.tempCache.type = types[idx][0];
event.tempCache.max = e;
event.tempCache.tars = tars.slice(0);
delete event.tempCache.more;
}
}
if (fs.length * 3 >= type) {
//都分给队友
tars = [];
f = type - 10 / (2 + fs[0].hp);
temp = type - Math.max(3, type); //让血厚的尽可能多拿
if (temp) {
if (fs.length < 3) {
tars.push(fs[1]);
if (temp >= 3) f -= 10 / (2 + fs[1].hp);
} else {
if (player !== fs[0]) {
tars.push(player);
temp -= Math.max(2, temp);
}
if (temp)
tars.addArray(
fs
.filter(i => fs[0] !== i && player !== i)
.sort((a, b) => {
return get.attitude(_status.event.player, b) - get.attitude(_status.event.player, a);
})
.slice(temp < 3 ? -1 : -2)
);
}
}
if (f > event.tempCache.max) {
event.tempCache.type = types[idx][0];
event.tempCache.max = f;
event.tempCache.more = fs[0];
event.tempCache.tars = tars.slice(0);
}
}
}
player
.chooseControl(list)
.set("ai", function () {
return _status.event.type;
})
.set("type", event.tempCache.type);
"step 2";
game.broadcastAll("closeDialog", event.videoId);
event.cardsx = [];
var type = result.control;
for (var j of cards) {
if (type == get.type2(j)) event.cardsx.push(j);
}
var time = 1000 - (get.utc() - event.time);
if (time > 0) game.delay(0, time);
player.$gain2(event.cardsx, false);
game.delayx();
if (_status.connectMode)
game.broadcastAll(function () {
_status.noclearcountdown = true;
});
event.given_map = {};
event.num = 0;
"step 3";
if (event.cardsx.length > 1) {
player.chooseCardButton("兴乱:请选择要分配的牌", true, event.cardsx, [1, Math.min(3, event.cardsx.length)]).set("ai", function (button) {
if (ui.selected.buttons.length == 0) return get.buttonValue(button);
return 0;
});
} else if (event.cardsx.length == 1) {
event._result = { links: event.cardsx.slice(0), bool: true };
} else {
event.goto(6);
}
"step 4";
if (result.bool) {
var cards = result.links;
event.togive = cards.slice(0);
player
.chooseTarget("选择获得" + get.translation(cards) + "的角色", event.cardsx.length == 1, (card, player, target) => {
var map = _status.event.getParent().given_map;
var togive = _status.event.getParent().togive;
return (map[target.playerid] || []).length + togive.length <= 3;
})
.set("ai", function (target) {
let targets = _status.event.targets,
att = get.attitude(_status.event.player, target);
if (targets.length) {
if (targets.includes(target)) return Math.max(1, att * _status.event.value);
return 0;
}
return att * _status.event.value;
})
.set(
"value",
cards.reduce((p, c) => p + get.value(c, player, "raw"), 0)
)
.set("more", event.tempCache.more)
.set(
"targets",
(function () {
let arr = [],
arr2 = [];
if (event.tempCache.more && (event.given_map[event.tempCache.more.playerid] || []).length + cards.length <= 3) return [event.tempCache.more];
for (let cur of event.tempCache.tars) {
let map = (event.given_map[cur.playerid] || []).length;
if (map + cards.length <= 3) {
if (map) arr2.push(cur);
else arr.push(cur);
}
}
if (arr.length) return arr;
return arr2;
})()
);
}
"step 5";
if (result.bool) {
event.cardsx.removeArray(event.togive);
if (result.targets.length) {
var id = result.targets[0].playerid,
map = event.given_map;
if (!map[id]) map[id] = [];
map[id].addArray(event.togive);
}
if (event.cardsx.length > 0) event.goto(3);
} else event.goto(3);
"step 6";
if (_status.connectMode) {
game.broadcastAll(function () {
delete _status.noclearcountdown;
game.stopCountChoose();
});
}
var list = [];
for (var i in event.given_map) {
var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i];
if (player == source) event.num += event.given_map[i].length;
player.line(source, "green");
game.log(source, "获得了", event.given_map[i]);
list.push([source, event.given_map[i]]);
}
game.loseAsync({
gain_list: list,
giver: player,
animate: "gain2",
}).setContent("gaincardMultiple");
"step 7";
var list = [];
for (var i in event.given_map) {
var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i];
if (event.given_map[i].length >= num) list.push(source);
}
list.sortBySeat();
player.line(list);
for (var i of list) {
i.loseHp();
}
},
},
//许靖
twboming: {
audio: "boming",
enable: "phaseUse",
usable: 2,
filter: function (event, player) {
return player.countCards("he");
},
filterCard: true,
position: "he",
filterTarget: lib.filter.notMe,
discard: false,
lose: false,
delay: false,
content: function () {
player.give(cards, target);
},
check: function (card) {
return 5 - get.value(card);
},
ai: {
order: 10,
result: {
target: function (player, target) {
if (!ui.selected.cards.length) return 0;
var card = ui.selected.cards[0];
if (get.attitude(player, target) < 0 && player.hasSkill("twejian")) {
var dam = get.damageEffect(target, player, target);
if (dam > 0) return dam;
var type = get.type(card, target),
ts = target.getCards("he", function (card) {
return get.type(card) == type;
});
if (ts.length) {
var val = get.value(ts, target);
if (val > get.value(card)) return -Math.max(1, val);
return 0;
}
}
return get.value(card, target) / 1.5;
},
},
},
group: "twboming_draw",
subSkill: {
draw: {
audio: "boming",
trigger: { player: "phaseJieshuBegin" },
forced: true,
locked: false,
filter: function (event, player) {
var num = 0;
for (var target of game.filterPlayer(i => i != player)) {
target.getHistory("gain", evt => (num += evt.cards.length));
if (num > 1) return true;
}
return false;
},
content: function () {
player.draw(2);
},
},
},
},
twejian: {
audio: "ejian",
trigger: {
global: ["gainAfter", "loseAsyncAfter"],
},
filter: function (event, player) {
if (event.name == "gain") {
var cards = event.getg(event.player);
if (!cards.length) return false;
var cards2 = event.getl(player).cards2;
for (var i of cards2) {
if (
cards.includes(i) &&
event.player.countCards("he", card => {
return card != i && get.type2(card) == get.type2(i);
})
)
return true;
}
return false;
} else {
if (event.type != "gain") return false;
var cards = event.getl(player).cards2;
if (!cards.length) return false;
return game.hasPlayer(current => {
if (current == player) return false;
var cardsx = event.getg(current);
for (var i of cardsx) {
if (
cards.includes(i) &&
current.countCards("he", card => {
return card != i && get.type2(card) == get.type2(i);
})
)
return true;
}
return false;
});
}
},
logTarget: function (event, player) {
if (event.name == "gain") return event.player;
else {
var cards = event.getl(player).cards2;
return game.filterPlayer(current => {
if (current == player) return false;
var cardsx = event.getg(current);
for (var i of cardsx) {
if (
cards.includes(i) &&
current.countCards("he", card => {
return card != i && get.type2(card) == get.type2(i);
})
)
return true;
}
return false;
});
}
},
direct: true,
content: function () {
"step 0";
if (trigger.name == "gain") event.targets = [trigger.player];
else {
var cards = trigger.getl(player).cards2;
event.targets = game.filterPlayer(current => {
if (current == player) return false;
var cardsx = trigger.getg(current);
for (var i of cardsx) {
if (
cards.includes(i) &&
current.countCards("he", card => {
return card != i && get.type2(card) == get.type2(i);
})
)
return true;
}
return false;
});
}
"step 1";
var target = event.targets.shift();
event.target = target;
player.chooseBool(get.prompt("twejian", target), "当其他角色得到你的牌后若其有其他与此牌类型相同的牌你可以令其选择一项1.受到你造成的1点伤害2.弃置这些牌").set("ai", () => {
return get.attitude(player, _status.event.getParent().target) < 0;
});
"step 2";
if (result.bool) {
player.logSkill("twejian", target);
var cards = trigger.getg(target);
event.cards = cards;
event.cardType = [];
for (var card of cards) {
event.cardType.add(get.type(card, "trick", target));
}
var list = ["选项一", "选项二"];
target
.chooseControl(list)
.set("prompt", "恶荐:请选择一项")
.set("choiceList", ["受到1点伤害", "弃置所有除" + get.translation(cards) + "外的" + get.translation(event.cardType) + "牌"])
.set("ai", function () {
var player = _status.event.player;
var types = _status.event.cardType,
cards = player.getCards("he", function (card) {
return types.includes(get.type2(card));
});
if (cards.length == 1) return "选项二";
if (cards.length >= 2) {
for (var i = 0; i < cards.length; i++) {
if (get.tag(cards[i], "save")) return "选项一";
}
}
if (player.hp == 1) return "选项二";
for (var i = 0; i < cards.length; i++) {
if (get.value(cards[i]) >= 8) return "选项一";
}
if (cards.length > 2 && player.hp > 2) return "选项一";
if (cards.length > 3) return "选项一";
return "选项二";
})
.set("cardType", event.cardType);
} else event.goto(4);
"step 3";
if (result.control == "选项一") target.damage();
else
target.discard(
target.getCards("he", card => {
return event.cardType.includes(get.type2(card)) && !cards.includes(card);
})
);
"step 4";
if (event.targets.length > 0) event.goto(1);
else event.finish();
},
ai: {
expose: 0.3,
},
},
//张飞
twxuhe: {
audio: "retishen",
trigger: { player: "shaMiss" },
check: function (event, player) {
return get.attitude(player, event.target) < 0;
},
logTarget: "target",
content: function () {
"step 0";
trigger.target
.chooseControl()
.set("choiceList", ["受到" + get.translation(player) + "对你造成的1点伤害", "令" + get.translation(player) + "使用的下一张牌对你造成的伤害+2"])
.set("ai", function () {
var target = _status.event.player,
player = _status.event.getParent().player;
if (
target.hp <= 3 &&
target.hp > 1 &&
player.countCards("hs", function (card) {
return get.tag(card, "damage") && player.canUse(card, target);
}) > 0
)
return 0;
return 1;
});
"step 1";
var target = trigger.target;
switch (result.index) {
case 0:
player.line(target, "fire");
target.damage();
break;
case 1:
target.line(player, "fire");
player.storage.twxuhe_damage = target;
trigger.getParent().twxuhe = true;
player.addTempSkill("twxuhe_damage");
break;
}
},
subSkill: {
damage: {
charlotte: true,
onremove: true,
mark: true,
intro: { content: "本回合使用的下一张牌对$造成伤害时,此伤害+2" },
trigger: {
source: "damageBegin1",
player: "useCardAfter",
},
direct: true,
filter: function (event, player) {
if (event.name == "useCard") return !event.twxuhe;
if (!event.card) return false;
var evt = event.getParent(2);
var history = player.getHistory("useCard");
return evt.name == "useCard" && history[history.indexOf(evt) - 1].twxuhe;
},
content: function () {
if (trigger.name != "useCard") trigger.num += 2;
player.removeSkill("twxuhe_damage");
},
},
},
},
//薛综
twjiexun: {
intro: { content: "已发动#次" },
audio: "jiexun",
trigger: { player: "phaseJieshuBegin" },
onremove: true,
direct: true,
derivation: ["twfunanx", "twjiexunx"],
content: function () {
"step 0";
var suits = {};
game.countPlayer(current => {
for (var card of current.getCards("ej")) {
if (typeof suits[get.suit(card)] != "number") suits[get.suit(card)] = 0;
suits[get.suit(card)]++;
}
});
var choices = lib.suit.slice();
choices.push("cancel2");
var str = lib.suit
.map(suit => {
return get.translation(suit) + "" + get.cnNumber(suits[suit] || 0) + "张";
})
.join("");
player
.chooseControl(choices)
.set("prompt", get.prompt("twjiexun") + "(已发动过" + get.cnNumber(player.countMark("twjiexun")) + "次)")
.set("ai", function () {
var player = _status.event.player;
var map = {};
game.countPlayer(current => {
for (var card of current.getCards("ej")) {
if (typeof map[get.suit(card)] != "number") map[get.suit(card)] = 0;
map[get.suit(card)]++;
}
});
for (var suit in map) map[suit] = Math.abs(map[suit]);
var bool = game.hasPlayer(current => get.attitude(player, current) > 0 && player != current);
var list = lib.suit.slice().sort((a, b) => (bool ? 1 : -1) * ((map[b] || 0) - (map[a] || 0)));
if ((bool && map[list[0]] > 0) || !bool || player.hasMark("twjiexun")) return list[0];
return "cancel2";
})
.set("prompt2", get.skillInfoTranslation("twjiexun", player) + "<br>" + str);
"step 1";
if (result.control != "cancel2") {
var suit = result.control;
event.suit = suit;
var num1 = game.countPlayer(function (current) {
return current.countCards("ej", { suit: suit });
});
var num2 = player.countMark("twjiexun");
event.num1 = num1;
event.num2 = num2;
var str = "令一名其他角色摸" + get.cnNumber(num1) + "张牌";
if (num2) str += ",然后弃置" + get.cnNumber(num2) + "张牌";
player
.chooseTarget("请选择【诫训】的目标", str, lib.filter.notMe)
.set("ai", function (target) {
var player = _status.event.player,
att = get.attitude(player, target);
return _status.event.eff * get.sgn(att) + att / 114514;
})
.set("eff", num1 >= num2 && num1 > 0 ? 1 : -1);
} else event.finish();
"step 2";
if (result.bool) {
var target = result.targets[0];
event.target = target;
player.logSkill("twjiexun", target);
if (player.hasMark("twjiexun") || event.num1) player.addExpose(0.2);
player.popup(event.suit);
game.log(player, "选择了", "#y" + get.translation(event.suit));
player.addMark("twjiexun", 1, false);
if (event.num1) target.draw(event.num1);
} else event.finish();
"step 3";
if (event.num2) target.chooseToDiscard(event.num2, true, "he");
else event.finish();
"step 4";
if (result.bool && result.autochoose && result.cards.length == result.rawcards.length && !player.hasSkill("funan_jiexun")) {
player
.chooseControl()
.set("choiceList", ["摸" + get.cnNumber(event.num2) + "张牌,将【诫训】的发动次数归零", "修改【复难】和【诫训】"])
.set("ai", () => _status.event.choice)
.set("prompt", "诫训:选择一项")
.set("choice", event.num2 >= 4 ? 0 : event.num2 <= 1 ? 1 : [0, 1].randomGet());
} else event.finish();
"step 5";
if (result.index == 0) {
player.draw(event.num2);
player.removeMark("twjiexun", player.countMark("twjiexun"), false);
game.log(player, "归零了", "#g【诫训】", "的发动次数");
} else {
game.log(player, "修改了", "#g【复难】", "和", "#g【诫训】");
player.addSkill("funan_jiexun");
}
},
},
//张宁
twxingzhui: {
audio: 2,
enable: "phaseUse",
usable: 1,
mahouSkill: true,
filter: function (event, player) {
return !player.hasSkill("twxingzhui_mahou");
},
content: function () {
"step 0";
player.loseHp();
player
.chooseControl("1回合", "2回合", "3回合")
.set("prompt", "请选择施法时长")
.set("ai", function () {
return 2;
});
"step 1";
player.storage.twxingzhui_mahou = [result.index + 1, result.index + 1];
player.addTempSkill("twxingzhui_mahou", { player: "die" });
},
ai: {
order: 2,
result: {
player: function (player, target) {
if (!player.hasFriend()) return 0;
if (player.hp > 1) return 1;
return 0;
},
},
},
subSkill: {
mahou: {
trigger: { global: "phaseEnd" },
forced: true,
popup: false,
charlotte: true,
content: function () {
"step 0";
var list = player.storage.twxingzhui_mahou;
list[1]--;
if (list[1] == 0) {
game.log(player, "的", "#g星坠", "魔法生效");
player.logSkill("twxingzhui");
var num = list[0];
event.num = num;
var cards = game.cardsGotoOrdering(get.cards(num * 2)).cards;
event.cards = cards;
player.showCards(cards, get.translation(player) + "发动了【星坠】");
player.removeSkill("twxingzhui_mahou");
} else {
game.log(player, "的", "#g星坠", "魔法剩余", "#g" + list[1] + "回合");
player.markSkill("twxingzhui_mahou");
event.finish();
}
"step 1";
var cards2 = [];
for (var card of event.cards) {
if (get.color(card, false) == "black") cards2.push(card);
}
if (!cards2.length) event.finish();
else {
event.cards2 = cards2;
var str = "令一名其他角色获得其中的黑色牌(" + get.translation(cards2) + "";
if (cards2.length >= event.num) str += ",然后对其造成" + get.cnNumber(event.num) + "点伤害";
player.chooseTarget("请选择〖星坠〗的目标", str, lib.filter.notMe).set("ai", function (target) {
var player = _status.event.player;
if (_status.event.getParent().cards2.length >= _status.event.getParent().num) return get.damageEffect(target, player, player, "thunder");
return get.attitude(player, target);
});
}
"step 2";
if (result.bool) {
var target = result.targets[0];
player.line(target);
target.gain(event.cards2, "gain2");
if (event.cards2.length >= num) target.damage(event.num, "thunder");
}
},
mark: true,
onremove: true,
marktext: "♗",
intro: {
name: "施法:星坠",
markcount: function (storage) {
if (storage) return storage[1];
return 0;
},
content: function (storage) {
if (storage) return "经过" + storage[1] + "个“回合结束时”后,亮出牌堆顶的" + get.cnNumber(storage[0] * 2) + "张牌并执行后续效果";
return "未指定施法效果";
},
},
},
},
},
twjuchen: {
audio: 2,
trigger: { player: "phaseJieshuBegin" },
filter: function (event, player) {
return (
game.hasPlayer(function (current) {
return current != player && current.countCards("h") > player.countCards("h");
}) &&
game.hasPlayer(function (current) {
return current != player && current.hp > player.hp;
})
);
},
logTarget: function (event, player) {
return game.players.sortBySeat(player);
},
content: function () {
"step 0";
event.num = 0;
event.cards = [];
event.targets = game.players.sortBySeat(player);
"step 1";
var target = targets[num];
if (target.countCards("he")) target.chooseToDiscard("he", true);
else event._result = { bool: false };
"step 2";
if (result.bool && Array.isArray(result.cards)) event.cards.addArray(result.cards);
event.num++;
if (event.num < targets.length) event.goto(1);
else game.delayx();
"step 3";
var cards = cards.filter(function (i) {
return get.position(i, true) == "d" && get.color(i, false) == "red";
});
if (cards.length) player.gain(cards, "gain2");
},
},
//于夫罗
twjiekuang: {
audio: 2,
trigger: { global: "useCardToTargeted" },
filter: function (event, player) {
if (!event.target || event.targets.length > 1) return false;
if (_status.dying.length) return false;
if (player == event.player) return false;
if (event.target.hp >= player.hp) return false;
if (!["basic", "trick"].includes(get.type(event.card))) return false;
return true;
},
usable: 1,
direct: true,
content: function () {
"step 0";
player
.chooseControl("失去体力", "减体力上限", "cancel2")
.set("prompt", get.prompt2("twjiekuang", trigger.target))
.set("ai", function (card) {
if (_status.event.aisave) {
if (player.isDamaged()) return "减体力上限";
return "失去体力";
}
return "cancel2";
})
.set(
"aisave",
(function () {
var save = false;
if (get.attitude(player, trigger.target) > 2) {
if (trigger.card.name == "sha") {
if (player.countCards("h", "shan") || player.getEquip(2) || trigger.target.hp == 1 || player.hp > trigger.target.hp + 1) {
if (!trigger.target.countCards("h", "shan") || trigger.target.countCards("h") < player.countCards("h")) {
save = true;
}
}
} else if (trigger.card.name == "juedou" && trigger.target.hp == 1) {
save = true;
} else if (trigger.card.name == "shunshou" && get.attitude(player, trigger.player) < 0 && get.attitude(trigger.player, trigger.target) < 0) {
save = true;
}
}
return save;
})()
);
"step 1";
if (result.control != "cancel2") {
player.logSkill("twjiekuang", trigger.target);
player[result.control == "失去体力" ? "loseHp" : "loseMaxHp"]();
player.addTempSkill("twjiekuang_after");
trigger.getParent().twjiekuang = true;
trigger.getParent().targets.remove(trigger.target);
trigger.getParent().triggeredTargets4.remove(trigger.target);
trigger.getParent().targets.push(player);
trigger.untrigger();
game.delayx();
trigger.player.line(player);
} else player.storage.counttrigger.twjiekuang--;
},
subSkill: {
after: {
charlotte: true,
trigger: { global: "useCardAfter" },
filter: function (event, player) {
return event.twjiekuang;
},
direct: true,
content: function () {
player.removeSkill("twjiekuang_after");
var card = get.autoViewAs({
name: trigger.card.name,
nature: trigger.card.nature,
isCard: true,
});
if (
!game.countPlayer2(current => {
return current.hasHistory("damage", evt => evt.card == trigger.card);
}) &&
player.canUse(card, trigger.player, false)
) {
player.useCard(card, trigger.player, false);
}
},
},
},
},
twneirao: {
audio: 2,
derivation: "twluanlve",
trigger: { player: "phaseZhunbeiBegin" },
forced: true,
juexingji: true,
skillAnimation: true,
animationColor: "gray",
filter: function (event, player) {
return Math.max(0, player.hp) + player.maxHp <= 9;
},
content: function () {
"step 0";
player.awakenSkill("twneirao");
player.removeSkills("twjiekuang");
"step 1";
var num = player.countCards("he"),
cards = [];
player.discard(player.getCards("he"));
for (var i = 0; i < num; i++) {
var card = get.cardPile(function (card) {
return card.name == "sha" && !cards.includes(card);
});
if (card) cards.push(card);
}
if (cards.length) player.gain(cards, "gain2");
"step 2";
player.addSkills("twluanlve");
},
},
twluanlve: {
audio: 2,
enable: "phaseUse",
onremove: true,
locked: false,
viewAs: {
name: "shunshou",
storage: { twluanlve: true },
},
viewAsFilter: function (player) {
return player.isPhaseUsing() && player.countCards("hs", { name: "sha" }) >= player.countMark("twluanlve");
},
filterCard: function (card, player) {
if (player.countMark("twluanlve") == 0) return false;
return card.name == "sha";
},
selectCard: function () {
var player = _status.event.player;
if (player.countMark("twluanlve") == 0) return -1;
return player.countMark("twluanlve");
},
onChooseToUse: function (event) {
if (!game.online && event.type == "phase") {
var targets = [];
game.countPlayer2(current => {
var history = current.getHistory("useCard");
if (!history.length) return false;
for (var evt of history) {
2024-05-06 06:44:20 +00:00
if (evt.card && evt.card.name == "shunshou" && evt.getParent("phaseUse") === event.getParent("phaseUse")) {
targets.addArray(evt.targets);
}
}
});
event.set("twluanlve_ban", targets);
}
},
position: "hs",
log: false,
group: ["twluanlve_directHit"],
precontent: function () {
player.logSkill("twluanlve");
player.addMark("twluanlve", 1, false);
},
ai: {
order: function () {
return get.order({ name: "shunshou" }) + 1;
},
},
mod: {
playerEnabled: function (card, player, target) {
if (!_status.event.twluanlve_ban || !Array.isArray(_status.event.twluanlve_ban)) return;
if (player.isPhaseUsing() && card.name == "shunshou" && card.storage && card.storage.twluanlve && _status.event.twluanlve_ban.includes(target)) return false;
},
},
subSkill: {
directHit: {
trigger: { player: "useCard" },
filter: function (event, player) {
return event.card.name == "shunshou";
},
direct: true,
content: function () {
trigger.directHit.addArray(game.players);
game.log(trigger.card, "不可被响应");
},
ai: {
directHit_ai: true,
skillTagFilter: function (player, tag, arg) {
return arg && arg.card && arg.card.name == "shunshou";
},
},
},
},
},
//冯习
twqingkou: {
audio: 2,
trigger: { player: "phaseZhunbeiBegin" },
filter: function (event, player) {
return game.hasPlayer(function (current) {
return player.canUse("juedou", current, false);
});
},
direct: true,
content: function () {
"step 0";
player
.chooseTarget(get.prompt("twqingkou"), "视为对一名其他角色使用一张【决斗】", function (card, player, target) {
return player.canUse("juedou", target, false);
})
.set("ai", function (target) {
var player = _status.event.player;
return get.effect(target, { name: "juedou" }, player, player);
});
"step 1";
if (result.bool) {
var target = result.targets[0];
event.target = target;
player.logSkill("twqingkou", target);
player.useCard({ name: "juedou", isCard: true, storage: { twqingkou: true } }, target, false);
player.addTempSkill("twqingkou_after");
}
},
subSkill: {
after: {
trigger: { global: "useCardAfter" },
filter: function (event, player) {
return event.card.storage && event.card.storage.twqingkou;
},
charlotte: true,
direct: true,
content: function () {
var targets = game
.filterPlayer(current => {
return current.hasHistory("sourceDamage", function (evt) {
return evt.card == trigger.card;
});
})
.sortBySeat();
for (var target of targets) {
target.draw();
if (target == player) {
player.skip("phaseJudge");
game.log(player, "跳过了", "#y判定阶段");
player.skip("phaseDiscard");
game.log(player, "跳过了", "#y弃牌阶段");
}
}
},
},
},
},
//张既
twdingzhen: {
audio: 2,
trigger: { global: "roundStart" },
filter: function (event, player) {
return game.hasPlayer(function (current) {
return get.distance(player, current) <= Math.max(0, player.hp);
});
},
direct: true,
content: function () {
"step 0";
player
.chooseTarget(get.prompt2("twdingzhen"), [1, Infinity], function (card, player, target) {
return get.distance(player, target) <= player.hp;
})
.set("ai", function (target) {
var player = _status.event.player;
if (target == player) return 0;
return Math.max(-get.attitude(player, target), 1);
});
"step 1";
if (result.bool) {
result.targets.sortBySeat();
var targets = result.targets;
event.targets = targets;
player.logSkill("twdingzhen", targets);
event.num = 0;
} else event.finish();
"step 2";
var target = targets[num];
event.target = target;
target
.chooseToDiscard("h", { name: "sha" }, "定镇:弃置一张【杀】,或本轮你于回合内使用的第一张牌不能指定" + get.translation(player) + "为目标")
.set("ai", function (card) {
if (_status.event.goon) return 1;
return 0;
})
.set(
"goon",
get.attitude(target, player) < 0 &&
player.countCards("hs") <= 3 &&
target.countCards("hs", card => {
return target.hasValueTarget(card);
}) > 1
);
"step 3";
if (result.bool) target.addExpose(0.1);
else {
target.addSkill("twdingzhen_target");
target.markAuto("twdingzhen_target", [player]);
}
"step 4";
if (event.num < event.targets.length - 1) {
event.num++;
event.goto(2);
}
},
subSkill: {
target: {
charlotte: true,
onremove: true,
mark: true,
silent: true,
trigger: { global: "roundStart" },
firstDo: true,
content: function () {
player.removeSkill("twdingzhen_target");
},
intro: {
markcount: () => 0,
content: "回合内使用的第一张牌不能指定$为目标",
},
mod: {
playerEnabled: function (card, player, target) {
if (_status.currentPhase == player && !player.countUsed() && player.getStorage("twdingzhen_target").includes(target)) return false;
},
},
},
},
},
twyouye: {
audio: 2,
trigger: { global: "phaseJieshuBegin" },
filter: function (event, player) {
return (
event.player != player &&
!event.player.getHistory("sourceDamage", function (evt) {
return evt.player == player;
}).length &&
player.getExpansions("twyouye").length < 5
);
},
forced: true,
group: "twyouye_give",
content: function () {
player.addToExpansion(get.cards(), "gain2").gaintag.add("twyouye");
},
marktext: "蓄",
intro: {
name: "蓄(攸业)",
content: "expansion",
markcount: "expansion",
},
onremove: function (player, skill) {
var cards = player.getExpansions(skill);
if (cards.length) player.loseToDiscardpile(cards);
},
subSkill: {
give: {
audio: "twyouye",
trigger: { source: "damageSource", player: "damageEnd" },
filter: function (event, player) {
return player.getExpansions("twyouye").length;
},
forced: true,
content: function () {
"step 0";
event.boolx = _status.currentPhase && _status.currentPhase.isIn();
event.cards = player.getExpansions("twyouye");
if (_status.connectMode)
game.broadcastAll(function () {
_status.noclearcountdown = true;
});
event.given_map = {};
"step 1";
if (event.cards.length > 1) {
player.chooseCardButton("攸业:请选择要分配的牌", true, event.cards, [1, event.cards.length]).set("ai", function (button) {
if (ui.selected.buttons.length) return 0;
return get.value(button.link, _status.event.player);
});
} else if (event.cards.length == 1) event._result = { links: event.cards.slice(0), bool: true };
else event.finish();
"step 2";
if (result.bool) {
var cards = result.links;
event.cards2 = cards;
player
.chooseTarget(
"选择一名角色获得" + get.translation(cards),
function (card, player, target) {
var evt = _status.event.getParent();
var cards = evt.cards,
cards2 = evt.cards2.slice();
if (cards.removeArray(cards2).length > 0 || !evt.boolx) return true;
return target == _status.currentPhase;
},
event.cards.length == 1
)
.set("ai", function (target) {
var att = get.attitude(_status.event.player, target);
if (_status.event.enemy) return Math.max(0.01, 100 - att);
else if (att > 0) return Math.max(0.1, att / (1 + target.countCards("h") + (_status.event.getParent().given_map[target.playerid] || 0)));
else return Math.max(0.01, (100 + att) / 100);
})
.set("enemy", get.value(cards[0], player, "raw") < 0);
}
"step 3";
if (result.bool) {
var cards = event.cards2;
event.cards.removeArray(cards);
event.togive = cards.slice(0);
if (result.targets.length) {
if (result.targets[0] == _status.currentPhase) event.boolx = false;
var id = result.targets[0].playerid,
map = event.given_map;
if (!map[id]) map[id] = [];
map[id].addArray(event.togive);
}
if (event.cards.length > 0) event.goto(1);
} else event.goto(1);
"step 4";
if (_status.connectMode)
game.broadcastAll(function () {
delete _status.noclearcountdown;
game.stopCountChoose();
});
var list = [];
for (var i in event.given_map) {
var source = (_status.connectMode ? lib.playerOL : game.playerMap)[i];
player.line(source, "green");
list.push([source, event.given_map[i]]);
game.log(source, "获得了", event.given_map[i]);
}
game.loseAsync({
gain_list: list,
giver: player,
animate: "gain2",
}).setContent("gaincardMultiple");
},
},
},
},
//荀谌
twweipo: {
audio: "mjweipo",
enable: "phaseUse",
usable: 1,
filter: function (event, player) {
return game.hasPlayer(function (current) {
return current.countCards("he");
});
},
filterTarget: function (card, player, target) {
return target.countCards("he");
},
content: function () {
"step 0";
target.chooseToDiscard("he", true);
"step 1";
var list = ["binglinchengxiax"];
list.addArray(get.zhinangs());
player.chooseButton(["危迫:令其获得一张智囊牌或【兵临城下】", [list, "vcard"]], true).set("ai", function (button) {
return _status.event.getParent().target.getUseValue({ name: button.link[2] });
});
"step 2";
if (result.bool) {
var name = result.links[0][2],
card = false;
game.log(player, "选择了", "#y" + get.translation(name));
if (name == "binglinchengxiax") {
if (!_status.binglinchengxiax) {
_status.binglinchengxiax = [
["spade", 7],
["club", 7],
["club", 13],
];
game.broadcastAll(function () {
lib.inpile.add("binglinchengxiax");
});
}
if (_status.binglinchengxiax.length) {
var info = _status.binglinchengxiax.randomRemove();
card = game.createCard2("binglinchengxiax", info[0], info[1]);
}
}
if (!card) card = get.cardPile(name);
if (card) target.gain(card, "gain2");
}
},
ai: {
order: 7.1,
result: {
target: function (player, target) {
if (target == player) return player.countCards("he") ? 10 : 0.01;
return (target.countCards("he") + 0.5) * Math.sqrt(Math.max(1, target.hp));
},
},
},
},
twmouzhi: {
audio: "mjmouzhi",
intro: { content: "上次受到伤害的颜色:$" },
trigger: { player: "damageBegin4" },
forced: true,
group: "twmouzhi_mark",
filter: function (event, player) {
if (!event.card || get.color(event.card) == "none") return false;
var all = player.getAllHistory("damage");
if (!all.length) return false;
return all[all.length - 1].card && get.color(all[all.length - 1].card) == get.color(event.card);
},
content: function () {
trigger.cancel();
},
ai: {
effect: {
target: (card, player, target) => {
if (typeof card === "object" && get.tag(card, "damage")) {
let color = get.color(card);
if (color === "none") return;
let all = target.getAllHistory("damage");
if (!all.length || !all[all.length - 1].card) return;
if (get.color(all[all.length - 1].card) === color) return "zeroplayertarget";
}
},
},
},
subSkill: {
mark: {
trigger: { player: "damage" },
silent: true,
firstDo: true,
content: function () {
if (!trigger.card || get.color(trigger.card) == "none") player.unmarkSkill("twmouzhi");
else {
player.markSkill("twmouzhi");
player.storage.twmouzhi = get.color(trigger.card);
game.broadcastAll(
function (player, color) {
if (player.marks.twmouzhi) {
player.marks.twmouzhi.firstChild.innerHTML = "<font color=" + color + ">谋</font>";
}
player.storage.twmouzhi = color;
},
player,
player.storage.twmouzhi
);
}
},
},
},
},
//蒋钦
twshangyi: {
audio: "shangyi",
enable: "phaseUse",
usable: 1,
filter: function (event, player) {
return (
player.countCards("he") &&
game.hasPlayer(function (current) {
return current != player && current.countCards("h");
})
);
},
filterTarget: function (card, player, target) {
return target != player && target.countCards("h");
},
filterCard: true,
position: "he",
content: function () {
"step 0";
target.viewHandcards(player);
var chooseButton;
if (player.countCards("h")) chooseButton = player.chooseButton([1, 2], ['###尚义###<div class="text center">选择' + get.translation(target) + "的一张手牌以弃置,或选择你与其的各一张牌以交换</div>", '<div class="text center">' + get.translation(target) + "的手牌</div>", target.getCards("h"), '<div class="text center">你的手牌</div>', player.getCards("h")], true);
else chooseButton = player.chooseButton(['###尚义###<div class="text center">弃置' + get.translation(target) + "的一张手牌</div>", '<div class="text center">' + get.translation(target) + "的手牌</div>", target.getCards("h")], true);
chooseButton.set("target", target);
chooseButton.set("ai", function (button) {
var player = _status.event.player,
owner = get.owner(button.link),
color = get.color(button.link, owner),
value = get.value(button.link, owner);
if (player.countCards("h")) {
if (!ui.selected.buttons.length) {
if (
player.countCards("h", function (card) {
return get.color(card, player) == "red" && get.value(card) < 6;
}) &&
color == "red" &&
value > 7
)
return value * 3;
return value;
} else {
if (get.value(ui.selected.buttons[0].link) < 4) return 0;
return 4 + (get.color(ui.selected.buttons[0].link, get.owner(ui.selected.buttons[0].link)) == "red" ? 3 : 1) - value;
}
} else {
if (color == "black") return value * 1.5;
return value;
}
});
chooseButton.set("filterButton", function (button) {
if (get.itemtype(button.link) != "card") return false;
if (!ui.selected.buttons.length && get.owner(button.link) != _status.event.target) return false;
if (ui.selected.buttons.length && get.owner(ui.selected.buttons[0].link) == get.owner(button.link)) return false;
return true;
});
"step 1";
if (result.bool) {
if (result.links.length == 1) {
target.discard(result.links[0]).discarder = player;
if (get.color(result.links[0], target) != "black") event.finish();
} else {
var links = result.links.slice();
if (get.owner(links[0]) != player) links.reverse();
var card1 = links[0],
card2 = links[1];
player.swapHandcards(target, [card1], [card2]);
if (get.color(card1, player) != "red" || get.color(card2, target) != "red") event.finish();
}
} else event.finish();
"step 2";
player.draw();
},
ai: {
order: 10,
result: { target: -1 },
},
},
twxiangyu: {
group: "twxiangyu_lose",
shaRelated: true,
audio: "zniaoxiang",
trigger: { player: "useCardToPlayered" },
filter: function (event, player) {
return event.card.name == "sha" && get.distance(player, event.player) < player.getAttackRange();
},
forced: true,
logTarget: "target",
init: function (player) {
var target = _status.currentPhase;
if (!target || !target != player) return;
if (!player.getStorage("twxiangyu_range").length) {
var targets = game.filterPlayer(current => {
return current.getHistory("lose").length;
});
if (targets.length) {
player.addTempSkill("twxiangyu_range");
player.markAuto("twxiangyu_range", targets);
}
}
},
content: function () {
var id = trigger.target.playerid;
var map = trigger.getParent().customArgs;
if (!map[id]) map[id] = {};
if (typeof map[id].shanRequired == "number") {
map[id].shanRequired++;
} else map[id].shanRequired = 2;
},
mod: {
attackRange: function (player, num) {
return num + Math.min(5, player.getStorage("twxiangyu_range").length);
},
},
subSkill: {
lose: {
trigger: {
global: ["loseAfter", "equipAfter", "addJudgeAfter", "gainAfter", "loseAsyncAfter", "addToExpansionAfter"],
},
filter: function (event, player) {
return (
player == _status.currentPhase &&
game.hasPlayer(function (current) {
if (player.getStorage("twxiangyu_range").includes(current)) return false;
var evt = event.getl(current);
return evt && evt.cards2 && evt.cards2.length > 0;
})
);
},
silent: true,
charlotte: true,
content: function () {
player.addTempSkill("twxiangyu_range");
player.markAuto(
"twxiangyu_range",
game.filterPlayer(function (current) {
if (player.getStorage("twxiangyu_range").includes(current)) return false;
var evt = trigger.getl(current);
return evt && evt.cards2 && evt.cards2.length > 0;
})
);
player.syncStorage("twxiangyu_range");
},
},
range: {
marktext: "羽",
intro: {
content: function (storage, player) {
var num = Math.min(5, storage ? storage.length : 0);
return "攻击范围+" + num;
},
},
charlotte: true,
onremove: true,
},
},
},
//顾雍
twgyshenxing: {
audio: "xinshenxing",
enable: "phaseUse",
filter: function (event, player) {
return player.countCards("he") >= Math.min(2, player.countMark("twgyshenxing"));
},
selectCard: function () {
return Math.min(2, _status.event.player.countMark("twgyshenxing"));
},
prompt: function () {
return "弃置" + get.cnNumber(Math.min(2, _status.event.player.countMark("twgyshenxing"))) + "张牌并摸一张牌";
},
check: function (card) {
var num = _status.event.player.countCards("h", { color: get.color(card) });
if (get.position(card) == "e") num++;
return (Math.max(4, 7.1 - num) - get.value(card)) / num;
},
filterCard: true,
position: "he",
content: function () {
player.draw();
player.addMark("twgyshenxing", 1);
},
marktext: "慎",
intro: { content: "已发动过#次" },
ai: {
order: function (item, player) {
if (!player.hasMark("twgyshenxing")) return 10;
return 1;
},
result: { player: 1 },
},
},
twbingyi: {
audio: "bingyi_xin_guyong",
trigger: { player: "phaseJieshuBegin" },
filter: function (event, player) {
return player.countCards("h");
},
filterx: function (event, player) {
var cards = player.getCards("h");
if (cards.length == 1) return true;
var color = get.color(cards[0], player),
type = get.type2(cards[0], player);
for (var i = 1; i < cards.length; i++) {
if (color && get.color(cards[i], player) != color) color = false;
if (type && get.type2(cards[i], player) != type) type = false;
if (!color && !type) return false;
}
return true;
},
filtery: function (event, player) {
var cards = player.getCards("h");
if (player.countCards("h") <= 1) return false;
var color = get.color(cards[0], player),
type = get.type2(cards[0], player);
var colorx = true,
typex = true;
for (var i = 1; i < cards.length; i++) {
if (color && get.color(cards[i], player) != color) colorx = false;
if (type && get.type2(cards[i], player) != type) typex = false;
}
return colorx && typex;
},
direct: true,
content: function () {
"step 0";
event.boolx = false;
if (lib.skill.twbingyi.filtery(trigger, player)) event.boolx = true;
if (lib.skill.twbingyi.filterx(trigger, player)) {
player.chooseTarget(get.prompt("twbingyi"), "选择至多" + get.cnNumber(player.countCards("h")) + "名角色,你展示所有手牌,这些角色各摸一张牌" + (event.boolx ? ",然后你移去所有“慎”" : ""), [0, player.countCards("h")]).set("ai", function (target) {
return get.attitude(_status.event.player, target);
}).animate = false;
} else
player.chooseBool(get.prompt("twbingyi"), "展示所有手牌").ai = function () {
return false;
};
"step 1";
if (result.bool) {
player.logSkill("twbingyi");
player.showHandcards(get.translation(player) + "发动了【秉壹】");
event.targets = result.targets;
} else event.finish();
"step 2";
if (targets && targets.length) {
player.line(targets, "green");
targets.sortBySeat();
game.asyncDraw(targets);
}
"step 3";
if (event.boolx) {
player.removeMark("twgyshenxing", player.countMark("twgyshenxing"));
}
},
ai: { expose: 0.1 },
},
bingyi_xin_guyong: { audio: 2 },
//陈武董袭
twyilie: {
audio: "spyilie",
trigger: { player: "phaseUseBegin" },
direct: true,
content: function () {
"step 0";
player
.chooseControl("选项一", "选项二", "背水!", "cancel2")
.set("choiceList", ["本阶段内使用【杀】的次数上限+1", "本回合内使用【杀】指定处于连环状态的目标后,或使用【杀】被【闪】抵消时,摸一张牌", "背水失去1点体力并依次执行上述所有选项"])
.set("ai", function () {
if (
player.countCards("hs", function (card) {
return get.name(card) == "sha" && player.hasValueTarget(card);
}) > player.getCardUsable({ name: "sha" })
) {
return player.hp > 2 ? 2 : 0;
}
return 1;
})
.set("prompt", get.prompt("twyilie"));
"step 1";
if (result.control != "cancel2") {
player.logSkill("twyilie");
game.log(player, "选择了", "#g【毅烈】", "的", "#y" + result.control);
if (result.index % 2 == 0) player.addTempSkill("twyilie_add", "phaseUseEnd");
if (result.index > 0) player.addTempSkill("twyilie_miss");
if (result.index == 2) player.loseHp();
}
},
subSkill: {
add: {
charlotte: true,
mod: {
cardUsable: function (card, player, num) {
if (card.name == "sha") return num + 1;
},
},
mark: true,
intro: { content: "本阶段使用【杀】的次数上限+1" },
},
miss: {
charlotte: true,
audio: "spyilie",
trigger: { player: ["useCardToTargeted", "shaMiss"] },
filter: function (event, player, name) {
if (name == "useCardToTargeted") return event.card.name == "sha" && event.target.isLinked();
return true;
},
forced: true,
content: function () {
player.draw();
},
},
},
},
twfenming: {
audio: "spfenming",
trigger: { player: "phaseZhunbeiBegin" },
filter: function (event, player) {
return game.hasPlayer(function (target) {
return target != player && (target.countCards("he") || !target.isLinked());
});
},
direct: true,
content: function () {
"step 0";
player
.chooseTarget(get.prompt2("twfenming"), function (card, player, target) {
return target != player && (target.countCards("he") || !target.isLinked());
})
.set("ai", function (target) {
var player = _status.event.player;
return get.damageEffect(target, player, player);
});
"step 1";
if (result.bool) {
var target = result.targets[0];
event.target = target;
player.logSkill("twfenming", target);
var list = [],
choiceList = ["令" + get.translation(target) + "弃置一张牌", "令" + get.translation(target) + "横置", "背水!横置并依次令" + get.translation(target) + "执行上述所有选项"];
if (target.countCards("he")) list.push("选项一");
else choiceList[0] = '<span style="opacity:0.5">' + choiceList[0] + "</span>";
if (!target.isLinked()) list.push("选项二");
else choiceList[1] = '<span style="opacity:0.5">' + choiceList[1] + "</span>";
if (target.countCards("he") && !target.isLinked() && !player.isLinked()) list.push("背水!");
else choiceList[2] = '<span style="opacity:0.5">' + choiceList[2] + "</span>";
if (list.length == 1) event._result = { control: list[0] };
else
player
.chooseControl(list)
.set("choiceList", choiceList)
.set("ai", function () {
var list = _status.event.controls;
if (list.includes("背水!")) return "背水!";
if (list.includes("选项一")) return "选项一";
return "选项二";
})
.set("prompt", "奋命:请选择一项");
} else event.finish();
"step 2";
game.log(player, "选择了", "#y" + result.control);
if (result.control == "背水!" && !player.isLinked()) player.link(true);
if (result.control != "选项二") target.chooseToDiscard("he", true);
if (result.control != "选项一" && !target.isLinked()) target.link(true);
},
},
//韩当
twgongji: {
audio: "regongji",
enable: "phaseUse",
usable: 1,
position: "he",
filterCard: true,
locked: false,
filter: function (event, player) {
return player.countCards("he");
},
check: function (card) {
var base = 0,
player = _status.event.player,
suit = get.suit(card, player),
added = false,
added2 = false,
added3;
if (
get.type(card) == "equip" &&
game.hasPlayer(function (target) {
var att = get.attitude(player, target);
if (att >= 0) return 0;
if (
target.countCards("he", function (card) {
return get.value(card) > 5;
})
)
return -att;
})
)
base += 6;
var hs = player.getCards("h");
var muniu = player.getEquip("muniu");
if (muniu && card != muniu && muniu.cards) hs = hs.concat(muniu.cards);
for (var i of hs) {
if (i != card && get.name(i) == "sha") {
if (get.suit(i, player) == suit) {
if (player.hasValueTarget(i, false)) {
added3 = true;
base += 5.5;
}
} else {
if (player.hasValueTarget(i, false)) added2 = true;
if (!added && !player.hasValueTarget(i, null, true) && player.hasValueTarget(i, false, true)) {
base += 4;
added = true;
}
}
}
}
if (added3 && !added2) base -= 4.5;
return base - get.value(card);
},
content: function () {
"step 0";
player.addTempSkill("twgongji2");
player.markAuto("twgongji2", [get.suit(cards[0], player)]);
"step 1";
if (get.type(cards[0], null, cards[0].original == "h" ? player : false) == "equip") {
player
.chooseTarget("是否弃置一名角色的一张牌?", function (card, player, target) {
return player != target && target.countCards("he");
})
.set("ai", function (target) {
var player = _status.event.player;
return get.effect(target, { name: "guohe_copy2" }, player, player);
});
} else event.finish();
"step 2";
if (result.bool) {
player.line(result.targets, "green");
player.discardPlayerCard(result.targets[0], "he", true);
}
},
mod: {
attackRangeBase: function () {
return Infinity;
},
},
ai: {
order: 4.5,
result: { player: 1 },
},
},
twgongji2: {
charlotte: true,
onremove: true,
mark: true,
intro: { content: "使用$花色的杀无任何次数限制" },
trigger: { player: "useCard1" },
filter: function (event, player) {
if (_status.currentPhase == player && event.card.name == "sha" && player.getStorage("twgongji2").includes(get.suit(event.card)) && event.addCount !== false) return true;
return false;
},
forced: true,
locked: false,
popup: false,
firstDo: true,
content: function () {
trigger.addCount = false;
if (player.stat[player.stat.length - 1].card.sha > 0) {
player.stat[player.stat.length - 1].card.sha--;
}
},
mod: {
cardUsable: function (card, player) {
if (card.name == "sha") {
const suit = get.suit(card);
if (suit === "unsure" || player.getStorage("twgongji2").includes(suit)) return Infinity;
}
},
aiOrder: function (player, card, num) {
if (get.name(card) == "sha" && !player.getStorage("twgongji2").includes(get.suit(card))) return num + 1;
},
},
},
twjiefan: {
skillAnimation: true,
animationColor: "wood",
audio: "jiefan_re_handang",
limited: true,
enable: "phaseUse",
filterTarget: true,
content: function () {
"step 0";
player.awakenSkill("twjiefan");
event.players = game.filterPlayer(function (current) {
return current != target && current.inRange(target);
});
event.players.sortBySeat();
"step 1";
if (event.players.length) {
event.current = event.players.shift();
event.current.addTempClass("target");
player.line(event.current, "green");
if (!event.current.countCards("he") || !target.isIn()) event._result = { bool: false };
else {
event.current
.chooseToDiscard({ subtype: "equip1" }, "he", "解烦:弃置一张武器牌,或令" + get.translation(target) + "摸一张牌")
.set("ai", function (card) {
if (!_status.event.target.isIn()) return 0;
if (get.attitude(_status.event.player, _status.event.target) < 0) return 7 - get.value(card);
return -1;
})
.set("target", target);
}
} else {
player.addSkill("twjiefan2");
player.markAuto("twjiefan2", [target]);
event.finish();
}
"step 2";
if (!result.bool && target.isIn()) target.draw();
event.goto(1);
},
ai: {
order: 5,
result: {
target: function (player, target) {
if (player.hp > 2 && game.phaseNumber < game.players.length * 2) return 0;
var num = 0,
players = game.filterPlayer();
for (var i = 0; i < players.length; i++) {
if (players[i] != target && players[i].inRange(target)) {
num++;
}
}
return num;
},
},
},
},
twjiefan2: {
charlotte: true,
onremove: true,
trigger: { global: "dying" },
filter: function (event, player) {
return player.getStorage("twjiefan2").includes(event.player);
},
forced: true,
popup: false,
content: function () {
player.removeSkill("twjiefan2");
player.restoreSkill("twjiefan");
},
},
jiefan_re_handang: { audio: 2 },
//纪灵
twshuangren: {
audio: "shuangren",
trigger: { player: "phaseUseBegin" },
filter: function (event, player, name) {
if (!player.countCards("h")) return false;
if (name == "phaseUseEnd")
return !player.hasHistory("sourceDamage", function (evt) {
return evt.card.name == "sha" && event.getParent("phaseUse") == evt;
});
return true;
},
direct: true,
group: "twshuangren_end",
preHidden: true,
content: function () {
"step 0";
var forced =
event.getParent(2).name == "twshuangren_end" &&
game.hasPlayer(current => {
return player.canCompare(current);
});
var str = "与一名角色拼点若你你可以视为对至多两名至其的距离不大于1的角色使用一张【杀】没赢其可以视为对你使用一张【杀】";
player
.chooseTarget(forced ? "双刃:选择一名角色" : get.prompt("twshuangren"), str, forced, (card, player, target) => {
return player.canCompare(target);
})
.set("ai", target => {
if (_status.event.goon) return get.effect(target, { name: "sha" }, _status.event.player);
return 0;
})
.set("goon", event.triggername != "phaseUseBegin" || (player.countCards("hs", "sha") > 0 && player.hasValueTarget({ name: "sha" })));
"step 1";
if (result.bool) {
var target = result.targets[0];
event.target = target;
player.logSkill("twshuangren", target);
if (player.canCompare(target)) player.chooseToCompare(target);
else event.finish();
} else event.finish();
"step 2";
if (result.bool) {
event.sha = true;
player
.chooseTarget([1, 2], "请选择【杀】的目标", true, function (card, player, target) {
if (!player.canUse("sha", target, false, false)) return false;
return get.distance(target, _status.event.targetx) <= 1;
})
.set("ai", function (target) {
var player = _status.event.player;
return get.effect(target, { name: "sha" }, player, player);
})
.set("targetx", target);
} else target.chooseBool("双刃:是否视为对" + get.translation(player) + "使用一张杀?").set("choice", get.effect(player, { name: "sha" }, target, target) > 0);
"step 3";
if (result.bool) {
if (event.sha == true) {
result.targets.sortBySeat();
for (var i of result.targets) {
player.useCard({ name: "sha", isCard: true }, i, false);
}
} else target.useCard({ name: "sha", isCard: true }, player, false);
}
},
subSkill: {
end: {
audio: "shuangren",
trigger: { player: "phaseUseEnd" },
filter: function (event, player, name) {
if (!player.countCards("h")) return false;
return (
!player.hasHistory("useSkill", function (evt) {
return evt.skill == "twshuangren";
}) &&
!player.hasHistory("sourceDamage", function (evt) {
return evt.card && evt.card.name == "sha";
})
);
},
direct: true,
preHidden: true,
content: function () {
"step 0";
player
.chooseToDiscard(get.prompt("twshuangren"), "弃置一张牌发动〖双刃〗", "he")
.set("ai", function (card) {
if (_status.event.goon) return 5 - get.value(card);
return 0;
})
.set(
"goon",
(function () {
return player.hasCard(function (card) {
if (player.needsToDiscard() > 1) return card.number > 10 && get.value(card) <= 5;
return (card.number >= 9 && get.value(card) <= 5) || get.value(card) <= 3;
});
})()
)
.setHiddenSkill("twshuangren")
.set("logSkill", "twshuangren");
"step 1";
if (result.bool) {
player.useSkill("twshuangren");
}
},
},
},
},
//法正
twxuanhuo: {
audio: "rexuanhuo",
trigger: { player: "phaseDrawEnd" },
filter: function (event, player) {
return player.countCards("he") > 1 && game.countPlayer() > 2;
},
direct: true,
content: function () {
"step 0";
var ai2 = function (target) {
var player = _status.event.player;
if (get.attitude(player, target) <= 0) return 0;
var list = ["sha", "juedou"];
var num = Math.max.apply(
Math,
list.map(function (i) {
return target.getUseValue({ name: i, isCard: true }, false);
})
);
if (target.hasSkillTag("nogain")) num /= 4;
return num;
};
player.chooseCardTarget({
prompt: get.prompt2("twxuanhuo"),
filterCard: true,
selectCard: 2,
position: "he",
filterTarget: lib.filter.notMe,
goon: game.hasPlayer(function (current) {
return current != player && ai2(player, current) > 0;
}),
ai1: function (card) {
if (!_status.event.goon) return 0;
return 7 - get.value(card);
},
ai2: ai2,
});
"step 1";
if (result.bool) {
var target = result.targets[0];
event.target = target;
player.logSkill("twxuanhuo", target);
player.give(result.cards, target);
} else event.finish();
"step 2";
if (
game.hasPlayer(function (current) {
return current != player && current != target;
})
)
player
.chooseTarget(
function (card, player, target) {
return target != player && target != _status.event.target;
},
"选择" + get.translation(target) + "使用【杀】或【决斗】的目标",
true
)
.set("target", target)
.set("ai", function (target) {
var evt = _status.event;
var list = ["sha", "juedou"];
return Math.max.apply(
Math,
list.map(function (i) {
var card = { name: i, isCard: true };
if (!evt.target.canUse(card, target, false)) return 0;
return get.effect(target, card, evt.target, evt.player);
})
);
});
else event.finish();
"step 3";
var target2 = result.targets[0];
event.target2 = target2;
player.line(target2);
var vcards = [];
if (target.canUse({ name: "sha", isCard: true }, target2, false)) vcards.push(["基本", "", "sha"]);
if (target.canUse({ name: "juedou", isCard: true }, target2, false)) vcards.push(["锦囊", "", "juedou"]);
if (!vcards.length) {
if (!target.countCards("h")) event.finish();
else event._result = { index: 1 };
} else if (!target.countCards("h")) {
event.vcards = vcards;
event._result = { index: 0 };
} else {
event.vcards = vcards;
target.chooseControl().set("choiceList", ["视为对" + get.translation(target2) + "使用一张【杀】或【决斗】", "令" + get.translation(player) + "获得你的两张牌"]);
}
"step 4";
if (result.index == 0) {
if (event.vcards.length == 1) event._result = { links: event.vcards, bool: true };
else
target.chooseButton(["请选择要对" + get.translation(event.target2) + "使用的牌", [event.vcards, "vcard"]], true).set("ai", function (button) {
var player = _status.event.player;
return get.effect(_status.event.getParent().target2, { name: button.link[2], isCard: true }, player, player);
});
} else {
player.gainPlayerCard(target, 2, "he", true);
event.finish();
}
"step 5";
if (result.bool) target.useCard({ name: result.links[0][2], isCard: true }, false, event.target2);
},
ai: {
expose: 0.15,
},
},
twenyuan: {
audio: "reenyuan",
group: ["twenyuan1", "twenyuan2"],
},
twenyuan1: {
audio: "reenyuan",
trigger: {
global: ["gainAfter", "loseAsyncAfter"],
},
direct: true,
filter: function (event, player) {
var cards = event.getg(player);
if (!cards.length || cards.length < 2) return false;
return game.countPlayer(current => {
if (current == player) return false;
var evt = event.getl(current);
if (evt && evt.cards && evt.cards.filter(card => cards.includes(card)).length >= 2) return true;
return false;
});
},
check: function (event, player) {
var cards = event.getg(player);
var target = game.filterPlayer(current => {
if (current == player) return false;
var evt = event.getl(current);
if (evt && evt.cards && evt.cards.filter(card => cards.includes(card)).length >= 2) return true;
return false;
})[0];
return get.attitude(player, target) > 0;
},
logTarget: function (event, player) {
var cards = event.getg(player);
return game.filterPlayer(current => {
if (current == player) return false;
var evt = event.getl(current);
if (evt && evt.cards && evt.cards.filter(card => cards.includes(card)).length >= 2) return true;
return false;
});
},
content: function () {
"step 0";
var target = lib.skill.twenyuan1.logTarget(trigger, player)[0];
event.target = target;
var list = ["摸一张牌"];
var prompt2 = "令" + get.translation(target) + "摸一张牌";
if ((!target.countCards("h") || !target.countCards("e")) && target.isDamaged()) {
list.push("回复1点体力");
prompt2 += "或回复1点体力";
}
list.push("cancel2");
player
.chooseControl(list)
.set("prompt", get.prompt("twenyuan", target))
.set("prompt2", prompt2)
.set("ai", () => _status.event.choice)
.set(
"choice",
(function () {
if (get.attitude(player, target) > 0) {
if (target.hp <= 2 && list.includes("回复1点体力")) return "回复1点体力";
return 0;
}
return "cancel2";
})()
);
"step 1";
if (result.control == "cancel2") {
event.finish();
return;
}
player.logSkill("twenyuan1", target);
if (result.control == "回复1点体力") target.recover();
else target.draw();
},
},
twenyuan2: {
audio: "reenyuan",
trigger: { player: "damageEnd" },
logTarget: "source",
filter: function (event, player) {
return event.source && event.source.isIn();
},
check: function (event, player) {
var att = get.attitude(player, event.source);
var num = event.source.countCards("h");
if (att <= 0) return true;
if (get.effect(event.source, { name: "losehp" }, player, event.source) > 0) return true;
if (num > 2) return true;
if (num) return att < 4;
return false;
},
prompt2: "令其选择一项1.失去1点体力2.交给你一张手牌,若此牌的花色不为♥,你摸一张牌。",
content: function () {
"step 0";
event.count = trigger.num;
"step 1";
var target = trigger.source;
event.count--;
if (!target.countCards("h")) event._result = { bool: false };
else
target.chooseCard("h", "恩怨:将一张手牌交给" + get.translation(player) + "或失去1点体力").set("ai", function (card) {
if (get.attitude(_status.event.player, _status.event.getParent().player) > 0) {
if (get.suit(card) != "heart") return 15 - get.value(card);
return 11 - get.value(card);
} else {
var num = 12 - _status.event.player.hp * 2;
if (get.suit(card) != "heart") num -= 2;
return num - get.value(card);
}
});
"step 2";
var target = trigger.source;
if (result.bool) {
var card = result.cards[0];
event.card = card;
target.give(card, player);
} else {
target.loseHp();
event.goto(4);
}
"step 3";
if (get.suit(card) != "heart") player.draw();
"step 4";
var target = trigger.source;
if (target.isIn() && event.count > 0 && player.hasSkill("twenyuan"))
player.chooseBool(get.prompt("twenyuan", target), lib.skill.twenyuan2.prompt2).set("ai", function () {
var evt = _status.event.getTrigger();
return lib.skill.twenyuan2.check(evt, evt.player);
});
else event.finish();
"step 5";
if (result.bool) {
player.logSkill("twenyuan2", trigger.source);
event.goto(1);
}
},
},
//马岱
twqianxi: {
audio: "qianxi",
trigger: { player: "phaseZhunbeiBegin" },
preHidden: true,
content: function () {
"step 0";
player.draw();
"step 1";
if (player.hasCard(card => lib.filter.cardDiscardable(card, player, "tweqianxi"), "he")) player.chooseToDiscard("he", true);
else event.finish();
"step 2";
if (
!result.bool ||
!game.hasPlayer(target => {
return player != target && get.distance(player, target) <= 1;
})
) {
event.finish();
return;
}
event.color = get.color(result.cards[0], player);
player
.chooseTarget(function (card, player, target) {
return player != target && get.distance(player, target) <= 1;
}, true)
.set("ai", function (target) {
return get.effect(target, { name: "sha" }, _status.event.player, _status.event.player) + 5;
});
"step 3";
if (result.bool) {
var target = result.targets[0];
player.line(target);
target.storage.twqianxi2 = event.color;
target.addTempSkill("twqianxi2");
player.addTempSkill("twqianxi_self");
player.markAuto("twqianxi_self", [target]);
}
},
subSkill: {
self: {
audio: "qianxi",
charlotte: true,
onremove: true,
forced: true,
trigger: { player: "phaseJieshuBegin" },
filter: function (event, player) {
return player.hasHistory("sourceDamage", evt => {
if (!evt.card || evt.card.name != "sha" || !evt.player.isIn()) return false;
if (player.getStorage("twqianxi_self").includes(evt.player)) return true;
return false;
});
},
content: function () {
"step 0";
var targets = [];
player.getHistory("sourceDamage", evt => {
if (!evt.card || evt.card.name != "sha") return false;
if (player.getStorage("twqianxi_self").includes(evt.player)) {
targets.add(evt.player);
}
return false;
});
player.line(targets);
for (var target of targets) {
target.storage.twqianxi3 = target.storage.twqianxi2;
target.addTempSkill("twqianxi3", { player: "phaseAfter" });
}
},
},
},
},
twqianxi2: {
mark: true,
charlotte: true,
onremove: true,
intro: {
markcount: () => 0,
content: function (storage) {
return "不能使用或打出" + get.translation(storage) + "手牌";
},
},
mod: {
cardEnabled2: function (card, player) {
if (get.itemtype(card) == "card" && get.color(card) == player.getStorage("twqianxi2") && get.position(card) == "h") return false;
},
},
},
twqianxi3: {
mod: {
cardEnabled2: function (card, player) {
if (get.itemtype(card) == "card" && get.color(card) != player.getStorage("twqianxi3") && get.position(card) == "h") return false;
},
},
mark: true,
intro: {
content: function (storage) {
return "不能使用或打出非" + get.translation(storage) + "手牌";
},
},
charlotte: true,
onremove: true,
},
//牛金
twcuorui: {
audio: "cuorui",
limited: true,
skillAnimation: true,
animationColor: "thunder",
trigger: { player: "phaseZhunbeiBegin" },
filter: function (event, player) {
return game.hasPlayer(function (current) {
return current.countCards("h") > player.countCards("h");
});
},
check: function (event, player) {
var num = 0;
for (var target of game.players) {
if (target != player && target.countCards("h") > num) num = target.countCards("h");
}
num = Math.min(num, 5 + player.countCards("h"));
return num - player.countCards("h") >= 2;
},
prompt: function (event, player) {
var num = 0;
for (var target of game.players) {
if (target != player && target.countCards("h") > num) num = target.countCards("h");
}
num = Math.min(num, 5 + player.countCards("h"));
return get.prompt("twcuorui") + "(可摸" + get.cnNumber(num - player.countCards("h")) + "张牌)";
},
content: function () {
"step 0";
player.awakenSkill("twcuorui");
var num = 0;
for (var target of game.players) {
if (target != player && target.countCards("h") > num) num = target.countCards("h");
}
num = Math.min(num, 5 + player.countCards("h"));
player.drawTo(num);
if (!player.isDisabledJudge()) {
player.disableJudge();
event.finish();
} else
player.chooseTarget("挫锐是否对一名其他角色造成1点伤害", lib.filter.notMe).set("ai", function (target) {
var player = _status.event.player;
return get.damageEffect(target, player, player);
});
"step 1";
if (result.bool) {
player.line(result.targets[0]);
result.targets[0].damage();
}
},
},
twliewei: {
audio: "liewei",
trigger: { source: "dieAfter" },
forced: true,
content: function () {
"step 0";
if (!player.hasSkill("twcuorui", null, null, false) || !player.awakenedSkills.includes("twcuorui")) event._result = { index: 0 };
else
player
.chooseControl()
.set("prompt", "裂围:请选择一项")
.set("choiceList", ["摸两张牌", "重置〖挫锐〗"])
.set("ai", function () {
return 1;
});
"step 1";
if (result.index == 0) player.draw(2);
else player.restoreSkill("twcuorui");
},
},
//母兵脸
twzhengrong: {
audio: "drlt_zhenrong",
trigger: { player: "useCardAfter", source: "damageSource" },
filter: function (event, player) {
if (!event.isPhaseUsing(player)) return false;
if (event.name == "damage")
return (
player
.getHistory("sourceDamage", evt => {
return evt.getParent("phaseUse") == event.getParent("phaseUse");
})
.indexOf(event) == 0
);
if (!event.targets || event.targets.every(target => target == player)) return false;
return (
player
.getAllHistory("useCard", function (evt) {
if (!evt.isPhaseUsing(player)) return false;
if (evt.targets.every(target => target == player)) return false;
return true;
})
.indexOf(event) %
2 ==
1
);
},
direct: true,
content: function () {
"step 0";
if (
!game.hasPlayer(function (target) {
return target != player && target.countCards("he");
})
) {
event.finish();
return;
}
player
.chooseTarget(get.prompt("twzhengrong"), "将一名其他角色的一张牌置于武将牌上,称为“荣”", function (card, player, target) {
return target != player && target.countCards("he");
})
.set("ai", function (target) {
return get.effect(target, { name: "guohe_copy2" }, _status.event.player, _status.event.player);
});
"step 1";
if (result.bool) {
var target = result.targets[0];
event.target = result.targets[0];
player.logSkill("twzhengrong", target);
player.choosePlayerCard(target, "he", true);
} else event.finish();
"step 2";
if (result.bool) player.addToExpansion(result.links, target, "give").gaintag.add("twzhengrong");
},
marktext: "荣",
onremove: function (player, skill) {
var cards = player.getExpansions(skill);
if (cards.length) player.loseToDiscardpile(cards);
},
intro: {
content: "expansion",
markcount: "expansion",
},
},
twhongju: {
derivation: ["twqingce", "twsaotao"],
audio: "drlt_hongju",
trigger: { player: "phaseZhunbeiBegin" },
forced: true,
juexingji: true,
skillAnimation: true,
animationColor: "thunder",
filter: function (event, player) {
return player.getExpansions("twzhengrong").length >= 3;
},
content: function () {
"step 0";
player.awakenSkill("twhongju");
player.draw(player.getExpansions("twzhengrong").length);
"step 1";
if (player.countCards("h") == 0) event.goto(3);
else {
var next = player.chooseToMove("鸿举:请选择要交换的手牌和“荣”");
next.set("list", [
[get.translation(player) + "(你)的“荣”", player.getExpansions("twzhengrong"), "twzhengrong_tag"],
["手牌区", 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 player.getUseValue(a) - player.getUseValue(b);
}),
cards2 = cards.splice(0, player.getExpansions("twzhengrong").length);
return [cards2, cards];
});
}
"step 2";
if (result.bool) {
var pushs = result.moved[0],
gains = result.moved[1];
pushs.removeArray(player.getExpansions("twzhengrong"));
gains.removeArray(player.getCards("h"));
if (!pushs.length || pushs.length != gains.length) return;
player.addToExpansion(pushs, player, "giveAuto").gaintag.add("twzhengrong");
game.log(player, "将", pushs, "作为“荣”置于武将牌上");
player.gain(gains, "gain2");
}
"step 3";
player.addSkills("twqingce");
player
.chooseBool("是否减1点体力上限并获得〖扫讨〗")
.set("ai", () => _status.event.bool)
.set("bool", player.isDamaged() && player.countCards("h") >= 3 ? (Math.random() < 0.5 ? true : false) : false);
"step 4";
if (result.bool) {
player.loseMaxHp();
player.addSkills("twsaotao");
game.delayx();
}
},
ai: {
combo: "twzhengrong",
},
},
twqingce: {
enable: "phaseUse",
audio: "drlt_qingce",
filter: function (event, player) {
return player.getExpansions("twzhengrong").length > 0;
},
chooseButton: {
dialog: function (event, player) {
return ui.create.dialog("清侧:请选择要移去的“荣”", player.getExpansions("twzhengrong"), "hidden");
},
backup: function (links, player) {
return {
card: links[0],
filterCard: function () {
return false;
},
selectCard: -1,
filterTarget: function (card, player, target) {
return target.countDiscardableCards(player, "hej") > 0;
},
delay: false,
audio: "drlt_qingce",
content: lib.skill.twqingce.contentx,
ai: {
result: {
target: function (player, target) {
return get.effect(target, { name: "guohe" }, player, target);
},
},
},
};
},
prompt: () => "弃置一名角色区域内的一张牌",
},
contentx: function () {
"step 0";
var card = lib.skill.twqingce_backup.card;
player.loseToDiscardpile([card]);
"step 1";
if (target.countDiscardableCards(player, "hej") > 0) player.discardPlayerCard("hej", true, target);
},
ai: {
combo: "twzhengrong",
order: 8,
result: {
player: function (player) {
if (
game.hasPlayer(function (target) {
return get.effect(target, { name: "guohe" }, player, player) > 4 * Math.max(0, 5 - player.getExpansions("twzhengrong").length);
})
)
return 1;
return 0;
},
},
},
},
twsaotao: {
audio: 2,
trigger: { player: "useCard" },
filter: function (event, player) {
return event.card.name == "sha" || get.type(event.card) == "trick";
},
forced: true,
content: function () {
trigger.directHit.addArray(game.players);
},
ai: { directHit_ai: true },
},
//大小乔
twxingwu: {
audio: "xingwu",
trigger: { player: "phaseDiscardBegin" },
filter: function (event, player) {
return player.countCards("he");
},
direct: true,
content: function () {
"step 0";
player
.chooseCard("he", get.prompt("twxingwu"), "将一张牌置于武将牌上作为“星舞”")
.set("ai", function (card) {
if (_status.event.goon) return 20 - get.value(card);
return 7 - get.value(card);
})
.set("goon", player.needsToDiscard() || player.getExpansions("twxingwu").length > 1);
"step 1";
if (result.bool) {
player.logSkill("twxingwu");
var cards = result.cards;
player.addToExpansion(cards, player, "give").gaintag.add("twxingwu");
} else event.finish();
"step 2";
game.delayx();
if (player.getExpansions("twxingwu").length < 3 || !game.hasPlayer(current => current != player)) event.finish();
"step 3";
player
.chooseButton(["是否移去三张“星舞”牌并发射核弹?", player.getExpansions("twxingwu")], 3)
.set("ai", function (button) {
if (_status.event.goon) return 1;
return 0;
})
.set(
"goon",
game.hasPlayer(current => get.damageEffect(current, player, player) < 0)
);
"step 4";
if (result.bool) player.loseToDiscardpile(result.links);
else event.finish();
"step 5";
player.chooseTarget("星舞:选择一名其他角色", "弃置其装备区内的所有牌。然后对其造成2点伤害若其性别包含女性则改为1点", true, lib.filter.notMe).set("ai", function (target) {
return (
get.damageEffect(target, player, player) *
Math.sqrt(
4 +
target.countCards("e", function (card) {
return get.value(card, target) > 0;
})
) *
(target.hasSex("female") ? 1 : 2)
);
});
"step 6";
if (result.bool && result.targets && result.targets.length) {
var target = result.targets[0];
player.line(target, "green");
var num = target.countCards("e");
if (num) player.discardPlayerCard(target, "e", num, true);
target.damage(target.hasSex("female") ? 1 : 2);
}
},
intro: {
content: "expansion",
markcount: "expansion",
onunmark: function (storage, player) {
if (player.hasSkill("twpingting")) return;
player.removeAdditionalSkill("twpingting");
},
},
onremove: function (player, skill) {
if (player.hasSkill("twpingting")) return;
var cards = player.getExpansions(skill);
if (cards.length) player.loseToDiscardpile(cards);
},
},
twpingting: {
audio: 2,
trigger: { global: ["roundStart", "dying"] },
init: function (player, skill) {
if (player.getExpansions("twxingwu").length) player.addAdditionalSkill(skill, ["tianxiang", "liuli"]);
else player.removeAdditionalSkill(skill);
},
filter: function (event, player) {
if (event.name == "dying") return player == _status.currentPhase && event.player != player;
return true;
},
forced: true,
group: "twpingting_update",
derivation: ["tianxiang", "liuli"],
content: function () {
"step 0";
player.draw();
player.chooseCard("he", "娉婷:将一张牌置于武将牌上,称为“星舞”", true).set("ai", function (card) {
return -get.value(card);
});
"step 1";
if (result.bool) {
var cards = result.cards;
player.addToExpansion(cards, player, "give").gaintag.add("twxingwu");
}
},
onremove: function (player, skill) {
if (player.hasSkill("twxingwu")) return;
var cards = player.getExpansions(skill);
if (cards.length) player.loseToDiscardpile(cards);
},
subSkill: {
update: {
trigger: { player: ["loseAfter", "loseAsyncAfter", "addToExpansionAfter"] },
filter: function (event, player) {
var cards = player.getExpansions("twxingwu"),
skills = player.additionalSkills.twpingting;
return !((cards.length && skills && skills.length) || (!cards.length && (!skills || !skills.length)));
},
forced: true,
silent: true,
content: function () {
lib.skill.twpingting.init(player, "twpingting");
},
},
},
},
tianxiang_daxiaoqiao: { audio: 2, inherit: "tianxiang" },
liuli_daxiaoqiao: { audio: 2, inherit: "liuli" },
//傅肜
twxuewei: {
audio: "xuewei",
trigger: { global: "phaseUseBegin" },
filter: function (event, player) {
return event.player != player && game.players.length > 2 && !player.hasSkill("twxuewei_round");
},
direct: true,
content: function () {
"step 0";
player
.chooseTarget(get.prompt2("twxuewei"), function (card, player, target) {
return target != player && target != _status.event.getTrigger().player;
})
.set("ai", function (target) {
if (get.attitude(player, _status.event.getTrigger().player) >= 0) return 0;
return get.attitude(player, target);
});
"step 1";
if (result.bool) {
var target = result.targets[0];
event.target = target;
player.logSkill("twxuewei", trigger.player, false);
player.addTempSkill("twxuewei_round", "roundStart");
player.line2([trigger.player, target]);
trigger.player
.chooseControl("选项一", "选项二")
.set("choiceList", ["本回合不能对" + get.translation(target) + "使用【杀】且手牌上限-2", "令" + get.translation(player) + "视为对你使用一张【决斗】"])
.set("ai", function () {
var player = _status.event.player,
source = _status.event.getParent().player;
if (get.effect(player, { name: "juedou" }, source, player) > 0) return 1;
if (player.hp - player.countCards("h") > 2 || player.hp <= 2) return 0;
return 1;
});
} else event.finish();
"step 2";
game.log(trigger.player, "选择了", "#g【血卫】", "的", "#y" + result.control);
if (result.control == "选项一") {
trigger.player.markAuto("twxuewei_block", [target]);
trigger.player.addTempSkill("twxuewei_block");
} else player.useCard({ name: "juedou", isCard: true }, trigger.player, false);
},
subSkill: {
round: { charlotte: true },
block: {
charlotte: true,
onremove: true,
locked: true,
mark: true,
marktext: "卫",
intro: {
content: function (storage, player) {
if (!storage || !storage.length) return;
return "不能对" + get.translation(storage) + "使用【杀】;手牌上限-" + 2 * storage.length;
},
},
mod: {
maxHandcard: function (player, num) {
return num - 2 * player.getStorage("twxuewei_block").length;
},
playerEnabled: function (card, player, target) {
if (card.name == "sha" && player.getStorage("twxuewei_block").includes(target)) return false;
},
},
},
},
},
twliechi: {
audio: "liechi",
trigger: { player: "damageEnd" },
filter: function (event, player) {
return event.source && event.source.hp >= player.hp && (event.source.countCards("h") > player.countCards("h") || event.source.countCards("he"));
},
direct: true,
content: function () {
"step 0";
var num = trigger.source.countCards("h") - player.countCards("h");
event.num = num;
var list = [],
choiceList = ["令" + get.translation(trigger.source) + "弃置" + get.cnNumber(num) + "张手牌", "弃置" + get.translation(trigger.source) + "一张牌", "背水!弃置一张装备牌,然后依次执行以上所有选项"];
if (trigger.source.countCards("h") > player.countCards("h")) list.push("选项一");
else choiceList[0] = '<span style="opacity:0.5">' + choiceList[0] + "</span>";
if (trigger.source.countCards("he")) list.push("选项二");
else choiceList[1] = '<span style="opacity:0.5">' + choiceList[1] + "</span>";
if (
trigger.source.countCards("h") > player.countCards("h") &&
trigger.source.countCards("he") &&
player.countCards("he", { type: "equip" }) &&
game.getGlobalHistory("changeHp", evt => {
return evt.player == player && evt.getParent()._dyinged;
}).length
)
list.push("背水!");
else choiceList[2] = '<span style="opacity:0.5">' + choiceList[2] + "(未进入过濒死状态)</span>";
player
.chooseControl(list, "cancel2")
.set("prompt", get.prompt("twliechi", trigger.source))
.set("choiceList", choiceList)
.set("ai", () => _status.event.choice)
.set(
"choice",
(function () {
if (get.attitude(player, trigger.source) > 0) return "cancel2";
if (list.includes("背水!")) return "背水!";
if (num > 1) return "选项一";
return "选项二";
})()
);
"step 1";
if (result.control != "cancel2") {
player.logSkill("twliechi", trigger.source);
game.log(player, "选择了", "#g【烈斥】", "的", "#y" + result.control);
if (result.control == "背水!") player.chooseToDiscard("he", { type: "equip" }, true);
if (result.control != "选项二") trigger.source.chooseToDiscard("h", num, true);
if (result.control != "选项一") player.discardPlayerCard(trigger.source, "he", true);
}
},
},
//卢植
twmingren: {
marktext: "任",
intro: {
content: "expansion",
markcount: "expansion",
},
onremove: function (player, skill) {
var cards = player.getExpansions(skill);
if (cards.length) player.loseToDiscardpile(cards);
},
group: "twmingren_change",
audio: "nzry_mingren_1",
trigger: { global: "phaseBefore", player: "enterGame" },
forced: true,
locked: false,
filter: function (event, player) {
return (event.name != "phase" || game.phaseNumber == 0) && !player.getExpansions("twmingren").length;
},
content: function () {
"step 0";
player.draw();
"step 1";
if (!player.countCards("h")) event.finish();
else
player.chooseCard("h", "明任:将一张手牌置于武将牌上,称为“任”", true).set("ai", function (card) {
return 6 - get.value(card);
});
"step 2";
if (result.bool) player.addToExpansion(result.cards[0], player, "give", "log").gaintag.add("twmingren");
},
subSkill: {
change: {
audio: "nzry_mingren_1",
trigger: { player: ["phaseUseBegin", "phaseUseEnd"] },
filter: function (event, player) {
return player.countCards("he") && player.getExpansions("twmingren").length;
},
direct: true,
content: function () {
"step 0";
player.chooseCard("he", get.prompt("twmingren"), "用一张牌替换“任”(" + get.translation(player.getExpansions("twmingren")[0]) + "").set("ai", function (card) {
var player = _status.event.player;
var color = get.color(card);
if (color == get.color(player.getExpansions("twmingren")[0])) return false;
var num = 0;
var list = [];
player.countCards("he", function (cardx) {
if (cardx != card || get.color(cardx) != color) return false;
if (list.includes(cardx.name)) return false;
list.push(cardx.name);
switch (cardx.name) {
case "wuxie":
num += game.countPlayer() / 2.2;
break;
case "caochuan":
num += 1.1;
break;
case "shan":
num += 1;
break;
}
});
return num * (30 - get.value(card));
});
"step 1";
if (result.bool) {
player.logSkill("twmingren");
player.addToExpansion(result.cards[0], "log", "give", player).gaintag.add("twmingren");
var card = player.getExpansions("twmingren")[0];
if (card) player.gain(card, "gain2");
}
},
},
},
2024-05-06 14:15:59 +00:00
ai:{
combo: "twzhenliang",
},
},
twzhenliang: {
group: ["twzhenliang_1", "twzhenliang_2"],
audio: "nzry_zhenliang_1",
mark: true,
zhuanhuanji: true,
marktext: "☯",
intro: {
content: function (storage, player, skill) {
if (player.storage.twzhenliang == true) return "当你或你攻击范围内的一名角色于你的回合外受到伤害时,你可以弃置一张牌令此伤害-1。然后若你以此法弃置的牌颜色与“任”的颜色相同你摸一张牌。";
return "出牌阶段限一次。你可以弃置一张牌并对攻击范围内的一名角色造成1点伤害。然后若你以此法弃置的牌颜色与“任”的颜色相同你摸一张牌。";
},
},
subSkill: {
1: {
audio: "nzry_zhenliang_1",
enable: "phaseUse",
filter: function (event, player) {
if (player.storage.twzhenliang) return false;
return game.hasPlayer(function (current) {
return player.inRange(current);
});
},
position: "he",
filterCard: true,
filterTarget: function (card, player, target) {
return player.inRange(target);
},
check: function (card) {
var player = _status.event.player,
cardx = player.getExpansions("twmingren")[0];
if (cardx && get.color(cardx, player) == get.color(card, player)) return 10 - get.value(card);
return 7 - get.value(card);
},
prompt: "弃置一张牌并对攻击范围内的一名角色造成1点伤害",
content: function () {
"step 0";
player.changeZhuanhuanji("twzhenliang");
var cardx = player.getExpansions("twmingren")[0];
target.damage("nocard");
if (!cardx || get.color(cards[0], player) != get.color(cardx, player)) event.finish();
"step 1";
player.draw();
},
ai: {
order: 5,
result: {
player: function (player, target) {
return get.damageEffect(target, player, player);
},
},
},
},
2: {
audio: "nzry_zhenliang_1",
trigger: { global: "damageBegin4" },
filter: function (event, player) {
if (_status.currentPhase == player || !player.storage.twzhenliang) return false;
return player.countCards("he") && event.num > 0 && (event.player == player || player.inRange(event.player));
},
direct: true,
content: function () {
"step 0";
player
.chooseToDiscard("he", get.prompt("twzhenliang", trigger.player), "弃置一张牌令此伤害-1")
.set("ai", function (card) {
if (_status.event.goon) {
var player = _status.event.player,
cardx = player.getExpansions("twmingren")[0];
if (cardx && get.color(cardx, player) == get.color(card, player)) return 10 - get.value(card);
return 6 - get.value(card);
}
return 0;
})
.set("goon", get.attitude(player, trigger.player) > 0).logSkill = ["twzhenliang", trigger.player];
"step 1";
if (result.bool) {
player.changeZhuanhuanji("twzhenliang");
var cardx = player.getExpansions("twmingren")[0];
if (cardx && get.color(result.cards[0], player) == get.color(cardx, player)) player.draw();
trigger.num--;
}
},
},
},
},
//张南
twfenwu: {
audio: 2,
trigger: { player: "phaseJieshuBegin" },
filter: function (event, player) {
return game.hasPlayer(function (current) {
return current != player && player.canUse("sha", current, false, false);
});
},
direct: true,
content: function () {
"step 0";
var list = [];
player.getHistory("useCard", function (evt) {
if (get.type(evt.card) != "basic") return;
var name = evt.card.name,
nature = game.hasNature(evt.card) ? get.nature(evt.card) : "";
if (!list.includes(name + nature)) list.push(name + nature);
});
event.addDamage = list.length > 1;
player
.chooseTarget(get.prompt("twfenwu"), "失去1点体力并视为使用一张无距离限制的【杀】" + (event.addDamage ? "(伤害基数+1" : ""), function (card, player, target) {
return target != player && player.canUse("sha", target, false, false);
})
.set("ai", function (target) {
var player = _status.event.player;
if (player.hp + player.countCards("hs", { name: ["tao", "jiu"] }) <= 1) return -1;
var num = 1;
if (
(!target.mayHaveShan(
player,
"use",
target.getCards("h", i => {
return i.hasGaintag("sha_notshan");
})
) ||
player.hasSkillTag(
"directHit_ai",
true,
{
target: target,
card: { name: "sha" },
},
true
)) &&
!target.hasSkillTag("filterDamage", null, {
player: player,
card: { name: "sha" },
})
) {
num = 1.3;
}
return get.effect(target, { name: "sha" }, player, player) * num;
});
"step 1";
if (result.bool) {
var num = 1;
var target = result.targets[0];
player.logSkill("twfenwu", target);
player.loseHp();
if (event.addDamage) {
num = 2;
game.log("#y杀", "的伤害基数+1");
}
player.useCard({ name: "sha", isCard: true }, target, false).baseDamage = num;
}
},
},
//呼厨泉
twfupan: {
audio: 3,
trigger: {
player: "damageEnd",
source: "damageSource",
},
check: () => true,
onremove: true,
content: function () {
"step 0";
if (!player.storage.twfupan) player.storage.twfupan = {};
player.draw(trigger.num);
"step 1";
if (
player.countCards("he") &&
game.hasPlayer(current => {
return !(player.storage.twfupan[current.playerid] >= 2) && player != current;
})
) {
player.chooseCardTarget({
filterCard: true,
selectCard: 1,
position: "he",
forced: true,
targetprompt: function (target) {
return !_status.event.player.storage.twfupan[target.playerid] ? "你摸两张牌" : "对其<br>造成伤害";
},
filterTarget: function (card, player, target) {
return !(player.storage.twfupan[target.playerid] >= 2) && player != target;
},
ai1: function (card) {
var player = _status.event.player;
if (get.value(card, false, "raw") < 0) return 20 * get.value(card);
if (player == _status.currentPhase) return 20 - player.getUseValue(card);
return 20 - get.value(card);
},
ai2: function (target) {
var player = _status.event.player;
var att = get.attitude(player, target);
if (ui.selected.cards.length && get.value(ui.selected.cards[0], false, "raw") < 0) {
return -0.1 - att;
}
if (player.storage.twfupan[target.playerid] === undefined) return 5;
else if (player.storage.twfupan[target.playerid] === 1) return get.damageEffect(target, player, player);
return 1;
},
prompt: "请选择要交出的卡牌和目标角色",
});
} else event.finish();
"step 2";
if (result.bool) {
var cards = result.cards,
target = result.targets[0];
player.line(target, "green");
player.give(cards, target);
event.target = target;
if (!player.storage.twfupan[target.playerid]) {
player.storage.twfupan[target.playerid] = 1;
player.draw(2);
event.finish();
} else {
player
.chooseBool("复叛:是否对" + get.translation(target) + "造成1点伤害", "然后你不能再因此技能交给其牌")
.set("ai", () => _status.event.bool)
.set("bool", get.damageEffect(target, player, player) > 0);
}
}
"step 3";
if (result.bool) {
player.line(target, "fire");
target.damage();
player.storage.twfupan[target.playerid]++;
}
},
ai: {
maixie: true,
maixie_hp: true,
threaten: 0.9,
},
},
//刘璋
twyaohu: {
audio: "yinlang",
trigger: { player: "phaseBegin" },
direct: true,
filter: function (event, player) {
return (
!player.hasSkill("twyaohu_round") &&
game.hasPlayer(function (current) {
return current.group && current.group != "unknown";
})
);
},
content: function () {
"step 0";
var list = [];
game.countPlayer(function (current) {
if (current.group && current.group != "unknown") list.add(current.group);
});
list.sort(function (a, b) {
return lib.group.indexOf(a) - lib.group.indexOf(b);
});
if (!player.hasSkill("twyaohu")) list.push("cancel2");
player
.chooseControl(list)
.set("prompt", "邀虎:请选择一个势力")
.set("ai", function () {
return _status.event.choice;
})
.set(
"choice",
(function () {
var getn = function (group) {
return game.countPlayer(function (current) {
if (current.group != group) return false;
if (player == current) return 2;
if (get.attitude(current, player) > 0) return 1;
return 1.3;
});
};
list.sort(function (a, b) {
return getn(b) - getn(a);
});
return list[0];
})()
);
"step 1";
if (result.control != "cancel2") {
player.logSkill(
"twyaohu",
game.filterPlayer(function (current) {
return current.group == result.control;
})
);
game.log(player, "选择了", "#y" + get.translation(result.control + 2));
player.storage.yaohu = result.control;
player.storage.twyaohu = result.control;
player.markSkill("twyaohu");
}
},
ai: { combo: "jutu" },
intro: { content: "已选择了$势力" },
group: "twyaohu_gain",
subSkill: {
round: {},
gain: {
audio: "yinlang",
trigger: { global: "phaseUseBegin" },
filter: function (event, player) {
return event.player.group == player.storage.yaohu && event.player.isIn() && player.getExpansions("jutu").length > 0;
},
forced: true,
locked: false,
logTarget: "player",
content: function () {
"step 0";
var target = trigger.player;
event.target = target;
target.chooseButton(["选择获得一张“生”", player.getExpansions("jutu")], true).set("ai", function (button) {
return get.value(button.link, player);
});
"step 1";
if (result.bool) {
target.gain(result.links, "give", player);
}
"step 2";
if (
game.hasPlayer(function (current) {
return current != player && current != target;
})
) {
player
.chooseTarget(true, "选择" + get.translation(target) + "使用【杀】的目标", function (card, player, target) {
return target != player && target != _status.event.source;
})
.set("source", target)
.set("ai", function (target) {
var evt = _status.event;
return get.effect(target, { name: "sha" }, evt.source, evt.player);
});
} else {
event._result = { bool: false };
event.goto(4);
}
"step 3";
var target2 = result.targets[0];
player.line(target2, "green");
target
.chooseToUse(
function (card, player, event) {
if (get.name(card) != "sha") return false;
return lib.filter.filterCard.apply(this, arguments);
},
"对" + get.translation(target2) + "使用一张杀,否则本回合使用伤害牌指定" + get.translation(player) + "为目标时须交给" + get.translation(player) + "两张牌,否则此牌对" + get.translation(player) + "无效"
)
.set("targetRequired", true)
.set("complexSelect", true)
.set("filterTarget", function (card, player, target) {
if (target != _status.event.sourcex && !ui.selected.targets.includes(_status.event.sourcex)) return false;
return lib.filter.targetEnabled.apply(this, arguments);
})
.set("sourcex", target2)
.set("addCount", false);
"step 4";
if (!result.bool) player.addTempSkill("twyaohu_effect");
},
},
effect: {
audio: "yinlang",
trigger: { global: "useCardToPlayer" },
charlotte: true,
forced: true,
filter: function (event, player) {
return event.target == player && get.tag(event.card, "damage");
},
logTarget: "player",
content: function () {
"step 0";
var hs = trigger.player.getCards("he");
if (hs.length < 2) event._result = { bool: false };
else
trigger.player
.chooseCard(2, "交给" + get.translation(player) + "两张牌,否则取消" + get.translation(trigger.card) + "对其的目标", "he")
.set("ai", card => {
if (_status.event.goon) return 5 - get.value(card);
return 0;
})
.set("goon", get.effect(player, trigger.card, trigger.player, trigger.player) > 0);
"step 1";
if (result.bool) {
trigger.player.give(result.cards, player);
} else {
trigger.untrigger();
trigger.targets.remove(player);
trigger.getParent().triggeredTargets1.remove(player);
}
},
},
},
},
//李遗
twjiaohua: {
audio: 2,
trigger: { global: "gainAfter" },
filter: function (event, player) {
if (event.getParent().name != "draw") return false;
if (event.player != player && !event.player.isMinHp()) return false;
var cards = event.cards,
list = ["basic", "trick", "equip"];
for (var card of cards) if (list.includes(get.type2(card))) list.remove(get.type2(card));
for (var type of event.player.getStorage("twjiaohua_gained")) if (list.includes(type)) list.remove(type);
return list.length > 0;
},
check: function (event, player) {
return get.attitude(player, event.player) > 0;
},
prompt2: function (event, player) {
var cards = event.cards,
list = ["basic", "trick", "equip"];
for (var card of cards) if (list.includes(get.type2(card))) list.remove(get.type2(card));
for (var type of event.player.getStorage("twjiaohua_gained")) if (list.includes(type)) list.remove(type);
var name = event.player == player ? "你" : get.translation(event.player);
return (
"令" +
name +
"从牌堆或弃牌堆中获得一张" +
(event.player.isUnderControl(true)
? list
.map(i => get.translation(i) + "牌")
.join("、")
.replace(/(.*)、/, "$1或")
: "本次未获得的类别的牌")
);
},
logTarget: "player",
content: function () {
trigger.player.addTempSkill("twjiaohua_gained");
var cards = trigger.cards,
list = ["basic", "trick", "equip"];
for (var card of cards) if (list.includes(get.type2(card))) list.remove(get.type2(card));
for (var type of trigger.player.getStorage("twjiaohua_gained")) if (list.includes(type)) list.remove(type);
list.randomSort();
var card = get.cardPile(function (card) {
return list.includes(get.type2(card));
});
if (card) {
trigger.player.gain(card, "gain2");
trigger.player.markAuto("twjiaohua_gained", [get.type2(card)]);
}
},
subSkill: {
gained: { onremove: true, charlotte: true },
},
},
//阎象
twkujian: {
audio: 3,
enable: "phaseUse",
filterCard: true,
selectCard: [1, 3],
usable: 1,
discard: false,
lose: false,
delay: false,
filterTarget: lib.filter.notMe,
global: "twkujian_ai",
check: function (card) {
if (ui.selected.cards.length && ui.selected.cards[0].name == "du") return 0;
if (!ui.selected.cards.length && card.name == "du") return 20;
var player = get.owner(card);
if (ui.selected.cards.length >= Math.max(2, player.countCards("h") - player.hp)) return 0;
if (player.hp == player.maxHp || player.storage.jsprende < 0 || player.countCards("h") <= 1) {
var players = game.filterPlayer();
for (var i = 0; i < players.length; i++) {
if (players[i].hasSkill("haoshi") && !players[i].isTurnedOver() && !players[i].hasJudge("lebu") && get.attitude(player, players[i]) >= 3 && get.attitude(players[i], player) >= 3) {
return 11 - get.value(card);
}
}
if (player.countCards("h") > player.hp) return 10 - get.value(card);
if (player.countCards("h") > 2) return 6 - get.value(card);
return -1;
}
return 10 - get.value(card);
},
content: function () {
player.give(cards, target).gaintag.add("twkujianx");
player.addSkill("twkujian_draw");
player.addSkill("twkujian_discard");
},
ai: {
expose: 0.2,
order: 7,
result: {
target: function (player, target) {
if (target.hasSkillTag("nogain")) return 0;
if (ui.selected.cards.length && ui.selected.cards[0].name == "du") {
if (target.hasSkillTag("nodu")) return 0;
return -10;
}
if (target.hasJudge("lebu")) return 0;
var nh = target.countCards("h");
var np = player.countCards("h");
if (player.hp == player.maxHp || player.storage.jsprende < 0 || player.countCards("h") <= 1) {
if (nh >= np - 1 && np <= player.hp && !target.hasSkill("haoshi")) return 0;
}
return Math.max(1, 5 - nh);
},
},
effect: {
target: function (card, player, target) {
if (player == target && get.type(card) == "equip") {
if (player.countCards("e", { subtype: get.subtype(card) })) {
if (
game.hasPlayer(function (current) {
return current != player && get.attitude(player, current) > 0;
})
) {
return 0;
}
}
}
},
},
},
subSkill: {
draw: {
audio: "twkujian",
trigger: { global: ["useCardAfter", "respondAfter"] },
forced: true,
logTarget: "player",
charlotte: true,
filter: function (event, player) {
return event.player.hasHistory("lose", evt => {
if (event != evt.getParent()) return false;
for (var i in evt.gaintag_map) {
if (evt.gaintag_map[i].includes("twkujianx")) return true;
}
});
},
content: function () {
"step 0";
game.asyncDraw([player, trigger.player]);
"step 1";
game.delayx();
},
},
discard: {
audio: "twkujian",
trigger: {
global: ["loseAfter", "equipAfter", "addJudgeAfter", "gainAfter", "loseAsyncAfter", "addToExpansionAfter"],
},
forced: true,
logTarget: function (event, player) {
return game.filterPlayer(function (current) {
var evt = event.getl(current);
if (!evt || !evt.hs || !evt.hs.length) return false;
if (event.name == "lose") {
var name = event.getParent().name;
if (name == "useCard" || name == "respond") return false;
for (var i in event.gaintag_map) {
if (event.gaintag_map[i].includes("twkujianx")) return true;
}
return false;
}
return current.hasHistory("lose", function (evt) {
if (event != evt.getParent()) return false;
for (var i in evt.gaintag_map) {
if (evt.gaintag_map[i].includes("twkujianx")) return true;
}
return false;
});
});
},
charlotte: true,
filter: function (event, player) {
return game.hasPlayer(function (current) {
var evt = event.getl(current);
if (!evt || !evt.hs || !evt.hs.length) return false;
if (event.name == "lose") {
var name = event.getParent().name;
if (name == "useCard" || name == "respond") return false;
for (var i in event.gaintag_map) {
if (event.gaintag_map[i].includes("twkujianx")) return true;
}
return false;
}
return current.hasHistory("lose", function (evt) {
if (event != evt.getParent()) return false;
for (var i in evt.gaintag_map) {
if (evt.gaintag_map[i].includes("twkujianx")) return true;
}
return false;
});
});
},
content: function () {
"step 0";
var event = trigger;
var targets = game.filterPlayer(function (current) {
var evt = event.getl(current);
if (!evt || !evt.hs || !evt.hs.length) return false;
if (event.name == "lose") {
var name = event.getParent().name;
if (name == "useCard" || name == "respond") return false;
for (var i in event.gaintag_map) {
if (event.gaintag_map[i].includes("twkujianx")) return true;
}
return false;
}
return current.hasHistory("lose", function (evt) {
if (event != evt.getParent()) return false;
for (var i in evt.gaintag_map) {
if (evt.gaintag_map[i].includes("twkujianx")) return true;
}
return false;
});
});
targets.add(player);
targets.sortBySeat();
_status.event.targets = targets;
"step 1";
var target = targets.shift();
if (target.countCards("he") > 0) target.chooseToDiscard("he", true);
if (targets.length > 0) event.redo();
},
},
ai: {
charlotte: true,
ai: {
effect: {
2024-05-11 08:40:41 +00:00
player_use(card, player, target) {
if (
card.cards &&
card.cards.some(i => i.hasGaintag("twkujianx")) &&
game.hasPlayer(current => {
return get.attitude(player, current) > 0;
})
)
return [1, 1];
},
},
},
mod: {
aiOrder: function (player, card, num) {
if (
get.itemtype(card) == "card" &&
card.hasGaintag("twkujianx") &&
game.hasPlayer(current => {
return get.attitude(player, current) > 0;
})
)
return num + 0.5;
},
aiValue: function (player, card, num) {
if (
get.itemtype(card) == "card" &&
card.hasGaintag("twkujianx") &&
game.hasPlayer(current => {
return get.attitude(player, current) > 0;
})
)
return num + 0.5;
},
},
},
},
},
twruilian: {
audio: 2,
trigger: { global: "roundStart" },
direct: true,
content: function () {
"step 0";
player.chooseTarget(get.prompt2("twruilian")).set("ai", function (target) {
var player = _status.event.player,
att = get.attitude(player, target),
eff = att / (player == target ? 2 : 1) + 1;
if (att >= 0) {
if (target.hasSkill("yongsi")) return eff * 5;
if (target.hasSkill("zhiheng") || target.hasSkill("rezhiheng")) return eff * 4;
if (target.hasSkill("rekurou")) return eff * 3;
if (target.hasSkill("xinlianji") || target.hasSkill("dclianji")) return eff * 2;
if (target.needsToDiscard()) return eff * 1.5;
return eff;
}
return 0;
});
"step 1";
if (result.bool) {
var target = result.targets[0];
player.logSkill("twruilian", target);
player.markAuto("twruilian2", [target]);
player.addSkill("twruilian2");
}
},
},
twruilian2: {
trigger: { global: "phaseEnd" },
direct: true,
charlotte: true,
onremove: true,
filter: function (event, player) {
return player.getStorage("twruilian2").includes(event.player);
},
intro: { content: "已选择$" },
content: function () {
"step 0";
player.removeSkill("twruilian2");
var target = trigger.player;
event.target = target;
var cards = [];
target.getHistory("lose", function (evt) {
if (evt.type == "discard") cards.addArray(evt.cards2);
});
if (cards.length < 2) event.finish();
else event.cards = cards;
"step 1";
var list = [];
for (var type of ["basic", "trick", "equip"]) {
for (var card of event.cards) {
if (get.type2(card) == type) {
list.push(type);
break;
}
}
}
list.push("cancel2");
player
.chooseControl(list)
.set("prompt", "睿敛:是否与" + get.translation(target) + "各获得一种类型的牌?")
.set("ai", function () {
var player = _status.event.player,
list = _status.event.controls;
if (player.hp <= 3 && !player.countCards("h", { name: ["shan", "tao"] }) && list.includes("basic")) return "basic";
if (player.countCards("he", { type: "equip" }) < 2 && list.includes("equip")) return "equip";
if (list.includes("trick")) return "trick";
return list.remove("cancel2").randomGet();
});
"step 2";
if (result.control != "cancel2") {
player.logSkill("twruilian2", target);
var type = result.control;
var list = [target, player].sortBySeat(_status.currentPhase),
cards = [];
for (var current of list) {
var card = get.discardPile(function (card) {
return get.type2(card) == type && !cards.includes(card);
});
if (card) {
cards.push(card);
current.gain(card, "gain2");
}
}
}
},
},
//夏侯恩
twfujian: {
audio: 2,
group: "twfujian_lose",
trigger: {
global: "phaseBefore",
player: ["enterGame", "phaseZhunbeiBegin"],
},
filter: function (event, player) {
if (player.getEquips(1).length) return false;
return event.name != "phase" || game.phaseNumber == 0;
},
forced: true,
content: function () {
var card = get.cardPile2(function (card) {
return get.type(card) == "equip" && get.subtype(card) == "equip1";
});
event.card = card;
if (card) player.equip(card);
else {
game.log("但是牌堆中没有武器牌了!");
event.finish();
}
},
subSkill: {
lose: {
audio: "twfujian",
trigger: {
player: "loseAfter",
global: ["equipAfter", "addJudgeAfter", "gainAfter", "loseAsyncAfter", "addToExpansionAfter"],
},
filter: function (event, player) {
if (player == _status.currentPhase) return false;
if (event.name == "gain" && event.player == player) return false;
var evt = event.getl(player);
if (evt && evt.cards2 && evt.cards2.some(i => get.subtype(i) == "equip1")) return true;
return false;
},
forced: true,
content: function () {
player.loseHp();
},
},
},
},
twjianwei: {
audio: 2,
trigger: { player: "phaseZhunbeiBegin" },
filter: function (event, player) {
if (!player.getEquips(1).length) return false;
return game.hasPlayer(function (current) {
return player.inRange(current) && player.canCompare(current);
});
},
pindianCheck: function (player, target) {
var hs = player.getCards("h").sort(function (a, b) {
return b.number - a.number;
});
var ts = target.getCards("h").sort(function (a, b) {
return b.number - a.number;
});
if (!hs.length || !ts.length) return 0;
if (Math.min(13, hs[0].number + player.getAttackRange()) > ts[0].number || (ts[0].number > 9 && get.value(ts[0]) <= 5) || target.countCards("j")) return true;
return false;
},
direct: true,
locked: false,
group: ["twjianwei_pindian", "twjianwei_zhaocha"],
content: function () {
"step 0";
player
.chooseTarget(get.prompt("twjianwei"), "与攻击范围内的一名角色拼点。若你赢,你获得其每个区域里的一张牌;若其赢,其获得你装备区里的武器牌", function (card, player, target) {
return player.inRange(target) && player.canCompare(target);
})
.set("ai", function (target) {
var player = _status.event.player;
if (lib.skill.twjianwei.pindianCheck(player, target)) return -5 * get.attitude(player, target);
return -get.attitude(player, target);
});
"step 1";
if (result.bool) {
var target = result.targets[0];
event.target = target;
player.logSkill("twjianwei", target);
player.chooseToCompare(target);
} else event.finish();
"step 2";
if (result.bool) {
var num = 0;
if (target.countCards("h")) num++;
if (target.countCards("e")) num++;
if (target.countCards("j")) num++;
if (num) {
player.gainPlayerCard(target, num, "hej", true).set("filterButton", function (button) {
for (var i = 0; i < ui.selected.buttons.length; i++) {
if (get.position(button.link) == get.position(ui.selected.buttons[i].link)) return false;
}
return true;
});
}
} else if (!result.tie) {
var card = player.getEquips(1);
if (card.length) target.gain(card, player, "give");
}
},
mod: {
aiValue: function (player, card, num) {
if (card.name == "qinggang" || card.name == "qibaodao") return num / 5;
},
},
ai: {
unequip: true,
unequip_ai: true,
skillTagFilter: function (player, tag, arg) {
if (!arg || !arg.card || arg.card.name != "sha" || !player.getEquip(1)) return false;
},
},
subSkill: {
pindian: {
audio: "twjianwei",
trigger: { player: "compare", target: "compare" },
filter: function (event, player) {
if (!player.getEquips(1).length || player.getAttackRange() <= 0) return false;
if (event.player == player) return !event.iwhile;
return true;
},
forced: true,
locked: false,
content: function () {
var num = player.getAttackRange();
if (player == trigger.player) {
trigger.num1 += num;
if (trigger.num1 > 13) trigger.num1 = 13;
} else {
trigger.num2 += num;
if (trigger.num2 > 13) trigger.num2 = 13;
}
game.log(player, "的拼点牌点数+" + num);
},
},
//你是故意找茬是不是
zhaocha: {
trigger: { global: "phaseZhunbeiBegin" },
filter: function (event, player) {
if (event.player == player) return false;
return event.player.canCompare(player);
},
direct: true,
content: function () {
"step 0";
trigger.player
.chooseBool("剑威:是否与" + get.translation(player) + "拼点?", "若你赢,你获得其装备区里的武器牌;若其赢,其获得你每个区域里的一张牌")
.set("ai", () => _status.event.choice)
.set("choice", get.attitude(trigger.player, player) < 0 && !lib.skill.twjianwei.pindianCheck(player, trigger.player));
"step 1";
if (result.bool) {
trigger.player.logSkill("twjianwei", player);
trigger.player.chooseToCompare(player);
} else event.finish();
"step 2";
if (!result.tie) {
if (result.bool) {
var card = player.getEquips(1);
if (card.length) trigger.player.gain(card, player, "give");
} else {
var num = 0;
if (trigger.player.countCards("h")) num++;
if (trigger.player.countCards("e")) num++;
if (trigger.player.countCards("j")) num++;
if (num)
player.gainPlayerCard(trigger.player, num, "hej", true).set("filterButton", function (button) {
for (var i = 0; i < ui.selected.buttons.length; i++) {
if (get.position(button.link) == get.position(ui.selected.buttons[i].link)) return false;
}
return true;
});
}
}
},
},
},
},
//夏侯尚
twtanfeng: {
audio: 2,
trigger: { player: "phaseZhunbeiBegin" },
filter: function (event, player) {
return game.hasPlayer(function (current) {
return current != player && current.countDiscardableCards(player, "hej") > 0;
});
},
direct: true,
content: function () {
"step 0";
player
.chooseTarget(get.prompt2("twtanfeng"), function (card, player, target) {
return target != player && target.countDiscardableCards(player, "hej") > 0;
})
.set("ai", function (target) {
var player = _status.event.player,
num = 1;
if (get.attitude(player, target) > 0) num = 3;
else if (!target.countCards("he") || !target.canUse("sha", player)) {
if (target.hp + target.countCards("hs", { name: ["tao", "jiu"] }) <= 1) num = 2;
else num = 1.2;
}
return get.effect(target, { name: "guohe" }, player, player) * num * (player.hp <= 1 && get.attitude(player, target) <= 0 ? 0 : 1);
})
.setHiddenSkill(event.name);
"step 1";
if (result.bool) {
var target = result.targets[0];
event.target = target;
player.logSkill("twtanfeng", target);
player.discardPlayerCard(target, "hej", true);
} else event.finish();
"step 2";
target.chooseCardTarget({
position: "hes",
prompt: "选择一张牌当做【杀】对" + get.translation(player) + "使用",
prompt2: "或点击“取消”受到其造成的1点火焰伤害并令其跳过本回合的一个阶段准备阶段和结束阶段除外",
filterCard: function (card, player) {
return player.canUse(get.autoViewAs({ name: "sha" }, [card]), _status.event.getParent().player, false);
},
filterTarget: function (card, player, target) {
var source = _status.event.getParent().player;
if (target != source && !ui.selected.targets.includes(source)) return false;
card = get.autoViewAs({ name: "sha" }, [card]);
return lib.filter.filterTarget.apply(this, arguments);
},
selectTarget: function () {
var card = get.card(),
player = get.player();
if (!card) return;
card = get.autoViewAs({ name: "sha" }, [card]);
var range = [1, 1];
game.checkMod(card, player, range, "selectTarget", player);
return range;
},
ai1: function (card) {
var player = _status.event.player,
target = _status.event.getParent().player;
var eff = get.effect(target, get.autoViewAs({ name: "sha" }, [card]), player, player);
var eff2 = get.damageEffect(player, target, player, "fire");
if (eff < 0 || eff2 > 0 || eff2 > eff || get.tag(card, "recover")) return 0;
return (player.hp == 1 ? 10 : 6) - get.value(card);
},
ai2: function (target) {
if (target == _status.event.getParent().player) return 100;
return get.effect(target, { name: "sha" }, _status.event.player);
},
});
"step 3";
if (result.bool) {
var cards = result.cards,
targets = result.targets;
var cardx = get.autoViewAs({ name: "sha" }, cards);
target.useCard(cardx, cards, targets, false);
event.finish();
} else {
player.line(target, "fire");
target.damage(1, "fire");
}
"step 4";
if (!target.isIn()) {
event.finish();
return;
}
var list = [];
var list2 = [];
event.map = {
phaseJudge: "判定阶段",
phaseDraw: "摸牌阶段",
phaseUse: "出牌阶段",
phaseDiscard: "弃牌阶段",
};
for (var i of ["phaseJudge", "phaseDraw", "phaseUse", "phaseDiscard"]) {
if (!player.skipList.includes(i)) {
i = event.map[i];
list.push(i);
if (i != "判定阶段" && i != "弃牌阶段") list2.push(i);
}
}
target
.chooseControl(list)
.set("prompt", "探锋:令" + get.translation(player) + "跳过一个阶段")
.set("ai", function () {
return _status.event.choice;
})
.set(
"choice",
(function () {
var att = get.attitude(target, player);
var num = player.countCards("j");
if (att > 0) {
if (list.includes("判定阶段") && num > 0) return "判定阶段";
return "弃牌阶段";
}
if (list.includes("摸牌阶段") && player.hasJudge("lebu")) return "摸牌阶段";
if ((list.includes("出牌阶段") && player.hasJudge("bingliang")) || player.needsToDiscard() > 0) return "出牌阶段";
return list2.randomGet();
})()
);
"step 5";
for (var i in event.map) {
if (event.map[i] == result.control) player.skip(i);
}
target.popup(result.control);
target.line(player);
game.log(player, "跳过了", "#y" + result.control);
},
},
//宗预
twzhibian: {
audio: "zhibian",
trigger: { player: "phaseUseBegin" },
filter: function (event, player) {
return game.hasPlayer(current => current != player && player.canCompare(current));
},
direct: true,
content: function () {
"step 0";
player
.chooseTarget(get.prompt("twzhibian"), "与一名其他角色拼点", function (card, player, target) {
return target != player && player.canCompare(target);
})
.set("ai", function (target) {
if (!_status.event.goon) return false;
var att = get.attitude(player, target);
if (
att < 0 &&
(target.countCards("h") > 1 ||
target.countCards("e", function (card) {
return player.canEquip(card) && get.effect(player, card, target, player) > 0;
}))
)
return -att / Math.sqrt(target.countCards("h"));
if (!player.isDamaged()) return false;
if (att <= 0) return (1 - att) / Math.sqrt(target.countCards("h"));
return Math.sqrt((2 / att) * Math.sqrt(target.countCards("h")));
})
.set(
"goon",
(function () {
if (
!player.hasCard(function (card) {
return card.number >= 14 - player.hp && get.value(card) <= 5;
})
)
return false;
return true;
})()
);
"step 1";
if (result.bool) {
var target = result.targets[0];
event.target = target;
player.logSkill("twzhibian", target);
player.chooseToCompare(target);
} else event.finish();
"step 2";
if (result.bool) {
var list = [],
list2 = ["将" + get.translation(target) + "区域中的一张牌移动到你的区域内", "回复1点体力", "背水!弃置一张非基本牌,并依次执行上述所有选项"];
if (
target.countCards("h") ||
target.hasCard(function (card) {
return player.canEquip(card);
}, "e") ||
target.hasCard(function (card) {
return player.canAddJudge(card);
}, "j")
)
list.push("选项一");
else list2[0] = '<span style="opacity:0.5">' + list2[0] + "</span>";
if (player.isDamaged()) list.push("选项二");
else list2[1] = '<span style="opacity:0.5">' + list2[1] + "</span>";
if (!list.length) {
event.finish();
return;
}
if (player.countCards("he", card => get.type(card) != "basic")) list.push("背水!");
else list2[2] = '<span style="opacity:0.5">' + list2[2] + "</span>";
list.push("cancel2");
player
.chooseControl(list)
.set("prompt", "直辩:选择一项")
.set("choiceList", list2)
.set("ai", function () {
var target = _status.event.getParent().target;
if (
_status.event.controls.includes("背水!") &&
player.isDamaged() &&
(target.countCards("h") ||
target.countCards("e", function (card) {
return player.canEquip(card) && get.value(card, target) >= 4 + player.getDamagedHp();
}))
)
return 2;
if (
player.isDamaged() &&
(player.hp <= 2 ||
(!target.countCards("h") &&
!target.countCards("e", function (card) {
return player.canEquip(card) && get.value(card, target) >= 4 + player.getDamagedHp();
})))
)
return 1;
return 0;
});
} else {
player.loseHp();
event.finish();
}
"step 3";
if (result.control != "cancel2") {
event.control = result.control;
if (
result.control == "背水!" &&
player.countCards("he", function (card) {
return get.type(card) != "basic";
})
)
player.chooseToDiscard("he", true, function (card) {
return get.type(card) != "basic";
});
} else event.finish();
"step 4";
if (event.control == "选项一" || event.control == "背水!") {
player.choosePlayerCard(target, "hej", true).set("ai", get.buttonValue);
} else event.goto(6);
"step 5";
if (result.bool) {
var card = result.cards[0];
switch (get.position(card)) {
case "h":
player.gain(card, target, "giveAuto");
break;
case "e":
target.$give(card, player, false);
player.equip(card);
break;
case "j":
target.$give(card, player, false);
player.addJudge(card);
break;
}
}
"step 6";
if (event.control == "选项二" || event.control == "背水!") player.recover();
},
},
twyuyan: {
audio: "yuyan",
trigger: { target: "useCardToTarget" },
filter: function (event, player) {
return event.card.name == "sha" && event.card.isCard && player.hp < event.player.hp;
},
forced: true,
logTarget: "player",
content: function () {
"step 0";
var num = get.number(trigger.card),
str = "";
if (typeof num == "number") str = "点数大于" + get.cnNumber(num) + "的";
else str = "非基本";
if (
(typeof num == "number" &&
(num >= 13 ||
!trigger.player.hasCard(function (card) {
if (_status.connectMode && get.position(card) == "h") return true;
return get.number(card) > num;
}, "he"))) ||
(typeof num != "number" &&
!trigger.player.hasCard(function (card) {
if (_status.connectMode && get.position(card) == "h") return true;
return get.type(card) != "basic";
}, "he"))
)
event._result = { bool: false };
else
trigger.player
.chooseCard(
"he",
function (card) {
if (typeof _status.event.number == "number") return get.number(card) > _status.event.number;
return get.type(card) != "basic";
},
"交给" + get.translation(player) + "一张" + str + "牌,或取消" + get.translation(trigger.card) + "对其的目标"
)
.set("number", num)
.set("ai", function (card) {
if (card.name == "shan" || card.name == "tao" || card.name == "jiu") return false;
return 6 - get.value(card);
});
"step 1";
if (result.bool) trigger.player.give(result.cards, player);
else {
trigger.targets.remove(player);
trigger.getParent().triggeredTargets2.remove(player);
trigger.untrigger();
}
},
ai: {
effect: {
2024-05-11 08:40:41 +00:00
target_use(card, player, target, current) {
if (card.name == "sha" && player.hp > target.hp && get.attitude(player, target) < 0) {
var num = get.number(card);
var bs = player.getCards("h", function (cardx) {
return (typeof num == "number" ? get.number(cardx) > num : get.type(cardx) != "basic") && !["", "", ""].includes(cardx.name);
});
if (bs.length < 2) return 0;
if (player.hasSkill("jiu") || player.hasSkill("tianxianjiu")) return;
if (bs.length <= 2) {
for (var i = 0; i < bs.length; i++) {
if (get.value(bs[i]) < 6) {
return [1, 0, 1, -0.5];
}
}
return 0;
}
return [1, 0, 1, -0.5];
}
},
},
},
},
//周处
twguoyi: {
audio: "zhangming",
trigger: { player: "useCardToTargeted" },
filter: function (event, player) {
if (event.target == player || (event.card.storage && event.card.storage.twguoyi)) return false;
return (event.card.name == "sha" || get.type(event.card) == "trick") && (event.target.isMaxHp() || event.target.isMaxHandcard() || player.countCards("h") <= player.getDamagedHp() + 1);
},
check: function (event, player) {
return get.attitude(player, event.target) <= 0;
},
logTarget: "target",
group: "twguoyi_reuse",
content: function () {
"step 0";
event.bool1 = false;
event.bool2 = false;
if (trigger.target.isMaxHp() || trigger.target.isMaxHandcard()) event.bool1 = true;
if (player.countCards("h") <= player.getDamagedHp() + 1) event.bool2 = true;
if (!trigger.target.countCards("he")) event._result = { index: 0 };
else
trigger.target
.chooseControl()
.set("choiceList", ["本回合不能使用或打出手牌", "弃置" + get.cnNumber(player.getDamagedHp() + 1) + "张牌"])
.set("ai", function () {
var player = _status.event.player;
if (player.countCards("h") <= player.getHandcardLimit()) return 0;
return 1;
});
"step 1";
player.addTempSkill("twguoyi_" + result.index);
if (result.index == 0) trigger.target.addTempSkill("twguoyi_hand");
else trigger.target.chooseToDiscard("he", player.getDamagedHp() + 1, true);
"step 2";
if ((event.bool1 && event.bool2) || (player.hasSkill("twguoyi_0") && player.hasSkill("twguoyi_1"))) {
if (!trigger.getParent().twguoyi_reuse)
trigger.getParent().twguoyi_reuse = {
name: trigger.card.name,
nature: trigger.card.nature,
isCard: true,
storage: { twguoyi: true },
};
}
},
subSkill: {
0: { charlotte: true },
1: { charlotte: true },
hand: {
charlotte: true,
mark: true,
intro: { content: "不能使用或打出手牌" },
mod: {
cardEnabled2: function (card) {
if (get.position(card) == "h") return false;
},
},
},
reuse: {
charlotte: true,
trigger: { player: "useCardAfter" },
filter: function (event, player) {
return event.twguoyi_reuse;
},
direct: true,
content: function () {
var card = trigger.twguoyi_reuse;
for (var i of trigger.targets) {
if (!i.isIn() || !player.canUse(card, i, false)) return;
}
if (trigger.addedTarget && !trigger.addedTarget.isIn()) return;
if (trigger.addedTargets && trigger.addedTargets.length) {
for (var i of trigger.addedTargets) {
if (!i.isIn()) return;
}
}
var next = player.useCard(get.copy(card), trigger.targets, false);
if (trigger.addedTarget) next.addedTarget = trigger.addedTarget;
if (trigger.addedTargets && trigger.addedTargets.length) next.addedTargets = trigger.addedTargets.slice(0);
},
},
},
},
twchuhai: {
audio: "chuhai",
trigger: { global: "phaseEnd" },
filter: function (event, player) {
var targets = [];
player.getHistory("sourceDamage", evt => {
if (player != evt.player && evt._dyinged) targets.add(evt.player);
});
return targets.length >= 2;
},
forced: true,
locked: false,
dutySkill: true,
skillAnimation: true,
animationColor: "wood",
group: "twchuhai_lose",
content: function () {
"step 0";
game.log(player, "成功完成使命");
player.awakenSkill("twchuhai");
if (!player.isDisabledJudge()) player.disableJudge();
event.current = player.next;
"step 1";
if (!event.current.countCards("he")) event.goto(3);
else event.current.chooseCard("交给" + get.translation(player) + "一张牌", "he", true).set("ai", get.disvalue2);
"step 2";
if (result.bool && result.cards && result.cards.length) event.current.give(result.cards, player);
"step 3";
event.current = event.current.next;
if (event.current != player) event.goto(1);
},
subSkill: {
lose: {
audio: "chuhai",
trigger: {
global: ["gainAfter", "loseAsyncAfter"],
},
forced: true,
dutySkill: true,
filter: function (event, player) {
var cards = event.getg(player);
if (!cards.length) return false;
return game.hasPlayer(current => {
if (current == player) return false;
var evt = event.getl(current);
if (evt && evt.cards && evt.cards.length) return true;
return false;
});
},
content: function () {
"step 0";
var cards = trigger.getg(player);
if (!cards.length) {
event.finish();
return;
}
player
.chooseCard("h", "除害:将其中一张得到的牌置入弃牌堆", true, function (card) {
return _status.event.cards.includes(card);
})
.set("ai", function (card) {
return -get.value(card);
})
.set("cards", cards);
"step 1";
if (result.bool) player.loseToDiscardpile(result.cards);
},
},
},
},
//桥公
twyizhu: {
audio: "yizhu",
group: ["twyizhu_use", "twyizhu_discard"],
trigger: { player: "phaseJieshuBegin" },
forced: true,
locked: false,
content: function () {
"step 0";
player.draw(2);
"step 1";
var hs = player.getCards("he");
if (!hs.length) event.finish();
else if (hs.length <= 2) event._result = { bool: true, cards: hs };
else player.chooseCard("he", true, 2, "选择两张牌洗入牌堆");
"step 2";
if (result.bool) {
player.$throw(result.cards.length, 1000);
player.lose(result.cards, ui.cardPile).insert_index = function () {
return ui.cardPile.childNodes[get.rand(0, game.players.length * 2 - 2)];
};
player.markAuto("twyizhu", result.cards);
} else event.finish();
"step 3";
game.updateRoundNumber();
game.delayx();
},
intro: {
mark: function (dialog, content, player) {
if (player == game.me || player.isUnderControl()) dialog.addAuto(content);
else {
var names = [];
for (var i of content) names.add(i.name);
return get.translation(names);
}
},
},
subSkill: {
use: {
audio: "yizhu",
trigger: { global: "useCardToPlayer" },
filter: function (event, player) {
return (
player.getStorage("twyizhu").length &&
event.player != player &&
event.targets.length == 1 &&
event.cards.filter(function (i) {
return player.getStorage("twyizhu").includes(i);
}).length > 0
);
},
logTarget: "player",
forced: true,
locked: false,
content: function () {
"step 0";
var list = [];
if (
!game.hasPlayer(function (current) {
return current != trigger.target && lib.filter.targetEnabled2(trigger.card, trigger.player, current);
})
)
event.goto(3);
var filter = function (event, player) {
var card = event.card,
info = get.info(card);
if (info.allowMultiple == false) return false;
if (!info.multitarget) {
return game.hasPlayer(current => lib.filter.targetEnabled2(card, player, current));
}
return false;
};
var enable = filter(trigger.getParent(), trigger.player);
var prompt2 = "操作提示:";
if (enable) prompt2 += "选择一名合法的其他角色,以增加其为目标;或";
prompt2 += "选择目标角色(" + get.translation(trigger.target) + ")和另一名合法的角色,以取消前者为目标并增加后者为目标";
player
.chooseTarget("遗珠:是否" + (enable ? "增加或" : "") + "修改目标?", prompt2, [enable ? 1 : 2, 2], (card, player, target) => {
var evt = _status.event.getTrigger(),
card = evt.card;
if (target == evt.target) return true;
if (ui.selected.targets.length && ui.selected.targets[0] != evt.target) return false;
return lib.filter.targetEnabled2(card, evt.player, target);
})
.set("targetprompt", target => {
return target == _status.event.targetx ? "取消目标" : "增加目标";
})
.set("filterOk", () => {
if (ui.selected.targets.length == 1 && ui.selected.targets[0] == _status.event.targetx) return false;
return true;
})
.set("ai", target => {
var evt = _status.event.getTrigger(),
card = evt.card,
player = _status.event.player;
if (target == evt.target && get.effect(evt.target, card, evt.player, player) < 0) return 100;
if (target == evt.target) return -100;
return get.effect(target, card, evt.player, player);
})
.set("targetx", trigger.target)
.set("card", trigger.card);
"step 1";
if (result.bool) {
var target = result.targets[result.targets[0] == trigger.target ? 1 : 0];
if (result.targets.length > 1) {
player.line2([trigger.target, target]);
trigger.targets.remove(trigger.target);
trigger.getParent().triggeredTargets1.remove(trigger.target);
trigger.untrigger();
} else player.line(target);
trigger.targets.push(target);
}
"step 2";
var list = trigger.cards.filter(function (i) {
return player.getStorage("twyizhu").includes(i);
});
player.unmarkAuto("twyizhu", list);
player.draw();
game.delayx();
},
},
discard: {
trigger: {
global: ["loseAfter", "cardsDiscardAfter", "loseAsyncAfter", "equipAfter"],
},
silent: true,
forced: true,
locked: false,
filter: function (event, player) {
return (
player.getStorage("twyizhu").length &&
event.getd().filter(function (i) {
return player.getStorage("twyizhu").includes(i);
}).length > 0
);
},
content: function () {
var list = trigger.getd().filter(function (i) {
return player.getStorage("twyizhu").includes(i);
});
player.unmarkAuto("twyizhu", list);
},
},
},
},
twluanchou: {
audio: "luanchou",
enable: "phaseUse",
usable: 1,
selectTarget: 2,
filterTarget: true,
multitarget: true,
multiline: true,
content: function () {
"step 0";
game.filterPlayer()
.sortBySeat()
.forEach(function (current) {
current.removeSkills("twgonghuan");
});
"step 1";
targets.sortBySeat();
for (var i of targets) i.addSkills("twgonghuan");
},
derivation: "twgonghuan",
ai: {
order: 10,
expose: 0.2,
result: {
target: function (player, target) {
return Math.max(0.1, target.hp) * (get.attitude(player, target) + 20);
},
},
},
},
twgonghuan: {
audio: "gonghuan",
trigger: { global: "damageBegin4" },
usable: 1,
filter: function (event, player) {
if (event.player == player) return false;
return !event.twgonghuan && event.player.hp <= player.hp && event.player.hasSkill("twgonghuan");
},
check: function (event, player) {
if (get.damageEffect(event.player, event.source, player) > 0 || (get.attitude(player, event.player) > 0 && get.damageEffect(event.player, event.source, event.player) > 0)) return false;
return get.attitude(player, event.player) > 0 && event.player.hp < player.hp && ((["君", "主"].includes(lib.translate[event.player.identity]) && !["野", "内"].includes(lib.translate[player.identity])) || player.hp + player.hujia - event.num > 0);
},
logTarget: "player",
content: function () {
trigger.cancel();
player
.damage(trigger.source ? trigger.source : "nosource", trigger.nature, trigger.num)
.set("card", trigger.card)
.set("cards", trigger.cards).twgonghuan = true;
},
},
//桥蕤
twxiawei: {
audio: 2,
trigger: { player: "phaseZhunbeiBegin" },
direct: true,
locked: false,
group: ["twxiawei_init", "twxiawei_lose", "twxiawei_unmark"],
content: function () {
"step 0";
player
.chooseControl("1", "2", "3", "4", "cancel2")
.set("prompt", get.prompt("twxiawei"))
.set("prompt2", "妄行将X+1张牌置于武将牌上称为“威”")
.set("ai", function () {
var player = _status.event.player;
if (player.maxHp > 3) return 3;
return Math.min(3, player.countCards("he") + 1);
});
"step 1";
if (result.control != "cancel2") {
var num = result.index + 1,
cards = get.cards(num + 1);
player.logSkill("twxiawei");
player.addTempSkill("wangxing");
player.addMark("wangxing", num, false);
player.$gain2(cards, false);
game.log(player, "将", cards, "作为“威”置于了武将牌上");
player.loseToSpecial(cards, "twxiawei").visible = true;
} else event.finish();
"step 2";
player.markSkill("twxiawei");
game.delayx();
},
marktext: "威",
intro: {
mark: function (dialog, storage, player) {
var cards = player.getCards("s", function (card) {
return card.hasGaintag("twxiawei");
});
if (!cards || !cards.length) return;
dialog.addAuto(cards);
},
markcount: function (storage, player) {
return player.countCards("s", function (card) {
return card.hasGaintag("twxiawei");
});
},
onunmark: function (storage, player) {
var cards = player.getCards("s", function (card) {
return card.hasGaintag("twxiawei");
});
if (cards.length) {
player.loseToDiscardpile(cards);
}
},
},
mod: {
aiOrder: function (player, card, num) {
if (get.itemtype(card) == "card" && card.hasGaintag("twxiawei")) return num + 0.5;
},
},
subSkill: {
init: {
audio: "twxiawei",
trigger: { global: "phaseBefore", player: "enterGame" },
filter: function (event, player) {
return event.name != "phase" || game.phaseNumber == 0;
},
forced: true,
locked: false,
content: function () {
"step 0";
var cards = [];
for (var i = 1; i <= 2; i++) {
var card = get.cardPile2(function (card) {
return !cards.includes(card) && get.type(card) == "basic";
});
if (card) cards.push(card);
}
if (cards.length) {
player.$gain2(cards, false);
game.log(player, "将", cards, "作为“威”置于了武将牌上");
player.loseToSpecial(cards, "twxiawei").visible = true;
} else event.finish();
"step 1";
player.markSkill("twxiawei");
game.delayx();
},
},
lose: {
audio: "twxiawei",
trigger: { player: "phaseBegin" },
filter: function (event, player) {
return player.countCards("s", function (card) {
return card.hasGaintag("twxiawei");
});
},
forced: true,
locked: false,
content: function () {
var cards = player.getCards("s", function (card) {
return card.hasGaintag("twxiawei");
});
player.loseToDiscardpile(cards);
},
},
unmark: {
trigger: { player: "loseAfter" },
filter: function (event, player) {
if (!event.ss || !event.ss.length) return false;
return !player.countCards("s", function (card) {
return card.hasGaintag("twxiawei");
});
},
charlotte: true,
forced: true,
silent: true,
content: function () {
player.unmarkSkill("twxiawei");
},
},
},
},
wangxing: {
trigger: { player: "phaseEnd" },
charlotte: true,
onremove: true,
forced: true,
popup: false,
filter: function (event, player) {
return player.countMark("wangxing") > 0;
},
content: function () {
"step 0";
player.chooseToDiscard("he", player.countMark("wangxing"), "妄行:请弃置" + get.cnNumber(player.countMark("wangxing")) + "张牌或减1点体力上限").set("ai", function (card) {
var player = _status.event.player;
if (player.maxHp == 1) return 100 - get.value(card);
return 5 + Math.max(0, 5 - player.maxHp) - get.value(card);
});
"step 1";
if (!result.bool) player.loseMaxHp();
},
intro: { content: "回合结束时,你须弃置#张牌否则减1点体力上限" },
},
twqiongji: {
audio: 2,
trigger: { player: ["useCardAfter", "respondAfter", "damageBegin3"] },
filter: function (event, player) {
if (event.name == "damage")
return !player.countCards("s", function (card) {
return card.hasGaintag("twxiawei");
});
return (
!player.hasSkill("twqiongji_silent") &&
player.getHistory("lose", function (evt) {
if (evt.getParent() != event) return false;
for (var i in evt.gaintag_map) {
if (evt.gaintag_map[i].includes("twxiawei")) return true;
}
return false;
}).length > 0
);
},
forced: true,
content: function () {
if (trigger.name == "damage") trigger.num++;
else {
player.draw();
player.addTempSkill("twqiongji_silent");
}
},
ai: {
combo: "twxiawei",
halfneg: true,
},
subSkill: { silent: { charlotte: true } },
},
//卞夫人
twwanwei: {
audio: "wanwei",
trigger: { global: "damageBegin4" },
filter: function (event, player) {
return event.player.isMinHp();
},
check: function (event, player) {
return get.attitude(player, event.player) > 0 && event.player.hp < player.hp;
},
usable: 1,
logTarget: "player",
prompt2: function (event, player) {
if (player != event.player) {
return "防止" + get.translation(event.player) + "即将受到的" + event.num + "点伤害然后你失去1点体力";
} else if (
event.player == player ||
!game.hasPlayer(function (current) {
return current != player && current.maxHp > player.maxHp;
})
) {
return "于当前回合的结束阶段获得牌堆顶的牌并亮出牌堆底的牌,若展示的牌能被使用,你使用之";
}
},
content: function () {
if (trigger.player != player) {
trigger.cancel();
player.loseHp();
}
if (
trigger.player == player ||
!game.hasPlayer(function (current) {
return current != player && current.maxHp > player.maxHp;
})
)
player.addTempSkill("twwanwei_effect");
},
subSkill: {
effect: {
audio: "wanwei",
charlotte: true,
trigger: { global: "phaseJieshuBegin" },
prompt2: "获得牌堆顶的牌并亮出牌堆底的牌,若展示的牌能被使用,你使用之",
content: function () {
"step 0";
var card = get.cards()[0];
player.gain(card, "gain2");
"step 1";
var card = get.bottomCards()[0];
ui.cardPile.appendChild(card);
game.updateRoundNumber();
player.showCards([card], get.translation(player) + "挽危:牌堆底的牌");
if (player.hasUseTarget(card)) player.chooseUseTarget(card, true);
},
},
},
},
twyuejian: {
audio: "yuejian",
enable: "phaseUse",
filterCard: true,
selectCard: function () {
var player = _status.event.player;
var num = Math.max(1, player.countCards("h") - player.getHandcardLimit());
return [1, num];
},
complexCard: true,
discard: false,
loseTo: "cardPile",
insert: true,
visible: true,
delay: false,
position: "he",
usable: 1,
check: function (card) {
if (ui.selected.cards.length >= 3) return 0;
var player = _status.event.player;
var num = Math.max(1, player.countCards("h") - player.getHandcardLimit());
if (num >= 3) return 5 - get.value(card);
if (num >= 2 && player.isDamaged() && ui.selected.cards.length < 1) return 7 - get.value(card);
if (num >= 1 && player.isDamaged() && !ui.selected.cards.length) return 6 - get.value(card);
return 0;
},
content: function () {
"step 0";
player.$throw(cards.length);
var next = player.chooseToMove();
next.set("list", [["牌堆顶", cards], ["牌堆底"]]);
next.set("prompt", "约俭:将这些牌置于牌堆顶或牌堆底");
next.set("processAI", function (list) {
var cards = list[0][1],
player = _status.event.player;
var target = player.next;
var att = get.sgn(get.attitude(player, target));
var top = [];
var judges = target.getCards("j");
var stopped = false;
if (player != target || !target.hasWuxie()) {
for (var i = 0; i < judges.length; i++) {
var judge = get.judge(judges[i]);
cards.sort(function (a, b) {
return (judge(b) - judge(a)) * att;
});
if (judge(cards[0]) * att < 0) {
stopped = true;
break;
} else {
top.unshift(cards.shift());
}
}
}
var bottom;
if (!stopped) {
cards.sort(function (a, b) {
return (get.value(b, player) - get.value(a, player)) * att;
});
while (cards.length) {
if (get.value(cards[0], player) <= 5 == att > 0) break;
top.unshift(cards.shift());
}
}
bottom = cards.sort(function (a, b) {
return player.getUseValue(a) - player.getUseValue(b);
});
return [top, bottom];
});
"step 1";
var top = result.moved[0];
var bottom = result.moved[1];
top.reverse();
for (var i = 0; i < top.length; i++) {
top[i].fix();
ui.cardPile.insertBefore(top[i], ui.cardPile.firstChild);
}
for (i = 0; i < bottom.length; i++) {
bottom[i].fix();
ui.cardPile.appendChild(bottom[i]);
}
player.popup(get.cnNumber(top.length) + "上" + get.cnNumber(bottom.length) + "下");
game.log(player, "将" + get.cnNumber(top.length) + "张牌置于牌堆顶");
game.updateRoundNumber();
game.delayx();
"step 2";
if (cards.length >= 3) player.gainMaxHp();
"step 3";
if (cards.length >= 2) player.recover();
"step 4";
if (cards.length >= 1) {
player.addSkill("twyuejian_effect");
player.addMark("twyuejian_effect", 1, false);
}
},
ai: {
order: 5,
result: { player: 1 },
},
subSkill: {
effect: {
charlotte: true,
onremove: true,
marktext: "俭",
intro: {
content: "手牌上限+#",
},
mod: {
maxHandcard: function (player, num) {
return num + player.countMark("twyuejian_effect");
},
},
},
},
},
//陈震
twmuyue: {
audio: 1,
enable: "phaseUse",
usable: 1,
filter: function (event, player) {
return player.countCards("he") || player.hasSkill("twmuyue_effect");
},
chooseButton: {
dialog: function () {
var list = [];
for (var i of lib.inpile) {
var type = get.type(i);
if (type == "basic" || type == "trick") list.push([type, "", i]);
}
return ui.create.dialog("睦约", [list, "vcard"]);
},
check: function (button) {
if (
!get.cardPile2(function (cardx) {
return cardx.name == button.link[2];
})
)
return 0;
return get.value({ name: button.link[2] });
},
backup: function (links, player) {
return {
audio: "twmuyue",
filterCard: function (card, player, target) {
return !player.hasSkill("twmuyue_effect");
},
selectCard: function () {
var player = _status.event.player;
return player.hasSkill("twmuyue_effect") ? -1 : 1;
},
check: function (card) {
return 7 - get.value(card);
},
position: "he",
card: links[0],
filterTarget: true,
content: function () {
"step 0";
var card = lib.skill.twmuyue_backup.card;
event.card = card;
player.removeSkill("twmuyue_effect");
var cardx = get.cardPile2(function (cardx) {
return cardx.name == card[2];
});
player.line(target, "green");
if (cardx) target.gain(cardx, "gain2");
else {
player.chat("无牌可得了吗?!");
game.log("但是牌堆中已经没有", "#g【" + get.translation(card[2]) + "】", "了!");
}
"step 1";
if (cards && cards.length && get.name(cards[0], player) == card[2]) player.addSkill("twmuyue_effect");
},
ai: {
result: {
target: function (player, target) {
var att = Math.abs(get.attitude(player, target));
if (target.hasSkill("nogain")) att /= 10;
return att / Math.sqrt(get.distance(player, target, "absolute"));
},
},
},
};
},
prompt: function (links, player) {
return (player.hasSkill("twmuyue_effect") ? "" : "弃置一张牌,") + "令一名角色从牌堆中获得一张【" + get.translation(links[0][2]) + "】";
},
},
ai: {
order: 3,
result: { player: 1 },
},
subSkill: {
effect: {
charlotte: true,
mark: true,
intro: { content: "下一次发动【睦约】无需弃牌" },
},
backup: {},
},
},
twchayi: {
audio: 1,
trigger: { player: "phaseJieshuBegin" },
direct: true,
content: function () {
"step 0";
player.chooseTarget(get.prompt2("twchayi"), lib.filter.notMe).set("ai", function (target) {
var player = _status.event.player;
return -get.attitude(player, target);
});
"step 1";
if (result.bool) {
var target = result.targets[0];
event.target = target;
player.logSkill("twchayi", target);
if (!target.countCards("h")) event._result = { index: 1 };
else target.chooseControl().set("choiceList", ["展示手牌", "下一次使用牌时候弃一张牌"]);
} else event.finish();
"step 2";
target.storage.twchayi_re = [result.index, target.countCards("h")];
target.addSkill("twchayi_re");
target.markSkill("twchayi_re");
if (result.index == 0) target.showCards(target.getCards("h"), get.translation(target) + "的手牌");
else {
target.addMark("twchayi_effect", 1, false);
target.addSkill("twchayi_effect");
}
},
subSkill: {
effect: {
intro: { content: "使用下一张牌时弃置&张牌" },
charlotte: true,
onremove: true,
audio: "twchayi",
trigger: { player: "useCard" },
forced: true,
content: function () {
player.chooseToDiscard("he", true, player.countMark("twchayi_effect"));
player.removeSkill("twchayi_effect");
},
},
re: {
charlotte: true,
onremove: true,
audio: "twchayi",
trigger: { player: "phaseEnd" },
direct: true,
filter: function (event, player) {
return player.storage.twchayi_re;
},
content: function () {
if (player.countCards("h") != player.storage.twchayi_re[1]) {
player.popup("察异");
if (player.storage.twchayi_re[0] == 0) {
player.addMark("twchayi_effect", 1, false);
player.addSkill("twchayi_effect");
} else player.showCards(player.getCards("h"), get.translation(player) + "的手牌");
}
player.removeSkill("twchayi_re");
},
marktext: "异",
intro: {
markcount: function (storage, player) {
if (!storage || !storage.length) return 0;
return storage[1];
},
content: function (storage, player) {
if (!storage || !storage.length) return;
return "下个回合结束时,若你的手牌数不为" + storage[1] + ",你" + (storage[0] == 0 ? "下次使用牌时弃置一张牌" : "展示所有手牌");
},
},
},
},
},
//费祎
twshengxi: {
audio: "shengxi_feiyi",
trigger: { player: "phaseJieshuBegin" },
filter: function (event, player) {
return player.getHistory("useCard").length > 0 && player.getHistory("sourceDamage").length == 0;
},
direct: true,
content: function () {
"step 0";
var list = get.zhinangs();
player.chooseButton(["###" + get.prompt("twshengxi") + "###获得一张智囊并摸一张牌", [list, "vcard"]]).set("ai", function (card) {
return (Math.random() + 0.5) * get.value({ name: card.link[2] }, _status.event.player);
});
"step 1";
if (result.bool) {
player.logSkill("twshengxi");
var card = get.cardPile2(function (card) {
return card.name == result.links[0][2];
});
if (card) player.gain(card, "gain2");
player.draw();
}
},
group: "twshengxi_zhunbei",
subfrequent: ["zhunbei"],
subSkill: {
zhunbei: {
audio: "shengxi_feiyi",
trigger: { player: "phaseZhunbeiBegin" },
frequent: true,
prompt2: "从游戏外或牌堆中获得一张【调剂盐梅】",
content: function () {
if (!_status.tiaojiyanmei_suits || _status.tiaojiyanmei_suits.length > 0) {
if (!lib.inpile.includes("tiaojiyanmei")) {
game.broadcastAll(function () {
lib.inpile.add("tiaojiyanmei");
});
}
if (!_status.tiaojiyanmei_suits) _status.tiaojiyanmei_suits = lib.suit.slice(0);
player.gain(game.createCard2("tiaojiyanmei", _status.tiaojiyanmei_suits.randomRemove(), 6), "gain2");
} else {
var card = get.cardPile2(function (card) {
return card.name == "tiaojiyanmei";
});
if (card) player.gain(card, "gain2");
}
},
},
},
},
twkuanji: {
audio: "fyjianyu",
trigger: {
player: "loseAfter",
global: ["cardsDiscardAfter", "loseAsyncAfter", "equipAfter"],
},
filter: function (event, player) {
if (event.name != "cardsDiscard") {
return event.getd(player, "cards2").length > 0;
} else {
if (event.cards.filterInD("d").length <= 0) return false;
var evt = event.getParent();
if (evt.name != "orderingDiscard") return false;
var evtx = evt.relatedEvent || evt.getParent();
if (evtx.player != player) return false;
if (evtx.name == "useCard") return false;
return player.hasHistory("lose", evtxx => {
return evtx == (evtxx.relatedEvent || evtxx.getParent());
});
}
},
usable: 1,
direct: true,
content: function () {
"step 0";
var cards = [];
if (trigger.name != "cardsDiscard") {
cards = trigger.getd(player, "cards2");
} else cards = trigger.cards.filterInD("d");
player.chooseButton(["宽济:是否将一张牌交给一名其他角色?", cards]).set("ai", function (button) {
var player = _status.event.player;
if (
game.hasPlayer(function (current) {
return current != player && get.attitude(player, current) > 0;
})
)
return Math.abs(get.value(button.link, "raw")) + 1;
return -get.value(button.link, "raw");
});
"step 1";
if (result.bool) {
var card = result.links[0];
event.card = card;
player.chooseTarget("请选择【宽济】的目标", "令一名其他角色获得" + get.translation(card), lib.filter.notMe).set("ai", function (target) {
var player = _status.event.player;
return get.attitude(player, target) * get.value(_status.event.getParent().card, target) * (target.hasSkillTag("nogain") ? 0.1 : 1);
});
} else {
player.storage.counttrigger.twkuanji--;
event.finish();
}
"step 2";
if (result.bool) {
var target = result.targets[0];
player.logSkill("twkuanji", target);
target.gain(card, "gain2");
}
},
},
shengxi_feiyi: { audio: 2 },
//王越
twyulong: {
audio: 2,
trigger: { player: "useCardToPlayered" },
filter: function (event, player) {
if (!event.isFirstTarget) return false;
if (event.card.name != "sha") return false;
return event.targets.some(target => player.canCompare(target));
},
direct: true,
content: function () {
"step 0";
player
.chooseTarget(get.prompt2("twyulong"), (card, player, target) => {
return _status.event.getTrigger().targets.includes(target) && player.canCompare(target);
})
.set("ai", target => {
if (player.hasCard(card => get.value(card) < 6, "h")) return -get.attitude(_status.event.player, target);
});
"step 1";
if (result.bool) {
var target = result.targets[0];
player.logSkill("twyulong", target);
if (player.canCompare(target)) {
player.chooseToCompare(target);
}
} else {
event.finish();
}
"step 2";
if (result.bool) {
var color = get.color(result.player, false);
if (color == "black") trigger.getParent().baseDamage++;
else if (color == "red") trigger.directHit.addArray(game.players);
trigger.getParent().twyulong = true;
player.addTempSkill("twyulong_addCount");
}
},
subSkill: {
addCount: {
charlotte: true,
forced: true,
trigger: { source: "damageSource" },
filter: function (event, player) {
if (!event.card || event.card.name != "sha") return false;
var evt = event.getParent(2);
if (evt.name != "useCard" || !evt.twyulong) return false;
return true;
},
content: function () {
var evt = trigger.getParent(2);
if (evt.addCount !== false) {
evt.addCount = false;
if (player.stat[player.stat.length - 1].card.sha > 0) {
player.stat[player.stat.length - 1].card.sha--;
}
}
},
},
},
},
twjianming: {
audio: 2,
trigger: { player: ["useCard", "respond"] },
filter: function (event, player) {
if (event.card.name != "sha" || !lib.suit.includes(get.suit(event.card))) return false;
var list = [];
player.getHistory("useCard", function (evt) {
if (evt.card.name == "sha") {
if (event.card != evt.card) list.push(get.suit(evt.card));
}
});
player.getHistory("respond", function (evt) {
if (evt.card.name == "sha") {
if (event.card != evt.card) list.push(get.suit(evt.card));
}
});
return !list.includes(get.suit(event.card));
},
forced: true,
content: function () {
player.draw();
},
},
//李彦
twzhenhu: {
audio: 2,
trigger: { player: "useCardToPlayer" },
filter: function (event, player) {
if (!event.isFirstTarget || !get.tag(event.card, "damage")) return false;
return (
!player.hasSkillTag("noCompareSource") &&
game.hasPlayer(target => {
return player.canCompare(target, true);
})
);
},
direct: true,
content: function () {
"step 0";
player
.chooseTarget(get.prompt2("twzhenhu"), [1, 3], function (card, player, target) {
return player.canCompare(target, true);
})
.set("ai", function (target) {
var player = _status.event.player,
targets = _status.event.getTrigger().targets;
var num = 0;
if (player.hasSkill("twlvren")) num += 2 * (ui.selected.targets.length + 1);
if (player.hasSkill("twchuanshu_effect")) num += 3;
var hs = player.getCards("h").sort((a, b) => get.number(b) - get.number(a));
if (hs.length == 0) return -1;
var ts = target.getCards("h").sort((a, b) => get.number(b) - get.number(a));
if (Math.min(13, get.number(hs[0]) + num) <= get.number(ts[0])) return -1;
return get.effect(target, { name: "guohe_copy2" }, player, player) / 2 + (targets.includes(target) ? get.damageEffect(target, player, player) : 0);
});
"step 1";
if (result.bool) {
var targets = result.targets.sortBySeat();
event.targets = targets;
player.logSkill("twzhenhu", targets);
player.draw();
} else event.finish();
"step 2";
player
.chooseToCompare(targets, function (card) {
return get.number(card);
})
.setContent("chooseToCompareMeanwhile");
"step 3";
if (result.winner && result.winner == player) {
event.targets.remove(result.winner);
player.line(event.targets, trigger.card.nature);
player.addTempSkill("twzhenhu_add");
if (!trigger.card.storage) trigger.card.storage = {};
trigger.card.storage.twzhenhu = event.targets;
} else player.loseHp();
},
subSkill: {
add: {
charlotte: true,
onremove: true,
forced: true,
popup: false,
trigger: { global: "damageBegin1" },
filter: function (event, player) {
if (!event.card || !event.card.storage) return false;
var targets = event.card.storage.twzhenhu;
return targets && targets.includes(event.player);
},
content: function () {
trigger.num++;
},
},
},
},
twlvren: {
audio: 2,
trigger: { source: "damageBegin3" },
filter: function (event, player) {
return event.player != player && event.player.isIn() && !event.player.hasMark("twlvren");
},
logTarget: "player",
forced: true,
locked: false,
group: ["twlvren_more", "twlvren_add"],
content: function () {
trigger.player.addMark("twlvren", 1);
},
ai: {
effect: {
player: function (card, player, target) {
if (target && target.hasMark("twlvren")) return 0.33;
},
},
},
marktext: "刃",
intro: { name2: "刃", content: "mark" },
subSkill: {
more: {
audio: "twlvren",
trigger: { player: "useCard2" },
filter: function (event, player) {
var card = event.card,
info = get.info(card);
if (info.allowMultiple == false) return false;
if (event.targets && !info.multitarget) {
return (
get.tag(card, "damage") &&
event.targets &&
game.hasPlayer(function (target) {
return target.hasMark("twlvren") && !event.targets.includes(target) && lib.filter.targetEnabled2(card, player, target);
})
);
}
return false;
},
direct: true,
content: function () {
"step 0";
player
.chooseTarget(get.prompt("twlvren"), "为" + get.translation(trigger.card) + "额外指定一个有“刃”的角色为目标", function (card, player, target) {
var evt = _status.event.getTrigger();
return target.hasMark("twlvren") && !evt.targets.includes(target) && lib.filter.targetEnabled2(evt.card, player, target);
})
.set("ai", function (target) {
return get.effect(target, _status.event.getTrigger().card, _status.event.player);
});
"step 1";
if (result.bool) {
var targets = result.targets;
player.logSkill("twlvren", targets);
player.line(targets, trigger.card.nature);
trigger.targets.addArray(targets);
for (var i of targets) i.removeMark("twlvren", i.countMark("twlvren"), false);
}
},
},
add: {
audio: "twlvren",
trigger: { player: "compare", target: "compare" },
filter: function (event, player) {
if (player != event.target && event.iwhile) return false;
return true;
},
forced: true,
locked: false,
content: function () {
var num = 2 * trigger.lose_list.length;
if (player == trigger.player) {
trigger.num1 += num;
if (trigger.num1 > 13) trigger.num1 = 13;
} else {
trigger.num2 += num;
if (trigger.num2 > 13) trigger.num2 = 13;
}
game.log(player, "的拼点牌点数+", num);
},
},
},
},
//童渊
twchaofeng: {
audio: 2,
enable: ["chooseToUse", "chooseToRespond"],
hiddenCard: function (player, name) {
if (!["sha", "shan"].includes(name)) return false;
return player.hasCard(function (card) {
const name2 = get.name(card);
return (name2 == "sha" || name2 == "shan") && name != name2;
}, "hs");
},
filter: function (event, player) {
const names = [];
if (event.filterCard(get.autoViewAs({ name: "sha" }, "unsure"), player, event)) names.push("shan");
if (event.filterCard(get.autoViewAs({ name: "shan" }, "unsure"), player, event)) names.push("sha");
return (
names.length > 0 &&
player.hasCard(function (card) {
return names.includes(get.name(card));
}, "hs")
);
//return false;
},
group: "twchaofeng_compare",
chooseButton: {
dialog: function (event, player) {
var list = [];
if (event.filterCard({ name: "sha" }, player, event)) {
list.push(["基本", "", "sha"]);
for (var j of lib.inpile_nature) list.push(["基本", "", "sha", j]);
}
if (event.filterCard({ name: "shan" }, player, event)) {
list.push(["基本", "", "shan"]);
}
var dialog = ui.create.dialog("朝凤", [list, "vcard"], "hidden");
dialog.direct = true;
return dialog;
},
check: function (button) {
var player = _status.event.player;
var card = { name: button.link[2], nature: button.link[3] };
if (
_status.event.getParent().type != "phase" ||
game.hasPlayer(function (current) {
return player.canUse(card, current) && get.effect(current, card, player, player) > 0;
})
) {
switch (button.link[2]) {
case "shan":
return 5;
case "sha":
if (button.link[3] == "fire") return 2.95;
else if (button.link[3] == "thunder" || button.link[3] == "ice") return 2.92;
else return 2.9;
}
}
return 0;
},
backup: function (links, player) {
return {
audio: "twchaofeng",
name: links[0][2],
filterCard: function (card, player, target) {
if (lib.skill.twchaofeng_backup.name == "sha") return get.name(card) == "shan";
else return get.name(card) == "sha";
},
selectCard: 1,
check: function (card, player, target) {
return 6 - get.value(card);
},
viewAs: { name: links[0][2], nature: links[0][3] },
position: "hs",
popname: true,
};
},
prompt: function (links, player) {
var view, use;
if (links[0][2] == "sha") {
use = "【闪】";
view = get.translation(links[0][3] || "") + "【" + get.translation(links[0][2]) + "】";
} else {
use = "【杀】";
view = "【闪】";
}
return "将一张" + use + "当做" + view + (_status.event.name == "chooseToUse" ? "使用" : "打出");
},
},
ai: {
skillTagFilter: function (player, tag) {
var name;
switch (tag) {
case "respondSha":
name = "shan";
break;
case "respondShan":
name = "sha";
break;
}
if (!player.countCards("hs", name)) return false;
},
order: function (item, player) {
if (player && _status.event.type == "phase") {
var max = 0;
if (player.countCards("hs", "shan") > 0 && lib.inpile_nature.some(i => player.getUseValue({ name: "sha", nature: i }) > 0)) {
var temp = get.order({ name: "sha" });
if (temp > max) max = temp;
}
if (max > 0) max += 0.3;
return max;
}
return 4;
},
result: {
player: 1,
},
respondSha: true,
respondShan: true,
fireAttack: true,
},
subSkill: {
compare: {
audio: "twchaofeng",
trigger: { player: "phaseUseBegin" },
direct: true,
content: function () {
"step 0";
player
.chooseTarget(get.prompt("twchaofeng"), "选择至多三名角色共同拼点。赢的角色视为对所有没赢的角色使用一张火【杀】", [1, 3], (card, player, target) => {
return player.canCompare(target);
})
.set("ai", function (target) {
var player = _status.event.player,
targets = _status.event.getTrigger().targets;
var num = 0,
card = { name: "sha", nature: "fire", isCard: true };
if (target.hasSkill("twlvren")) num += 2 * (ui.selected.targets.length + 1);
if (target.hasSkill("twchuanshu_effect")) num += 3;
var hs = player.getCards("h").sort((a, b) => get.number(b) - get.number(a));
var ts = target.getCards("h").sort((a, b) => get.number(b) - get.number(a));
if (get.number(hs[0]) <= Math.min(13, get.number(ts[0]) + num)) {
return 6 + get.effect(player, card, target, target);
}
return get.effect(target, { name: "guohe_copy2" }, player, player) / 2 + get.effect(target, card, player, player);
});
"step 1";
if (result.bool) {
event.targets = result.targets;
player.logSkill("twchaofeng_compare", event.targets);
player.chooseToCompare(event.targets).setContent("chooseToCompareMeanwhile");
}
"step 2";
if (result.winner) {
var targets = [player].addArray(event.targets).sortBySeat(player);
targets.remove(result.winner);
var card = { name: "sha", nature: "fire", isCard: true };
var targetsx = targets.filter(function (target) {
return result.winner.canUse(card, target, false);
});
if (targetsx.length) result.winner.useCard(card, targetsx, "noai").set("addCount", false);
}
},
},
},
},
twchuanshu: {
audio: 2,
trigger: { player: "phaseZhunbeiBegin" },
limited: true,
skillAnimation: true,
animationColor: "qun",
direct: true,
content: function () {
"step 0";
player.chooseTarget(get.prompt2("twchuanshu")).set("ai", target => get.attitude(_status.event.player, target));
"step 1";
if (result.bool) {
player.awakenSkill("twchuanshu");
var target = result.targets[0];
player.logSkill("twchuanshu", target);
target.addMark("twchuanshu_mark", 1, false);
target.addSkill("twchuanshu_effect");
target.markAuto("twchuanshu_effect", [player]);
player.addSkill("twchuanshu_clear");
player.markAuto("twchuanshu_clear", [target]);
}
},
subSkill: {
mark: {
charlotte: true,
},
effect: {
audio: "twchuanshu",
trigger: {
player: "compare",
target: "compare",
},
direct: true,
forced: true,
charlotte: true,
nopop: true,
mark: true,
intro: {
content: function (storage, player) {
var shisyou = player.getStorage("twchuanshu_effect").filter(i => i.isIn());
var str = "<li>拼点牌点数+3";
if (player.hasMark("twchuanshu_mark")) {
str += "<li>使用的下一张【杀】对除" + get.translation(shisyou) + "外的角色造成伤害时,此伤害+" + player.countMark("twchuanshu_mark") + "";
if (!shisyou.includes(player)) {
str += "<li>使用的下一张【杀】结算结束后," + get.translation(shisyou) + "摸等同于伤害值的牌;";
}
}
str = str.slice(0, -1) + "。";
return str;
},
},
filter: function (event, player, name) {
if (event.player == player && event.iwhile > 0) return false;
return (player == event.player ? event.num1 : event.num2) < 13;
},
content: function () {
game.log(player, "的拼点牌点数+3");
if (player == trigger.player) trigger.num1 = Math.min(13, trigger.num1 + 3);
else trigger.num2 = Math.min(13, trigger.num2 + 3);
},
group: "twchuanshu_damage",
},
damage: {
charlotte: true,
trigger: { player: ["useCard", "useCardAfter"], source: "damageBegin1" },
filter: function (event, player, name) {
if (name == "useCard") return event.card.name == "sha" && player.hasMark("twchuanshu_mark");
if (name == "damageBegin1") return event.card && event.card.twchuanshu_mark && !player.getStorage("twchuanshu_effect").includes(event.player);
return (
event.card.twchuanshu_mark &&
player.hasHistory("sourceDamage", function (evt) {
return evt.card == event.card;
}) &&
player.getStorage("twchuanshu_effect").filter(function (target) {
return target.isIn() && target != player;
}).length
);
},
forced: true,
content: function () {
var name = event.triggername;
if (name == "useCard") {
var num = player.countMark("twchuanshu_mark");
trigger.card.twchuanshu_mark = num;
player.removeMark("twchuanshu_mark", num, false);
} else if (name == "damageBegin1") trigger.num++;
else {
var num1 = trigger.card.twchuanshu_mark;
var num2 = 0;
player.getHistory("sourceDamage", function (evt) {
if (evt.card == trigger.card) num2 += evt.num;
});
var targets = player.getStorage("twchuanshu_effect").filter(function (target) {
return target.isIn() && target != player;
});
if (targets.length == 1) targets[0].draw(num1 * num2);
else game.asyncDraw(targets, num1 * num2);
}
},
},
clear: {
charlotte: true,
onremove: true,
trigger: { player: "phaseBegin" },
filter: function (event, player) {
return player.getStorage("twchuanshu_clear").length;
},
forced: true,
silent: true,
content: function () {
"step 0";
var targets = player.getStorage("twchuanshu_clear");
for (var target of targets) {
target.unmarkAuto("twchuanshu_effect", [player]);
if (!target.getStorage("twchuanshu_effect").length) target.removeSkill("twchuanshu_effect");
}
"step 1";
player.removeSkill("twchuanshu_clear");
},
},
},
},
//徐庶
twjiange: {
audio: 2,
enable: ["chooseToUse", "chooseToRespond"],
filterCard: function (card, player) {
return get.type(card) != "basic";
},
usable: 1,
locked: false,
viewAs: { name: "sha", storage: { twjiange: true } },
viewAsFilter: function (player) {
if (
!player.countCards("hes", function (card) {
return get.type(card) != "basic";
})
)
return false;
},
position: "hes",
selectCard: function () {
return _status.event.skill == "twjiange" ? 1 : Infinity;
},
precontent: function () {
if (player != _status.currentPhase) {
player
.when({ player: ["useCard", "respond"] })
.filter(evt => evt.skill == "twjiange")
.then(() => player.draw());
}
event.getParent().addCount = false;
},
prompt: "将一张非基本牌当杀使用或打出",
check: function (card) {
var val = get.value(card);
if (_status.event.name == "chooseToRespond") return 1 / Math.max(0.1, val);
return 6 - val;
},
ai: {
order: function (item, player) {
var target = _status.currentPhase;
if (!target || target != player) return 7;
return 1;
},
respondSha: true,
skillTagFilter: function (player) {
if (
!player.countCards("hes", function (card) {
return get.type(card) != "basic";
})
)
return false;
},
},
mod: {
targetInRange: function (card) {
if (card.storage && card.storage.twjiange) return true;
},
cardUsable: function (card, player, num) {
if (card.storage && card.storage.twjiange) return Infinity;
},
},
},
twxiawang: {
audio: 2,
trigger: { global: "damageEnd" },
filter: function (event, player) {
if (!event.source || get.distance(player, event.player) > 1 || !player.canUse("sha", event.source, false, false)) return false;
return player.countCards("h") > 0;
},
direct: true,
content: function () {
player
.chooseToUse(
function (card, player, event) {
if (get.name(card) != "sha") return false;
return lib.filter.filterCard.apply(this, arguments);
},
"侠望:是否对" + get.translation(trigger.source) + "使用一张杀?"
)
.set("logSkill", "twxiawang")
.set("complexSelect", true)
.set("filterTarget", function (card, player, target) {
if (target != _status.event.sourcex && !ui.selected.targets.includes(_status.event.sourcex)) return false;
return lib.filter.filterTarget.apply(this, arguments);
})
.set("sourcex", trigger.source);
player.addTempSkill("twxiawang_damage");
},
subSkill: {
damage: {
trigger: { player: "useCardAfter" },
forced: true,
popup: false,
charlotte: true,
filter: function (event, player) {
if (event.card.name != "sha") return false;
if (event.getParent(2).name != "twxiawang") return false;
if (!player.hasHistory("sourceDamage", evt => evt.card == event.card)) return false;
for (var phase of lib.phaseName) {
var evt = event.getParent(phase);
if (evt && evt.name == phase) return true;
}
return false;
},
content: function () {
player.popup();
player.removeSkill("twjiange_damage");
for (var phase of lib.phaseName) {
var evt = event.getParent(phase);
if (evt && evt.name == phase) {
var name = ["准备", "判定", "摸牌", "出牌", "弃牌", "结束"][lib.phaseName.indexOf(phase)];
game.log(player, "令", _status.currentPhase, "结束了" + name + "阶段");
player.line(_status.currentPhase, "thunder");
evt.skipped = true;
}
}
},
},
},
},
//好萌
twgongge: {
audio: 3,
trigger: { player: "useCardToPlayered" },
filter: function (event, player) {
if (!event.isFirstTarget || !event.targets) return false;
return get.tag(event.card, "damage");
},
direct: true,
usable: 1,
content: function () {
"step 0";
player
.chooseTarget(get.prompt2("twgongge"), function (card, player, target) {
var trigger = _status.event.getTrigger();
return trigger.targets.includes(target);
})
.set("ai", function (target) {
var player = _status.event.player;
var trigger = _status.event.getTrigger();
var att = get.attitude(player, target);
var damageNum = trigger.getParent().baseDamage;
var map = trigger.getParent().customArgs,
id = target.playerid;
if (map[id]) {
if (typeof map[id].baseDamage == "number") damageNum = map[id].baseDamage;
if (typeof map[id].extraDamage == "number") damageNum += map[id].extraDamage;
}
if (
target.hasSkillTag("filterDamage", null, {
player: trigger.player,
card: trigger.card,
})
)
damageNum = 1;
var num =
target.getSkills(null, false, false).filter(function (skill) {
var info = get.info(skill);
return info && !info.charlotte;
}).length + 1;
var list = [0, 0, 0];
var player = _status.event.player;
list[0] = num;
list[1] = get.effect(target, { name: "guohe_copy2" }, player, player) > 0 ? (target.hp - damageNum < player.hp ? num : num - Math.min(player.getCards("he"), num - 1)) : 0;
if (_status.event.yimie(trigger, player, target, damageNum)) list[2] = (get.recoverEffect(target, player, player) > get.damageEffect(target, player, player) ? Math.min(num - 1, target.getDamagedHp()) : num - 1) * 2;
return Math.max.apply(Math, list);
})
.set("yimie", function (trigger, player, target, damageNum) {
var hit = true;
var att = get.attitude(player, target);
if (get.type(trigger.card) == "trick" && trigger.player.countCards("hs", { name: "wuxie" })) hit = false;
if (
trigger.card.name == "huogong" &&
trigger.player.countCards("h", function (card) {
var list = [];
for (var i of player.getCards("h")) list.push(get.suit(i));
return !list.includes(get.suit(card));
})
)
hit = false;
var key;
switch (trigger.card.name) {
case "sha":
case "wanjian":
key = ["shan"];
break;
case "juedou":
case "nanman":
case "jiedao":
key = ["sha"];
break;
default:
key = [];
break;
}
if (get.type(trigger.card) == "trick") key.push("wuxie");
key.push("caochuan");
var bool1 = get.recoverEffect(target, player, player) > 0 ? 1 : -1;
var bool2 = (att > 0 && !hit) || (target.countCards("hs", { name: key }) && !trigger.getParent().directHit.includes(target)) ? 1 : -1;
if (att <= 0 && target.hp - damageNum > 0) return false;
return (bool1 = bool2 && att != 0);
});
"step 1";
if (result.bool) {
var target = result.targets[0];
event.target = target;
player.logSkill("twgongge", target);
var num =
target.getSkills(null, false, false).filter(function (skill) {
var info = get.info(skill);
return info && !info.charlotte;
}).length + 1;
event.num = num;
var list = [];
var choiceList = ["摸" + get.cnNumber(num) + "张牌,若" + get.translation(target) + "响应此牌,则你跳过下个摸牌阶段", "弃置" + get.translation(target) + get.cnNumber(num) + "张牌,此牌结算完毕后,若" + get.translation(target) + "的体力值不小于你,你交给" + get.translation(target) + get.cnNumber(num - 1) + "张牌", "令此牌对" + get.translation(target) + "造成的伤害+" + (num - 1) + ",此伤害结算完成后,其回复等量的体力值"];
list.push("摸牌");
if (target.countDiscardableCards(player, "he")) list.push("拆牌");
else choiceList[1] = '<span style="opacity:0.5">' + choiceList[1] + "</span>";
list.push("加伤");
player
.chooseControl(list)
.set("prompt", "攻阁:请选择一项(" + get.translation(target) + "对应X值" + (num - 1) + "")
.set("ai", () => _status.event.choice)
.set(
"choice",
(function () {
var att = get.attitude(player, target);
var damageNum = trigger.getParent().baseDamage;
var map = trigger.getParent().customArgs,
id = target.playerid;
if (map[id]) {
if (typeof map[id].baseDamage == "number") damageNum = map[id].baseDamage;
if (typeof map[id].extraDamage == "number") damageNum += map[id].extraDamage;
}
if (
target.hasSkillTag("filterDamage", null, {
player: trigger.player,
card: trigger.card,
})
)
damageNum = 1;
var yimie = function () {
if (damageNum == 1) return false;
var hit = true;
if (get.type(trigger.card) == "trick" && trigger.player.countCards("hs", { name: "wuxie" })) hit = false;
if (
trigger.card.name == "huogong" &&
trigger.player.countCards("h", function (card) {
var list = [];
for (var i of player.getCards("h")) list.push(get.suit(i));
return !list.includes(get.suit(card));
})
)
hit = false;
var key;
switch (trigger.card.name) {
case "sha":
case "wanjian":
key = ["shan"];
break;
case "juedou":
case "nanman":
case "jiedao":
key = ["sha"];
break;
default:
key = [];
break;
}
key.push("caochuan");
var bool1 = get.recoverEffect(target, player, player) > 0 ? 1 : -1;
var bool2 = (att > 0 && !hit) || (target.countCards("hs", { name: key }) && !trigger.getParent().directHit.includes(target)) ? 1 : -1;
if (att <= 0 && target.hp - damageNum > 0) return false;
return (bool1 = bool2 && att != 0);
};
if (yimie()) return "加伤";
if (list.includes("拆牌") && get.effect(target, { name: "guohe_copy2" }, player, player) > 0 && target.hp - damageNum < player.hp) return "拆牌";
return "摸牌";
})()
)
.set("choiceList", choiceList);
} else {
player.storage.counttrigger.twgongge--;
event.finish();
}
"step 2";
game.log(player, "选择了", "#y" + result.control);
switch (result.control) {
case "摸牌":
player.draw(num);
player.addTempSkill("twgongge_buff1");
var evt = {
card: trigger.card,
target: target,
};
player.storage.twgongge_buff1 = evt;
break;
case "拆牌":
player.discardPlayerCard(num, target, "he", true);
player.addTempSkill("twgongge_buff2");
var evt = {
card: trigger.card,
target: target,
num: num - 1,
};
player.storage.twgongge_buff2 = evt;
break;
case "加伤":
player.addTempSkill("twgongge_buff3");
var evt = {
card: trigger.card,
target: target,
num: num - 1,
};
player.storage.twgongge_buff3 = evt;
break;
}
},
subSkill: {
//摸牌后续
buff1: {
charlotte: true,
onremove: true,
trigger: { global: ["useCard", "respond"] },
filter: function (event, player) {
if (player.skipList.includes("phaseDraw")) return false;
if (!Array.isArray(event.respondTo) || player != event.respondTo[0]) return false;
var evt = player.storage.twgongge_buff1;
if (evt.target == event.player && evt.card == event.respondTo[1]) return true;
return false;
},
direct: true,
popup: false,
content: function () {
player.skip("phaseDraw");
game.log(player, "跳过了下个", "#g摸牌阶段");
player.addTempSkill("twgongge_buff1_mark", "phaseDrawSkipped");
},
},
//拆牌后续
buff2: {
charlotte: true,
onremove: true,
trigger: { player: "useCardAfter" },
filter: function (event, player) {
if (!player.countCards("he")) return false;
var evt = player.storage.twgongge_buff2;
if (evt.card == event.card && evt.target.isIn() && evt.target.hp >= player.hp) return true;
return false;
},
direct: true,
popup: false,
content: function () {
"step 0";
var evt = player.storage.twgongge_buff2;
var target = evt.target,
num = evt.num;
event.target = target;
if (player.countCards("he") <= num) event._result = { bool: true, cards: player.getCards("he") };
else player.chooseCard("he", num, "攻阁:交给" + get.translation(target) + get.cnNumber(num) + "张牌", true);
"step 1";
if (result.bool) player.give(result.cards, target);
},
},
//加伤后续
buff3: {
charlotte: true,
onremove: true,
trigger: { source: "damageBegin1", player: "useCardAfter" },
filter: function (event, player) {
if (!event.card) return false;
var evt = player.storage.twgongge_buff3;
if (evt.card == event.card && evt.target.isIn() && (event.name == "useCard" || event.player == evt.target)) return true;
return false;
},
direct: true,
popup: false,
content: function () {
var evt = player.storage.twgongge_buff3;
if (trigger.name == "damage") trigger.num += evt.num;
else if (evt.target.isIn()) evt.target.recover(evt.num);
},
},
buff1_mark: {
mark: true,
intro: {
content: "跳过下一个摸牌阶段",
},
},
},
},
//魏续
twsuizheng: {
audio: 3,
trigger: { global: "phaseBefore", player: "enterGame" },
filter: function (event, player) {
return game.hasPlayer(current => current != player) && (event.name != "phase" || game.phaseNumber == 0);
},
forced: true,
content: function () {
"step 0";
player.chooseTarget("请选择【随征】的目标", lib.translate.twsuizheng_info, lib.filter.notMe, true).set("ai", function (target) {
var player = _status.event.player;
return Math.max(1 + get.attitude(player, target) * get.threaten(target), Math.random());
});
"step 1";
if (result.bool) {
var target = result.targets[0];
player.line(target);
game.log(player, "选择了", target, "作为", "“随征”角色");
player.markAuto("twsuizheng", [target]);
player.addSkill("twsuizheng_draw");
player.addSkill("twsuizheng_xianfu");
}
},
ai: { expose: 0.3 },
intro: { content: "已选择$为“随征”角色" },
subSkill: {
draw: {
charlotte: true,
audio: "twsuizheng",
trigger: { global: "damageSource" },
filter: function (event, player) {
return player.getStorage("twsuizheng").includes(event.source);
},
forced: true,
logTarget: "source",
content: function () {
player.draw();
},
},
xianfu: {
audio: "twsuizheng",
trigger: { global: "damageEnd" },
filter: function (event, player) {
return player.getStorage("twsuizheng").includes(event.player) && event.player.isIn();
},
forced: true,
charlotte: true,
logTarget: "player",
content: function () {
"step 0";
player
.chooseToDiscard(2, "随征:弃置两张基本牌", "若你弃牌,你令" + get.translation(trigger.player) + "回复1点体力或点击“取消”失去1点体力令" + get.translation(trigger.player) + "获得一张【杀】或【决斗】", { type: "basic" })
.set("ai", function (card) {
if (_status.event.refuse) return -1;
return 6 - get.value(card);
})
.set("refuse", get.attitude(player, trigger.player) <= 0 || get.effect(player, { name: "losehp" }) >= 0);
"step 1";
if (result.bool) trigger.player.recover();
else {
player.loseHp();
var card = get.cardPile(function (card) {
return card.name == "sha" || card.name == "juedou";
});
if (card) trigger.player.gain(card, "gain2");
}
},
},
},
},
twtuidao: {
audio: 2,
trigger: { player: "phaseZhunbeiBegin" },
filter: function (event, player) {
var targets = player.getStorage("twsuizheng");
if (!targets.length) return false;
return targets.some(target => target.hp <= 2 || !target.isIn());
},
check: function (event, player) {
var targets = player.getStorage("twsuizheng");
var val = 0;
for (var target of targets) {
if (target.hp <= 2 && target.isIn()) val -= get.attitude(player, target);
else if (!target.isIn()) val += 6;
}
return val > 0;
},
limited: true,
skillAnimation: true,
animationColor: "thunder",
content: function () {
"step 0";
player.awakenSkill("twtuidao");
var list1 = ["equip3", "equip4"].map(i => get.translation(i)),
list2 = ["basic", "trick", "equip"].map(i => get.translation(i));
var targets = player.getStorage("twsuizheng"),
str = get.translation(targets);
if (targets.length) str = "与" + str;
player
.chooseButton(2, true, ["颓盗:废除你" + str + "的一个坐骑栏废除并选择一个类别", "坐骑栏", [list1, "tdnodes"], "类别", [list2, "tdnodes"]])
.set("filterButton", function (button) {
var list = _status.event.list,
link = button.link;
if (ui.selected.buttons.length) {
if (list.includes(ui.selected.buttons[0].link) && list.includes(link)) return false;
if (!list.includes(ui.selected.buttons[0].link) && !list.includes(link)) return false;
}
return true;
})
.set("ai", function (button) {
var player = _status.event.player;
var list = _status.event.list,
link = button.link;
if (list.includes(link)) {
if (player.hasDisabledSlot(4)) return "攻击马";
if (player.hasDisabledSlot(3)) return "防御马";
return "攻击马";
}
if (!list.includes(link)) {
var player = _status.event.player;
var targets = player.getStorage("twsuizheng");
for (var target of targets) {
if (target.isIn()) {
var listx = [0, 0, 0],
list2 = ["basic", "trick", "equip"].map(i => get.translation(i));
for (var i of target.getCards("he")) listx[list2.indexOf(get.translation(get.type2(i)))]++;
return list2[listx.indexOf(Math.max.apply(Math, listx))];
}
}
return 1 + Math.random();
}
})
.set("list", list1);
"step 1";
if (result.links[0].indexOf("马") == -1) result.links.reverse();
var subtype = result.links[0] == "防御马" ? "equip3" : "equip4",
type = { 基本: "basic", 锦囊: "trick", 装备: "equip" }[result.links[1]];
player.disableEquip(subtype);
var targets = player.getStorage("twsuizheng");
for (var target of targets) {
if (target && target.isIn()) {
target.disableEquip(subtype);
var cards = target.getCards("he", card => get.type2(card) == type);
player.gain(cards, target, "give");
event.gainners = cards;
} else {
var cards = [];
for (var i = 1; i <= 2; i++) {
var card = get.cardPile2(function (card) {
return !cards.includes(card) && get.type2(card) == type;
});
if (card) cards.push(card);
else break;
}
player.gain(cards, "gain2");
event.gainners = cards;
}
}
"step 2";
player
.chooseTarget("请重新选择【随征】目标", true, function (card, player, target) {
return !player.getStorage("twsuizheng").includes(target);
})
.set("ai", function (target) {
var player = _status.event.player;
return Math.max(1 + get.attitude(player, target) * get.threaten(target), Math.random());
});
"step 3";
if (result.bool) {
var target = result.targets[0];
player.line(target);
game.log(player, "选择了", target, "作为", "“随征”角色");
delete player.storage.twsuizheng;
player.markAuto("twsuizheng", [target]);
}
},
ai: { combo: "twsuizheng" },
},
//曹休
twqianju: {
audio: 2,
trigger: { source: "damageSource" },
filter: function (event, player) {
return get.distance(player, event.player) <= 1 && player.countCards("e") < 5;
},
forced: true,
usable: 1,
content: function () {
var card = get.cardPile(function (card) {
return get.type(card) == "equip" && player.canEquip(card);
});
if (card) {
player.$gain2(card);
game.delayx();
player.equip(card);
}
},
mod: {
globalFrom: function (from, to, distance) {
return distance - from.countCards("e");
},
},
},
twqingxi: {
audio: "xinqingxi",
trigger: { player: "useCardToPlayered" },
filter: function (event, player) {
return event.card.name == "sha" && player.getHistory("useCard", evt => evt.card.name == "sha").indexOf(event.getParent()) == 0;
},
check: function (event, player) {
return true;
},
logTarget: "target",
content: function () {
"step 0";
var target = trigger.target;
event.target = target;
if (!target.countCards("e")) event._result = { index: 0 };
else
target
.chooseControl()
.set("ai", function () {
if (_status.event.goon || player.hp > 2) return 0;
return 1;
})
.set("choiceList", ["令" + get.translation(player) + "摸" + get.cnNumber(Math.max(1, player.countCards("e"))) + "张牌,且此【杀】不可被响应", "弃置装备区中的所有牌并弃置" + get.translation(player) + "装备区等量的牌,此【杀】造成的伤害+1"])
.set("goon", get.attitude(target, player) > 0);
"step 1";
if (result.index == 0) {
player.draw(Math.max(1, player.countCards("e")));
trigger.getParent().directHit.add(target);
game.log(trigger.card, "不可被", target, "响应");
event.finish();
} else {
var num = target.countCards("e");
target.discard(target.getCards("e"));
target.discardPlayerCard(player, "e", num, true);
}
"step 2";
var map = trigger.customArgs;
var id = target.playerid;
if (!map[id]) map[id] = {};
if (!map[id].extraDamage) map[id].extraDamage = 0;
map[id].extraDamage++;
game.log(trigger.card, "对", target, "造成的伤害+1");
game.delayx();
},
},
//孙翊
twzaoli: {
audio: "zaoli",
trigger: { player: "phaseUseBegin" },
init: function (player) {
if (player.isPhaseUsing()) {
var hs = player.getCards("h");
player.getHistory("gain", function (evt) {
hs.removeArray(evt.cards);
});
if (hs.length) player.addGaintag(hs, "twzaoli");
}
},
filter: function (event, player) {
return player.countCards("he");
},
forced: true,
group: "twzaoli_mark",
content: function () {
"step 0";
if (player.countCards("h", card => get.type(card) != "equip")) {
player
.chooseCard("h", [1, Infinity], true, "躁厉:请选择至少一张非装备手牌,你弃置这些牌和所有装备牌", (card, player) => {
return get.type(card) != "equip" && lib.filter.cardDiscardable(card, player, "twzaoli");
})
.set("ai", function (card) {
if (!card.hasGaintag("twzaoli_temp")) return 5 - get.value(card);
return 1;
});
}
"step 1";
var cards = player.getCards("he", { type: "equip" });
var subtype = [];
event.subtype = subtype.addArray(cards.map(card => get.subtype(card)));
cards.addArray(result.cards || []);
if (cards.length) player.discard(cards);
event.cards = cards;
"step 2";
player.draw(cards.length);
"step 3";
var num = 0;
if (event.subtype.length) {
for (var i of event.subtype) {
var card = get.cardPile2(function (card) {
return get.type(card) == "equip" && get.subtype(card) == i;
});
if (card) {
num++;
player.$gain2(card);
game.delayx();
player.equip(card);
}
}
}
if (num <= 2) event.finish();
"step 4";
player.loseHp();
},
onremove: function (player) {
player.removeGaintag("twzaoli");
},
mod: {
cardEnabled2: function (card, player) {
if (player.isPhaseUsing() && get.itemtype(card) == "card" && card.hasGaintag("twzaoli")) return false;
},
},
subSkill: {
mark: {
trigger: { player: ["phaseUseBegin", "phaseUseAfter", "phaseAfter"] },
filter: function (event, player) {
return player.countCards("h");
},
direct: true,
firstDo: true,
content: function () {
if (event.triggername == "phaseUseBegin") {
var hs = player.getCards("h");
player.getHistory("gain", function (evt) {
hs.removeArray(evt.cards);
});
if (hs.length) player.addGaintag(hs, "twzaoli");
} else {
player.removeGaintag("twzaoli");
}
},
},
},
},
//邓芝
twjimeng: {
audio: "jimeng",
enable: "phaseUse",
usable: 1,
filter: function (event, player) {
return game.hasPlayer(function (current) {
return current.countGainableCards(player, "he") > 0;
});
},
filterTarget: function (card, player, target) {
return target != player && target.countGainableCards(player, "hej") > 0;
},
content: function () {
"step 0";
player.gainPlayerCard(target, "hej", true);
"step 1";
var hs = player.getCards("he");
if (hs.length) {
if (hs.length == 1) event._result = { bool: true, cards: hs };
else player.chooseCard(true, "交给" + get.translation(target) + "一张牌", "he", true);
} else event.finish();
"step 2";
player.give(result.cards, target);
"step 3";
if (target.hp >= player.hp) player.draw();
},
ai: {
order: 8,
result: {
player: function (player, target) {
if (target.hp >= player.hp) return 1;
return 0;
},
target: function (player, target) {
return get.effect(target, { name: "shunshou" }, player, target) / 10;
},
},
},
},
//杨仪
twgongsun: {
audio: "gongsun",
trigger: { player: "phaseUseBegin" },
forced: true,
direct: true,
filter: function (event, player) {
return game.hasPlayer(current => player.inRange(current));
},
content: function () {
"step 0";
player
.chooseTarget("共损:请选择一名攻击范围内的角色", lib.translate.twgongsun_info, true, function (card, player, target) {
return player != target && player.inRange(target);
})
.set("ai", function (target) {
return -get.attitude(_status.event.player, target) * (1 + target.countCards("h"));
});
"step 1";
if (result.bool) {
var target = result.targets[0];
event.target = target;
player.logSkill("twgongsun", target);
player.addTempSkill("twgongsun_shadow", { player: ["phaseBegin", "die"] });
player
.chooseControl(lib.suit)
.set("prompt", "共损:请选择一个花色")
.set("ai", function (button) {
return lib.suit.randomGet();
});
} else event.finish();
"step 2";
var suit = result.control;
player.popup(suit + 2, "soil");
game.log(player, "选择了", suit + 2);
player.storage.twgongsun_shadow.push([target, suit]);
player.markSkill("twgongsun_shadow");
},
},
twgongsun_shadow: {
global: "twgongsun_shadow2",
init: function (player, skill) {
if (!player.storage[skill]) player.storage[skill] = [];
},
marktext: "损",
onremove: true,
intro: {
content: function (shadow) {
var str = "";
for (var i = 0; i < shadow.length; i++) {
if (i > 0) str += "<br>";
str += get.translation(shadow[i][0]);
str += "";
str += get.translation(shadow[i][1]);
}
return str;
},
},
mod: {
cardEnabled: function (card, player) {
var list = player.storage.twgongsun_shadow;
for (var i = 0; i < list.length; i++) {
if (list[i][1] == card.suit) return false;
}
},
cardRespondable: function (card, player) {
var list = player.storage.twgongsun_shadow;
for (var i = 0; i < list.length; i++) {
if (list[i][1] == card.suit) return false;
}
},
cardSavable: function (card, player) {
var list = player.storage.twgongsun_shadow;
for (var i = 0; i < list.length; i++) {
if (list[i][1] == card.suit) return false;
}
},
cardDiscardable: function (card, player) {
var list = player.storage.twgongsun_shadow;
for (var i = 0; i < list.length; i++) {
if (list[i][1] == card.suit) return false;
}
},
},
},
twgongsun_shadow2: {
mod: {
cardEnabled: function (card, player) {
if (
game.hasPlayer(function (current) {
var list = current.storage.twgongsun_shadow;
if (!list) return false;
for (var i = 0; i < list.length; i++) {
if (list[i][0] == player && list[i][1] == card.suit) return true;
}
return false;
})
)
return false;
},
cardSavable: function (card, player) {
if (
game.hasPlayer(function (current) {
var list = current.storage.twgongsun_shadow;
if (!list) return false;
for (var i = 0; i < list.length; i++) {
if (list[i][0] == player && list[i][1] == card.suit) return true;
}
return false;
})
)
return false;
},
cardRespondable: function (card, player) {
if (
game.hasPlayer(function (current) {
var list = current.storage.twgongsun_shadow;
if (!list) return false;
for (var i = 0; i < list.length; i++) {
if (list[i][0] == player && list[i][1] == card.suit) return true;
}
return false;
})
)
return false;
},
cardDiscardable: function (card, player) {
if (
game.hasPlayer(function (current) {
var list = current.storage.twgongsun_shadow;
if (!list) return false;
for (var i = 0; i < list.length; i++) {
if (list[i][0] == player && list[i][1] == card.suit) return true;
}
return false;
})
)
return false;
},
},
},
//濮阳兴
twzhengjian: {
audio: 2,
trigger: {
global: "phaseBefore",
player: "enterGame",
},
forced: true,
locked: false,
filter: function (event, player) {
if (event.name == "phase" && game.phaseNumber != 0) return false;
return !player.hasSkill("twzhengjian_eff0") && !player.hasSkill("twzhengjian_eff1");
},
content: function () {
"step 0";
player
.chooseControl()
.set("prompt", "征建:请选择一种效果")
.set("choiceList", ["令“出牌阶段内未使用过非基本牌”的其他角色受到惩罚", "令“出牌阶段内未得到过牌”的其他角色受到惩罚"])
.set("ai", () => (Math.random() <= 0.5 ? 0 : 1));
"step 1";
player.addSkill("twzhengjian_eff" + result.index);
game.log(player, "获得了", "#g【征建】", "的", "#y效果" + get.cnNumber(result.index + 1, true));
game.delayx();
},
onremove: true,
subSkill: {
eff0: {
audio: "twzhengjian",
trigger: { global: "phaseUseEnd" },
forced: true,
charlotte: true,
marktext: "建",
mark: true,
filter: function (event, player) {
if (event.player == player || event._twzhengjian || !event.player.isIn()) return false;
if (
event.player.hasHistory("useCard", function (evt) {
return evt.getParent("phaseUse") == event && get.type(evt.card) != "basic";
})
)
return false;
return player.storage.twzhengjian || event.player.countCards("he") > 0;
},
logTarget: "player",
content: function () {
"step 0";
trigger._twzhengjian = true;
var target = trigger.player;
event.target = target;
if (player.storage.twzhengjian) {
player
.chooseBool("征建:是否对" + get.translation(target) + "造成1点伤害")
.set("ai", () => _status.event.goon)
.set("goon", get.damageEffect(target, player, _status.event.player) > 0);
} else {
target.chooseCard("he", true, "交给" + get.translation(player) + "一张牌");
}
"step 1";
if (result.bool) {
if (result.cards && result.cards.length) {
target.give(result.cards, player).type = "twzhengjian";
} else target.damage();
}
player.chooseBool("是否变更【征建】的效果?").set("ai", () => Math.random() > 0.5);
"step 2";
if (result.bool) {
player.removeSkill("twzhengjian_eff0");
player.addSkill("twzhengjian_eff1");
game.log(player, "将", "#g【征建】", "的效果变更为", "#y效果二");
}
},
intro: {
content: function (storage, player) {
if (player.storage.twzhengjian) return "其他角色的出牌阶段结束时若其本阶段内未使用过非基本牌则你可对其造成1点伤害然后你可失去此效果并获得〖征建〗的效果二。";
return "其他角色的出牌阶段结束时,若其本阶段内未使用过非基本牌,则其须交给你一张牌,然后你可失去此效果并获得〖征建〗的效果二。";
},
},
},
eff1: {
audio: "twzhengjian",
trigger: { global: "phaseUseEnd" },
forced: true,
charlotte: true,
marktext: "征",
mark: true,
filter: function (event, player) {
if (event.player == player || event._twzhengjian || !event.player.isIn()) return false;
if (
event.player.hasHistory("gain", function (evt) {
return evt.getParent("phaseUse") == event;
})
)
return false;
return player.storage.twzhengjian || event.player.countCards("he") > 0;
},
logTarget: "player",
content: function () {
"step 0";
trigger._twzhengjian = true;
var target = trigger.player;
event.target = target;
if (player.storage.twzhengjian) {
player
.chooseBool("征建:是否对" + get.translation(target) + "造成1点伤害")
.set("ai", () => _status.event.goon)
.set("goon", get.damageEffect(target, player, _status.event.player) > 0);
} else {
target.chooseCard("he", true, "交给" + get.translation(player) + "一张牌");
}
"step 1";
if (result.bool) {
if (result.cards && result.cards.length) {
target.give(result.cards, player).type = "twzhengjian";
} else target.damage();
}
player.chooseBool("是否变更【征建】的效果?").set("ai", () => Math.random() > 0.5);
"step 2";
if (result.bool) {
player.removeSkill("twzhengjian_eff1");
player.addSkill("twzhengjian_eff0");
game.log(player, "将", "#g【征建】", "的效果变更为", "#y效果一");
}
},
intro: {
content: function (storage, player) {
if (player.storage.twzhengjian) return "其他角色的出牌阶段结束时若其本阶段内未得到过牌则你可对其造成1点伤害然后你可失去此效果并获得〖征建〗的效果一。";
return "其他角色的出牌阶段结束时,若其本阶段内未得到过牌,则其须交给你一张牌,然后你可失去此效果并获得〖征建〗的效果一。";
},
},
},
},
},
twzhongchi: {
audio: 2,
trigger: {
player: "gainAfter",
global: "loseAsyncAfter",
},
forced: true,
skillAnimation: true,
animationColor: "wood",
filter: function (event, player) {
if (player.storage.twzhengjian || !player.hasSkill("twzhengjian", null, null, false) || !event.getg(player).length) return false;
var num1 = game.countPlayer2();
var list = [];
player.getAllHistory("gain", function (evt) {
if (evt.type == "twzhengjian") list.add(evt.source);
});
return list.length >= Math.ceil(num1 / 2);
},
content: function () {
"step 0";
player.awakenSkill("twzhongchi");
"step 1";
player.recover(2);
player.addSkill("twzhongchi_effect");
player.storage.twzhengjian = true;
"step 2";
game.delayx();
},
subSkill: {
effect: {
mark: true,
marktext: "斥",
intro: { content: "受到渠道为【杀】的伤害+1" },
trigger: { player: "damageBegin1" },
forced: true,
filter: function (event, player) {
return event.card && event.card.name == "sha";
},
content: function () {
trigger.num++;
},
},
},
ai: {
combo: "twzhengjian",
},
},
//田豫
twzhenxi: {
audio: 2,
trigger: { player: "useCardToPlayered" },
direct: true,
filter: function (event, player) {
var target = event.target;
return (
event.card.name == "sha" &&
(target.countCards("h") > 0 ||
target.hasCard(function (card) {
return game.hasPlayer(function (current) {
return current != target && current.canEquip(card);
});
}, "e") ||
target.hasCard(function (card) {
return game.hasPlayer(function (current) {
return current != target && current.canAddJudge(card);
});
}, "j"))
);
},
usable: 1,
content: function () {
"step 0";
var target = trigger.target;
event.target = target;
var str = get.translation(target);
var list = ["弃置" + str + "的" + get.cnNumber(get.distance(player, target)) + "张手牌", "将" + str + "装备区或判定区内的一张牌移动到另一名角色的对应区域内"];
var choices = [];
if (target.countCards("h") > 0) choices.push("选项一");
else list[0] = '<span style="opacity:0.5">' + list[0] + "</span>";
if (
target.hasCard(function (card) {
return game.hasPlayer(function (current) {
return current != target && current.canEquip(card);
});
}, "e") ||
target.hasCard(function (card) {
return game.hasPlayer(function (current) {
return current != target && current.canAddJudge(card);
});
}, "j")
)
choices.push("选项二");
else list[1] = '<span style="opacity:0.5">' + list[1] + "</span>";
if (choices.length == 2 && (target.hp > player.hp || target.isMaxHp())) choices.push("全部执行");
choices.push("cancel2");
player
.chooseControl(choices)
.set("choiceList", list)
.set("prompt", get.prompt("twzhenxi", target))
.set("ai", function () {
var player = _status.event.player,
target = _status.event.getTrigger().target;
var eff1 = 0,
eff2 = 0;
var choices = _status.event.controls.slice(0);
if (choices.includes("选项一")) {
eff1 = -get.distance(player, target) * get.attitude(player, target);
}
if (choices.includes("选项二")) {
var equip = 0,
judge = 0,
att = get.attitude(player, target);
var es = target.getCards("e"),
js = target.getCards("j");
for (var i of es) {
var val = get.value(i);
if (att > 0) {
if (
val <= Math.min(0, equip) &&
game.hasPlayer(function (current) {
return current != target && current.canEquip(i) && get.effect(current, i, player, player) > 0;
})
)
equip = val;
} else {
if (
val > Math.max(0, equip) &&
game.hasPlayer(function (current) {
return current != target && current.canEquip(i) && get.effect(current, i, player, player) > 0;
})
)
equip = val;
}
}
for (var i of js) {
var card = { name: i.viewAs || i.name };
var effect = get.effect(target, card, player, player);
if (effect < 0) {
game.countPlayer(function (current) {
if (current != target && current.canAddJudge(i)) {
var eff = get.effect(current, card, player, player);
judge = Math.max(eff, judge);
}
});
}
}
eff2 = Math.max(-equip * att, judge);
}
if (eff1 > 0) {
if (eff2 > 0) {
if (choices.includes("全部执行")) return "全部执行";
else if (eff2 >= eff1) return "选项二";
}
return "选项一";
} else if (eff2 > 0) return "选项二";
return "cancel2";
});
"step 1";
if (result.control == "cancel2") {
event.finish();
return;
}
player.logSkill("twzhenxi", target);
event.control = result.control;
if (event.control != "选项二") player.discardPlayerCard(target, true, "h", get.distance(player, target));
if (event.control == "选项一") event.finish();
"step 2";
if (
event.control != "选项一" &&
(target.hasCard(function (card) {
return game.hasPlayer(function (current) {
return current != target && current.canEquip(card);
});
}, "e") ||
target.hasCard(function (card) {
return game.hasPlayer(function (current) {
return current != target && current.canAddJudge(card);
});
}, "j"))
) {
player
.chooseTarget(true, "将" + get.translation(target) + "区域内的一张牌移动给另一名角色", function (card, player, target) {
var source = _status.event.preTarget;
if (source == target) return false;
return (
source.hasCard(function (card) {
return target.canEquip(card);
}, "e") ||
source.hasCard(function (card) {
return target.canAddJudge(card);
}, "j")
);
})
.set("preTarget", target)
.set("ai", function (target) {
var player = _status.event.player,
source = _status.event.preTarget;
var att = get.attitude(player, source);
var es = source.getCards("e", function (card) {
return target.canEquip(card);
}),
js = source.getCards("j", function (card) {
return target.canAddJudge(card);
});
var eff = 0;
for (var i of es) {
var val = get.value(i, source);
if (att > 0 ? val <= 0 : val > 0) {
eff = Math.max(eff, get.effect(target, i, player, player));
}
}
for (var i of js) {
var card = { name: i.viewAs || i.name };
if (get.effect(source, card, player, player) < 0) {
eff = Math.max(eff, get.effect(target, card, player, player));
}
}
return eff;
});
} else event.finish();
"step 3";
if (result.bool) {
var target2 = result.targets[0];
event.target2 = target2;
player
.choosePlayerCard(
"ej",
true,
function (button) {
var player = _status.event.player;
var targets0 = _status.event.targets0;
var targets1 = _status.event.targets1;
if (get.attitude(player, targets0) > 0 && get.attitude(player, targets1) < 0) {
if (get.position(button.link) == "j") return 12;
if (get.value(button.link, targets0) < 0 && get.effect(targets1, button.link, player, targets1) > 0) return 10;
return 0;
} else {
if (get.position(button.link) == "j") return -10;
return get.value(button.link) * get.effect(targets1, button.link, player, targets1);
}
},
target
)
.set("targets0", target)
.set("targets1", target2)
.set("filterButton", function (button) {
var targets1 = _status.event.targets1;
if (get.position(button.link) == "j") {
return targets1.canAddJudge(button.link);
} else {
return targets1.canEquip(button.link);
}
})
.set("ai", function (button) {
var player = _status.event.player,
target = _status.event.targets1,
source = _status.event.targets0;
var att = get.attitude(player, source);
var card = button.link;
if (get.position(card) == "e") {
var val = get.value(card);
if (att > 0 ? val > 0 : val <= 0) return 0;
return get.effect(target, card, player, player);
}
var cardx = { name: card.viewAs || card.name };
if (get.effect(source, cardx, player, player) >= 0) return 0;
return get.effect(target, cardx, player, player);
});
} else {
event.finish();
}
"step 4";
if (result.bool && result.links.length) {
var link = result.links[0];
if (get.position(link) == "e") {
event.target2.equip(link);
} else if (link.viewAs) {
event.target2.addJudge({ name: link.viewAs }, [link]);
} else {
event.target2.addJudge(link);
}
target.$give(link, event.target2, false);
game.log(target, "的", link, "被移动给了", event.target2);
game.delay();
}
},
ai: {
unequip_ai: true,
skillTagFilter: function (player, tag, arg) {
if (!arg || !arg.name || arg.name != "sha") return false;
if (player.storage.counttrigger && player.storage.counttrigger.twzhenxi) return false;
if (!arg.target) return false;
var card = arg.target.getEquip(2);
return (
card &&
get.value(card) > 0 &&
game.hasPlayer(function (current) {
return current != arg.target && current.canEquip(card) && get.effect(current, card, player, player) > 0;
})
);
},
},
},
twyangshi: {
audio: 2,
trigger: { player: "damageEnd" },
forced: true,
content: function () {
if (
game.hasPlayer(function (current) {
return current != player && !player.inRange(current);
})
) {
player.addSkill("twyangshi_distance");
player.addMark("twyangshi_distance", 1, false);
} else {
var card = get.cardPile2(function (card) {
return card.name == "sha";
});
if (card) player.gain(card, "gain2");
else game.log("但是牌堆里已经没有杀了!");
}
},
subSkill: {
distance: {
charlotte: true,
onremove: true,
mod: {
attackRange: function (player, num) {
return num + player.countMark("twyangshi_distance");
},
},
intro: {
content: "攻击范围+#",
},
},
},
},
//全琮
zhenshan: {
audio: 2,
enable: ["chooseToUse", "chooseToRespond"],
filter: function (event, player) {
if (event.type == "wuxie" || player.hasSkill("zhenshan_used")) return false;
var nh = player.countCards("h");
if (
!game.hasPlayer(function (current) {
return current != player && current.countCards("h") < nh;
})
) {
return false;
}
for (var i of lib.inpile) {
if (get.type(i) != "basic") continue;
var card = { name: i, isCard: true };
if (event.filterCard(card, player, event)) return true;
if (i == "sha") {
for (var j of lib.inpile_nature) {
card.nature = j;
if (event.filterCard(card, player, event)) return true;
}
}
}
return false;
},
chooseButton: {
dialog: function (event, player) {
var list = [];
for (var i of lib.inpile) {
if (get.type(i) != "basic") continue;
var card = { name: i, isCard: true };
if (event.filterCard(card, player, event)) list.push(["基本", "", i]);
if (i == "sha") {
for (var j of lib.inpile_nature) {
card.nature = j;
if (event.filterCard(card, player, event)) list.push(["基本", "", i, j]);
}
}
}
return ui.create.dialog("振赡", [list, "vcard"], "hidden");
},
check: function (button) {
var player = _status.event.player;
var card = { name: button.link[2], nature: button.link[3] };
if (card.name == "jiu") return 0;
if (
game.hasPlayer(function (current) {
return get.effect(current, card, player, player) > 0;
})
) {
if (card.name == "sha") {
var eff = player.getUseValue(card);
if (eff > 0) return 2.9 + eff / 10;
return 0;
} else if (card.name == "tao" || card.name == "shan") {
return 4;
}
}
return 0;
},
backup: function (links, player) {
return {
filterCard: function () {
return false;
},
viewAs: {
name: links[0][2],
nature: links[0][3],
isCard: true,
},
selectCard: -1,
precontent: function () {
"step 0";
player
.chooseTarget(
"选择一名手牌数小于你的角色交换手牌",
function (card, player, target) {
return target != player && target.countCards("h") < player.countCards("h");
},
true
)
.set("ai", function (target) {
return get.attitude(player, target) * Math.sqrt(target.countCards("h") + 1);
});
"step 1";
if (result.bool) {
player.logSkill("zhenshan", result.targets);
player.addTempSkill("zhenshan_used");
player.swapHandcards(result.targets[0]);
delete event.result.skill;
} else event.finish();
"step 2";
game.delayx();
},
};
},
prompt: function (links, player) {
return "选择" + get.translation(links[0][3] || "") + "【" + get.translation(links[0][2]) + "】的目标";
},
},
subSkill: {
used: { charlotte: true },
},
ai: {
order: function () {
var player = _status.event.player;
var event = _status.event;
var nh = player.countCards("h");
if (
game.hasPlayer(function (current) {
return get.attitude(player, current) > 0 && current.countCards("h") < nh;
})
) {
if (event.type == "dying") {
if (event.filterCard({ name: "tao" }, player, event)) {
return 0.5;
}
} else {
if (event.filterCard({ name: "tao" }, player, event) || event.filterCard({ name: "shan" }, player, event)) {
return 4;
}
if (event.filterCard({ name: "sha" }, player, event)) {
return 2.9;
}
}
}
return 0;
},
save: true,
respondSha: true,
respondShan: true,
skillTagFilter: function (player, tag, arg) {
if (player.hasSkill("zhenshan_used")) return false;
var nh = player.countCards("h");
return game.hasPlayer(function (current) {
return current != player && current.countCards("h") < nh;
});
},
result: {
player: function (player) {
if (_status.event.type == "dying") {
return get.attitude(player, _status.event.dying);
} else {
return 1;
}
},
},
},
},
//吴景
twfenghan: {
audio: 2,
trigger: { player: "useCardToPlayered" },
direct: true,
usable: 1,
filter: function (event, player) {
return event.isFirstTarget && event.targets.length > 0 && (event.card.name == "sha" || (get.type(event.card, false) == "trick" && get.tag(event.card, "damage") > 0));
},
content: function () {
"step 0";
var num = trigger.targets.length;
player.chooseTarget([1, num], get.prompt("twfenghan"), "令至多" + get.cnNumber(num) + "名角色各摸一张牌").set("ai", function (target) {
return Math.sqrt(5 - Math.min(4, target.countCards("h"))) * get.attitude(_status.event.player, target) * (target.hasSkillTag("nogain") ? 0.1 : 1);
});
"step 1";
if (result.bool) {
var targets = result.targets.sortBySeat();
player.logSkill("twfenghan", targets);
if (targets.length > 1) game.asyncDraw(targets);
else {
targets[0].draw();
event.finish();
}
} else {
player.storage.counttrigger.twfenghan--;
event.finish();
}
"step 2";
game.delayx();
},
},
twcongji: {
audio: 2,
trigger: {
player: "loseAfter",
global: "loseAsyncAfter",
},
direct: true,
filter: function (event, player) {
if (player == _status.currentPhase || event.type != "discard" || event.getlx === false || !game.hasPlayer(current => current != player)) return false;
var evt = event.getl(player);
for (var i of evt.cards2) {
if (get.color(i, player) == "red" && get.position(i, true) == "d") return true;
}
return false;
},
content: function () {
"step 0";
var cards = [],
cards2 = trigger.getl(player).cards2;
for (var i of cards2) {
if (get.color(i, player) == "red" && get.position(i, true) == "d") cards.push(i);
}
player
.chooseButton(["从击:选择任意张牌交给其他角色", cards], [1, cards.length])
.set(
"goon",
game.hasPlayer(function (current) {
return current != player && get.attitude(player, current) > 0;
})
)
.set("ai", function (button) {
if (_status.event.goon) return get.value(button.link);
return button.link.name == "du" ? 1 : 0;
});
"step 1";
if (result.bool) {
event.cards = result.links;
player.chooseTarget("选择一名角色获得以下牌:", get.translation(cards), true, lib.filter.notMe).set("ai", function (target) {
var player = _status.event.player,
cards = _status.event.getParent().cards;
if (cards[0].name == "du") return -get.attitude(player, target);
var att = get.attitude(player, target);
if (att <= 0) return 0;
if (target.hasSkillTag("nogain")) att /= 10;
if (target.hasJudge("lebu")) att /= 4;
return get.value(cards, target) * att;
});
} else event.finish();
"step 2";
if (result.bool) {
var target = result.targets[0];
player.logSkill("twcongji", target);
target.gain(cards, "gain2");
}
},
},
//王粲
twdianyi: {
audio: 2,
trigger: { player: "phaseEnd" },
forced: true,
filter: function (event, player) {
if (!player.getHistory("sourceDamage").length) return player.countCards("h") != 4;
return player.countCards("h") > 0;
},
content: function () {
var num = player.countCards("h");
if (player.getHistory("sourceDamage").length) player.chooseToDiscard("h", true, num);
else if (num > 4) player.chooseToDiscard("h", true, num - 4);
else player.drawTo(4);
},
},
twyingji: {
audio: 2,
enable: ["chooseToUse", "chooseToRespond"],
hiddenCard: function (player, name) {
return player != _status.currentPhase && lib.inpile.includes(name) && player.countCards("h") == 0;
},
filter: function (event, player) {
if (player == _status.currentPhase || player.countCards("h") > 0) return false;
for (var i of lib.inpile) {
if (i == "wuxie") continue;
var type = get.type(i);
if ((type == "basic" || type == "trick") && event.filterCard({ name: i, isCard: true }, player, event)) return true;
if (i == "sha") {
for (var j of lib.inpile_nature) {
if (event.filterCard({ name: i, nature: j, isCard: true }, player, event)) return true;
}
}
}
return false;
},
chooseButton: {
dialog: function (event, player) {
var list = [];
for (var i of lib.inpile) {
if (i == "wuxie") continue;
var type = get.type(i);
if (type == "basic" || type == "trick") {
var card = { name: i, isCard: true };
if (event.filterCard(card, player, event)) list.push([type, "", i]);
if (i == "sha") {
for (var j of lib.inpile_nature) {
card.nature = j;
if (event.filterCard(card, player, event)) list.push(["基本", "", "sha", j]);
}
}
}
}
return ui.create.dialog("应机", [list, "vcard"]);
},
check: function (button) {
var player = _status.event.player;
var card = { name: button.link[2], nature: button.link[3] };
var val = _status.event.getParent().type == "phase" ? player.getUseValue(card) : 1;
return val;
},
backup: function (links, player) {
return {
viewAs: {
name: links[0][2],
nature: links[0][3],
isCard: true,
},
filterCard: () => false,
selectCard: -1,
precontent: function () {
player.logSkill("twyingji");
player.draw("nodelay");
delete event.result.skill;
},
};
},
prompt: function (links) {
return "将一张手牌当做" + (get.translation(links[0][3]) || "") + get.translation(links[0][2]) + "使用";
},
},
ai: {
fireAttack: true,
respondShan: true,
respondSha: true,
skillTagFilter: function (player) {
if (player == _status.currentPhase || player.countCards("h") > 0) return false;
},
order: 10,
result: {
player: function (player) {
if (_status.event.dying) return get.attitude(player, _status.event.dying) > 0;
return 1;
},
},
},
group: ["twyingji_wuxie"],
},
twyingji_wuxie: {
enable: "chooseToUse",
viewAs: {
name: "wuxie",
isCard: true,
},
viewAsFilter: function (player) {
return player != _status.currentPhase && player.countCards("h") == 0;
},
filterCard: () => false,
prompt: "视为使用【无懈可击】并摸一张牌",
selectCard: [0, 1],
check: () => 1,
precontent: function () {
player.logSkill("twyingji");
player.draw("nodelay");
delete event.result.skill;
},
ai: {
order: 4,
},
},
twshanghe: {
trigger: { player: "dying" },
limited: true,
audio: 2,
filter: function (event, player) {
return game.hasPlayer(function (current) {
return current != player && current.countCards("he") > 0;
});
},
prompt: "是否发动【觞贺】?",
skillAnimation: true,
animationColor: "soil",
logTarget: (event, player) => game.filterPlayer(current => current != player),
content: function () {
"step 0";
player.awakenSkill("twshanghe");
event.targets = game.filterPlayer(current => current != player);
event.num = 0;
event.jiu = false;
"step 1";
event.current = targets[num];
if (!event.current.countCards("he")) event.goto(3);
else
event.current.chooseCard("交给" + get.translation(player) + "一张牌", "he", true).set("ai", function (card) {
var evt = _status.event.getParent();
return 100 - get.value(card);
});
"step 2";
if (result.bool && result.cards && result.cards.length) {
event.current.give(result.cards, player);
if (!event.jiu && get.name(result.cards[0], player) == "jiu") event.jiu = true;
}
"step 3";
event.num++;
if (event.num < targets.length) event.goto(1);
else if (!event.jiu && player.hp < 1) player.recover(1 - player.hp);
},
},
//王昶
twkaiji: {
audio: 2,
trigger: { player: "phaseZhunbeiBegin" },
direct: true,
content: function () {
"step 0";
var num = 1 + player.getStorage("twkaiji").length;
player.chooseTarget([1, num], get.prompt("twkaiji"), "令至多" + get.cnNumber(num) + "名角色各摸一张牌").set("ai", function (target) {
return Math.sqrt(5 - Math.min(4, target.countCards("h"))) * get.attitude(_status.event.player, target) * (target.hasSkillTag("nogain") ? 0.1 : 1);
});
"step 1";
if (result.bool) {
var targets = result.targets.sortBySeat();
event.targets = targets;
player.logSkill("twkaiji", targets);
if (targets.length == 1) targets[0].draw();
else game.asyncDraw(targets);
} else event.finish();
"step 2";
if (targets.length > 1) game.delayx();
if (
game.hasPlayer(function (current) {
return (
targets.includes(current) &&
current.hasHistory("gain", function (evt) {
return evt.getParent(2) == event && get.type(evt.cards[0], current) != "basic";
})
);
})
)
player.draw();
},
group: "twkaiji_count",
subSkill: {
count: {
trigger: { global: "dying" },
forced: true,
firstDo: true,
silent: true,
popup: false,
charlotte: true,
filter: function (event, player) {
return !player.getStorage("twkaiji").includes(event.player);
},
content: function () {
player.markAuto("twkaiji", [trigger.player]);
},
},
},
},
twshepan: {
audio: 2,
trigger: { target: "useCardToTargeted" },
usable: 1,
direct: true,
filter: function (event, player) {
return player != event.player;
},
content: function () {
"step 0";
var target = trigger.player;
event.target = target;
var choiceList = ["摸一张牌", "将" + get.translation(target) + "区域内的一张牌置于牌堆顶"];
var choices = ["选项一"];
if (target.countCards("hej") > 0) choices.push("选项二");
else choiceList[1] = '<span style="opacity:0.5">' + choiceList[1] + "</span>";
choices.push("cancel2");
player
.chooseControl(choices)
.set("choiceList", choiceList)
.set(
"choice",
(function () {
if (choices.length > 2 && get.effect(target, { name: "guohe_copy" }, player, player) > 0) return 1;
return 0;
})()
);
"step 1";
if (result.control != "cancel2") {
player.logSkill("twshepan", target);
if (result.index == 1) player.choosePlayerCard(target, "hej", true);
else {
player.draw();
event.goto(3);
}
} else {
player.storage.counttrigger.twshepan--;
event.finish();
}
"step 2";
var card = result.cards[0];
target.$throw(get.position(card) == "h" ? 1 : card, 1000);
target.lose(card, ui.cardPile, "insert");
"step 3";
game.delayx();
if (target.isIn() && player.countCards("h") == target.countCards("h")) {
player.storage.counttrigger.twshepan--;
player.chooseBool("是否令" + get.translation(trigger.card) + "对自己无效?").set("ai", function () {
var evt = _status.event.getTrigger();
return get.effect(evt.target, evt.card, evt.player, evt.target) < 0;
});
} else event.finish();
"step 4";
if (result.bool) trigger.excluded.add(player);
},
},
//曹肇
twfuzuan: {
audio: 2,
enable: "phaseUse",
usable: 1,
filter: function (event, player) {
return game.hasPlayer(function (current) {
return (
current.getSkills(null, false, false).filter(function (i) {
return get.is.zhuanhuanji(i, current);
}).length > 0
);
});
},
filterTarget: function (card, player, target) {
return (
target.getSkills(null, false, false).filter(function (i) {
return get.is.zhuanhuanji(i, target);
}).length > 0
);
},
content: function () {
"step 0";
var list = target.getSkills(null, false, false).filter(function (i) {
return get.is.zhuanhuanji(i, target);
});
if (list.length == 1) {
event._result = { control: list[0] };
} else
player
.chooseControl(list)
.set("prompt", "选择变更" + get.translation(target) + "一个技能的状态")
.set("choice", list.includes("twfeifu") ? "twfeifu" : 0)
.set("ai", () => _status.event.choice);
"step 1";
var skill = result.control;
target.changeZhuanhuanji(skill);
target.popup(skill, "wood");
game.log(target, "的", "#g【" + get.translation(skill) + "】", "发生了状态变更");
game.delayx();
},
ai: {
order: 8,
result: {
target: function (player, target) {
if (!target.hasSkill("twfeifu")) return 0;
return target.storage.twfeifu ? -1 : 1;
},
},
},
group: "twfuzuan_damage",
subSkill: {
damage: {
audio: "twfuzuan",
trigger: {
player: "damageEnd",
source: "damageSource",
},
direct: true,
filter: function (event, player) {
return game.hasPlayer(function (current) {
return (
current.getSkills(null, false, false).filter(function (i) {
return get.is.zhuanhuanji(i, current);
}).length > 0
);
});
},
content: function () {
"step 0";
player.chooseTarget(lib.skill.twfuzuan.filterTarget, get.prompt("twfuzuan"), "变更一名角色的一个转换技的状态").set("ai", function (target) {
var player = _status.event.player;
return get.effect(target, "twfuzuan", player, player);
});
"step 1";
if (result.bool) {
var target = result.targets[0];
player.logSkill("twfuzuan", target);
var next = game.createEvent("twfuzuan");
next.player = player;
next.target = target;
next.setContent(lib.skill.twfuzuan.content);
}
},
},
},
},
twchongqi: {
audio: 2,
trigger: {
global: "phaseBefore",
player: "enterGame",
},
forced: true,
filter: function (event, player) {
return event.name != "phase" || game.phaseNumber == 0;
},
logTarget: () => game.filterPlayer().sortBySeat(),
content: function () {
"step 0";
game.filterPlayer()
.sortBySeat()
.forEach(function (current) {
current.addSkills("twfeifu");
});
//game.log(player,'令所有其他角色获得了技能','#g【非服】')
game.delayx();
"step 1";
player.chooseTarget("是否减1点体力上限并令一名其他角色获得技能【复纂】", lib.filter.notMe).set("ai", function (target) {
var player = _status.event.player;
if (player.hasUnknown() && !target.isZhu) return 0;
if (player.getEnemies().includes(target)) return 0;
return get.attitude(player, target);
});
"step 2";
if (result.bool) {
player.loseMaxHp();
var target = result.targets[0];
player.line(target, "fire");
target.addSkills("twfuzuan");
game.delayx();
}
},
derivation: "twfeifu",
},
twfeifu: {
audio: 2,
trigger: {
player: "useCardToPlayered",
target: "useCardToTargeted",
},
zhuanhuanji: true,
forced: true,
mark: true,
marktext: "☯",
intro: {
content: function (storage, player) {
return (storage ? "当你使用【杀】指定唯一目标后" : "当你成为【杀】的唯一目标后") + "目标角色须交给使用者一张牌。若此牌为装备牌,则使用者可使用此牌。";
},
},
filter: function (event, player, name) {
return event.card.name == "sha" && event.targets.length == 1 && event.player.isIn() && event.target.countCards("he") > 0 && (name == "useCardToPlayered") == Boolean(player.storage.twfeifu);
},
logTarget: function (event, player) {
return player.storage.twfeifu ? event.target : event.player;
},
content: function () {
"step 0";
player.changeZhuanhuanji("twfeifu");
trigger.target.chooseCard("he", true, "非服:交给" + get.translation(trigger.player) + "一张牌", "若选择装备牌,则其可以使用此牌");
"step 1";
if (result.bool) {
var card = result.cards[0];
event.card = card;
trigger.target.give(card, trigger.player);
} else event.finish();
"step 2";
var target = trigger.player;
if (target.getCards("h").includes(card) && get.type(card, target) == "equip" && target.hasUseTarget(card)) target.chooseUseTarget(card, "nopopup");
},
},
//Powered by @污言噫对
twjingce: {
marktext: "策",
intro: {
name: "策",
content: "mark",
},
audio: 2,
trigger: { player: "useCardAfter" },
filter: function (event, player) {
var evt = event.getParent("phaseUse");
if (!evt || evt.player != player) return false;
var history = player.getHistory("useCard", function (evtx) {
return evtx.getParent("phaseUse") == evt;
});
return history && history.indexOf(event) == player.hp - 1;
},
frequent: true,
content: function () {
"step 0";
player.draw(2);
"step 1";
if (
player.getHistory("sourceDamage").length ||
player.getHistory("gain", function (evt) {
return evt.getParent("phaseUse") == trigger.getParent("phaseUse") && evt.getParent().name == "draw";
}).length > 1
)
player.addMark("twjingce", 1);
},
},
yuzhang: {
audio: 2,
trigger: {
player: "damageEnd",
},
filter: function (event, player) {
return event.source && player.hasMark("twjingce");
},
direct: true,
content: function () {
"step 0";
var choiceList = ["令" + get.translation(trigger.source) + "本回合不能再使用或打出牌"];
if (trigger.source.countCards("he")) choiceList.push("令" + get.translation(trigger.source) + "弃置两张牌");
player
.chooseControl("cancel2")
.set("prompt2", get.prompt2("yuzhang"))
.set("choiceList", choiceList)
.set("ai", function () {
var player = _status.event.player,
source = _status.event.source;
if (get.attitude(player, source) >= 0) return "cancel2";
if (source.hasSkillTag("noh") || source.hasSkillTag("noe") || source.countCards("h") >= 4) return 0;
if (source.hp > 1 && source.countCards("he") > 1) return 1;
return [0, 1].randomGet();
})
.set("source", trigger.source);
"step 1";
if (result.control != "cancel2") {
player.logSkill("yuzhang", trigger.source);
player.removeMark("twjingce", 1);
if (result.index == 0) trigger.source.addTempSkill("yuzhang_dontuse");
else trigger.source.chooseToDiscard("he", 2, true);
}
},
group: "yuzhang_skip",
subSkill: {
skip: {
audio: "yuzhang",
trigger: {
player: ["phaseZhunbeiBefore", "phaseJudgeBefore", "phaseDrawBefore", "phaseUseBefore", "phaseDiscardBefore", "phaseJieshuBefore"],
},
filter: function (event, player) {
return player.hasMark("twjingce");
},
prompt2: function (event, player) {
var str = "弃置一枚“策”并跳过";
var list = lib.skill.yuzhang.subSkill.skip.trigger.player.slice();
list = list.map(i => i.slice(0, -6));
str += ["准备", "判定", "摸牌", "出牌", "弃牌", "结束"][list.indexOf(event.name)];
str += "阶段";
return str;
},
check: function (event, player) {
if (event.name == "phaseDiscard") return player.needsToDiscard();
if (event.name == "phaseJudge") return player.countCards("j");
return false;
},
content: function () {
player.removeMark("twjingce", 1);
trigger.cancel();
},
},
dontuse: {
charlotte: true,
mark: true,
mod: {
cardEnabled2: function (card) {
return false;
},
},
intro: {
content: "不能使用或打出牌",
},
},
},
ai: {
combo: "twjingce",
},
},
twlihuo: {
trigger: { player: "useCard1" },
filter: function (event, player) {
if (event.card.name == "sha" && !game.hasNature(event.card)) return true;
return false;
},
audio: "lihuo",
prompt2: function (event) {
return "将" + get.translation(event.card) + "改为火属性";
},
audioname: ["re_chengpu"],
check: function (event, player) {
return game.hasPlayer(function (current) {
return !event.targets.includes(current) && player.canUse(event.card, current) && get.effect(current, { name: "sha", nature: "fire", cards: event.cards.slice(0) }, player, player) > 0;
});
},
content: function () {
game.setNature(trigger.card, "fire");
trigger.card.twlihuo_buffed = true;
},
group: ["twlihuo2", "twlihuo3"],
ai: {
fireAttack: true,
},
},
twlihuo2: {
trigger: { player: "useCard2" },
filter: function (event, player) {
if (event.card.name != "sha" || !game.hasNature(event.card, "fire")) return false;
return game.hasPlayer(function (current) {
return !event.targets.includes(current) && player.canUse(event.card, current);
});
},
direct: true,
content: function () {
"step 0";
player
.chooseTarget(get.prompt("twlihuo"), "为" + get.translation(trigger.card) + "增加一个目标", function (card, player, target) {
return !_status.event.sourcex.includes(target) && player.canUse(_status.event.card, target);
})
.set("sourcex", trigger.targets)
.set("card", trigger.card)
.set("ai", function (target) {
var player = _status.event.player;
return get.effect(target, _status.event.card, player, player);
});
"step 1";
if (result.bool) {
if (!event.isMine() && !_status.connectMode) game.delayx();
event.target = result.targets[0];
} else {
event.finish();
}
"step 2";
player.logSkill("twlihuo", event.target);
trigger.targets.push(event.target);
},
},
twlihuo3: {
trigger: { player: "useCardAfter" },
filter: function (event, player) {
return (event.card.twlihuo_buffed =
true &&
player.getHistory("sourceDamage", function (evt) {
return evt.card == event.card && evt._dyinged;
}).length > 0);
},
forced: true,
audio: "lihuo",
audioname: ["re_chengpu"],
content: function () {
player.loseHp();
},
},
twchunlao: {
audio: "chunlao",
trigger: { player: "phaseZhunbeiBegin" },
direct: true,
filter: function (event, player) {
return (
game.hasPlayer(function (current) {
return current.countCards("hej") > 0;
}) &&
!game.hasPlayer(function (current) {
return current.getExpansions("twchunlao").length > 0;
})
);
},
content: function () {
"step 0";
player
.chooseTarget(get.prompt("twchunlao"), "将一名角色区域内的一张牌作为“醇”置于其武将牌上", function (card, player, target) {
return target.countCards("hej") > 0;
})
.set("ai", function (target) {
return get.attitude(_status.event.player, target) * (player == target ? 1 : 2);
});
"step 1";
if (result.bool) {
var target = result.targets[0];
event.target = target;
player.logSkill("twchunlao", target);
player.choosePlayerCard(target, "hej", true);
} else event.finish();
"step 2";
if (result.bool) {
target.addToExpansion(result.cards, target, "give").gaintag.add("twchunlao");
}
},
intro: {
content: "expansion",
markcount: "expansion",
},
group: ["twchunlao_sha", "twchunlao_dying"],
subSkill: {
sha: {
trigger: { global: "useCard" },
direct: true,
filter: function (event, player) {
return event.card.name == "sha" && event.player.countCards("he") > 0 && event.player.getExpansions("twchunlao").length > 0;
},
content: function () {
"step 0";
event.target = trigger.player;
event.target
.chooseCard("he", "醇醪:是否交给" + get.translation(player) + "一张牌,令" + get.translation(trigger.card) + "的伤害值基数+1")
.set("ai", function (card) {
if (!_status.event.goon) return 3.5 - get.value(card);
return 7 - get.value(card);
})
.set(
"goon",
(function () {
if (get.attitude(target, player) < 0) return false;
var d1 = true;
if (trigger.player.hasSkill("jueqing") || trigger.player.hasSkill("gangzhi")) d1 = false;
for (var target of trigger.targets) {
if (
!target.mayHaveShan(
player,
"use",
target.getCards("h", i => {
return i.hasGaintag("sha_notshan");
})
) ||
trigger.player.hasSkillTag(
"directHit_ai",
true,
{
target: target,
card: trigger.card,
},
true
)
) {
if (!target.hasSkill("gangzhi")) d1 = false;
if (
!target.hasSkillTag("filterDamage", null, {
player: trigger.player,
card: trigger.card,
}) &&
get.attitude(player, target) < 0
)
return true;
}
}
return d1;
})()
);
if (!event.target.isUnderControl(true) && !event.target.isOnline()) game.delayx();
"step 1";
if (result.bool) {
target.logSkill("twchunlao", player);
if (!target.hasSkill("twchunlao")) game.trySkillAudio("twchunlao", player);
if (player != target) target.give(result.cards, player, "giveAuto");
trigger.baseDamage++;
}
},
},
dying: {
audio: "chunlao",
trigger: { global: "dying" },
logTarget: "player",
filter: function (event, player) {
return event.player.getExpansions("twchunlao").length > 0;
},
prompt2: (event, player) => "移去" + get.translation(event.player) + "武将牌上的“醇”并摸一张牌然后令其回复1点体力",
check: function (event, player) {
return get.attitude(player, event.player) > 0;
},
content: function () {
var target = trigger.player,
cards = target.getExpansions("twchunlao");
if (cards.length) target.loseToDiscardpile(cards);
player.draw();
target.recover();
},
},
},
},
//张曼成
twfengji: {
audio: 2,
mahouSkill: true,
trigger: { player: "phaseUseBegin" },
filter: function (event, player) {
return !player.getExpansions("twfengji").length && !player.hasSkill("twfengji_mahou") && player.countCards("he");
},
direct: true,
content: function () {
"step 0";
player.chooseCard("he", get.prompt2("twfengji")).set("ai", function (card) {
var name = card.name,
num = 0;
for (var i = 0; i < ui.cardPile.childNodes.length; i++) {
if (ui.cardPile.childNodes[i].name == name) num++;
}
if (num < 2) return false;
return 8 - get.value(card);
});
"step 1";
if (result.bool) {
player.logSkill("twfengji");
player.addToExpansion(result.cards, player, "giveAuto").gaintag.add("twfengji");
player
.chooseControl("1回合", "2回合", "3回合")
.set("prompt", "请选择施法时长")
.set("ai", function () {
var player = _status.event.player;
var safe = Math.min(player.getHandcardLimit(), player.countCards("h", "shan"));
if (safe < Math.min(3, game.countPlayer())) {
var next = player.next;
while (next != player && get.attitude(next, player) > 0) {
safe++;
next = next.next;
}
}
return Math.max(2, Math.min(safe, 3, game.countPlayer())) - 1;
});
} else event.finish();
"step 2";
player.storage.twfengji_mahou = [result.index + 1, result.index + 1];
player.addTempSkill("twfengji_mahou", { player: "die" });
},
marktext: "示",
onremove: function (player, skill) {
var cards = player.getExpansions(skill);
if (cards.length) player.loseToDiscardpile(cards);
},
intro: {
content: "expansion",
markcount: "expansion",
},
subSkill: {
mahou: {
trigger: { global: "phaseEnd" },
forced: true,
popup: false,
charlotte: true,
content: function () {
var list = player.storage.twfengji_mahou;
list[1]--;
if (list[1] == 0) {
game.log(player, "的“蜂集”魔法生效");
player.logSkill("twfengji");
var cards = player.getExpansions("twfengji");
if (cards.length) {
var cards2 = [],
num = list[0];
for (var card of cards) {
for (var i = 0; i < num; i++) {
var card2 = get.cardPile2(function (cardx) {
return cardx.name == card.name && !cards2.includes(cardx);
});
if (card2) cards2.push(card2);
else break;
}
}
game.delayx();
if (cards2.length) player.gain(cards2, "gain2");
player.loseToDiscardpile(cards);
}
player.removeSkill("twfengji_mahou");
} else {
game.log(player, "的“蜂集”魔法剩余", "#g" + list[1] + "回合");
player.markSkill("twfengji_mahou");
}
},
ai: { threaten: 2.5 },
mark: true,
onremove: true,
//该图标为灵魂宝石
marktext: "♗",
intro: {
name: "施法:蜂集",
markcount: function (storage) {
if (storage) return storage[1];
return 0;
},
content: function (storage) {
if (storage) {
return "经过" + storage[1] + "个“回合结束时”后,若有“示”,则从牌堆中获得" + storage[0] + "张和“示”名称相同的牌";
}
return "未指定施法效果";
},
},
},
},
},
twyiju: {
audio: 2,
locked: false,
mod: {
attackRangeBase: function (player, num) {
if (player.getExpansions("twfengji").length) return player.hp;
},
cardUsable: function (card, player, num) {
if (card.name == "sha" && player.getExpansions("twfengji").length) return num - 1 + player.hp;
},
},
trigger: { player: "damageBegin3" },
filter: function (event, player) {
return player.getExpansions("twfengji").length > 0;
},
forced: true,
content: function () {
trigger.num++;
var cards = player.getExpansions("twfengji");
if (cards.length) player.loseToDiscardpile(cards);
},
ai: {
halfneg: true,
combo: "twfengji",
},
},
twbudao: {
audio: 2,
trigger: { player: "phaseZhunbeiBegin" },
derivation: ["twzhouhu", "twharvestinori", "twzuhuo", "twzhouzu", "twhuangjin", "twguimen", "twdidao"],
limited: true,
skillAnimation: true,
animationColor: "metal",
check: function (event, player) {
return !player.hasUnknown() || !player.hasFriend();
},
skillValue: {
twzhouhu: target => (Math.random() < 0.6 ? 0.1 : 1),
twzuhuo: (target, player) => (get.damageEffect(target, player, player) > 0 ? 0.1 : 1),
twharvestinori: target => 0.9 + Math.random() / 5,
twhuangjin: target => Math.random() / 5,
twguimen: target => Math.sqrt(Math.min(3, target.countCards("he", { suit: "spade" }))) * 0.09,
twzhouzu: target => {
var rand = Math.random();
if (rand < 0.8) return 1 - Math.sqrt(0.8 - rand);
return 1;
},
twdidao: (target, player) => {
if (
[target, player].some(current =>
current.getSkills().some(skill => {
var info = get.info(skill);
if (!info || !info.ai || !info.ai.rejudge) return false;
return true;
})
)
) {
return 0.05;
}
return 0.85 + Math.random() / 5;
},
},
content: function () {
"step 0";
player.awakenSkill("twbudao");
player.loseMaxHp();
player.recover();
var skills = lib.skill.twbudao.derivation,
map = lib.skill.twbudao.skillValue;
skills = skills.randomGets(3);
var target = game.filterPlayer().sort((a, b) => get.attitude(player, b) - get.attitude(player, a))[0];
if (player.identity == "nei" || get.attitude(player, target) < 6) target = player;
player
.chooseControl(skills)
.set(
"choiceList",
skills.map(function (i) {
return '<div class="skill">【' + get.translation(lib.translate[i + "_ab"] || get.translation(i).slice(0, 2)) + "】</div><div>" + get.skillInfoTranslation(i, player) + "</div>";
})
)
.set("displayIndex", false)
.set("prompt", "布道:选择获得一个技能")
.set("ai", () => {
return _status.event.choice;
})
.set("choice", skills.sort((a, b) => (map[b](target, player) || 0.5) - (map[a](target, player) || 0.5))[0]);
"step 1";
var skill = result.control;
player.addSkills(skill);
event.twbudao_skill = skill;
player.chooseTarget(lib.filter.notMe, "是否令一名其他角色也获得【" + get.translation(skill) + "】?").set("ai", function (target) {
var player = _status.event.player;
if (player.identity == "nei") return 0;
return get.attitude(player, target);
});
"step 2";
if (result.bool) {
var target = result.targets[0];
event.target = target;
player.line(target, "green");
target.addSkills(event.twbudao_skill);
var cards = target.getCards("he");
if (!cards.length) event.finish();
else if (cards.length == 1) event._result = { bool: true, cards: cards };
else target.chooseCard("he", true, "交给" + get.translation(player) + "一张牌作为学费");
} else event.finish();
"step 3";
if (result.bool) target.give(result.cards, player);
},
},
twzhouhu: {
audio: 2,
mahouSkill: true,
enable: "phaseUse",
usable: 1,
filter: function (event, player) {
return !player.hasSkill("twzhouhu_mahou") && player.countCards("h", lib.skill.twzhouhu.filterCard) > 0;
},
filterCard: { color: "red" },
check: function (card) {
if (_status.event.player.isHealthy()) return 0;
return 7 - get.value(card);
},
content: function () {
"step 0";
player
.chooseControl("1回合", "2回合", "3回合")
.set("prompt", "请选择施法时长")
.set("ai", function () {
var player = _status.event.player;
var safe = 1;
if (safe < Math.min(3, game.countPlayer(), player.getDamagedHp())) {
var next = player.next;
while (next != player && get.attitude(next, player) > 0) {
safe++;
next = next.next;
}
}
return Math.max(1, Math.min(safe, 3, game.countPlayer(), player.getDamagedHp())) - 1;
});
"step 1";
player.storage.twzhouhu_mahou = [result.index + 1, result.index + 1];
player.addTempSkill("twzhouhu_mahou", { player: "die" });
},
ai: {
order: 2,
result: {
player: 1,
},
},
subSkill: {
mahou: {
trigger: { global: "phaseEnd" },
forced: true,
popup: false,
charlotte: true,
content: function () {
var list = player.storage.twzhouhu_mahou;
list[1]--;
if (list[1] == 0) {
game.log(player, "的“咒护”魔法生效");
player.logSkill("twzhouhu");
var num = list[0];
player.recover(num);
player.removeSkill("twzhouhu_mahou");
} else {
game.log(player, "的“咒护”魔法剩余", "#g" + list[1] + "回合");
player.markSkill("twzhouhu_mahou");
}
},
mark: true,
onremove: true,
marktext: "♗",
intro: {
name: "施法:咒护",
markcount: function (storage) {
if (storage) return storage[1];
return 0;
},
content: function (storage) {
if (storage) {
return "经过" + storage[1] + "个“回合结束时”后,回复" + storage[0] + "点体力";
}
return "未指定施法效果";
},
},
},
},
},
twharvestinori: {
audio: 2,
mahouSkill: true,
enable: "phaseUse",
usable: 1,
filter: function (event, player) {
return !player.hasSkill("twharvestinori_mahou") && player.countCards("h", lib.skill.twharvestinori.filterCard) > 0;
},
filterCard: { color: "black" },
check: function (card) {
return 8 - get.value(card);
},
content: function () {
"step 0";
player
.chooseControl("1回合", "2回合", "3回合")
.set("prompt", "请选择施法时长")
.set("ai", function () {
var player = _status.event.player;
var safe = player.hp;
if (safe < Math.min(3, game.countPlayer())) {
var next = player.next;
while (next != player && get.attitude(next, player) > 0) {
safe++;
next = next.next;
}
}
return Math.max(1, Math.min(safe, 3, game.countPlayer())) - 1;
});
"step 1";
player.storage.twharvestinori_mahou = [result.index + 1, result.index + 1];
player.addTempSkill("twharvestinori_mahou", { player: "die" });
},
ai: {
order: 8,
result: {
player: 1,
},
},
subSkill: {
mahou: {
trigger: { global: "phaseEnd" },
forced: true,
popup: false,
charlotte: true,
content: function () {
var list = player.storage.twharvestinori_mahou;
list[1]--;
if (list[1] == 0) {
game.log(player, "的“丰祈”魔法生效");
player.logSkill("twharvestinori");
var num = list[0] * 2;
player.draw(num);
player.removeSkill("twharvestinori_mahou");
} else {
game.log(player, "的“丰祈”魔法剩余", "#g" + list[1] + "回合");
player.markSkill("twharvestinori_mahou");
}
},
mark: true,
onremove: true,
marktext: "♗",
intro: {
name: "施法:丰祈",
markcount: function (storage) {
if (storage) return storage[1];
return 0;
},
content: function (storage) {
if (storage) {
return "经过" + storage[1] + "个“回合结束时”后,摸" + storage[0] * 2 + "张牌";
}
return "未指定施法效果";
},
},
},
},
},
twzuhuo: {
audio: 2,
mahouSkill: true,
enable: "phaseUse",
usable: 1,
filter: function (event, player) {
return !player.hasSkill("twzuhuo_mahou") && player.countCards("he", lib.skill.twzuhuo.filterCard) > 0;
},
filterCard: function (card) {
return get.type(card) != "basic";
},
position: "he",
check: function (card) {
return 7 - get.value(card);
},
content: function () {
"step 0";
player
.chooseControl("1回合", "2回合", "3回合")
.set("prompt", "请选择施法时长")
.set("ai", function () {
var player = _status.event.player;
var safe = Math.min(player.getHandcardLimit(), player.countCards("h", "shan"));
if (safe < Math.min(3, game.countPlayer())) {
var next = player.next;
while (next != player && get.attitude(next, player) > 0) {
safe++;
next = next.next;
}
}
return Math.max(2, Math.min(safe, 3, game.countPlayer())) - 1;
});
"step 1";
player.storage.twzuhuo_mahou = [result.index + 1, result.index + 1];
player.addTempSkill("twzuhuo_mahou", { player: "die" });
},
ai: {
order: 2,
result: {
player: 1,
},
},
subSkill: {
mahou: {
trigger: { global: "phaseEnd" },
forced: true,
popup: false,
charlotte: true,
content: function () {
var list = player.storage.twzuhuo_mahou;
list[1]--;
if (list[1] == 0) {
game.log(player, "的“阻祸”魔法生效");
player.logSkill("twzuhuo");
var num = list[0];
player.addSkill("twzuhuo_effect");
player.addMark("twzuhuo_effect", num, false);
player.removeSkill("twzuhuo_mahou");
} else {
game.log(player, "的“阻祸”魔法剩余", "#g" + list[1] + "回合");
player.markSkill("twzuhuo_mahou");
}
},
mark: true,
onremove: true,
marktext: "♗",
intro: {
name: "施法:阻祸",
markcount: function (storage) {
if (storage) return storage[1];
return 0;
},
content: function (storage) {
if (storage) {
return "经过" + storage[1] + "个“回合结束时”后,获得" + storage[0] + "层“防止一次伤害”的效果";
}
return "未指定施法效果";
},
},
},
effect: {
charlotte: true,
onremove: true,
trigger: { player: "damageBegin2" },
forced: true,
filter: function (event, player) {
return player.hasMark("twzuhuo_effect");
},
content: function () {
trigger.cancel();
player.removeMark("twzuhuo_effect", 1, false);
if (!player.countMark("twzuhuo_effect")) player.removeSkill("twzuhuo_effect");
},
marktext: "阻︎",
intro: {
onremove: true,
content: "防止接下来的#次伤害",
},
},
},
},
twzhouzu: {
audio: 2,
enable: "phaseUse",
usable: 1,
mahouSkill: true,
filter: function (event, player) {
return !player.hasSkill("twzhouzu_mahou");
},
filterTarget: function (card, player, target) {
return player != target;
},
line: false,
delay: false,
content: function () {
"step 0";
player
.chooseControl("1回合", "2回合", "3回合")
.set("prompt", "请选择施法时长")
.set("ai", function () {
var player = _status.event.player;
var safe = 1;
if (safe < Math.min(3, game.countPlayer())) {
var next = player.next;
while (next != player && get.attitude(next, player) > 0) {
safe++;
next = next.next;
}
}
return Math.max(2, Math.min(safe, 3, game.countPlayer())) - 1;
});
"step 1";
player.storage.twzhouzu_mahou = [result.index + 1, result.index + 1, target];
player.addTempSkill("twzhouzu_mahou", { player: "die" });
},
subSkill: {
mahou: {
trigger: {
global: "phaseEnd",
},
forced: true,
popup: false,
charlotte: true,
content: function () {
var list = player.storage.twzhouzu_mahou;
list[1]--;
if (list[1] == 0) {
game.log(player, "的“咒诅”魔法生效");
var num = list[0],
target = list[2];
player.logSkill("twzhouzu", target);
target.chooseToDiscard(get.translation(player) + "对你的“咒诅”魔法生效,请弃置" + get.cnNumber(list[0]) + "张牌", list[0], true);
target.damage("thunder");
player.removeSkill("twzhouzu_mahou");
} else {
game.log(player, "的“咒阻”魔法剩余", "#g" + list[1] + "回合");
player.markSkill("twzhouzu_mahou");
}
},
mark: true,
onremove: true,
marktext: "♗",
intro: {
name: "施法:咒诅",
markcount: function (storage) {
if (storage) return storage[1];
return 0;
},
content: function (storage) {
if (storage) {
return "经过" + storage[1] + "个“回合结束时”后,你令" + get.translation(storage[2]) + "弃置" + get.cnNumber(storage[0]) + "张牌然后你对其造成1点雷电伤害";
}
return "未指定施法效果";
},
},
},
},
ai: {
order: 1,
result: {
target: -5,
},
},
},
twhuangjin: {
audio: 2,
trigger: { target: "useCardToTarget" },
forced: true,
logTarget: "player",
filter: function (event, player) {
return event.card.name == "sha" && typeof get.number(event.card) == "number";
},
content: function () {
"step 0";
player.judge(function (result) {
var evt = _status.event.getTrigger();
if (Math.abs(get.number(result) - get.number(evt.card)) <= 1) return 2;
return -1;
}).judge2 = function (result) {
return result.bool;
};
"step 1";
if (result.bool) {
trigger.getParent().excluded.add(player);
}
},
ai: {
effect: {
2024-05-11 08:40:41 +00:00
target_use(card, player, target, current, isLink) {
if (card.name == "sha" && !isLink) return 0.8;
},
},
},
},
twguimen: {
audio: 2,
trigger: {
player: "loseAfter",
global: "loseAsyncAfter",
},
direct: true,
filter: function (event, player) {
if (event.type != "discard") return false;
var evt = event.getl(player);
for (var card of evt.cards2) {
if (get.suit(card, player) == "spade") return true;
}
return false;
},
forced: true,
content: function () {
"step 0";
var cards = [];
var evt = trigger.getl(player);
for (var card of evt.cards2) {
if (get.suit(card, player) == "spade") cards.push(card);
}
if (!cards.length) event.finish();
else event.cards = cards;
"step 1";
if (event.cards.length == 1) {
event._result = { bool: true, links: event.cards };
} else {
player.chooseButton(["鬼门:选择一张♠牌,为其进行判定", event.cards], true);
}
"step 2";
if (result.bool && result.links) {
event.judgingSpade = result.links[0];
event.cards.remove(event.judgingSpade);
game.log(player, "选择", "#y" + get.translation(event.judgingSpade), "进行判定");
player.judge(function (result) {
var card = _status.event.getParent().judgingSpade;
if (Math.abs(get.number(result) - get.number(card)) <= 1) return 4;
return -1;
}).judge2 = function (result) {
return result.bool;
};
} else event.finish();
"step 3";
if (result.bool && game.hasPlayer(current => current != player)) {
player.chooseTarget("选择一名其他角色对其造成2点雷电伤害", lib.filter.notMe, true).set("ai", target => get.damageEffect(target, player, player, "thunder"));
}
"step 4";
if (result.bool) {
player.line(result.targets[0], "thunder");
result.targets[0].damage(2, "thunder");
}
if (event.cards.length) event.goto(1);
},
},
twdidao: {
audio: 2,
trigger: { global: "judge" },
filter: function (event, player) {
return player.countCards("hes");
},
direct: true,
content: function () {
"step 0";
player
.chooseCard(get.translation(trigger.player) + "的" + (trigger.judgestr || "") + "判定为" + get.translation(trigger.player.judging[0]) + "" + get.prompt("twdidao"), "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;
})
.set("ai", function (card) {
var trigger = _status.event.getTrigger();
var player = _status.event.player;
var judging = _status.event.judging;
var result = trigger.judge(card) - trigger.judge(judging);
var attitude = get.attitude(player, trigger.player);
if (attitude == 0 || result == 0) {
if (trigger.player != player) return 0;
var checkx = get.color(card, player) == get.color(judging);
if (checkx > 0) return checkx;
return 0;
}
return result * (attitude > 0 ? 1 : -1);
})
.set("judging", trigger.player.judging[0]);
"step 1";
if (result.bool) {
player.respond(result.cards, "highlight", "twdidao", "noOrdering");
} else {
event.finish();
}
"step 2";
if (result.bool) {
player.$gain2(trigger.player.judging[0]);
player.gain(trigger.player.judging[0]);
var card = result.cards[0];
if (get.color(card, player) == get.color(trigger.player.judging[0])) player.draw("nodelay");
trigger.player.judging[0] = result.cards[0];
trigger.orderingCards.addArray(result.cards);
game.log(trigger.player, "的判定牌改为", result.cards[0]);
}
"step 3";
game.delay(2);
},
ai: {
rejudge: true,
tag: {
rejudge: 1,
},
},
},
//群曹操
twlingfa: {
audio: 2,
trigger: { global: "roundStart" },
direct: true,
content: function () {
"step 0";
if (game.roundNumber < 3 || !player.hasSkill("twlingfa")) {
var str;
switch (game.roundNumber) {
case 1:
str = "获得如下效果直到本轮结束其他角色使用【杀】时若其有牌则其需弃置一张牌否则受到你造成的1点伤害。";
break;
case 2:
str = "获得如下效果直到本轮结束其他角色使用【桃】结算结束后若其有牌则其需交给你一张牌否则受到你造成的1点伤害。";
break;
default:
str = "失去【令法】并获得【治暗】";
break;
}
player.chooseBool(get.prompt("twlingfa"), str);
} else event._result = { bool: true };
"step 1";
if (result.bool) {
switch (game.roundNumber) {
case 1:
player.logSkill("twlingfa", game.filterPlayer(current => current != player).sortBySeat());
player.addTempSkill("twlingfa_sha", "roundStart");
break;
case 2:
player.logSkill("twlingfa", game.filterPlayer(current => current != player).sortBySeat());
player.addTempSkill("twlingfa_tao", "roundStart");
break;
default:
player.logSkill("twlingfa");
player.addSkills(["twzhian"], ["twlingfa"]);
break;
}
}
},
subSkill: {
sha: {
audio: "twlingfa",
trigger: { global: "useCard" },
charlotte: true,
forced: true,
filter: function (event, player) {
return player != event.player && event.card.name == "sha" && event.player.countCards("he") > 0;
},
logTarget: "player",
content: function () {
"step 0";
game.delayx();
trigger.player
.chooseToDiscard("he", "令法:弃置一张牌,或受到来自" + get.translation(player) + "的1点伤害")
.set("goon", get.damageEffect(trigger.player, player, trigger.player) < 0)
.set("ai", function (card) {
if (!_status.event.goon) return 0;
return 8 - get.value(card);
});
"step 1";
if (!result.bool) {
trigger.player.damage();
}
},
mark: true,
marktext: '<span style="text-decoration: line-through;">杀</span>',
intro: {
content: "其他角色使用【杀】时若其有牌则其需弃置一张牌否则受到你造成的1点伤害。",
},
},
tao: {
audio: "twlingfa",
trigger: { global: "useCard" },
charlotte: true,
forced: true,
filter: function (event, player) {
return player != event.player && event.card.name == "tao" && event.player.countCards("he") > 0;
},
logTarget: "player",
content: function () {
"step 0";
game.delayx();
trigger.player
.chooseCard("he", "令法:交给" + get.translation(player) + "一张牌否则受到来自其的1点伤害")
.set("goon", get.damageEffect(trigger.player, player, trigger.player) < 0)
.set("ai", function (card) {
if (!_status.event.goon) return 0;
return 8 - get.value(card);
});
"step 1";
if (!result.bool) {
trigger.player.damage();
} else trigger.player.give(result.cards, player);
},
mark: true,
marktext: '<span style="text-decoration: line-through;">桃</span>',
intro: {
content: "其他角色使用【桃】结算结束后若其有牌则其需交给你一张牌否则受到你造成的1点伤害。",
},
},
},
derivation: "twzhian",
},
twzhian: {
audio: 2,
init: function (player) {
game.addGlobalSkill("twzhian_ai");
},
onremove: function (player) {
if (!game.hasPlayer(current => current.hasSkill("twzhian"), true)) game.removeGlobalSkill("twzhian_ai");
},
usable: 1,
trigger: { global: "useCardAfter" },
direct: true,
filter: function (event, player) {
var type = get.type(event.card);
if (type != "delay" && type != "equip") return false;
if (event.cards.length != 1) return false;
var position = get.position(event.cards[0]);
if (position == "e" || position == "j") return true;
return event.player.isIn();
},
content: function () {
"step 0";
var str = get.translation(trigger.cards[0]),
owner = get.owner(trigger.cards[0]);
var choiceList = ["弃置" + (owner ? get.translation(owner) + "区域内的" : "") + str, "弃置一张手牌并获得" + str, "对" + get.translation(trigger.player) + "造成1点伤害"];
var choices = [];
if (owner && lib.filter.canBeDiscarded(card, player, owner)) choices.push("选项一");
else choiceList[0] = '<span style="opacity:0.5">' + choiceList[0] + "</span>";
if (
owner &&
player.hasCard(function (card) {
return lib.filter.cardDiscardable(card, player, "twzhian");
}, "h") &&
lib.filter.canBeGained(card, player, owner)
)
choices.push("选项二");
else choiceList[1] = '<span style="opacity:0.5">' + choiceList[1] + "</span>";
if (trigger.player.isIn()) choices.push("选项三");
else choiceList[2] = '<span style="opacity:0.5">' + choiceList[2] + "</span>";
player
.chooseControl(choices, "cancel2")
.set("choiceList", choiceList)
.set("prompt", get.prompt("twzhian"))
.set("ai", function () {
var player = _status.event.player,
choices = _status.event.controls.slice(0);
var card = _status.event.getTrigger().cards[0],
owner = get.owner(card);
var getEffect = function (choice) {
if (choice == "cancel2") return 0.1;
if (choice == "选项三") {
return get.damageEffect(_status.event.getTrigger().player, player, player);
}
var result;
if (get.position(card) == "j") {
result =
-get.effect(
player,
{
name: card.viewAs || card.name,
cards: [card],
},
player,
player
) * get.sgn(get.attitude(player, owner));
} else result = -(get.value(card, owner) - 0.01) * get.sgn(get.attitude(player, owner));
if (choice == "选项一") return result;
if (
player.hasCard(function (cardx) {
return lib.filter.cardDiscardable(cardx, player, "twzhian") && get.value(cardx, player) < get.value(card, player);
}, "h")
)
return result * 1.2;
return 0;
};
choices.sort(function (a, b) {
return getEffect(b) - getEffect(a);
});
return choices[0];
});
"step 1";
if (result.control != "cancel2") {
var card = trigger.cards[0],
owner = get.owner(card);
switch (result.control) {
case "选项一":
player.logSkill("twzhian", owner);
owner.discard(card, "notBySelf");
event.finish();
break;
case "选项二":
player.chooseToDiscard("h", true).logSkill = ["twzhian", owner];
event.target = owner;
break;
case "选项三":
player.logSkill("twzhian", trigger.player);
trigger.player.damage();
event.finish();
break;
}
} else player.storage.counttrigger.twzhian--;
"step 2";
if (result.bool && target.getCards("ej").includes(trigger.cards[0])) player.gain(trigger.cards, target, "give", "bySelf");
},
subSkill: {
ai: {
trigger: { player: "dieAfter" },
filter: function (event, player) {
return !game.hasPlayer(current => current.hasSkill("twzhian"), true);
},
silent: true,
forceDie: true,
content: function () {
game.removeGlobalSkill("twzhian_ai");
},
ai: {
effect: {
2024-05-11 08:40:41 +00:00
player_use(card, player, target) {
if (get.type(card) !== "delay" && get.type(card) !== "equip") return 1;
let za = game.findPlayer(cur => cur.hasSkill("twzhian") && (!cur.storage.counttrigger || !cur.storage.counttrigger.twzhian) && get.attitude(player, cur) <= 0);
if (za) return [0.5, -0.8];
},
},
},
},
},
},
twyujue: {
audio: 2,
global: "twyujue_give",
trigger: {
player: "gainAfter",
global: "loseAsyncAfter",
},
direct: true,
filter: function (event, player) {
if (player == _status.currentPhase) return false;
var cards = event.getg(player);
if (!cards.length) return false;
return game.hasPlayer(function (current) {
if (current == player) return false;
var evt = event.getl(current);
if (!evt || !evt.cards2 || !evt.cards2.filter(card => cards.includes(card)).length) return false;
return !current.hasSkill("twyujue_effect0") || !current.hasSkill("twyujue_effect1");
});
},
content: function () {
"step 0";
var cards = trigger.getg(player);
var list = game
.filterPlayer(function (current) {
if (current == player) return false;
var evt = trigger.getl(current);
if (!evt || !evt.cards2 || !evt.cards2.filter(card => cards.includes(card)).length) return false;
return !current.hasSkill("twyujue_effect0") || !current.hasSkill("twyujue_effect1");
})
.sortBySeat();
event.targets = list;
"step 1";
var target = event.targets.shift();
if (target.isIn()) {
event.target = target;
var num = 2;
if (target.hasSkill("twyujue_effect0")) num--;
if (target.hasSkill("twyujue_effect1")) num--;
var cards = trigger.getg(player);
num = Math.min(num, trigger.getl(target).cards2.filter(i => cards.includes(i)).length);
if (num > 0) event.count = num;
else if (targets.length > 0) event.redo();
else event.finish();
} else if (targets.length > 0) event.redo();
else event.finish();
"step 2";
event.count--;
player.chooseBool(get.prompt("twyujue", target), "可令其选择本回合内未选择过的一项:⒈弃置攻击范围内一名角色的一张牌。⒉下一次使用牌时,从牌堆中获得一张同类别的牌。").set("ai", function () {
var evt = _status.event.getParent();
return get.attitude(evt.player, evt.target) > 0;
});
"step 3";
if (result.bool) {
player.logSkill("twyujue", target);
var list = [0, 1];
if (target.hasSkill("twyujue_effect0")) list.remove(0);
if (target.hasSkill("twyujue_effect1")) list.remove(1);
if (!list.length) event.goto(6);
else if (list.length == 1) event._result = { index: list[0] };
else
target
.chooseControl()
.set("choiceList", ["弃置攻击范围内一名角色的一张牌", "下一次使用牌时,从牌堆中获得一张同类别的牌"])
.set("ai", function () {
var player = _status.event.player;
if (
game.hasPlayer(function (current) {
return player.inRange(current) && current.countDiscardableCards(player, "he") > 0 && get.effect(current, { name: "guohe_copy2" }, player, player) > 0;
})
)
return 0;
return 1;
});
} else event.goto(6);
"step 4";
target.addTempSkill("twyujue_effect" + result.index);
if (result.index == 0) {
if (
game.hasPlayer(function (current) {
return target.inRange(current) && current.countDiscardableCards(target, "he") > 0;
})
) {
target
.chooseTarget("弃置攻击范围内一名角色的一张牌", true, function (card, player, target) {
return player.inRange(target) && target.countDiscardableCards(player, "he") > 0;
})
.set("ai", function (target) {
var player = _status.event.player;
return get.effect(target, { name: "guohe_copy2" }, player, player);
});
} else event.goto(6);
} else event.goto(6);
"step 5";
if (result.bool) {
var target2 = result.targets[0];
target.line(target2, "green");
target.discardPlayerCard(target2, "he", true);
}
"step 6";
game.delayx();
if (event.count > 0) event.goto(2);
else if (targets.length) event.goto(1);
},
subSkill: {
clear: {
onremove: true,
},
effect0: { charlotte: true },
effect1: {
charlotte: true,
trigger: { player: "useCard" },
usable: 1,
forced: true,
popup: false,
content: function () {
player.unmarkSkill("twyujue_effect1");
var type2 = get.type2(trigger.card, false);
var card = get.cardPile2(function (card) {
return get.type2(card, false) == type2;
});
if (card) trigger.player.gain(card, "gain2");
},
mark: true,
marktext: "爵",
intro: { content: "使用下一张牌时,从牌堆中获得一张类型相同的牌" },
},
},
},
twyujue_give: {
audio: 2,
enable: "phaseUse",
filter: function (event, player) {
if (!player.countCards("he")) return false;
var targets = game.filterPlayer(function (current) {
return current != player && current.hasSkill("twyujue");
});
if (!targets.length) return false;
for (var target of targets) {
var num = 2;
if (player.group == "qun" && target.hasZhuSkill("twfengqi", player)) num = 4;
if (target.countMark("twyujue_clear") < num) return true;
}
return false;
},
selectCard: function () {
var player = _status.event.player;
var targets = game.filterPlayer(function (current) {
return current != player && current.hasSkill("twyujue");
});
return [
1,
Math.max.apply(
Math,
targets.map(function (target) {
var num = 2;
if (player.group == "qun" && target.hasZhuSkill("twfengqi", player)) num = 4;
return num - target.countMark("twyujue_clear");
})
),
];
},
filterCard: true,
filterTarget: function (card, player, target) {
if (!target.hasSkill("twyujue")) return false;
var num = 2;
if (player.group == "qun" && target.hasZhuSkill("twfengqi", player)) num = 4;
return num - target.countMark("twyujue_clear") >= Math.max(1, ui.selected.cards.length);
},
selectTarget: function () {
var player = _status.event.player;
var targets = game.filterPlayer(function (current) {
return current != player && current.hasSkill("twyujue");
});
return targets.length > 1 ? 1 : -1;
},
complexSelect: true,
prompt: function () {
var player = _status.event.player;
var targets = game.filterPlayer(function (current) {
return current != player && current.hasSkill("twyujue");
});
return "将任意张牌交给" + get.translation(targets) + (targets.length > 1 ? "中的一人" : "");
},
position: "he",
discard: false,
lose: false,
delay: false,
check: function (card) {
if (ui.selected.cards.length) return 0;
var player = _status.event.player;
if (
game.hasPlayer(function (current) {
return lib.skill.twyujue_give.filterTarget(null, player, current) && get.attitude(player, current) > 0;
})
) {
var val = get.value(card);
if (val <= 0 && get.position(card) == "e") return 100 - val;
if (
!player.hasSkill("twyujue_effect1") &&
player.hasCard(function (cardx) {
return cardx != card && player.getUseValue(cardx, null, true) > 0;
}, "hs")
)
return 6 - get.value(card);
if (
!player.hasSkill("twyujue_effect0") &&
game.hasPlayer(function (current) {
return player.inRange(current) && current.countDiscardableCards(player, "he") > 0 && get.effect(current, { name: "guohe_copy2" }, player, player) > 0;
})
)
return 5.5 - get.value(card);
}
return 0;
},
content: function () {
game.trySkillAudio("twyujue", target);
player.give(cards, target);
target.addTempSkill("twyujue_clear");
target.addMark("twyujue_clear", cards.length, false);
},
ai: {
order: 10,
result: { target: 1 },
},
},
twgezhi: {
audio: 2,
trigger: { player: "useCard" },
direct: true,
filter: function (event, player) {
if (!player.countCards("h")) return false;
var evt = event.getParent("phaseUse");
if (!evt || evt.player != player) return false;
var type = get.type2(event.card, false);
return !player.hasHistory(
"useCard",
function (evtx) {
return evtx != event && get.type2(evtx.card, false) == type && evtx.getParent("phaseUse") == evt;
},
event
);
},
content: function () {
"step 0";
if (!event.isMine() && !event.isOnline()) game.delayx();
player.chooseCard("是否发动【革制】重铸一张牌?", lib.filter.cardRecastable).set("ai", function (card) {
return 5.5 - get.value(card);
});
"step 1";
if (result.bool) {
player.logSkill("twgezhi");
player.recast(result.cards);
}
},
group: "twgezhi_buff",
subSkill: {
buff: {
audio: "twgezhi",
trigger: { player: "phaseUseEnd" },
direct: true,
filter: function (event, player) {
return (
player.getHistory("lose", function (evt) {
return evt.getParent(3).name == "twgezhi" && evt.getParent("phaseUse") == event;
}).length > 1
);
},
content: function () {
"step 0";
player
.chooseTarget(get.prompt("twgezhi"), "你可以令一名角色选择获得一个其未获得过的效果:⒈攻击范围+2⒉手牌上限+2⒊加1点体力上限。", function (card, player, target) {
return !target.hasSkill("twgezhi_选项一") || !target.hasSkill("twgezhi_选项二") || !target.hasSkill("twgezhi_选项三");
})
.set("ai", function (target) {
return get.attitude(_status.event.player, target);
});
"step 1";
if (result.bool) {
var target = result.targets[0];
event.target = target;
player.logSkill("twgezhi", target);
var list = [];
for (var i = 1; i <= 3; i++) {
var str = "选项" + get.cnNumber(i, true);
if (!target.hasSkill("twgezhi_" + str)) list.push(str);
}
if (list.length == 1) event._result = { control: list[0] };
else
target
.chooseControl(list)
.set("choiceList", ["令自己的攻击范围+2", "令自己的手牌上限+2", "令自己的体力上限+1"])
.set("ai", function () {
var player = _status.event.player,
controls = _status.event.controls;
if (
controls.includes("选项一") &&
game.hasPlayer(function (current) {
return (get.realAttitude || get.attitude)(player, current) < 0 && get.distance(player, current, "attack") > 1;
})
)
return "选项一";
if (controls.includes("选项二") && player.needsToDiscard()) return "选项二";
if (controls.includes("选项三")) return "选项三";
return controls.randomGet();
});
} else {
event._triggered = null;
event.finish();
}
"step 2";
target.addSkill("twgezhi_" + result.control);
if (result.control == "选项三") target.gainMaxHp();
"step 3";
game.delayx();
},
},
选项一: {
charlotte: true,
mod: {
attackFrom: function (from, to, distance) {
return distance - 2;
},
},
mark: true,
marktext: " +2 ",
intro: { content: "攻击范围+2" },
},
选项二: {
charlotte: true,
mod: {
maxHandcard: function (player, num) {
return num + 2;
},
},
mark: true,
marktext: " +2 ",
intro: { content: "手牌上限+2" },
},
选项三: {
charlotte: true,
mark: true,
marktext: " +1 ",
intro: { content: "体力上限+1" },
},
},
},
twfengqi: {
audio: 2,
zhuSkill: true,
trigger: { player: "twgezhi_buffAfter" },
direct: true,
filter: function (event, player) {
if (!event.target || !event.target.isIn() || !player.hasZhuSkill("twfengqi", event.target)) return false;
var target = event.target;
return target.getStockSkills(true, true).some(skill => {
if (target.hasSkill(skill)) return false;
var info = get.info(skill);
return info && info.zhuSkill;
});
},
skillAnimation: true,
animationColor: "thunder",
content: function () {
"step 0";
event.target = trigger.target;
event.target.chooseBool(get.prompt("twfengqi"), "获得武将牌上的所有主公技");
"step 1";
if (result.bool) {
target.logSkill("twfengqi", player);
var skills = target.getStockSkills(true, true).filter(skill => {
if (target.hasSkill(skill)) return false;
var info = get.info(skill);
return info && info.zhuSkill;
});
target.addSkills(skills);
//for(var i of skills) target.addSkillLog(i);
}
},
ai: {
combo: "twyujue",
},
},
twsidai: {
audio: 2,
enable: "phaseUse",
usable: 1,
locked: false,
limited: true,
skillAnimation: true,
animationColor: "fire",
filter: function (event, player) {
var cards = player.getCards("h", { type: "basic" });
if (!cards.length) return false;
for (var i of cards) {
if (!game.checkMod(i, player, "unchanged", "cardEnabled2", player)) return false;
}
return event.filterCard(get.autoViewAs({ name: "sha", storage: { twsidai: true } }, cards), player, event);
},
viewAs: { name: "sha", storage: { twsidai: true } },
filterCard: { type: "basic" },
selectCard: -1,
check: () => 1,
onuse: function (result, player) {
player.awakenSkill("twsidai");
player.addTempSkill("twsidai_effect");
},
ai: {
order: 2.9,
result: {
target: function (player, target) {
2024-05-07 03:26:13 +00:00
if (get.attitude(player, target) >= 0) return -20;
var cards = ui.selected.cards.slice(0);
var names = [];
for (var i of cards) names.add(i.name);
if (names.length < player.hp) return 0;
if (player.hasUnknown() && (player.identity != "fan" || !target.isZhu)) return 0;
return lib.card.sha.ai.result.target.apply(this, arguments);
},
},
},
mod: {
cardUsable: function (card) {
if (card.storage && card.storage.twsidai) return Infinity;
},
targetInRange: function (card) {
if (card.storage && card.storage.twsidai) return true;
},
},
subSkill: {
effect: {
charlotte: true,
trigger: { source: "damageBegin1" },
filter: function (event, player) {
if (!event.card || !event.card.storage || !event.card.storage.twsidai || event.getParent().type != "card") return false;
for (var i of event.cards) {
if (i.name == "jiu") return true;
}
return false;
},
forced: true,
popup: false,
content: function () {
trigger.num *= 2;
game.log(trigger.card, "的伤害值", "#y×2");
},
group: ["twsidai_tao", "twsidai_shan"],
},
tao: {
trigger: { source: "damageSource" },
filter: function (event, player) {
if (!event.card || !event.card.storage || !event.card.storage.twsidai || !event.player.isIn()) return false;
for (var i of event.cards) {
if (i.name == "tao") return true;
}
return false;
},
forced: true,
popup: false,
content: function () {
trigger.player.loseMaxHp();
},
},
shan: {
trigger: { player: "useCardToPlayered" },
filter: function (event, player) {
if (!event.card || !event.card.storage || !event.card.storage.twsidai || !event.target.isIn()) return false;
for (var i of event.cards) {
if (i.name == "shan") return true;
}
return false;
},
forced: true,
popup: false,
content: function () {
"step 0";
trigger.target.chooseToDiscard("h", { type: "basic" }, "弃置一张基本牌,否则不能响应" + get.translation(trigger.card)).set("ai", function (card) {
var player = _status.event.player;
if (
player.hasCard("hs", function (cardx) {
return cardx != card && get.name(cardx, player) == "shan";
})
)
return 12 - get.value(card);
return 0;
});
"step 1";
if (!result.bool) trigger.directHit.add(trigger.target);
},
},
},
},
twjieyu: {
audio: 2,
trigger: { player: ["phaseJieshuBegin", "damageEnd"] },
round: 1,
filter: function (event, player) {
if (event.name != "phaseJieshu") {
var history = player.getHistory("damage");
for (var i of history) {
if (i == event) break;
return false;
}
var all = player.actionHistory;
for (var i = all.length - 2; i >= 0; i--) {
if (all[i].damage.length) return false;
if (all[i].isRound) break;
}
}
return (
player.countCards("h") > 0 &&
!player.hasCard(function (card) {
return !lib.filter.cardDiscardable(card, player, "twjieyu");
}, "h")
);
},
check: function (event, player) {
var cards = [],
names = [];
for (var i = 0; i < ui.discardPile.childNodes.length; i++) {
var card = ui.discardPile.childNodes[i];
if (get.type(card, false) == "basic" && !names.includes(card.name)) {
cards.push(card);
names.push(card.name);
}
}
if (!names.includes("shan") || !names.includes("tao")) return false;
if (player.countCards("h", "shan") < 2 && player.countCards("h", "tao") < 1) return true;
return false;
},
content: function () {
"step 0";
player.discard(player.getCards("h"));
"step 1";
var cards = [],
names = [];
for (var i = 0; i < ui.discardPile.childNodes.length; i++) {
var card = ui.discardPile.childNodes[i];
if (get.type(card, false) == "basic" && !names.includes(card.name)) {
cards.push(card);
names.push(card.name);
}
}
if (cards.length) player.gain(cards, "gain2");
},
},
twhanyu: {
audio: 2,
trigger: {
global: "phaseBefore",
player: "enterGame",
},
forced: true,
filter: function (event, player) {
return event.name != "phase" || game.phaseNumber == 0;
},
content: function () {
var cards = [],
types = ["basic", "trick", "equip"];
for (var i of types) {
var card = get.cardPile2(function (card) {
return get.type2(card, false) == i;
});
if (card) cards.push(card);
}
if (cards.length) player.gain(cards, "gain2");
},
},
twhengjiang: {
audio: "hengjiang",
trigger: { player: "useCardToPlayer" },
filter: function (event, player) {
return (
!player.hasSkill("twhengjiang2") &&
event.targets.length == 1 &&
["basic", "trick"].includes(get.type(event.card, false)) &&
player.isPhaseUsing() &&
game.hasPlayer(function (current) {
return player.inRange(current) && lib.filter.targetEnabled2(event.card, player, current);
})
);
},
prompt: "是否发动【横江】?",
prompt2: function (event, player) {
return "将" + get.translation(event.card) + "的目标改为" + get.translation(lib.skill.twhengjiang.logTarget(event, player));
},
logTarget: function (event, player) {
return game
.filterPlayer(function (current) {
return player.inRange(current) && lib.filter.targetEnabled2(event.card, player, current);
})
.sortBySeat();
},
check: function (event, player) {
var effect1 = get.effect(event.target, event.card, player, player);
var effect2 = 0,
targets = lib.skill.twhengjiang.logTarget(event, player);
for (var i of targets) effect2 += get.effect(i, event.card, player, player);
return effect2 > effect1;
},
content: function () {
var targets = lib.skill.twhengjiang.logTarget(trigger, player);
trigger.targets.length = 0;
trigger.targets.addArray(targets);
trigger.getParent().triggeredTargets1.length = 0;
trigger.getParent().twhengjiang_buffed = true;
player.addTempSkill("twhengjiang2", "phaseUseAfter");
},
},
twhengjiang2: {
charlotte: true,
trigger: { player: "useCardAfter" },
forced: true,
popup: false,
filter: function (event, player) {
return (
event.twhengjiang_buffed &&
game.hasPlayer2(function (current) {
return (
current != player &&
(current.hasHistory("useCard", function (evt) {
return evt.respondTo && evt.respondTo[1] == event.card;
}) ||
current.hasHistory("respond", function (evt) {
return evt.respondTo && evt.respondTo[1] == event.card;
}))
);
})
);
},
content: function () {
player.draw(
game.countPlayer2(function (current) {
return (
current != player &&
(current.hasHistory("useCard", function (evt) {
return evt.respondTo && evt.respondTo[1] == trigger.card;
}) ||
current.hasHistory("respond", function (evt) {
return evt.respondTo && evt.respondTo[1] == trigger.card;
}))
);
})
);
},
},
twyuanhu: {
audio: "yuanhu",
enable: "phaseUse",
usable: 1,
filter: function (event, player) {
return player.hasCard({ type: "equip" }, "eh");
},
filterCard: { type: "equip" },
filterTarget: function (card, player, target) {
var card = ui.selected.cards[0];
return target.canEquip(card);
},
discard: false,
lose: false,
prepare: "give",
position: "he",
check: function (card) {
if (get.position(card) == "h") return 9 - get.value(card);
return 7 - get.value(card);
},
content: function () {
"step 0";
target.equip(cards[0]);
"step 1";
event.goto(3);
switch (get.subtype(cards[0])) {
case "equip1":
if (
game.hasPlayer(function (current) {
return current != target && get.distance(target, current) == 1 && current.countCards("hej") > 0;
})
) {
player
.chooseTarget(true, "弃置一名距离" + get.translation(target) + "为1的角色区域内的一张牌", function (card, player, target) {
var current = _status.event.current;
return current != target && get.distance(current, target) == 1 && current.countCards("hej") > 0;
})
.set("current", target)
.set("ai", function (target) {
var player = _status.event.player;
return get.effect(target, { name: "guohe_copy" }, player, player);
});
event.goto(2);
}
break;
case "equip2":
target.draw();
break;
case "equip3":
case "equip4":
case "equip5":
case "equip6":
target.recover();
break;
}
"step 2";
var target = result.targets[0];
player.line(target);
player.discardPlayerCard(target, true, "hej");
"step 3";
if (target.hp <= player.hp || target.countCards("h") <= player.countCards("h")) {
player.draw();
player.addTempSkill("twyuanhu_end");
}
},
ai: {
order: 10,
result: {
player: function (player, target) {
if (get.attitude(player, target) == 0) return 0;
if (!ui.selected.cards.length) return;
var eff = get.effect(target, ui.selected.cards[0], player, player),
sub = get.subtype(ui.selected.cards[0], false);
if (target == player) eff += 4;
else {
var hp = player.hp,
hs = player.countCards("h", card => card != ui.selected.cards[0]);
var tp = target.hp,
ts = target.countCards("h");
if (sub == "equip2") ts++;
if (tp < target.maxHp && (sub == "equip3" || sub == "equip4" || sub == "equip5" || sub == "equip6")) tp++;
if (tp <= hp || ts <= hs) eff += 2;
}
if (sub == "equip1") {
var list = game
.filterPlayer(function (current) {
return current != target && get.distance(target, current) == 1 && current.countCards("hej") < 0;
})
.map(function (i) {
return get.effect(i, { name: "guohe_copy" }, player, player);
})
.sort((a, b) => b - a);
if (list.length) eff += list[0];
}
return eff;
},
target: function (player, target) {
if (!ui.selected.cards.length) return 0;
var sub = get.subtype(ui.selected.cards[0], false);
var eff = get.effect(target, ui.selected.cards[0], player, target);
if (sub == "equip2") eff += get.effect(target, { name: "draw" }, target, target);
if (target.isDamaged() && (sub == "equip3" || sub == "equip4" || sub == "equip5" || sub == "equip6")) eff += get.recoverEffect(target, player, player);
return eff;
},
},
},
subSkill: {
end: {
trigger: { player: "phaseJieshuBegin" },
direct: true,
charlotte: true,
filter: function (event, player) {
return player.hasSkill("twyuanhu") && player.hasCard({ type: "equip" }, "eh");
},
content: function () {
"step 0";
player.chooseCardTarget({
prompt: get.prompt("twyuanhu"),
prompt2: "将一张装备牌置入一名角色的装备区内。若此牌为武器牌你弃置与其距离为1的另一名角色区域的一张牌防具牌其摸一张牌坐骑牌或宝物牌其回复1点体力。然后若其体力值或手牌数不大于你则你摸一张牌。",
filterCard: lib.skill.twyuanhu.filterCard,
filterTarget: lib.skill.twyuanhu.filterTarget,
position: "he",
ai1: lib.skill.twyuanhu.check,
ai2: function (target) {
var player = _status.event.player;
return get.effect(target, "twyuanhu", player, player);
},
});
"step 1";
if (result.bool) {
result.skill = "twyuanhu";
player.useResult(result, event);
}
},
},
},
},
twjuezhu: {
audio: 2,
limited: true,
trigger: { player: "phaseZhunbeiBegin" },
direct: true,
filter: function (event, player) {
return player.hasEnabledSlot(3) || player.hasEnabledSlot(4);
},
skillAnimation: true,
animationColor: "water",
content: function () {
"step 0";
player
.chooseTarget(get.prompt2("twjuezhu"), [1, 2], function (card, player, target) {
return !ui.selected.targets.length && !target.hasSkill("feiying");
})
.set("multitarget", true)
.set("promptbar", "none")
.set("ai", function (target) {
if (player.hasUnknown()) return false;
return get.attitude(player, target);
});
"step 1";
if (result.bool) {
event.target = result.targets[0];
var list = [];
if (player.hasEnabledSlot(3)) list.push("equip3");
if (player.hasEnabledSlot(4)) list.push("equip4");
if (list.length == 1) event._result = { control: list[0] };
else player.chooseControl(list).set("prompt", "选择废除一个坐骑栏");
} else event.finish();
"step 2";
player.logSkill("twjuezhu", target);
player.awakenSkill("twjuezhu");
player.disableEquip(result.control);
target.disableJudge();
player.markAuto("twjuezhu_restore", [[target, result.control]]);
player.addSkill("twjuezhu_restore");
target.addSkills("feiying");
},
subSkill: {
restore: {
trigger: { global: "die" },
forced: true,
charlotte: true,
filter: function (event, player) {
for (var i of player.getStorage("twjuezhu_restore")) {
if (i[0] == event.player && player.hasDisabledSlot(i[1])) return true;
}
return false;
},
content: function () {
var list = [];
for (var i of player.getStorage("twjuezhu_restore")) {
if (i[0] == trigger.player && player.hasDisabledSlot(i[1])) list.push(i[1]);
}
player.enableEquip(list);
},
},
},
derivation: "feiying",
},
twfengpo: {
audio: "fengpo",
trigger: { player: "useCardToPlayered" },
logTarget: "target",
filter: function (event, player) {
return (event.card.name == "sha" || event.card.name == "juedou") && event.targets.length == 1 && event.target.countCards("h") > 0;
},
onremove: true,
content: function () {
"step 0";
event.target = trigger.target;
player.viewHandcards(trigger.target);
"step 1";
var num = target.countCards("h", player.storage.twfengpo ? { color: "red" } : { suit: "diamond" });
if (!num) {
event.finish();
return;
}
event.num = num;
player.chooseControl().set("choiceList", ["摸" + num + "张牌", "令" + get.translation(trigger.card) + "的伤害值基数+" + num]);
"step 2";
if (result.index == 0) player.draw(num);
else trigger.getParent().baseDamage += num;
},
group: "twfengpo_kill",
subSkill: {
kill: {
audio: "fengpo",
trigger: { source: "die" },
forced: true,
filter: (event, player) => !player.storage.twfengpo,
skillAnimation: true,
animationColor: "fire",
content: function () {
player.storage.twfengpo = true;
player.popup("凤魄");
game.log(player, "恢复了技能", "#g【凤魄】");
},
},
},
},
twmouzhu: {
audio: "mouzhu",
enable: "phaseUse",
usable: 1,
filterTarget: lib.filter.notMe,
contentBefore: function () {
var target = targets[0],
evt = event.getParent();
evt._target = target;
var list = game.filterPlayer(function (current) {
return current != player && current != target && current.hp <= player.hp;
});
if (!list.length) {
player.loseHp();
evt.finish();
} else {
evt.targets = list.sortBySeat();
player.line(list);
}
},
content: function () {
"step 0";
target
.chooseCard("he", "是否交给" + get.translation(player) + "一张牌?")
.set("ai", function (card) {
if (_status.event.goon) return 7 - get.value(card);
return 0;
})
.set("goon", get.attitude(target, player) > 0);
"step 1";
if (result.bool) {
target.give(result.cards, player);
} else {
game.log(target, "拒绝给牌");
}
},
contentAfter: function () {
"step 0";
var num = 0,
par = event.getParent();
player.getHistory("gain", function (evt) {
if (evt.getParent(2) == par) num += evt.cards.length;
});
if (!num) {
player.loseHp();
for (var i of targets) i.loseHp();
event.finish();
} else {
var target = event.getParent()._target;
event.target = target;
event.num = num;
var bool1 = player.canUse("sha", target, false),
bool2 = player.canUse("juedou", target, false);
if (bool1 && bool2)
target
.chooseControl("sha", "juedou")
.set("prompt", "谋诛:视为被" + get.translation(player) + "使用一张…")
.set("prompt2", "(伤害值基数:" + num + "")
.set("ai", function () {
var target = _status.event.player,
player = _status.event.getParent().player;
if (target.hasShan() || get.effect(target, { name: "sha" }, player, target) > 0) return "sha";
if (get.effect(target, { name: "juedou" }, player, target) > 0) return "juedou";
return "sha";
});
else if (bool1) event._result = { control: "sha" };
else if (bool2) event._result = { control: "juedou" };
else event.finish();
}
"step 1";
if (result.control && lib.card[result.control])
player.useCard(
{
name: result.control,
isCard: true,
},
false,
target
).baseDamage = num;
},
ai: {
order: 9,
result: {
target: function (player, target) {
if (get.attitude(player, target) >= 0) return 0;
var list = game.filterPlayer(function (current) {
return current != player && current != target && current.hp <= player.hp;
});
if (!list.length) return 0;
return (
-Math.min(-get.effect(target, { name: "sha" }, player, target), -get.effect(target, { name: "juedou" }, player, target)) *
list.reduce(function (num, current) {
return num + (2 + get.sgn(get.attitude(current, player)));
}, 0)
);
},
},
},
},
twyanhuo: {
audio: "yanhuo",
trigger: { player: "die" },
direct: true,
forceDie: true,
skillAnimation: true,
animationColor: "thunder",
filter: function (event, player) {
return (
player.countCards("he") > 0 &&
game.hasPlayer(function (current) {
return current != player && current.countCards("h") > 0;
})
);
},
content: function () {
"step 0";
var num = player.countCards("he"),
str = get.cnNumber(num);
event.num1 = num;
event.num2 = 1;
var list = ["令一名其他角色弃置" + str + "张牌"];
if (num > 1) {
list.push("令至多" + str + "名其他角色各弃置一张牌");
}
player.chooseControl("cancel2").set("choiceList", list).set("prompt", get.prompt("twyanhuo")).set("forceDie", true);
"step 1";
if (result.control != "cancel2") {
if (result.index == 0) {
event.num2 = event.num1;
event.num1 = 1;
}
player
.chooseTarget([1, event.num1], true, "请选择【延祸】的目标", function (card, player, target) {
return target != player && target.countCards("he") > 0;
})
.set("forceDie", true)
.set("ai", function (target) {
return -get.attitude(_status.event.player, target);
});
} else event.finish();
"step 2";
if (result.bool) {
var targets = result.targets.sortBySeat();
player.logSkill("twyanhuo", targets);
for (var i of targets) i.chooseToDiscard(true, "he", event.num2);
}
},
},
twshenxing: {
mod: {
globalFrom: function (player, target, distance) {
var es = player.getCards("e", function (card) {
return !ui.selected.cards.includes(card);
});
for (var i of es) {
var type = get.subtype(i);
if (type == "equip3" || type == "equip4" || type == "equip6") return distance;
}
return distance - 1;
},
maxHandcard: function (player, distance) {
var es = player.getCards("e", function (card) {
return !ui.selected.cards.includes(card);
});
for (var i of es) {
var type = get.subtype(i);
if (type == "equip3" || type == "equip4" || type == "equip6") return distance;
}
return distance + 1;
},
},
},
twdaoji: {
audio: "daoji",
enable: "phaseUse",
usable: 1,
filter: function (event, player) {
return player.hasCard(lib.skill.twdaoji.filterCard, "he");
},
filterCard: function (card) {
return get.type(card) != "basic";
},
position: "he",
filterTarget: function (card, player, target) {
return target != player && player.inRange(target) && target.hasCard(card => lib.filter.canBeGained(card, target, player), "he");
},
check: function (card) {
return 8 - get.value(card);
},
content: function () {
"step 0";
player.gainPlayerCard(target, "he", true);
"step 1";
if (result.bool && result.cards && result.cards.length == 1) {
var card = result.cards[0];
if (player.getCards("h").includes(card)) {
var type = get.type(card);
if (type == "basic") player.draw();
else if (type == "equip") {
if (player.hasUseTarget(card)) player.chooseUseTarget(card, "nopopup", true);
target.damage("nocard");
}
}
}
},
ai: {
order: 6,
result: {
target: function (player, target) {
var eff = get.effect(target, { name: "shunshou_copy2" }, player, target);
if (target.countCards("e") > 0) eff += get.damageEffect(target, player, target);
return eff;
},
},
},
},
xinzhenjun: {
audio: 2,
trigger: {
player: "phaseUseBegin",
},
direct: true,
filter: function (event, player) {
return player.countCards("he") > 0;
},
content: function () {
"step 0";
player.chooseCardTarget({
filterCard: true,
filterTarget: lib.filter.notMe,
position: "he",
prompt: get.prompt2("xinzhenjun"),
ai1: function (card) {
var player = _status.event.player;
if (card.name == "sha" && get.color(card) == "red") {
for (var i = 0; i < game.players.length; i++) {
var current = game.players[i];
if (current != player && get.attitude(player, current) > 0 && current.hasValueTarget(card)) return 7;
}
return 0;
}
return 7 - get.value(card);
},
ai2: function (target) {
var player = _status.event.player;
var card = ui.selected.cards[0];
var att = get.attitude(player, target);
if (get.value(card) < 0) return -att * 2;
if (target.countCards("h", { name: "sha", color: "red" }) || target.hasSkill("wusheng") || target.hasSkill("new_rewusheng") || target.hasSkill("wushen") || (card.name == "sha" && get.color(card) == "red" && target.hasValueTarget(card))) return att * 2;
var eff = 0;
game.countPlayer(function (current) {
if (target != current && get.distance(target, current, "attack") > 1) return;
var eff2 = get.damageEffect(current, player, player);
if (eff2 > eff) eff = eff2;
});
if (att > 0 && eff > 0) eff += 2 * att;
return eff;
},
});
"step 1";
if (result.bool) {
var target = result.targets[0];
event.target = target;
player.logSkill("xinzhenjun", target);
player.give(result.cards, target);
} else event.finish();
"step 2";
target.chooseToUse({
filterCard: function (card) {
return get.name(card) == "sha" && get.color(card) != "black" && lib.filter.cardEnabled.apply(this, arguments);
},
prompt: "请使用一张不为黑色的【杀】,否则" + get.translation(player) + "可以对你或你攻击范围内的一名其他角色造成1点伤害",
});
"step 3";
if (result.bool) {
var num = 1;
game.countPlayer2(function (current) {
current.getHistory("damage", function (evt) {
if (evt.getParent(evt.notLink() ? 4 : 8) == event) num += evt.num;
});
});
player.draw(num);
event.finish();
} else {
player
.chooseTarget("是否对" + get.translation(target) + "或其攻击范围内的一名角色造成1点伤害", function (card, player, target) {
return target == _status.event.targetx || _status.event.targetx.inRange(target);
})
.set("targetx", event.target).ai = function (target) {
var player = _status.event.player;
return get.damageEffect(target, player, player);
};
}
"step 4";
if (result.bool) {
player.line(result.targets);
result.targets[0].damage("nocard");
}
},
},
twmoukui: {
audio: "moukui",
trigger: { player: "useCardToPlayered" },
direct: true,
preHidden: true,
filter: function (event, player) {
return event.card && event.card.name == "sha";
},
content: function () {
"step 0";
var list = ["选项一"];
if (trigger.target.countDiscardableCards(player, "he") > 0) list.push("选项二");
list.push("背水!");
list.push("cancel2");
player
.chooseControl(list)
.set("choiceList", ["摸一张牌", "弃置" + get.translation(trigger.target) + "的一张牌", "背水!依次执行以上两项。然后若此【杀】未令其进入濒死状态,则其弃置你的一张牌。"])
.set("prompt", get.prompt("twmoukui", trigger.target))
.setHiddenSkill("twmoukui");
"step 1";
if (result.control != "cancel2") {
var target = trigger.target;
player.logSkill("twmoukui", target);
if (result.control == "选项一" || result.control == "背水!") player.draw();
if (result.control == "选项二" || result.control == "背水!") player.discardPlayerCard(target, true, "he");
if (result.control == "背水!") {
player.addTempSkill("twmoukui_effect");
var evt = trigger.getParent();
if (!evt.twmoukui_effect) evt.twmoukui_effect = [];
evt.twmoukui_effect.add(target);
}
}
},
subSkill: {
effect: {
trigger: { player: "useCardAfter" },
charlotte: true,
forced: true,
filter: function (event, player) {
return (
event.twmoukui_effect &&
event.twmoukui_effect.filter(function (current) {
return (
current.isIn() &&
!current.hasHistory("damage", function (evt) {
return evt._dyinged && evt.card == event.card;
})
);
}).length > 0
);
},
content: function () {
var list = trigger.twmoukui_effect
.filter(function (current) {
return (
current.isIn() &&
!current.hasHistory("damage", function (evt) {
return evt._dyinged && evt.card == event.card;
})
);
})
.sortBySeat();
for (var i of list) {
i.discardPlayerCard(player, true, "he").boolline = true;
}
},
},
},
},
twfuhan: {
audio: "fuhan",
trigger: { player: "phaseZhunbeiBegin" },
unique: true,
limited: true,
skillAnimation: true,
animationColor: "orange",
filter: function (event, player) {
return player.countMark("fanghun") > 0;
},
prompt: function (event, player) {
var num = Math.max(2, player.storage.fanghun);
num = Math.min(num, 8);
return get.prompt("twfuhan") + "(体力上限:" + num + "";
},
check: function (event, player) {
if (player.storage.fanghun >= Math.min(4, player.maxHp)) return true;
if (player.hp <= 2 && player.storage.fanghun >= 3) return true;
return false;
},
content: function () {
"step 0";
var num = Math.max(2, player.storage.fanghun);
num = Math.min(num, 8);
event.num = num;
player.removeMark("fanghun", player.storage.fanghun);
player.awakenSkill("twfuhan");
if (_status.characterlist) {
list = [];
for (var i = 0; i < _status.characterlist.length; i++) {
var name = _status.characterlist[i];
if (lib.character[name][1] == "shu") list.push(name);
}
} else if (_status.connectMode) {
list = get.charactersOL(function (i) {
return lib.character[i][1] != "shu";
});
} else {
list = get.gainableCharacters(function (info) {
return info[1] == "shu";
});
}
var players = game.players.concat(game.dead);
for (var i = 0; i < players.length; i++) {
list.remove(players[i].name);
list.remove(players[i].name1);
list.remove(players[i].name2);
}
list.remove("zhaoxiang");
player.chooseButton(["扶汉:选择获得一张武将牌上的所有技能", [list.randomGets(5), "character"]], true);
"step 1";
if (result.bool) {
var name = result.links[0];
player.flashAvatar("twhuashen", name);
game.log(player, "获得了", "#y" + get.translation(name), "的所有技能");
player.addSkills(lib.character[name][3]);
}
"step 2";
var num = event.num - player.maxHp;
if (num > 0) player.gainMaxHp(num);
else player.loseMaxHp(-num);
player.recover();
"step 3";
var card = get.cardPile("meiyingqiang", "field");
if (card) {
player.gain(card, "gain2", "log");
}
},
ai: {
combo: "refanghun",
},
},
twqueshi: {
trigger: {
global: "phaseBefore",
player: "enterGame",
},
forced: true,
locked: false,
filter: function (event, player) {
return (event.name != "phase" || game.phaseNumber == 0) && player.hasEquipableSlot(1);
},
content: function () {
if (!lib.inpile.includes("meiyingqiang")) {
lib.inpile.push("meiyingqiang");
player.equip(game.createCard("meiyingqiang", "diamond", 12));
} else {
var card = get.cardPile(function (card) {
return card.name == "meiyingqiang" && !player.getEquips(1).includes(card);
}, "field");
if (card) player.equip(card);
}
},
},
meiyingqiang: {
equipSkill: true,
trigger: {
player: ["loseAfter"],
global: ["equipAfter", "addJudgeAfter", "gainAfter", "loseAsyncAfter", "addToExpansionAfter"],
},
filter: function (event, player) {
if (player == _status.currentPhase) return false;
var evt = event.getl(player);
if (!evt || !evt.cards2 || !evt.cards2.length) return false;
var list = player.getHistory("lose", function (evt) {
return evt.cards2 && evt.cards2.length;
});
if (event.name == "lose") {
if (list.indexOf(event) != 0) return false;
} else {
if (
!player.hasHistory("lose", function (evt) {
return evt.getParent() == event && list.indexOf(evt) == 0;
})
)
return false;
}
return _status.connectMode || !lib.config.skip_shan || player.hasSha();
},
direct: true,
content: function () {
if (trigger.delay === false) game.delayx();
player
.chooseToUse("梅影枪:是否使用一张【杀】?", function (card) {
if (get.name(card) != "sha") return false;
return lib.filter.cardEnabled.apply(this, arguments);
})
.set("addCount", false).logSkill = "meiyingqiang";
},
},
cuijin: {
trigger: { global: "useCard" },
direct: true,
filter: function (event, player) {
return event.card.name == "sha" && (event.player == player || player.inRange(event.player)) && player.countCards("he") > 0;
},
checkx(event, player) {
let d1 = true,
e = false;
if (event.player.hasSkill("jueqing") || event.player.hasSkill("gangzhi")) d1 = false;
for (let tar of event.targets) {
if (event.card.name == "sha") {
if (
!tar.mayHaveShan(
player,
"use",
tar.getCards("h", i => {
return i.hasGaintag("sha_notshan");
})
) ||
event.player.hasSkillTag(
"directHit_ai",
true,
{
target: tar,
card: event.card,
},
true
)
) {
if (!tar.hasSkill("gangzhi")) d1 = false;
if (
!tar.hasSkillTag("filterDamage", null, {
player: event.player,
card: event.card,
})
) {
let att = get.attitude(_status.event.player, tar);
if (att > 0) return false;
if (att < 0) e = true;
}
}
} else e = true;
}
if (e) return true;
if (d1) return get.damageEffect(event.player, player, _status.event.player) > 0;
return false;
},
content: function () {
"step 0";
if (player != game.me && !player.isOnline()) game.delayx();
var target = trigger.player;
event.target = target;
player
.chooseToDiscard("he", get.prompt("cuijin", target), "弃置一张牌并令" + get.translation(trigger.player) + "使用的【杀】伤害+1但若其未造成伤害则你对其造成1点伤害。")
.set("ai", function (card) {
if (_status.event.goon) return 7 - get.value(card);
return 0;
})
.set("goon", lib.skill.cuijin.checkx(trigger, player)).logSkill = ["cuijin", target];
"step 1";
if (result.bool) {
if (typeof trigger.baseDamage != "number") trigger.baseDamage = 1;
trigger.baseDamage++;
player.addTempSkill("cuijin_damage");
player.markAuto("cuijin_damage", [trigger.card]);
}
},
subSkill: {
damage: {
trigger: { global: "useCardAfter" },
forced: true,
popup: false,
charlotte: true,
onremove: true,
filter: function (event, player) {
return player.storage.cuijin_damage.includes(event.card);
},
content: function () {
player.storage.cuijin_damage.remove(trigger.card);
if (!player.storage.cuijin_damage.length) player.removeSkill("cuijin_damage");
if (
trigger.player.isIn() &&
!game.hasPlayer2(function (current) {
return current.hasHistory("damage", function (evt) {
return evt.card == trigger.card;
});
})
) {
player.line(trigger.player, "green");
trigger.player.damage();
}
},
},
},
},
jintao: {
mod: {
cardUsable: function (card, player, num) {
if (card.name == "sha") return num + 1;
},
targetInRange: function (card) {
if (card.name == "sha") return true;
},
},
audio: 2,
trigger: { player: "useCard" },
forced: true,
filter: function (event, player) {
if (event.card.name != "sha") return false;
var evt = event.getParent("phaseUse");
if (!evt || evt.player != player) return false;
var index = player
.getHistory("useCard", function (evtx) {
return evtx.card.name == "sha" && evtx.getParent("phaseUse") == evt;
})
.indexOf(event);
return index == 0 || index == 1;
},
content: function () {
var evt = trigger.getParent("phaseUse");
var index = player
.getHistory("useCard", function (evtx) {
return evtx.card.name == "sha" && evtx.getParent("phaseUse") == evt;
})
.indexOf(trigger);
if (index == 0) {
game.log(trigger.card, "伤害+1");
if (typeof trigger.baseDamage != "number") trigger.baseDamage = 1;
trigger.baseDamage++;
} else {
game.log(trigger.card, "不可被响应");
trigger.directHit.addArray(game.players);
}
},
},
equan: {
audio: 2,
trigger: { global: "damageEnd" },
forced: true,
filter: function (event, player) {
return player == _status.currentPhase && event.player.isIn();
},
logTarget: "player",
content: function () {
trigger.player.addMark("equan", trigger.num, false);
},
group: ["equan_block", "equan_lose"],
marktext: "毒",
intro: {
name: "恶泉(毒)",
name2: "毒",
},
subSkill: {
lose: {
audio: "equan",
trigger: { player: "phaseZhunbeiBegin" },
forced: true,
filter: function () {
return game.hasPlayer(function (current) {
return current.hasMark("equan");
});
},
logTarget: function () {
return game.filterPlayer(function (current) {
return current.hasMark("equan");
});
},
content: function () {
game.countPlayer(function (current) {
var num = current.countMark("equan");
if (num) {
current.removeMark("equan", num);
current.loseHp(num);
}
});
},
},
block: {
trigger: { global: "dyingBegin" },
forced: true,
logTarget: "player",
filter: function (event, player) {
var evt = event.getParent(2);
return evt.name == "equan_lose" && evt.player == player;
},
content: function () {
trigger.player.addTempSkill("baiban");
},
},
},
},
manji: {
audio: 2,
trigger: { global: "loseHpAfter" },
forced: true,
filter: function (event, player) {
return player != event.player && (player.hp >= event.player.hp || player.isDamaged());
},
logTarget: "player",
content: function () {
if (player.hp <= trigger.player.hp) player.recover();
if (player.hp >= trigger.player.hp) player.draw();
},
},
beini: {
audio: 2,
enable: "phaseUse",
usable: 1,
filterTarget: function (card, player, target) {
return target.hp >= player.hp;
},
content: function () {
"step 0";
var str = get.translation(target);
player
.chooseControl()
.set("choiceList", ["摸两张牌,然后令" + str + "视为对自己使用【杀】", "令" + str + "摸两张牌,然后视为对其使用【杀】"])
.set("ai", function () {
var evt = _status.event.getParent(),
player = evt.player,
target = evt.target;
var card = { name: "sha", isCard: true },
att = get.attitude(player, target) > 0;
if (!target.canUse(card, player, false) || get.effect(player, card, target, player) >= 0) return 0;
if (att && (!player.canUse(card, target, false) || get.effect(target, card, player, player) >= 0)) return 1;
if (target.hasSkill("nogain") && player.canUse(card, target, false) && get.effect(target, card, player, player) > 0) return 1;
if (player.hasShan()) return 0;
if (att && target.hasShan()) return 1;
return 0;
});
"step 1";
var list = [player, target];
if (result.index == 1) list.reverse();
event.list = list;
list[0].draw(2);
"step 2";
var list = event.list;
if (list[1].isIn() && list[0].isIn() && list[1].canUse("sha", list[0], false)) list[1].useCard({ name: "sha", isCard: true }, list[0], false, "noai");
},
ai: {
order: 5,
expose: 0,
result: {
player: function (player, target) {
var card = { name: "sha", isCard: true },
att = get.attitude(player, target) > 0;
if (!target.canUse(card, player, false) || get.effect(player, card, target, player) >= 0) return 2;
if (att && (!player.canUse(card, target, false) || get.effect(target, card, player, player) >= 0)) return 2;
if (target.hasSkill("nogain") && player.canUse(card, target, false)) return get.effect(target, card, player, player);
if (player.hasShan()) return 1;
if (att && target.hasShan()) return 1;
return 0;
},
},
},
},
dingfa: {
audio: 2,
trigger: { player: "phaseDiscardAfter" },
direct: true,
filter: function (event, player) {
var num = 0;
player.getHistory("lose", function (evt) {
num += evt.cards2.length;
});
return num >= player.hp;
},
content: function () {
"step 0";
player
.chooseTarget(get.prompt("dingfa"), "操作提示:选择自己以回复体力,或选择其他角色以造成伤害", function (card, player, target) {
return target == player ? player.isDamaged() : true;
})
.set("ai", function (target) {
return target != player ? get.damageEffect(target, player, player) : get.recoverEffect(player, player, player);
});
"step 1";
if (result.bool) {
var target = result.targets[0];
player.logSkill("dingfa", target);
if (target == player) player.recover();
else target.damage();
}
},
},
dz_mantianguohai: {
mod: {
ignoredHandcard: function (card, player) {
if (get.name(card) == "dz_mantianguohai") return true;
},
cardDiscardable: function (card, player, name) {
if (name == "cardsDiscard" && get.name(card) == "dz_mantianguohai") return false;
},
},
},
twmiaolve: {
audio: 2,
trigger: {
global: "phaseBefore",
player: "enterGame",
},
filter: function (event, player) {
return event.name != "phase" || game.phaseNumber == 0;
},
forced: true,
locked: false,
content: function () {
if (!lib.inpile.includes("dz_mantianguohai")) lib.inpile.add("dz_mantianguohai");
if (!_status.dz_mantianguohai_suits) _status.dz_mantianguohai_suits = lib.suit.slice(0);
var list = _status.dz_mantianguohai_suits.randomRemove(2).map(function (i) {
return game.createCard2("dz_mantianguohai", i, 5);
});
if (list.length) player.gain(list, "gain2", "log");
},
group: "twmiaolve_damage",
subSkill: {
damage: {
trigger: { player: "damageEnd" },
direct: true,
content: function () {
"step 0";
event.count = trigger.num;
"step 1";
event.count--;
var list = ["dz_mantianguohai"];
list.addArray(get.zhinangs());
player.chooseButton([get.prompt("twmiaolve"), [list, "vcard"]]).set("ai", function (button) {
if (button.link[2] == "dz_mantianguohai" && player.countCards("hs", "dz_mantianguohai") < 2) return 10;
return get.value({ name: button.link[2] });
});
"step 2";
if (result.bool) {
player.logSkill("twmiaolve");
var name = result.links[0][2];
if (name == "dz_mantianguohai") {
if (!lib.inpile.includes("dz_mantianguohai")) lib.inpile.add("dz_mantianguohai");
if (!_status.dz_mantianguohai_suits) _status.dz_mantianguohai_suits = lib.suit.slice(0);
if (_status.dz_mantianguohai_suits.length) player.gain(game.createCard2("dz_mantianguohai", _status.dz_mantianguohai_suits.randomRemove(), 5), "gain2");
else {
var card = get.cardPile(function (card) {
return card.name == name;
});
if (card) player.gain(card, "gain2");
}
player.draw();
} else {
var card = get.cardPile(function (card) {
return card.name == name;
});
if (card) player.gain(card, "gain2");
}
if (event.count > 0 && player.hasSkill("twmiaolve")) event.goto(1);
}
},
},
},
},
twyingjia: {
audio: 2,
trigger: { global: "phaseEnd" },
direct: true,
filter: function (event, player) {
if (!player.countCards("he")) return false;
var history = player.getHistory("useCard"),
map = {};
for (var i of history) {
if (get.type2(i.card) == "trick") {
if (!map[i.card.name]) map[i.card.name] = true;
else return true;
}
}
return false;
},
content: function () {
"step 0";
player.chooseCardTarget({
prompt: get.prompt("twyingjia"),
prompt2: "弃置一张牌并令一名角色进行一个额外回合",
filterCard: lib.filter.cardDiscardable,
filterTarget: true,
ai1: function (card) {
return 8 - get.value(card);
},
ai2: function (target) {
if (target.hasJudge("lebu")) return -1;
var player = _status.event.player;
if (get.attitude(player, target) > 4) {
return get.threaten(target) / Math.sqrt(target.hp + 1) / Math.sqrt(target.countCards("h") + 1);
}
return -1;
},
});
"step 1";
if (result.bool) {
var target = result.targets[0];
player.logSkill("twyingjia", target);
player.discard(result.cards);
target.insertPhase();
}
},
},
gx_lingbaoxianhu: {
trigger: {
source: "damageSource",
global: "dieAfter",
},
forced: true,
equipSkill: true,
filter: function (event, player) {
if (event.name == "damage") return event.num > 1;
return true;
},
content: function () {
player.gainMaxHp();
player.recover();
},
},
gx_taijifuchen: {
trigger: { player: "useCardToPlayered" },
forced: true,
equipSkill: true,
filter: function (event, player) {
return event.card && event.card.name == "sha";
},
logTarget: "target",
content: function () {
"step 0";
var suit = get.suit(trigger.card);
var num = trigger.target.countCards("h", "shan");
var next = trigger.target
.chooseToDiscard("弃置一张牌,或不能响应" + get.translation(trigger.card), "he")
.set("ai", function (card) {
var num = _status.event.num;
if (num == 0) return 0;
if (card.name == "shan") return num > 1 ? 2 : 0;
return (get.suit(card) != _status.event.suit ? 9 : 6) - get.value(card);
})
.set("num", num);
if (lib.suit.includes(suit)) {
next.set("prompt2", "若弃置的是" + get.translation(suit) + "牌,则改为" + get.translation(player) + "获得之");
next.set("suit", suit);
}
"step 1";
if (result.bool) {
var card = result.cards[0];
if (get.suit(card, trigger.target) == get.suit(trigger.card, false) && get.position(card) == "d") player.gain(card, "gain2");
} else trigger.directHit.add(trigger.target);
},
},
gx_chongyingshenfu: {
trigger: { player: "damageEnd" },
forced: true,
equipSkill: true,
filter: function (event, player) {
if (!event.card || !event.card.name || player.getStorage("gx_chongyingshenfu_effect").includes(event.card.name)) return false;
if (player.hasSkillTag("unequip2")) return false;
if (
event.source.hasSkillTag("unequip", false, {
name: event.card.name,
target: player,
card: event.card,
})
)
return false;
return true;
},
content: function () {
player.markAuto("gx_chongyingshenfu_effect", [trigger.card.name]);
},
group: "gx_chongyingshenfu_effect",
subSkill: {
effect: {
trigger: { player: "damageBegin4" },
forced: true,
equipSkill: true,
filter: function (event, player) {
if (!event.card || !event.card.name || !player.storage.gx_chongyingshenfu_effect || !player.getStorage("gx_chongyingshenfu_effect").includes(event.card.name)) return false;
if (player.hasSkillTag("unequip2")) return false;
if (
event.source.hasSkillTag("unequip", false, {
name: event.card.name,
target: player,
card: event.card,
})
)
return false;
return true;
},
content: function () {
trigger.num--;
},
ai: {
effect: {
target: function (card, player, target) {
if (
typeof card == "object" &&
target.storage.gx_chongyingshenfu_effect &&
target.getStorage("gx_chongyingshenfu_effect").includes(card.name) &&
!target.hasSkillTag("unequip2") &&
(get.itemtype(player) !== "player" ||
(!player.hasSkillTag("jueqing", false, target) &&
!player.hasSkillTag("unequip", false, {
name: card.name,
target: target,
card: card,
})))
) {
if (
player &&
player.hasSkillTag("damageBonus", true, {
target: target,
card: card,
})
)
return 0.5;
return "zeroplayertarget";
}
},
},
},
onremove: true,
intro: {
content: "受到$造成的伤害-1",
},
},
},
},
twdanfa: {
audio: 2,
trigger: { player: ["phaseZhunbeiBegin", "phaseJieshuBegin"] },
filter: function (event, player) {
return player.countCards("he") > 0;
},
direct: true,
content: function () {
"step 0";
player.chooseCard("he", get.prompt("twdanfa"), "将一张牌作为“丹”置于武将牌上").set("ai", function (card) {
if (player.storage.twdanfa) {
var suit = get.suit(card);
for (var i of player.storage.twdanfa) {
if (get.suit(i, false) == suit) return 4 - get.value(card);
}
}
return 5.5 - get.value(card);
});
"step 1";
if (result.bool) {
var card = result.cards[0];
player.logSkill("twdanfa");
game.log(player, "将", card, "放在了武将牌上");
player.$give(card, player, false);
player.lose(card, ui.special, "toStorage");
player.markAuto("twdanfa", result.cards);
} else event.finish();
"step 2";
game.delayx();
},
mark: true,
intro: {
content: "cards",
onunmark: "throw",
},
group: "twdanfa_draw",
subSkill: {
draw: {
audio: "twdanfa",
trigger: { player: "useCard" },
forced: true,
locked: false,
filter: function (event, player) {
if (!player.storage.twdanfa || !player.storage.twdanfa.length) return false;
var suit = get.suit(event.card, false);
if (suit == "none" || (player.storage.twdanfa_count && player.storage.twdanfa_count.includes(suit))) return false;
for (var i of player.storage.twdanfa) {
if (get.suit(i, false) == suit) return true;
}
return false;
},
content: function () {
player.draw();
player.addTempSkill("twdanfa_count");
if (!player.storage.twdanfa_count) player.storage.twdanfa_count = [];
player.storage.twdanfa_count.push(get.suit(trigger.card, false));
},
},
count: { onremove: true },
},
},
twlingbao: {
enable: "phaseUse",
usable: 1,
filter: function (event, player) {
var list = player.getStorage("twdanfa");
if (list.length < 2) return false;
var suit = get.suit(list[0], false);
for (var i = 1; i < list.length; i++) {
if (get.suit(list[i], false) != suit) return true;
}
return false;
},
chooseButton: {
dialog: function (event, player) {
return ui.create.dialog("灵宝", player.storage.twdanfa);
},
filter: function (button, player) {
if (!ui.selected.buttons.length) return true;
return get.suit(button.link) != get.suit(ui.selected.buttons[0].link);
},
select: 2,
backup: function (links) {
var obj = get.copy(lib.skill["twlingbao_" + get.color(links)]);
obj.cards = links;
obj.audio = "twlingbao";
obj.filterCard = () => false;
obj.selectCard = -1;
return obj;
},
prompt: function (links) {
return lib.skill["twlingbao_" + get.color(links)].prompt;
},
check: function (button) {
var storage = _status.event.player.storage.twdanfa.slice(0);
storage.remove(button.link);
if (
storage.filter(function (card) {
return card.suit == button.link.suit;
}).length
)
return 1 + Math.random();
return 0;
},
},
subSkill: {
red: {
filterTarget: function (card, player, target) {
return target.isDamaged();
},
delay: false,
prompt: "令一名角色回复1点体力",
content: function () {
"step 0";
var cards = lib.skill.twlingbao_backup.cards;
player.$throw(cards, 1000);
player.unmarkAuto("twdanfa", cards);
game.log(player, "将", cards, "置入了弃牌堆");
game.delayx();
game.cardsDiscard(cards);
"step 1";
target.recover();
},
ai: {
tag: {
recover: 1,
},
result: {
target: 1.5,
},
},
},
black: {
filterTarget: function (card, player, target) {
return target.countDiscardableCards(player, "hej") > 0;
},
delay: false,
prompt: "弃置一名角色区域内至多两张区域不同的牌",
content: function () {
"step 0";
var cards = lib.skill.twlingbao_backup.cards;
player.$throw(cards, 1000);
player.unmarkAuto("twdanfa", cards);
game.log(player, "将", cards, "置入了弃牌堆");
game.delayx();
game.cardsDiscard(cards);
"step 1";
var num = 0;
if (target.countDiscardableCards(player, "h")) num++;
if (target.countDiscardableCards(player, "e")) num++;
if (target.countDiscardableCards(player, "j")) num++;
if (num) {
player.discardPlayerCard(target, [1, Math.max(2, num)], "hej", true).set("filterButton", function (button) {
for (var i = 0; i < ui.selected.buttons.length; i++) {
if (get.position(button.link) == get.position(ui.selected.buttons[i].link)) return false;
}
return true;
});
}
},
ai: {
tag: {
lose: 1.5,
loseCard: 1.5,
discard: 1.5,
},
result: {
target: function (player, target) {
if (
get.attitude(player, target) > 0 &&
target.countCards("e", function (card) {
return get.value(card, target) <= 0;
}) > 0 &&
target.countCards("j", function (card) {
return get.effect(target, card, target, target) < 0;
}) > 8
)
return 3;
if (
target.countCards("h") > 0 &&
target.countCards("e", function (card) {
return get.value(card, target) > 0;
}) > 0
)
return -2;
return 0;
},
},
},
},
none: {
selectTarget: 2,
filterTarget: function (card, player, target) {
if (!ui.selected.targets.length) return true;
return target.countCards("he") > 0;
},
complexSelect: true,
targetprompt: ["摸牌", "弃牌"],
delay: false,
prompt: "令一名角色摸一张牌并令另一名角色弃置一张牌",
multitarget: true,
multiline: true,
content: function () {
"step 0";
var cards = lib.skill.twlingbao_backup.cards;
player.$throw(cards, 1000);
player.unmarkAuto("twdanfa", cards);
game.log(player, "将", cards, "置入了弃牌堆");
game.delayx();
game.cardsDiscard(cards);
"step 1";
targets[0].draw();
targets[1].chooseToDiscard("he", true);
},
ai: {
result: {
target: function (player, target) {
if (!ui.selected.targets.length) return 1;
if (
target.countCards("e", function (card) {
return get.value(card, target) <= 0;
}) > 0
)
return 1;
return -1;
},
},
},
},
backup: { audio: "twlingbao" },
},
ai: {
order: 1,
result: { player: 1 },
combo: "twdanfa",
},
},
twsidao: {
audio: 2,
trigger: {
global: "phaseBefore",
player: "enterGame",
},
forced: true,
locked: false,
filter: function (event, player) {
return (event.name != "phase" || game.phaseNumber == 0) && !player.storage.twsidao;
},
content: function () {
"step 0";
player.chooseButton(["请选择你的初始法宝", [["gx_lingbaoxianhu", "gx_taijifuchen", "gx_chongyingshenfu"], "vcard"]], true).set("ai", function (button) {
return button.link[2] == "gx_chongyingshenfu" ? 2 : 1;
});
"step 1";
if (result.bool) {
var card = game.createCard2(result.links[0][2], "heart", 1);
lib.inpile.add(result.links[0][2]);
player.storage.twsidao = card;
player.chooseUseTarget(card, "nopopup", true);
}
},
group: "twsidao_equip",
subSkill: {
equip: {
audio: "twsidao",
trigger: { player: "phaseZhunbeiBegin" },
forced: true,
filter: function (event, player) {
var card = player.storage.twsidao;
return card && card.isInPile() && player.hasUseTarget(card);
},
content: function () {
player.chooseUseTarget(player.storage.twsidao, "nopopup", true);
},
},
},
},
twrangyi: {
audio: 2,
enable: "phaseUse",
usable: 1,
filter: function (event, player) {
return player.countCards("h") > 0;
},
filterTarget: lib.filter.notMe,
delay: 0,
content: function () {
"step 0";
event.cards = player.getCards("h");
player.give(event.cards, target).gaintag.add("twrangyi");
target.addTempSkill("twrangyi2");
"step 1";
target.chooseToUse({
prompt: "请使用得到的一张牌,或者受到来自" + get.translation(player) + "的1点伤害",
filterCard: function (card, player) {
if (get.itemtype(card) != "card" || !card.hasGaintag("twrangyi")) return false;
return lib.filter.filterCard(card, player, event);
},
cards: cards,
});
"step 2";
target.removeSkill("twrangyi2");
if (!result.bool) target.damage("nocard");
},
ai: {
order: 1,
result: {
target: function (player, target) {
var hs = player.getCards("h");
for (var i = 0; i < hs.length; i++) {
var hi = hs[i];
if (hi.name == "tao" || target.hasValueTarget(hi, null, true)) return 1;
}
return get.damageEffect(target, player, target);
},
},
},
},
twrangyi2: {
trigger: { player: "useCard" },
forced: true,
popup: false,
charlotte: true,
filter: function (event, player) {
var evt = event.getParent(2);
return (
evt.name == "twrangyi" &&
evt.player.isIn() &&
player.countCards("h", function (card) {
return card.hasGaintag("twrangyi");
}) > 0
);
},
content: function () {
var cards = player.getCards("h", function (card) {
return card.hasGaintag("twrangyi");
});
game.delayx();
player.give(cards, trigger.getParent(2).player);
},
onremove: function (player) {
player.removeGaintag("twrangyi");
},
},
twbaimei: {
audio: 2,
trigger: {
player: "damageBegin4",
},
forced: true,
filter: function (event, player) {
if (player.countCards("h")) return false;
if (event.hasNature()) return true;
return get.type(event.card, "trick") == "trick";
},
content: function () {
trigger.cancel();
},
ai: {
effect: {
target: function (card, player, target, current) {
if (target.countCards("h")) return;
if (get.tag(card, "natureDamage")) return "zeroplayertarget";
if (get.type(card) == "trick" && get.tag(card, "damage")) {
return "zeroplayertarget";
}
},
},
},
},
twhuzhu: {
audio: 2,
enable: "phaseUse",
usable: 1,
filter: function (e, player) {
return player.countCards("e") > 0;
},
filterTarget: function (card, player, target) {
return target != player && target.countCards("h") > 0;
},
content: function () {
"step 0";
target.chooseCard("交给" + get.translation(player) + "一张手牌", "h", true);
"step 1";
target.give(result.cards, player);
"step 2";
if (player.countGainableCards(player, "e")) target.gainPlayerCard(player, "e", true);
"step 3";
if (target.isDamaged() && target.hp <= player.hp) {
player.chooseBool("是否令" + get.translation(target) + "回复1点体力").set("ai", function () {
return get.recoverEffect(target, player, player);
});
}
"step 4";
if (result.bool) target.recover();
},
ai: {
order: 8,
result: {
target: function (player, target) {
var eff = target.isDamaged() && target.hp <= player.hp ? get.recoverEffect(target, player, target) : 0;
if (eff <= 0 && !player.countGainableCards(target, "e")) return -1;
return eff;
},
},
},
},
twliancai: {
audio: 2,
trigger: { player: ["turnOverEnd", "phaseJieshuBegin"] },
filter: function (card, player, target) {
return target == "phaseJieshuBegin" || player.countCards("h") < player.hp;
},
filterTarget: function (card, player, target) {
return target != player && target.countGainableCards(player, "e") > 0;
},
check: function (card, player) {
if (card.name == "turnOver") return true;
if (player.isTurnedOver()) return true;
if (player.hp - player.countCards("h") > 1) return true;
return game.hasPlayer(function (current) {
return lib.skill.twliancai.filterTarget(null, player, current) && lib.skill.twliancai.filterAI(current);
});
},
filterAI: function (target) {
var player = _status.event.player;
var att = get.attitude(player, target);
if (target.isDamaged() && target.countCards("e", "baiyin") && att > 0) return 2 * att;
return -att;
},
prompt2: function (card, player, target) {
return card.name == "phaseJieshu" ? "将武将牌翻面,然后获得一名其他角色装备区内的一张牌" : "将手牌摸至与体力值相同";
},
content: function () {
"step 0";
if (event.triggername == "phaseJieshuBegin") player.turnOver();
else {
player.draw(player.hp - player.countCards("h"));
event.finish();
}
"step 1";
player.chooseTarget("获得一名角色装备区内的一张牌", lib.skill.twliancai.filterTarget).ai = lib.skill.twliancai.filterAI;
"step 2";
if (result.bool) {
player.line(result.targets, "thunder");
player.gainPlayerCard("e", true, result.targets[0]);
}
},
},
twqijia: {
//group:'twqijia_alka',
audio: 2,
enable: "phaseUse",
filter: function (event, player) {
return player.countCards("e", function (card) {
return !player.getStorage("twqijia_alka").includes(get.subtype(card));
});
},
filterTarget: function (card, player, target) {
return target != player && player.canUse({ name: "sha" }, target);
},
position: "e",
filterCard: function (card, player) {
return !player.getStorage("twqijia_alka").includes(get.subtype(card));
},
content: function () {
"step 0";
player.addTempSkill("twqijia_alka");
player.storage.twqijia_alka.push(get.subtype(cards[0]));
player.useCard({ name: "sha" }, target, false);
},
subSkill: {
alka: {
charlotte: true,
onremove: function (player) {
delete player.storage.twqijia_alka;
delete player.storage.twzhuchen;
player.unmarkSkill("twzhuchen");
},
init: function (player, skill) {
if (!player.storage[skill]) player.storage[skill] = [];
if (!player.storage.twzhuchen) player.storage.twzhuchen = [];
},
mod: {
globalFrom: function (from, to, distance) {
if (from.storage.twzhuchen && from.storage.twzhuchen.includes(to)) return -Infinity;
},
},
},
},
check: function (card) {
return 7 - get.value(card);
},
ai: {
order: function () {
return get.order({ name: "sha" }) - 0.2;
},
result: {
target: function (player, target) {
return get.effect(target, { name: "sha" }, player, player);
},
},
},
},
twzhuchen: {
enable: "phaseUse",
filter: function (event, player) {
return player.countCards("h", lib.skill.twzhuchen.filterCard) > 0;
},
filterCard: function (card, player) {
var name = get.name(card, player);
return name == "tao" || name == "jiu";
},
filterTarget: lib.filter.notMe,
content: function () {
player.addTempSkill("twqijia_alka");
player.storage.twzhuchen.add(target);
player.markSkill("twzhuchen");
},
intro: {
content: function (content, player) {
return "至" + get.translation(content) + "的距离视为1";
},
},
},
twxiaolian: {
audio: 2,
trigger: { global: "useCardToTarget" },
logTarget: "target",
filter: function (event, player) {
return event.card && event.card.name == "sha" && event.player != player && event.targets.length == 1 && event.targets[0] != player;
},
check: function (event, player) {
return get.effect(event.targets[0], event.card, event.player, player) <= get.effect(player, event.card, event.player, player);
},
content: function () {
trigger.getParent().twxiaolian = trigger.targets[0];
trigger.targets.length = 0;
trigger.getParent().triggeredTargets2.length = 0;
trigger.targets.push(player);
},
group: "twxiaolian_damage",
subSkill: {
distance: {
sub: true,
charlotte: true,
init: function (player, skill) {
if (!player.storage[skill]) player.storage[skill] = [];
},
mark: true,
marktext: "马",
intro: {
content: "cards",
onunmark: "throw",
},
mod: {
globalTo: function (from, to, distance) {
if (from != to && to.storage.twxiaolian_distance) return distance + to.storage.twxiaolian_distance.length;
},
},
},
damage: {
sub: true,
trigger: { player: "damageEnd" },
direct: true,
filter: function (event, player) {
return event.getParent(2).twxiaolian != undefined;
},
content: function () {
"step 0";
var target = trigger.getParent(2).twxiaolian;
event.target = target;
player.chooseCard("是否将一张牌当做【马】置于" + get.translation(target) + "的武将牌旁?", "he").ai = function (card) {
if (get.attitude(_status.event.player, _status.event.getParent("twxiaolian_damage").target) > 2) return 7 - get.value(card);
return 0;
};
"step 1";
if (result.bool) {
player.logSkill("twxiaolian", target);
player.lose(result.cards, ui.special, "toStorage");
target.addSkill("twxiaolian_distance");
target.storage.twxiaolian_distance.addArray(result.cards);
target.markSkill("twxiaolian_distance");
}
},
},
},
},
twtijin: {
audio: 2,
trigger: { global: "useCardToPlayer" },
filter: function (event, player) {
return event.card && event.card.name == "sha" && event.player != player && event.target != player && event.targets.length == 1 && event.player.inRange(player);
},
logTarget: "target",
check: function (event, player) {
return get.effect(event.targets[0], event.card, event.player, player) <= get.effect(player, event.card, event.player, player);
},
content: function () {
"step 0";
trigger.targets.length = 0;
trigger.getParent().triggeredTargets1.length = 0;
trigger.targets.push(player);
var next = game.createEvent("twtijin_discard", null, trigger.getParent(2));
next.player = player;
next.target = trigger.player;
next.setContent(function () {
if (target.isDead() || !target.countCards("he")) return;
player.line(target, "green");
player.discardPlayerCard(target, true, "he");
});
},
},
twyanqin: {
audio: 2,
trigger: { player: "phaseBegin" },
direct: true,
content: function () {
"step 0";
var list = [];
if (player.group != "wei") list.push("wei2");
if (player.group != "shu") list.push("shu2");
list.push("cancel2");
player
.chooseControl(list)
.set("ai", function () {
return list.randomGet();
})
.set("prompt", get.prompt2("twyanqin"));
"step 1";
if (result.control != "cancel2") {
player.logSkill("twyanqin");
var group = result.control.slice(0, 3);
player.changeGroup(group);
}
},
},
twbaobian: {
audio: 2,
trigger: { source: "damageBegin2" },
filter: function (event, player) {
var card = event.card;
if (!card || (card.name != "sha" && card.name != "juedou")) return false;
return event.player.group == player.group || event.player.countCards("h") > event.player.hp;
},
check: function (event, player) {
var att = get.attitude(player, event.player);
if (event.player.group == player.group) return att > 0;
return att < 0;
},
logTarget: "player",
content: function () {
var target = trigger.player;
if (target.group == player.group) {
trigger.cancel();
var num = target.maxHp - target.countCards("h");
if (num) target.draw(num);
} else {
player.discardPlayerCard(target, "h", true, target.countCards("h") - target.hp);
}
},
},
chijie: {
audio: true,
trigger: {
global: "phaseBefore",
player: "enterGame",
},
direct: true,
filter: function (event, player) {
return (
(event.name != "phase" || game.phaseNumber == 0) &&
game.hasPlayer(function (current) {
return current.group != player.group && lib.group.includes(current.group);
})
);
},
content: function () {
"step 0";
var list = lib.group.filter(function (group) {
return (
group != player.group &&
game.hasPlayer(function (current) {
return current.group == group;
})
);
});
list.push("cancel2");
player
.chooseControl(list)
.set("prompt", get.prompt("chijie"))
.set("prompt2", "将自己的势力变更为场上存在的一个势力")
.set("ai", function () {
return list.randomGet();
});
"step 1";
if (result.control != "cancel2") {
player.logSkill("chijie");
player.changeGroup(result.control);
}
},
},
waishi: {
audio: 2,
enable: "phaseUse",
filter: function (event, player) {
let used = player.getStat("skill").waishi;
if (used && used > player.countMark("waishi_remover")) return false;
return player.countCards("he") > 0 && game.hasPlayer(target => target != player && target.countCards("h") > 0);
},
filterTarget: function (card, player, target) {
return target != player && target.countCards("h") >= ui.selected.cards.length;
},
filterCard: true,
position: "he",
check: function (card) {
if (
!game.hasPlayer(function (current) {
return current != _status.event.player && current.countCards("h") > ui.selected.cards.length;
})
)
return 0;
return 6 - get.value(card);
},
selectCard: function () {
if (!ui.selected.targets.length) return [1, game.countGroup()];
return [1, Math.min(ui.selected.targets[0].countCards("h"), game.countGroup())];
},
discard: false,
lose: false,
delay: 0,
content: function () {
"step 0";
player.choosePlayerCard(target, true, "h", cards.length);
"step 1";
player.swapHandcards(target, cards, result.cards);
game.delayex();
"step 2";
if (target.countCards("h") > player.countCards("h") || player.group == target.group) player.draw();
},
ai: {
order: 7,
result: {
player: function (player, target) {
if (player.countCards("h") < target.countCards("h") || player.group == target.group) return 1;
return 0.1;
},
},
},
subSkill: {
remover: {
charlotte: true,
onremove: function (player) {
player.clearMark("waishi_remover", false);
},
intro: {
content: "〖外使〗的发动次数+#",
},
},
},
},
renshe: {
audio: 2,
trigger: { player: "damageEnd" },
direct: true,
content: function () {
"step 0";
var choiceList = ["将势力变更为场上现存的一个其他势力", "令〖外使〗的发动次数+1直到下个出牌阶段结束", "与另一名其他角色各摸一张牌"];
var controls = ["选项二"];
if (
game.hasPlayer(current => {
return current.group != player.group && lib.group.includes(current.group);
})
)
controls.unshift("选项一");
if (game.hasPlayer(current => current != player)) controls.push("选项三");
player
.chooseControl(controls, "cancel2")
.set("prompt", get.prompt("renshe"))
.set("choiceList", choiceList)
.set("ai", function () {
if (
game.hasPlayer(function (current) {
return get.attitude(player, current) > 0 || current.hasSkillTag("nogain");
})
)
return "选项三";
return "选项二";
});
"step 1";
if (result.control == "cancel2") event.finish();
else {
player.logSkill("renshe");
switch (result.control) {
case "选项一":
event.goto(3);
break;
case "选项二":
player.addMark("waishi_remover", 1, false);
player.addTempSkill("waishi_remover", { player: "phaseUseAfter" });
event.finish();
break;
case "选项三":
player.chooseTarget("请选择一名角色,与其各摸一张牌", lib.filter.notMe, true).set("ai", function (target) {
if (target.hasSkillTag("nogain")) return 0.1;
return get.attitude(_status.event.player, target);
});
}
}
"step 2";
if (result.bool) {
var target = result.targets[0];
player.line(target, "green");
game.asyncDraw([player, target].sortBySeat());
}
game.delayex();
event.finish();
"step 3";
var list = lib.group.filter(function (group) {
return (
group != player.group &&
game.hasPlayer(function (current) {
return current.group == group;
})
);
});
player
.chooseControl(list)
.set("prompt", get.prompt("chijie"))
.set("prompt2", "将自己的势力变更为场上存在的一个势力")
.set("ai", function () {
return list.randomGet();
});
"step 4";
player.changeGroup(result.control);
},
},
//英文版特典武将凯撒
zhengfu: {
trigger: {
player: "useCardToPlayered",
},
check: function (event, player) {
return get.attitude(player, event.target) < 0;
},
filter: function (event, player) {
return event.card.name == "sha";
},
logTarget: "target",
line: false,
content: function () {
"step 0";
player.line(trigger.target, { color: [220, 90, 139] });
player
.chooseControl(["basic", "trick", "equip"])
.set("ai", function () {
var player = _status.event.target;
if (!player.countCards("h", "sha") && player.countCards("h", "shan")) return "trick";
return "basic";
})
.set("prompt", "请选择一种牌的类别")
.set("target", trigger.target);
"step 1";
trigger.target
.chooseCard("he", "交给" + get.translation(player) + "一张" + get.translation(result.control) + "牌,否则此【杀】不可被闪避", function (card) {
return get.type2(card) == _status.event.control;
})
.set("ai", function (card) {
var num = _status.event.num;
if (num == 0) return 0;
if (card.name == "shan") return num > 1 ? 2 : 0;
return 8 - get.value(card);
})
.set("num", trigger.target.countCards("h", "shan"))
.set("control", result.control);
"step 2";
if (result.bool) {
var cards = result.cards;
trigger.target.give(cards, player);
} else {
trigger.getParent().directHit.add(trigger.target);
game.delay();
}
},
},
};
export default skills;