10038 lines
298 KiB
JavaScript
10038 lines
298 KiB
JavaScript
import { lib, game, ui, get, ai, _status } from "../../noname.js";
|
||
|
||
/** @type { importCharacterConfig['skill'] } */
|
||
const skills = {
|
||
//江山如故·衰
|
||
//张举
|
||
jsrgqiluan: {
|
||
usable: 2,
|
||
enable: "chooseToUse",
|
||
hiddenCard(player, name) {
|
||
return (name === "sha" || name === "shan") && (player.getStat("skill").jsrgqiluan || 0) < 2 && player.countCards("he") > 0;
|
||
},
|
||
filter(event, player) {
|
||
return (event.filterCard({ name: "sha", isCard: true }, player, event) || event.filterCard({ name: "shan", isCard: true }, player, event)) && player.hasCard(card => lib.filter.cardDiscardable(card, player, "jsrgqiluan"));
|
||
},
|
||
chooseButton: {
|
||
dialog(event, player) {
|
||
const vcards = [];
|
||
if (event.filterCard({ name: "sha", isCard: true }, player, event)) vcards.push("sha");
|
||
if (event.filterCard({ name: "shan", isCard: true }, player, event)) vcards.push("shan");
|
||
return ui.create.dialog("起乱", [vcards, "vcard"], "hidden");
|
||
},
|
||
backup(links, player) {
|
||
return {
|
||
viewAs: { name: links[0][2], isCard: true },
|
||
filterCard: () => false,
|
||
selectCard: -1,
|
||
popname: true,
|
||
async precontent(event, trigger, player) {
|
||
delete event.result.skill;
|
||
const stat = player.getStat("skill");
|
||
if (!stat.jsrgqiluan) stat.jsrgqiluan = 0;
|
||
stat.jsrgqiluan++;
|
||
const evt = event.getParent();
|
||
player.logSkill("jsrgqiluan");
|
||
const { cards, targets } = await player
|
||
.chooseCardTarget({
|
||
prompt: "弃置任意张牌并选择等量角色",
|
||
position: "he",
|
||
filterCard: card => lib.filter.cardDiscardable(card, player, "jsrgqiluan"),
|
||
filterTarget: lib.filter.notMe,
|
||
selectCard: [1, Infinity],
|
||
selectTarget: [1, Infinity],
|
||
filterOk() {
|
||
return ui.selected.cards.length === ui.selected.targets.length;
|
||
},
|
||
forced: true,
|
||
})
|
||
.forResult();
|
||
player.line(targets);
|
||
targets.sortBySeat();
|
||
const cardsNum = cards.length;
|
||
await player.discard(cards);
|
||
let hasSomeoneUsed = false;
|
||
for (const target of targets) {
|
||
const cardName = event.result.card.name;
|
||
const chooseToRespondEvent = target.chooseToRespond("是否替" + get.translation(player) + "打出一张" + get.translation(cardName) + "?", {name: cardName});
|
||
chooseToRespondEvent.set("ai", () => {
|
||
const event = _status.event;
|
||
return get.attitude(event.player, event.source) - 2;
|
||
});
|
||
chooseToRespondEvent.set("source", player);
|
||
chooseToRespondEvent.set("skillwarn", "替" + get.translation(player) + "打出一张" + get.translation(cardName));
|
||
chooseToRespondEvent.noOrdering = true;
|
||
chooseToRespondEvent.autochoose = (cardName === "sha" ? lib.filter.autoRespondSha : lib.filter.autoRespondShan);
|
||
const { bool, card, cards } = (await chooseToRespondEvent).result;
|
||
if(bool){
|
||
hasSomeoneUsed = true;
|
||
event.result.card = card;
|
||
event.result.cards = cards;
|
||
event.result._apply_args = { throw: false };
|
||
target.addExpose(0.2)
|
||
await player.draw(cardsNum)
|
||
break;
|
||
}
|
||
}
|
||
if(!hasSomeoneUsed){
|
||
evt.goto(0);
|
||
}
|
||
},
|
||
};
|
||
},
|
||
prompt(links, player) {
|
||
return `请选择【${get.translation(links[0][2])}】的目标`;
|
||
},
|
||
},
|
||
//技能收益太低,不写AI了
|
||
},
|
||
jsrgxiangjia: {
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
filter(event, player) {
|
||
return player.getEquips(1).length > 0;
|
||
},
|
||
viewAs: {
|
||
name: "jiedao",
|
||
isCard: true,
|
||
},
|
||
filterCard: () => false,
|
||
selectCard: -1,
|
||
onuse(result, player) {
|
||
player.addTempSkill("jsrgxiangjia_effect");
|
||
},
|
||
//技能收益太低,先不写AI了
|
||
subSkill: {
|
||
effect: {
|
||
charlotte: true,
|
||
filter(event, player) {
|
||
const card = get.autoViewAs({ name: "jiedao", isCard: true });
|
||
return (
|
||
event.skill === "jsrgxiangjia" &&
|
||
event.targets.some(current => {
|
||
return current.isIn() && current.canUse(card, player);
|
||
})
|
||
);
|
||
},
|
||
popup: false,
|
||
async content(event, trigger, player) {
|
||
const card = get.autoViewAs({ name: "jiedao", isCard: true });
|
||
for (const target of trigger.targets) {
|
||
if (target.isIn() && target.canUse(card, player)) {
|
||
const result = await target
|
||
.chooseTarget(`是否对${get.translation(player)}使用【借刀杀人】?`, `操作提示:直接选择${get.translation(player)}使用【杀】的目标角色`, (card, player, target) => {
|
||
const source = get.event("source");
|
||
return lib.card.jiedao.filterAddedTarget(card, player, target, source);
|
||
})
|
||
.set("source", player)
|
||
.set("ai", target => {
|
||
const player = get.player(),
|
||
card = get.autoViewAs({ name: "jiedao", isCard: true });
|
||
const source = get.event("source");
|
||
let eff = get.effect(source, card, player, player);
|
||
_status.event.preTarget = source;
|
||
eff += get.effect(target, card, player, player);
|
||
delete _status.event.preTarget;
|
||
return eff;
|
||
})
|
||
.forResult();
|
||
if (result.bool) {
|
||
await target.useCard(get.autoViewAs({ name: "jiedao", isCard: true }), [player, result.targets[0]]);
|
||
}
|
||
}
|
||
}
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//陈蕃
|
||
jsrggangfen: {
|
||
trigger: { global: "useCardToPlayer" },
|
||
filter(event, player) {
|
||
if (event.card.name !== "sha") return false;
|
||
if (event.player === player || event.player.countCards("h") <= player.countCards("h")) return false;
|
||
return !event.targets.includes(player) && lib.filter.targetEnabled(event.card, event.player, player);
|
||
},
|
||
logTarget: "player",
|
||
prompt2(event, player) {
|
||
return `你可以成为该角色使用的${get.translation(event.card)}的额外目标,并令所有其他角色也选择是否成为此牌的目标。然后该角色展示所有手牌,若其中的黑色牌数量小于此牌目标数,则此牌无效。`;
|
||
},
|
||
check(event, player) {
|
||
if (
|
||
event.targets.reduce((p, c) => {
|
||
return p + get.effect_use(c, event.card, event.player, player) > 0;
|
||
}, 0) >= 0
|
||
)
|
||
return false;
|
||
//绝对保守策略:队友数大于来源牌数才发动技能
|
||
return game.countPlayer(current => event.targets.includes(current) || get.attitude(current, player) > 0) > event.player.countCards("h");
|
||
},
|
||
async content(event, trigger, player) {
|
||
trigger.targets.add(player);
|
||
const source = trigger.player;
|
||
const targets = game
|
||
.filterPlayer(current => {
|
||
return current !== player && current !== source && !trigger.targets.includes(current) && lib.filter.targetEnabled(trigger.card, source, current);
|
||
})
|
||
.sortBySeat();
|
||
for (const target of targets) {
|
||
const bool = await target
|
||
.chooseBool(`是否也成为${get.translation(trigger.card)}的目标?`, `若最终目标数大于${get.translation(source)}手牌中的黑色牌数,则此牌无效。`)
|
||
.set("ai", () => get.event("choice"))
|
||
.set(
|
||
"choice",
|
||
(() => {
|
||
if (get.attitude(target, player) < 0) return false;
|
||
return game.countPlayer(current => trigger.targets.includes(current) || get.attitude(current, player) > 0) > trigger.player.countCards("h");
|
||
})()
|
||
)
|
||
.forResult("bool");
|
||
if (bool) {
|
||
target.addExpose(0.15);
|
||
target.chat("我也上!");
|
||
target.line(source);
|
||
trigger.targets.add(target);
|
||
game.log(target, "也成为了", trigger.card, "的目标");
|
||
await game.asyncDelayx();
|
||
}
|
||
}
|
||
await source.showHandcards();
|
||
const blackNum = source.countCards("h", card => get.color(card, source) === "black");
|
||
if (blackNum < trigger.targets.length) {
|
||
trigger.getParent().all_excluded = true;
|
||
trigger.targets.length = 0;
|
||
trigger.untrigger();
|
||
}
|
||
},
|
||
ai: {
|
||
expose: 0.2,
|
||
threaten: 4.5,
|
||
},
|
||
},
|
||
jsrgdangren: {
|
||
zhuanhuanji: true,
|
||
enable: "chooseToUse",
|
||
filter(event, player) {
|
||
if (player.storage.jsrgdangren) return false;
|
||
const card = get.autoViewAs({ name: "tao", isCard: true });
|
||
return event.filterCard(card, player, event) && event.filterTarget(card, player, player);
|
||
},
|
||
viewAs: { name: "tao", isCard: true },
|
||
filterTarget(card, player, target) {
|
||
return target === player;
|
||
},
|
||
selectTarget: -1,
|
||
filterCard() {
|
||
return false;
|
||
},
|
||
selectCard: -1,
|
||
check() {
|
||
const player = get.player();
|
||
if (player.isDying()) return true;
|
||
return (
|
||
game.countPlayer(current => {
|
||
return current.hp <= 2 && get.attitude(player, current) > 0;
|
||
}) >
|
||
game.countPlayer(current => {
|
||
return current.hp <= 2 && get.attitude(player, current) <= 0;
|
||
})
|
||
);
|
||
},
|
||
prompt: "视为对自己使用【桃】",
|
||
async precontent(event, trigger, player) {
|
||
player.logSkill("jsrgdangren");
|
||
player.changeZhuanhuanji("jsrgdangren");
|
||
delete event.result.skill;
|
||
},
|
||
hiddenCard(player, name) {
|
||
return name === "tao";
|
||
},
|
||
mark: true,
|
||
marktext: "☯",
|
||
intro: {
|
||
content(storage) {
|
||
if (storage) return "当你可以对其他角色使用【桃】时,你须视为使用之。";
|
||
return "当你需要对自己使用【桃】时,你可以视为使用之";
|
||
},
|
||
},
|
||
group: "jsrgdangren_save",
|
||
subSkill: {
|
||
save: {
|
||
trigger: { player: "chooseToUseBegin" },
|
||
filter(event, player) {
|
||
if (event.responded || !player.storage.jsrgdangren) return false;
|
||
const card = get.autoViewAs({ name: "tao", isCard: true });
|
||
if (!event.filterCard(card, player, event)) return false;
|
||
const backup = _status.event;
|
||
_status.event = event;
|
||
const hasTarget = game.hasPlayer(current => {
|
||
return current !== player && event.filterTarget(card, player, current);
|
||
});
|
||
_status.event = backup;
|
||
return hasTarget;
|
||
},
|
||
async cost(event, trigger, player) {
|
||
const card = get.autoViewAs({ name: "tao", isCard: true });
|
||
const backup = _status.event;
|
||
_status.event = trigger;
|
||
const targets = game.filterPlayer(current => {
|
||
return current !== player && trigger.filterTarget(card, player, current);
|
||
});
|
||
_status.event = backup;
|
||
if (targets.length === 1) {
|
||
event.result = { bool: true, targets };
|
||
} else {
|
||
event.result = await player
|
||
.chooseTarget(true, "当仁:请选择【桃】的目标", (card, player, target) => {
|
||
return get.event("targets").includes(target);
|
||
})
|
||
.set("targets", targets)
|
||
.forResult();
|
||
}
|
||
},
|
||
async content(event, trigger, player) {
|
||
trigger.result = {
|
||
bool: true,
|
||
card: { name: "tao", isCard: true },
|
||
targets: event.targets,
|
||
};
|
||
trigger.untrigger();
|
||
trigger.set("responded", true);
|
||
player.changeZhuanhuanji("jsrgdangren");
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//卢植
|
||
jsrgruzong: {
|
||
trigger: { player: "phaseEnd" },
|
||
filter(event, player) {
|
||
const target = lib.skill.jsrgruzong.getTarget(player);
|
||
if (!target) return false;
|
||
const hs = player.countCards("h");
|
||
if (target !== player) return target.countCards("h") > hs;
|
||
return game.hasPlayer(current => current !== player && current.countCards("h") < hs);
|
||
},
|
||
getTarget(player) {
|
||
const targets = [];
|
||
player.checkHistory("useCard", evt => targets.addArray(evt.targets));
|
||
return targets.length === 1 ? targets[0] : null;
|
||
},
|
||
frequent: true,
|
||
async cost(event, trigger, player) {
|
||
const target = lib.skill.jsrgruzong.getTarget(player);
|
||
if (target !== player) {
|
||
const bool = await player.chooseBool(get.prompt("jsrgruzong", target), "将手牌数摸至与该角色相同").set("frequentSkill", "jsrgruzong");
|
||
if (bool) {
|
||
event.result = {
|
||
bool,
|
||
targets: [target],
|
||
cost_data: "drawToOthers",
|
||
};
|
||
}
|
||
} else {
|
||
event.result = await player
|
||
.chooseTarget(get.prompt("jsrgruzong"), "令任意名角色将手牌数摸至与你相同", (card, player, target) => {
|
||
return target.countCards("h") < player.countCards("h");
|
||
})
|
||
.set("ai", target => {
|
||
const player = get.player();
|
||
return (get.attitude(player, target) * Math.sqrt(player.countCards("h") - target.countCards("h"))) / (target.hasSkillTag("nogain") ? 1 : 10);
|
||
});
|
||
}
|
||
},
|
||
async content(event, trigger, player) {
|
||
if (event.cost_data === "drawToOthers") {
|
||
const num = Math.min(5, event.targets[0].countCards("h") - player.countCards("h"));
|
||
if (num > 0) await player.draw(num);
|
||
} else {
|
||
const num = player.countCards("h");
|
||
game.asyncDraw(event.targets.sortBySeat(), target => {
|
||
return Math.min(5, num - target.countCards("h"));
|
||
});
|
||
}
|
||
},
|
||
},
|
||
jsrgdaoren: {
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
filter(event, player) {
|
||
return player.countCards("h") > 0;
|
||
},
|
||
filterCard: true,
|
||
position: "h",
|
||
discard: false,
|
||
lose: false,
|
||
delay: false,
|
||
filterTarget: lib.filter.notMe,
|
||
check(card) {
|
||
return 6 - get.value(card);
|
||
},
|
||
async content(event, trigger, player) {
|
||
const target = event.target;
|
||
await player.give(event.cards, target);
|
||
const targets = game
|
||
.filterPlayer(current => {
|
||
return player.inRange(current) && target.inRange(current);
|
||
})
|
||
.sortBySeat();
|
||
for (const current of targets) {
|
||
player.line(current);
|
||
await current.damage("nocard");
|
||
await game.asyncDelayx();
|
||
}
|
||
},
|
||
ai: {
|
||
order: 2,
|
||
result: {
|
||
player(player, target) {
|
||
const targets = game.filterPlayer(current => {
|
||
return player.inRange(current) && target.inRange(current);
|
||
});
|
||
if (targets.length === 0) return false;
|
||
return targets.reduce((p, c) => {
|
||
let eff = get.damageEffect(c, player, player);
|
||
if (eff < 0 && c.hp <= 2) {
|
||
const att = get.attitude(player, c);
|
||
if (att > 0) eff *= Math.sqrt(att);
|
||
}
|
||
return p + eff;
|
||
}, 0);
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//刘表
|
||
jsrgyansha: {
|
||
trigger: { player: "phaseZhunbeiBegin" },
|
||
async cost(event, trigger, player) {
|
||
//AI摆了,交给157了
|
||
event.result = await player
|
||
.chooseTarget(get.prompt("jsrgyansha"), "你可以选择任意名角色,视为对这些角色使用【五谷丰登】,然后未被选择的角色依次可以将一张装备牌当作【杀】对目标角色使用。", [1, Infinity], (card, player, target) => {
|
||
return player.canUse({ name: "wugu", isCard: true }, target);
|
||
})
|
||
.forResult();
|
||
},
|
||
async content(event, trigger, player) {
|
||
const targets = event.targets.slice(0).sortBySeat();
|
||
await player.useCard({ name: "wugu", isCard: true }, targets);
|
||
const players = game.filterPlayer(current => !targets.includes(current)).sortBySeat();
|
||
for (const current of players) {
|
||
const aliveTargets = targets.filter(current => current.isIn());
|
||
if (!aliveTargets.length) break;
|
||
if (
|
||
current.isIn() &&
|
||
(current.countCards("e") > 0 ||
|
||
current.hasCard(card => {
|
||
if (_status.connectMode) return true;
|
||
return get.type(card) === "trick";
|
||
}, "hs"))
|
||
) {
|
||
}
|
||
const result = await current
|
||
.chooseCardTarget({
|
||
prompt: `是否将一张装备牌当作【杀】对${get.translation(targets)}${targets.length > 1 ? "中的一名角色" : ""}使用?`,
|
||
position: "hes",
|
||
filterCard(card) {
|
||
return get.type(card) === "equip";
|
||
},
|
||
filterTarget(card, player, target) {
|
||
if (!get.event("targets").includes(target)) return false;
|
||
card = get.autoViewAs({ name: "sha" }, ui.selected.cards);
|
||
return player.canUse(card, target, false);
|
||
},
|
||
ai1(card) {
|
||
return 7 - get.value(card);
|
||
},
|
||
ai2(target) {
|
||
const player = get.player(),
|
||
card = get.autoViewAs({ name: "sha" }, ui.selected.cards);
|
||
return get.effect(target, card, player, player);
|
||
},
|
||
targets: aliveTargets,
|
||
})
|
||
.forResult();
|
||
if (result.bool) {
|
||
await current.useCard(get.autoViewAs({ name: "sha" }, result.cards), result.cards, result.targets);
|
||
}
|
||
}
|
||
},
|
||
},
|
||
jsrgqingping: {
|
||
trigger: { player: "phaseJieshuBegin" },
|
||
frequent: true,
|
||
filter(event, player) {
|
||
const targets = game.filterPlayer(current => player.inRange(current)),
|
||
hs = player.countCards("h");
|
||
return targets.length > 0 && targets.every(current => current.countCards("h") <= hs);
|
||
},
|
||
async content(event, trigger, player) {
|
||
await player.draw(game.countPlayer(current => player.inRange(current)));
|
||
},
|
||
},
|
||
//张奂
|
||
jsrgzhushou: {
|
||
trigger: { global: "phaseEnd" },
|
||
filter(event, player) {
|
||
if (!player.getHistory("lose").length) return false;
|
||
const card = lib.skill.jsrgzhushou.getMaxCard();
|
||
if (!card) return false;
|
||
return game.hasPlayer(current => {
|
||
return current.hasHistory("lose", evt => {
|
||
return evt.cards2 && evt.cards2.includes(card);
|
||
});
|
||
});
|
||
},
|
||
async cost(event, trigger, player) {
|
||
const card = lib.skill.jsrgzhushou.getMaxCard();
|
||
const targets = game.filterPlayer(current => {
|
||
return current.hasHistory("lose", evt => {
|
||
return evt.cards2 && evt.cards2.includes(card);
|
||
});
|
||
});
|
||
const result = await player
|
||
.chooseTarget(get.prompt("jsrgzhushou"), `选择一名本回合内失去过${get.translation(card)}的角色,对其造成1点伤害。`, (card, player, target) => {
|
||
return get.event("targets").includes(target);
|
||
})
|
||
.set("targets", targets)
|
||
.set("ai", target => {
|
||
const player = get.player();
|
||
return get.damageEffect(target, player, player);
|
||
})
|
||
.forResult();
|
||
if (result.bool) {
|
||
event.result = {
|
||
bool: true,
|
||
targets: result.targets,
|
||
cards: [card],
|
||
};
|
||
}
|
||
},
|
||
async content(event, trigger, player) {
|
||
await player.showCards(event.cards, `${get.translation(player)}发动了【诛首】`);
|
||
await event.targets[0].damage("nocard");
|
||
},
|
||
getMaxCard() {
|
||
let cardsLost = [];
|
||
game.getGlobalHistory("cardMove", evt => {
|
||
if (evt.name === "cardsDiscard" || (evt.name === "lose" && evt.position === ui.discardPile)) {
|
||
cardsLost.addArray(evt.cards);
|
||
}
|
||
});
|
||
cardsLost = cardsLost.filterInD("d");
|
||
let max = 0;
|
||
return cardsLost.reduce(
|
||
(maxCard, card) => {
|
||
const num = get.number(card, false);
|
||
if (num > max) {
|
||
max = num;
|
||
return card;
|
||
} else if (num === max) {
|
||
return void 0;
|
||
}
|
||
return maxCard;
|
||
},
|
||
void 0
|
||
);
|
||
},
|
||
},
|
||
jsrgyangge: {
|
||
global: "jsrgyangge_mizhao",
|
||
derivation: "mizhao",
|
||
subSkill: {
|
||
mizhao: {
|
||
//直接继承mizhao
|
||
inherit: "mizhao",
|
||
usable: void 0,
|
||
filter(event, player) {
|
||
return player.countCards("h") > 0 && player.isMinHp() && game.hasPlayer(current => lib.skill.jsrgyangge_mizhao.filterTarget(void 0, player, current));
|
||
},
|
||
filterTarget(card, player, target) {
|
||
if (player === target) return false;
|
||
return target.hasSkill("jsrgyangge") && !target.hasMark("jsrgyangge");
|
||
},
|
||
prompt() {
|
||
const player = get.player();
|
||
const targets = game.filterPlayer(current => lib.skill.jsrgyangge_mizhao.filterTarget(void 0, player, current));
|
||
return `对${get.translation(targets)}${targets.length > 1 ? "中的一人" : ""}发动【密诏】`;
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//董卓
|
||
jsrgguanshi: {
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
viewAs: { name: "huogong" },
|
||
viewAsFilter(player) {
|
||
return player.hasCard(card => get.name(card) === "sha", "hs");
|
||
},
|
||
filterCard(card) {
|
||
return get.name(card) === "sha";
|
||
},
|
||
selectTarget: [1, Infinity],
|
||
onuse(result, player) {
|
||
player.addTempSkill("jsrgguanshi_effect");
|
||
},
|
||
position: "hs",
|
||
selectTargetAi(card) {
|
||
let cache = _status.event.getTempCache("jsrgguanshi", "targets");
|
||
if (Array.isArray(cache)) return cache.length;
|
||
let player = _status.event.player,
|
||
targets = [],
|
||
shas = player.mayHaveSha(player, "respond", player.getCards("h", i => {
|
||
return card === i;
|
||
}));
|
||
game.countPlayer(tar => {
|
||
if (player === tar) return;
|
||
let eff = get.effect(tar, get.autoViewAs({ name: "juedou" }, [card]), player, player);
|
||
if (eff <= 0) return;
|
||
if (get.attitude(player, tar) > 0) targets.push([tar, eff, 0]);
|
||
else targets.push([tar, eff, tar.mayHaveSha(player, "respond", null, "count")]);
|
||
});
|
||
targets.sort((a, b) => {
|
||
if (!a[2]) return -1;
|
||
if (!b[2]) return 1;
|
||
return b[1] / b[2] - a[1] / a[2];
|
||
});
|
||
for (let i = 0; i < targets.length; i++) {
|
||
if (targets[i][2] > shas) {
|
||
targets = targets.slice(0, i);
|
||
break;
|
||
}
|
||
else shas -= targets[i][2];
|
||
}
|
||
_status.event.putTempCache("jsrgguanshi", "targets", targets);
|
||
return targets.length;
|
||
},
|
||
check(card) {
|
||
let num = lib.skill.jsrgguanshi.selectTargetAi(card);
|
||
if (!num) return -1;
|
||
if (num === 1) return 4 - get.value(card);
|
||
return num + 5 - get.value(card);
|
||
},
|
||
ai: {
|
||
order: 9,
|
||
result: {
|
||
player(player, target) {
|
||
let tars = _status.event.putTempCache("jsrgguanshi", "targets", targets);
|
||
if (!tars) return lib.card.juedou.ai.result.player(player, target);
|
||
},
|
||
target(player, target) {
|
||
let tars = _status.event.putTempCache("jsrgguanshi", "targets", targets);
|
||
if (!tars) return lib.card.juedou.ai.result.target(player, target);
|
||
for (let tar of tars) {
|
||
if (tar[0] === target) return tar[1] / get.attitude(player, target);
|
||
}
|
||
return 0;
|
||
}
|
||
}
|
||
},
|
||
subSkill: {
|
||
effect: {
|
||
trigger: {
|
||
player: ["useCardToBefore", "useCardToAfter", "useCardToExcluded", "useCardToOmitted", "useCardToCancelled"],
|
||
},
|
||
forced: true,
|
||
charlotte: true,
|
||
popup: false,
|
||
firstDo: true,
|
||
priority: 100,
|
||
filter(event, player, name) {
|
||
if (event.type !== "card" || event.skill !== "jsrgguanshi") return false;
|
||
const isUnhurted = event.card.storage && event.card.storage.jsrgguanshi;
|
||
if (name === "useCardToBefore") return isUnhurted;
|
||
return (
|
||
!isUnhurted &&
|
||
event.target &&
|
||
!player.hasHistory("sourceDamage", evt => {
|
||
return evt.card === event.card && evt.getParent() === event;
|
||
})
|
||
);
|
||
},
|
||
async content(event, trigger, player) {
|
||
if (event.triggername === "useCardToBefore") {
|
||
trigger.setContent(lib.card.juedou.content);
|
||
} else {
|
||
const card = trigger.card;
|
||
if (!card.storage) card.storage = {};
|
||
card.storage.jsrgguanshi = true;
|
||
}
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgcangxiong: {
|
||
trigger: {
|
||
player: "loseAfter",
|
||
global: ["gainAfter", "loseAsyncAfter"],
|
||
},
|
||
getIndex(event, player, triggername) {
|
||
if (event.type === "discard") {
|
||
return event.getl(player).cards2 || [];
|
||
} else if (event.name === "gain") {
|
||
if (event.player === player) return;
|
||
const cardsGained = event.getg(event.player),
|
||
cardsLost = event.getl(player).cards2;
|
||
return cardsLost.filter(card => cardsGained.includes(card));
|
||
} else if (event.name === "loseAsync" && event.type === "gain") {
|
||
const cardsLost = event.getl(player).cards2;
|
||
if (!cardsLost.length) return [];
|
||
const cardsGained = [];
|
||
game.countPlayer2(
|
||
current => {
|
||
if (current !== player) cardsGained.addArray(event.getg(current));
|
||
},
|
||
null,
|
||
true
|
||
);
|
||
return cardsLost.filter(card => cardsGained.includes(card));
|
||
}
|
||
return [];
|
||
},
|
||
filter(event, player, name, card) {
|
||
if (player.isDisabledJudge()) return false;
|
||
if (event.type === "discard") return get.position(card, true) === "d";
|
||
else {
|
||
const owner = game.findPlayer2(
|
||
current => {
|
||
return current !== player && event.getg(current).includes(card);
|
||
},
|
||
null,
|
||
true
|
||
);
|
||
return owner.getCards("h").includes(card);
|
||
}
|
||
},
|
||
prompt2(event, player, name, card) {
|
||
return `将${get.translation(card)}作为蓄谋牌置入判定区${player.isPhaseUsing() ? ",然后摸一张牌。" : ""}`;
|
||
},
|
||
async content(event, trigger, player) {
|
||
const card = event.indexedData;
|
||
if (get.position(card) === "d") {
|
||
player.$gain2(card, false);
|
||
game.log(player, "使用", card, "进行了明目张胆的蓄谋");
|
||
} else {
|
||
get.owner(card).$giveAuto(card, player, false);
|
||
}
|
||
await game.asyncDelayx();
|
||
await player.addJudge({ name: "xumou_jsrg" }, [card]);
|
||
if (player.isPhaseUsing()) await player.draw();
|
||
},
|
||
},
|
||
jsrgjiebing: {
|
||
derivation: "jsrgbaowei",
|
||
trigger: { player: "phaseZhunbeiBegin" },
|
||
forced: true,
|
||
juexingji: true,
|
||
skillAnimation: true,
|
||
animationColor: "gray",
|
||
filter(event, player) {
|
||
const target = lib.skill.jsrgjiebing.getZhugong(player);
|
||
return (
|
||
target &&
|
||
player.countCards("j", card => {
|
||
return (card.viewAs || card.name) == "xumou_jsrg";
|
||
}) > target.getHp()
|
||
);
|
||
},
|
||
async content(event, trigger, player) {
|
||
player.awakenSkill("jsrgjiebing");
|
||
await player.gainMaxHp(2);
|
||
await player.recover(2);
|
||
await player.addSkills("jsrgbaowei");
|
||
},
|
||
ai: {
|
||
combo: "jsrgcangxiong",
|
||
},
|
||
getZhugong(player) {
|
||
const mode = get.mode();
|
||
if (mode === "identity") {
|
||
if (_status.mode === "purple") {
|
||
return game.findPlayer(current => {
|
||
return current.isZhu2() && current.identity.slice(0, 1) === player.identity.slice(0, 1);
|
||
});
|
||
}
|
||
return game.findPlayer(current => current.isZhu2());
|
||
} else {
|
||
return game.findPlayer(current => current.getSeatNum() === 1);
|
||
}
|
||
},
|
||
},
|
||
jsrgbaowei: {
|
||
trigger: { player: "phaseJieshuBegin" },
|
||
forced: true,
|
||
filter(event, player) {
|
||
return game.hasPlayer(current => {
|
||
return current !== player && (current.getHistory("useCard").length > 0 || current.getHistory("respond").length > 0);
|
||
});
|
||
},
|
||
async content(event, trigger, player) {
|
||
const targets = game.filterPlayer(current => {
|
||
return current !== player && (current.getHistory("useCard").length > 0 || current.getHistory("respond").length > 0);
|
||
});
|
||
if (targets.length > 2) {
|
||
await player.loseHp(2);
|
||
} else {
|
||
let target;
|
||
if (targets.length === 1) [target] = targets;
|
||
else
|
||
[target] = await player
|
||
.chooseTarget(true, "暴威:对一名目标角色造成2点伤害", (card, player, target) => {
|
||
return get.event("targets").includes(target);
|
||
})
|
||
.set("targets", targets)
|
||
.set("ai", target => {
|
||
const player = get.player();
|
||
return get.damageEffect(target, player, player) * (1.1 - get.sgn(get.attitude(player, target)));
|
||
}).forResult("targets");
|
||
player.line(target, "green");
|
||
target.damage(2);
|
||
}
|
||
},
|
||
ai: {
|
||
//这里应该写一个强命AI,但是比较麻烦,可能还要写全局AI技能,先摆了
|
||
},
|
||
},
|
||
//阳球
|
||
jsrgsaojian: {
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
filterTarget(card, player, target) {
|
||
return target.countCards("h") > 0;
|
||
},
|
||
async content(event, trigger, player) {
|
||
const target = event.target;
|
||
if (target.countCards("h") > 0) {
|
||
const [card] = await player
|
||
.choosePlayerCard(target, true, "h", "visible")
|
||
.set("ai", button => {
|
||
//开摆,直接随机选,不考虑有的没的
|
||
return get.event().getRand(button.link.cardid);
|
||
})
|
||
.forResult("cards");
|
||
const videoId = lib.status.videoId++;
|
||
game.addVideo("showCards", player, [`${get.translation(player)}对${get.translation(target)}发动了【扫奸】`, get.cardsInfo([card])]);
|
||
game.broadcastAll(
|
||
(card, id, player, target) => {
|
||
if (target === game.me) return;
|
||
const dialog = ui.create.dialog(`${get.translation(player)}对${get.translation(target)}发动了【扫奸】`, [card]);
|
||
dialog.forcebutton = true;
|
||
dialog.videoId = id;
|
||
},
|
||
card,
|
||
videoId,
|
||
player,
|
||
target
|
||
);
|
||
await game.asyncDelay(3);
|
||
game.broadcastAll("closeDialog", videoId);
|
||
for (let i = 0; i < 5; i++) {
|
||
const discarded = await target
|
||
.chooseToDiscard("h", true)
|
||
.set("ai", card => {
|
||
//开摆,直接随机弃牌,不考虑有的没的
|
||
return get.event().getRand(card.cardid);
|
||
})
|
||
.forResult("cards");
|
||
if (!discarded || !discarded.length || discarded[0] === card) break;
|
||
}
|
||
if (target.countCards("h") > player.countCards("h")) player.loseHp();
|
||
}
|
||
},
|
||
ai: {
|
||
order: 7,
|
||
result: {
|
||
target(player, target) {
|
||
//对面牌比自己少,就放心大胆弃牌
|
||
if (target.countCards("h") <= player.countCards("h") - 1) return -3;
|
||
//残血别浪
|
||
if (player.hp === 1 && get.effect(player, { name: "losehp" }, player, player) < 0) return 0;
|
||
//血多无所谓
|
||
return -1;
|
||
},
|
||
},
|
||
tag: {
|
||
loseCard: 1,
|
||
discard: 1,
|
||
},
|
||
},
|
||
},
|
||
//张角
|
||
jsrgxiangru: {
|
||
trigger: { global: "damageBegin2" },
|
||
filter(event, player) {
|
||
if (event.player.hp + event.player.hujia > event.num) return false;
|
||
const source = event.source;
|
||
if (!source || !source.isIn()) return false;
|
||
if (player !== event.player) {
|
||
return event.player.isDamaged() && player !== source && player.countCards("he") > 1;
|
||
}
|
||
return game.hasPlayer(current => {
|
||
return current !== source && current !== player && current.isDamaged() && current.countCards("he") >= 1;
|
||
});
|
||
},
|
||
async cost(event, trigger, player) {
|
||
const target = trigger.player,
|
||
source = trigger.source;
|
||
const targets = (
|
||
target === player
|
||
? game.filterPlayer(current => {
|
||
return current !== source && current !== player && current.isDamaged() && current.countCards("he") >= 1;
|
||
})
|
||
: [player]
|
||
).filter(current => current !== source && current !== target && current.countCards("he") >= 1);
|
||
targets.sortBySeat();
|
||
let cards = null,
|
||
giver = null;
|
||
const eventId = get.id(),
|
||
send = (target, source, current, eventId, eventNum) => {
|
||
lib.skill.jsrgxiangru.chooseTarget(target, source, current, eventId, eventNum);
|
||
game.resume();
|
||
},
|
||
humans = targets.filter(current => current === game.me || current.isOnline()),
|
||
locals = targets.slice(0);
|
||
locals.removeArray(humans);
|
||
//让读条不消失并显示读条
|
||
event._global_waiting = true;
|
||
let time = 10000;
|
||
if (lib.configOL && lib.configOL.choose_timeout) time = parseInt(lib.configOL.choose_timeout) * 1000;
|
||
targets.forEach(current => current.showTimer(time));
|
||
//先处理人类玩家
|
||
if (humans.length > 0) {
|
||
const solve = function (resolve, reject) {
|
||
return function (result, player) {
|
||
if (result && result.bool && !cards) {
|
||
resolve();
|
||
giver = player;
|
||
cards = result.cards;
|
||
} else reject();
|
||
};
|
||
};
|
||
await Promise.any(
|
||
humans.map(current => {
|
||
return new Promise(async (resolve, reject) => {
|
||
if (current.isOnline()) {
|
||
current.send(send, target, source, current, eventId, trigger.num);
|
||
current.wait(solve(resolve, reject));
|
||
} else {
|
||
const next = lib.skill.jsrgxiangru.chooseTarget(target, source, current, eventId, trigger.num);
|
||
const solver = solve(resolve, reject);
|
||
if (_status.connectMode) game.me.wait(solver);
|
||
const result = await next.forResult();
|
||
if (_status.connectMode && !cards) game.me.unwait(result, current);
|
||
else solver(result, current);
|
||
}
|
||
});
|
||
})
|
||
).catch(() => {});
|
||
game.broadcastAll("cancel", eventId);
|
||
}
|
||
//再处理单机的他人控制玩家/AI玩家
|
||
if (!cards && locals.length > 0) {
|
||
for (let current of locals) {
|
||
if (cards) continue;
|
||
const result = await lib.skill.jsrgxiangru.chooseTarget(target, source, current).forResult();
|
||
if (result.bool) {
|
||
giver = current;
|
||
cards = result.cards;
|
||
}
|
||
}
|
||
}
|
||
//清除读条
|
||
delete event._global_waiting;
|
||
for (var i of targets) i.hideTimer();
|
||
//处理结果
|
||
if (cards) {
|
||
event.result = {
|
||
bool: true,
|
||
targets: [player === target ? giver : target],
|
||
cost_data: { cards, giver },
|
||
};
|
||
game.broadcastAll(result => console.log(result), event.result);
|
||
}
|
||
},
|
||
async content(event, trigger, player) {
|
||
const { giver, cards } = event.cost_data;
|
||
await giver.give(cards, trigger.source);
|
||
await trigger.cancel();
|
||
},
|
||
chooseTarget(target, source, current, eventId, eventNum) {
|
||
const goon = (() => {
|
||
//资敌的代价太大,因此不到万不得已不给牌
|
||
if (get.attitude(current, target) < 4) return false;
|
||
if (current.countCards("hs", card => current.canSaveCard(card, target)) >= 1 - (target.hp + target.hujia - eventNum)) return false;
|
||
if (target == get.zhu(current) || get.attitude(current, source) > 0) return "长崎素世一般的恳求";
|
||
return "给点废牌算了";
|
||
})();
|
||
const next = current.chooseCard("he", 2);
|
||
next.set("prompt", `是否对${get.translation(target)}发动【相濡】?`);
|
||
next.set("prompt2", `选择交给${get.translation(source)}两张牌,然后防止${get.translation(target)}即将受到的致命伤害。`);
|
||
next.set("id", eventId);
|
||
next.set("_global_waiting", true);
|
||
next.set("ai", card => {
|
||
if (goon) {
|
||
if (goon.includes("长崎素世")) return 20 - get.value(card);
|
||
return 5 - get.value(card);
|
||
}
|
||
return 0;
|
||
});
|
||
return next;
|
||
},
|
||
},
|
||
jsrgwudao: {
|
||
derivation: "jsrgjinglei",
|
||
trigger: { global: "dying" },
|
||
forced: true,
|
||
juexingji: true,
|
||
skillAnimation: true,
|
||
animationColor: "gray",
|
||
filter(event, player) {
|
||
return player.countCards("h") === 0;
|
||
},
|
||
async content(event, trigger, player) {
|
||
player.awakenSkill("jsrgwudao");
|
||
await player.gainMaxHp();
|
||
await player.recover();
|
||
await player.addSkills("jsrgjinglei");
|
||
},
|
||
},
|
||
jsrgjinglei: {
|
||
trigger: { player: "phaseZhunbeiBegin" },
|
||
filter(event, player) {
|
||
return game.hasPlayer(current => !current.isMinHandcard());
|
||
},
|
||
async cost(event, trigger, player) {
|
||
event.result = await player
|
||
.chooseTarget(get.prompt("jsrgjinglei"), "选择一名其他角色,令任意名手牌数之和小于其的角色各对其造成1点雷属性伤害", (card, player, target) => !target.isMinHandcard())
|
||
.set("ai", target => {
|
||
//AI写的比较简单:不打队友,根据手牌数平方根酌情打牌多的
|
||
const player = get.player();
|
||
if (get.attitude(player, target) >= 0) return false;
|
||
return get.damageEffect(target, player, player, "thunder") * Math.sqrt(target.countCards("h"));
|
||
})
|
||
.forResult();
|
||
},
|
||
async content(event, trigger, player) {
|
||
const [target] = event.targets;
|
||
const maxmium = target.countCards("h");
|
||
const next = player.chooseTarget(true, `选择任意名手牌数之和小于${maxmium}的角色`, [1, Infinity]);
|
||
next.set("promptbar", "none");
|
||
next.set("maxmium", maxmium);
|
||
next.set("complexTarget", true);
|
||
next.set("filterTarget", (card, player, target) => {
|
||
const selected = ui.selected.targets,
|
||
maxmium = get.event("maxmium");
|
||
return (
|
||
selected.reduce((p, c) => {
|
||
return p + c.countCards("h");
|
||
}, target.countCards("h")) < maxmium
|
||
);
|
||
});
|
||
next.set("ai", target => {
|
||
//谁手牌少就选谁,没啥要考虑的
|
||
return 1 / (1 + target.countCards("h"));
|
||
});
|
||
const sources = await next.forResult("targets");
|
||
sources.sortBySeat();
|
||
player.line(sources, "thunder");
|
||
for (let source of sources) {
|
||
if (!source.isIn() || !target.isIn()) continue;
|
||
target.damage(source, "thunder");
|
||
}
|
||
},
|
||
},
|
||
//宋皇后
|
||
jsrgzhongzen: {
|
||
trigger: { player: "phaseDiscardBegin" },
|
||
forced: true,
|
||
filter(event, player) {
|
||
const hs = player.countCards("h");
|
||
return game.hasPlayer(current => {
|
||
if (current === player) return false;
|
||
const hs2 = current.countCards("h");
|
||
return hs2 > 0 && hs2 < hs;
|
||
});
|
||
},
|
||
logTarget(event, player) {
|
||
const hs = player.countCards("h");
|
||
return game.filterPlayer(current => {
|
||
if (current === player) return false;
|
||
const hs2 = current.countCards("h");
|
||
return hs2 > 0 && hs2 < hs;
|
||
});
|
||
},
|
||
async content(event, trigger, player) {
|
||
const targets = event.targets.slice(0);
|
||
targets.forEach(async target => {
|
||
if (player.isIn() && target.countCards("h") > 0) {
|
||
//暂时没有写给牌AI
|
||
await target.chooseToGive(player, "h", true);
|
||
}
|
||
});
|
||
},
|
||
group: "jsrgzhongzen_discard",
|
||
subSkill: {
|
||
discard: {
|
||
trigger: { player: "phaseDiscardEnd" },
|
||
forced: true,
|
||
filter(event, player) {
|
||
if (player.countCards("he") === 0) return false;
|
||
const cards = [];
|
||
player.getHistory("lose", evt => {
|
||
if (evt.type === "discard" && evt.getParent("phaseDiscard") === event) cards.addArray(evt.cards);
|
||
});
|
||
return (
|
||
cards.length > player.hp &&
|
||
cards.reduce((num, card) => {
|
||
if (num <= player.hp && get.suit(card, false) === "spade") num++;
|
||
return num;
|
||
}, 0) > player.hp
|
||
);
|
||
},
|
||
async content(event, trigger, player) {
|
||
await player.chooseToDiscard(true, "he", player.countCards("he"));
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgxuchong: {
|
||
trigger: { target: "useCardToTargeted" },
|
||
async cost(event, trigger, player) {
|
||
const current = _status.currentPhase;
|
||
const choices = ["摸一张牌"];
|
||
if (current) choices.push(`令${get.translation(current)}本回合的手牌上限+2`);
|
||
//暂时不写AI,默认摸牌,先爽再说
|
||
const control = await player.chooseControl("cancel2").set("choiceList", choices).forResult("control");
|
||
if (control !== "cancel2") {
|
||
event.result = {
|
||
bool: true,
|
||
targets: control === "选项二" ? [current] : [],
|
||
};
|
||
}
|
||
},
|
||
async content(event, trigger, player) {
|
||
if (event.targets && event.targets.length) {
|
||
const [target] = event.targets;
|
||
target.addTempSkill("jsrgxuchong_effect");
|
||
target.addMark("jsrgxuchong_effect", 2, false);
|
||
} else {
|
||
await player.draw();
|
||
}
|
||
await player.gain(lib.card.ying.getYing(1), "gain2");
|
||
},
|
||
subSkill: {
|
||
effect: {
|
||
mod: {
|
||
maxHandcard(player, num) {
|
||
return num + player.countMark("jsrgxuchong_effect");
|
||
},
|
||
},
|
||
onremove: true,
|
||
charlotte: true,
|
||
intro: {
|
||
content: "手牌上限+#",
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//曹节王甫
|
||
jsrgzonghai: {
|
||
trigger: { global: "dying" },
|
||
logTarget: "player",
|
||
round: 1,
|
||
filter(event, player) {
|
||
return event.player !== player && event.player.hp <= 0;
|
||
},
|
||
check(event, player) {
|
||
//理论上是小完杀+卖血
|
||
//先粗略地写一写,后面等157补
|
||
return get.attitude(player, event.player) < 0;
|
||
},
|
||
async content(event, trigger, player) {
|
||
const target = trigger.player;
|
||
const targets = await target
|
||
.chooseTarget([1, 2], true, "请选择至多两名角色", `${get.translation(player)}对你发动了【纵害】。你可以选择至多两名角色,只有这两名角色可以使用牌拯救你,且当此次濒死结算结束后,这两名角色均会受到来自${get.translation(player)}的1点伤害。`)
|
||
.set("ai", target => {
|
||
//自救还要挨一刀,最好的反制方法就是跟对面爆了
|
||
const evt = get.event(),
|
||
player = evt.player,
|
||
source = evt.getParent().player;
|
||
return get.damageEffect(target, source, player);
|
||
})
|
||
.set("forceDie", true)
|
||
.forResult("targets");
|
||
target.line(targets);
|
||
game.log(target, "选择了", targets);
|
||
targets.sortBySeat(_status.currentPhase || player);
|
||
const allPlayers = game.filterPlayer().sortBySeat();
|
||
if (!trigger._jsrgzonghai_id) trigger._jsrgzonghai_id = get.id();
|
||
const id = trigger._jsrgzonghai_id;
|
||
allPlayers.forEach(target => {
|
||
if (!targets.includes(target)) {
|
||
target.addTempSkill("jsrgzonghai_blocker");
|
||
target.markAuto("jsrgzonghai_blocker", [id]);
|
||
}
|
||
});
|
||
target
|
||
.when("dyingAfter")
|
||
.vars({ id, allPlayers, targets, source: player })
|
||
.assign({ forceDie: true })
|
||
.then(() => {
|
||
allPlayers.forEach(target => {
|
||
target.unmarkAuto("jsrgzonghai_blocker", [id]);
|
||
if (!target.getStorage("jsrgzonghai_blocker").length) target.removeSkill("jsrgzonghai_blocker");
|
||
});
|
||
if (source.isIn()) {
|
||
targets.forEach(target => target.damage(source));
|
||
}
|
||
});
|
||
},
|
||
subSkill: {
|
||
blocker: {
|
||
charlotte: true,
|
||
onremove: true,
|
||
mod: {
|
||
cardSavable: () => false,
|
||
cardEnabled: () => false,
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgjueyin: {
|
||
trigger: { player: "damageEnd" },
|
||
filter(event, player) {
|
||
return player.getHistory("damage")[0] === event;
|
||
},
|
||
async content(event, trigger, player) {
|
||
await player.draw(3);
|
||
const targets = game.filterPlayer().sortBySeat();
|
||
targets.forEach(current => {
|
||
current.addTempSkill("jsrgjueyin_damage");
|
||
current.addMark("jsrgjueyin_damage", 1, false);
|
||
});
|
||
},
|
||
subSkill: {
|
||
damage: {
|
||
onremove: true,
|
||
charlotte: true,
|
||
trigger: { player: "damageBegin1" },
|
||
forced: true,
|
||
async content(event, trigger, player) {
|
||
trigger.num++;
|
||
},
|
||
intro: {
|
||
content: "本回合受到的伤害+#",
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//梦袁绍
|
||
jsrgzhimeng: {
|
||
trigger: { player: "phaseZhunbeiBegin" },
|
||
logTarget() {
|
||
return game.filterPlayer(current => current.countCards("h") > 0).sortBySeat();
|
||
},
|
||
prompt: "是否发动【执盟】?",
|
||
async content(event, trigger, player) {
|
||
const { cards } = await game.cardsGotoOrdering(get.cards(game.countPlayer()));
|
||
await player.showCards(cards, `${get.translation(player)}发动了【执盟】`);
|
||
const targets = game.filterPlayer(current => current.countCards("h") > 0).sortBySeat();
|
||
//选牌
|
||
const showCardEvent = player.chooseCardOL(targets, `${get.translation(player)}发动了【执盟】,请展示一张手牌`, true);
|
||
showCardEvent.set("ai", card => {
|
||
if (get.event("_suits").includes(get.suit(card))) return 1 + Math.random();
|
||
return (1 - get.value(card)) * Math.random();
|
||
});
|
||
showCardEvent.set(
|
||
"_suits",
|
||
cards.map(card => get.suit(card, false))
|
||
);
|
||
showCardEvent.set("source", player);
|
||
showCardEvent.set("aiCard", target => {
|
||
const hs = target.getCards("h");
|
||
return { bool: true, cards: [hs.randomGet()] };
|
||
});
|
||
showCardEvent._args.remove("glow_result");
|
||
const result = await showCardEvent.forResult();
|
||
//选完了 展示牌
|
||
const videoId = lib.status.videoId++;
|
||
const cardsToShown = [];
|
||
for (let i = 0; i < targets.length; i++) {
|
||
cardsToShown.push(result[i].cards[0]);
|
||
game.log(targets[i], "展示了", result[i].cards[0]);
|
||
}
|
||
game.broadcastAll(
|
||
(targets, cards, id, player) => {
|
||
const dialog = ui.create.dialog(get.translation(player) + "发动了【执盟】", cards);
|
||
dialog.videoId = id;
|
||
const getName = function (target) {
|
||
if (target._tempTranslate) return target._tempTranslate;
|
||
var name = target.name;
|
||
if (lib.translate[name + "_ab"]) return lib.translate[name + "_ab"];
|
||
return get.translation(name);
|
||
};
|
||
for (let i = 0; i < targets.length; i++) {
|
||
dialog.buttons[i].querySelector(".info").innerHTML = getName(targets[i]) + get.translation(get.suit(cards[i], targets[i]));
|
||
}
|
||
},
|
||
targets,
|
||
cardsToShown,
|
||
videoId,
|
||
player
|
||
);
|
||
await game.asyncDelay(4);
|
||
game.broadcastAll("closeDialog", videoId);
|
||
//展示完了 开始拿牌
|
||
const suitsMap = {};
|
||
for (let i = 0; i < targets.length; i++) {
|
||
const target = targets[i],
|
||
card = cardsToShown[i],
|
||
suit = get.suit(card, target);
|
||
if (!(suit in suitsMap)) suitsMap[suit] = target;
|
||
else suitsMap[suit] = null;
|
||
}
|
||
const gain_list = [];
|
||
for (const data of Object.entries(suitsMap)) {
|
||
const [suit, target] = data;
|
||
if (target) {
|
||
const cardsToGain = cards.filter(card => get.suit(card, false) === suit);
|
||
if (cardsToGain.length) gain_list.push([target, cardsToGain]);
|
||
}
|
||
}
|
||
if (gain_list.length) {
|
||
await game
|
||
.loseAsync({
|
||
gain_list,
|
||
animate: "gain2",
|
||
})
|
||
.setContent("gaincardMultiple");
|
||
}
|
||
},
|
||
},
|
||
jsrgtianyu: {
|
||
trigger: { global: ["loseAsyncAfter", "cardsDiscardAfter"] },
|
||
frequent: true,
|
||
getIndex(event) {
|
||
return lib.skill.jsrgtianyu.getCards(event);
|
||
},
|
||
filter(event, player, triggername, card) {
|
||
return get.position(card, true) === "d";
|
||
},
|
||
frequent(event, player, triggername, card) {
|
||
return get.value(card, player) > 0;
|
||
},
|
||
getCards(event) {
|
||
const cards = event.getd().filter(card => {
|
||
return get.type(card, null, false) === "equip" || get.tag(card, "damage", null, false) > 0;
|
||
});
|
||
if (!cards.length) return [];
|
||
game.checkGlobalHistory("cardMove", evt => {
|
||
if (evt.name === "lose") cards.removeArray(evt.cards);
|
||
});
|
||
return cards;
|
||
},
|
||
prompt2(event, player, triggername, card) {
|
||
return `获得即将进入弃牌堆的${get.translation(card)}`;
|
||
},
|
||
async content(event, trigger, player) {
|
||
const cards = event.indexedData;
|
||
await player.gain(cards, "gain2");
|
||
},
|
||
},
|
||
jsrgzhuni: {
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
filterTarget: true,
|
||
selectTarget: -1,
|
||
multitarget: true,
|
||
multiline: true,
|
||
async content(event, trigger, player) {
|
||
let targets = event.targets.slice(0),
|
||
results = [],
|
||
forceTargets = [];
|
||
//XXX自选选择目标
|
||
if (player.hasSkill("jsrghezhi")) {
|
||
forceTargets = targets.filter(current => current !== player && current.group === "qun");
|
||
targets.removeArray(forceTargets);
|
||
}
|
||
//让读条不消失
|
||
event._global_waiting = true;
|
||
const send = (player, source) => {
|
||
lib.skill.jsrgzhuni.chooseTarget(player, source);
|
||
game.resume();
|
||
};
|
||
const solve = (result, chooser) => {
|
||
let target;
|
||
if (!result || !result.targets || result === "ai") {
|
||
target = game.filterPlayer(current => current !== player).randomGet();
|
||
} else target = result.targets[0];
|
||
results.push([chooser, target]);
|
||
if (chooser === player) {
|
||
forceTargets.forEach(current => results.push([current, target]));
|
||
}
|
||
};
|
||
let time = 10000;
|
||
if (lib.configOL && lib.configOL.choose_timeout) time = parseInt(lib.configOL.choose_timeout) * 1000;
|
||
targets.forEach(current => current.showTimer(time));
|
||
//分别处理人类玩家和其他玩家
|
||
const humans = targets.filter(current => current === game.me || current.isOnline()),
|
||
locals = targets.slice(0);
|
||
locals.removeArray(humans);
|
||
//Promise,爽!清瑶你有种抄过去
|
||
if (humans.length) {
|
||
await Promise.all(
|
||
humans.map((current, index) => {
|
||
return new Promise(async (resolve, reject) => {
|
||
if (current.isOnline()) {
|
||
current.send(send, current, player);
|
||
current.wait((result, player) => {
|
||
solve(result, player);
|
||
resolve();
|
||
});
|
||
} else if (current == game.me) {
|
||
const next = lib.skill.jsrgzhuni.chooseTarget(current, player);
|
||
const solver = (result, player) => {
|
||
solve(result, player);
|
||
resolve();
|
||
};
|
||
if (_status.connectMode) game.me.wait(solver);
|
||
const result = await next.forResult();
|
||
if (_status.connectMode) game.me.unwait(result, current);
|
||
else solver(result, current);
|
||
}
|
||
});
|
||
})
|
||
);
|
||
}
|
||
if (locals.length) {
|
||
for (let current of locals) {
|
||
const next = lib.skill.jsrgzhuni.chooseTarget(current, player);
|
||
const result = await next.forResult();
|
||
solve(result, current);
|
||
}
|
||
}
|
||
//清除读条
|
||
delete event._global_waiting;
|
||
for (var i of targets) i.hideTimer();
|
||
//统计票数
|
||
const ticketsMap = new Map();
|
||
results.forEach(data => {
|
||
const [source, current] = data;
|
||
source.line(current);
|
||
game.log(source, forceTargets.includes(source) ? "自愿选择" : "选择了", current, "作为讨伐目标");
|
||
ticketsMap.set(current, (ticketsMap.get(current) || 0) + 1);
|
||
});
|
||
console.log(ticketsMap);
|
||
let maxTicket = 0;
|
||
const target = ticketsMap.entries().reduce((target, data) => {
|
||
console.log(data);
|
||
const [current, ticket] = data;
|
||
if (ticket > maxTicket) {
|
||
maxTicket = ticket;
|
||
return current;
|
||
} else if (ticket === maxTicket) return false;
|
||
else return target;
|
||
}, false);
|
||
//上Buff
|
||
if (target) {
|
||
game.log(target, "成为了", "#g【执盟】", "的讨伐目标");
|
||
player.addTempSkill("jsrgzhuni_effect");
|
||
player.markAuto("jsrgzhuni_effect", [target]);
|
||
}
|
||
},
|
||
ai: {
|
||
order: 10,
|
||
result: { player: 1 },
|
||
threaten: 1.8,
|
||
},
|
||
chooseTarget(player, source) {
|
||
const next = player.chooseTarget(`${get.translation(source)}发动了【执盟】,请选择一名讨伐目标`, (card, player, target) => target !== source, true);
|
||
next.set("ai", target => -get.attitude(get.player(), target));
|
||
next.set("animate", false);
|
||
next.set("_global_waiting", true);
|
||
return next;
|
||
},
|
||
subSkill: {
|
||
effect: {
|
||
onremove: true,
|
||
mod: {
|
||
targetInRange(card, player, target) {
|
||
if (player.getStorage("jsrgzhuni_effect").includes(target)) {
|
||
return true;
|
||
}
|
||
},
|
||
cardUsableTarget(card, player, target) {
|
||
if (player.getStorage("jsrgzhuni_effect").includes(target)) {
|
||
return true;
|
||
}
|
||
},
|
||
},
|
||
charlotte: true,
|
||
intro: {
|
||
content: "对$使用牌无距离和次数限制",
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrghezhi: {
|
||
zhuSkill: true,
|
||
locked: true,
|
||
},
|
||
//江山如故·合
|
||
//蓄谋临时禁用
|
||
xumou_jsrg_temp: {
|
||
charlotte: true,
|
||
onremove: true,
|
||
mod: {
|
||
cardEnabled(card, player) {
|
||
if (!card.storage || !card.storage.xumou_jsrg) return;
|
||
if (player.getStorage("xumou_jsrg_temp").includes(get.name(card, false))) return false;
|
||
},
|
||
},
|
||
},
|
||
//404诸葛亮
|
||
jsrgwentian: {
|
||
audio: 2,
|
||
trigger: {
|
||
player: ["phaseZhunbeiBegin", "phaseJudgeBegin", "phaseDrawBegin", "phaseUseBegin", "phaseDiscardBegin", "phaseJieshuBegin"],
|
||
},
|
||
usable: 1,
|
||
prompt2: "观看牌堆顶的五张牌,将其中一张交给其他角色,并将其余牌置于牌堆顶或牌堆底",
|
||
group: "jsrgwentian_viewas",
|
||
async content(event, trigger, player) {
|
||
const cards = get.cards(5);
|
||
game.cardsGotoOrdering(cards);
|
||
const { result } = await player.chooseButton(["问天:将一张牌交给一名其他角色", cards], true);
|
||
if (result.bool) {
|
||
const { result: result2 } = await player.chooseTarget(`将${get.translation(result.links)}交给一名其他角色`, lib.filter.notMe, true).set("ai", target => {
|
||
return get.attitude(get.player(), target);
|
||
});
|
||
if (result2.bool) {
|
||
cards.removeArray(result.links);
|
||
const target = result2.targets[0];
|
||
player.line(target, "green");
|
||
await target.gain(result.links, "gain2").set("giver", player);
|
||
}
|
||
}
|
||
const next = player.chooseToMove();
|
||
next.set("list", [["牌堆顶", cards.filterInD()], ["牌堆底"]]);
|
||
next.set("prompt", "问天:点击将牌移动到牌堆顶或牌堆底");
|
||
next.processAI = list => {
|
||
const cards = list[0][1],
|
||
player = _status.event.player;
|
||
const top = [];
|
||
const judges = player.getCards("j");
|
||
let stopped = false;
|
||
if (!player.hasWuxie()) {
|
||
for (let i = 0; i < judges.length; i++) {
|
||
const judge = get.judge(judges[i]);
|
||
cards.sort((a, b) => judge(b) - judge(a));
|
||
if (judge(cards[0]) < 0) {
|
||
stopped = true;
|
||
break;
|
||
} else {
|
||
top.unshift(cards.shift());
|
||
}
|
||
}
|
||
}
|
||
let bottom;
|
||
if (!stopped) {
|
||
cards.sort((a, b) => get.value(b, player) - get.value(a, player));
|
||
while (cards.length) {
|
||
if (get.value(cards[0], player) <= 5) break;
|
||
top.unshift(cards.shift());
|
||
}
|
||
}
|
||
bottom = cards;
|
||
return [top, bottom];
|
||
};
|
||
const {
|
||
result: { moved },
|
||
} = await next;
|
||
const top = moved[0];
|
||
const bottom = moved[1];
|
||
top.reverse();
|
||
game.cardsGotoPile(top.concat(bottom), ["top_cards", top], (event, card) => {
|
||
if (event.top_cards.includes(card)) return ui.cardPile.firstChild;
|
||
return null;
|
||
});
|
||
player.popup(get.cnNumber(top.length) + "上" + get.cnNumber(bottom.length) + "下");
|
||
game.log(player, "将" + get.cnNumber(top.length) + "张牌置于牌堆顶");
|
||
game.asyncDelayx();
|
||
},
|
||
subSkill: {
|
||
viewas: {
|
||
audio: "jsrgwentian",
|
||
enable: "chooseToUse",
|
||
filter: function (event, player) {
|
||
for (const name of ["wuxie", "huogong"]) {
|
||
if (event.filterCard(get.autoViewAs({ name }, "unsure"), player, event)) return true;
|
||
}
|
||
return false;
|
||
},
|
||
hiddenCard: function (player, name) {
|
||
if (player.isTempBanned("jsrgwentian")) return false;
|
||
return name == "wuxie";
|
||
},
|
||
viewAs: function (cards, player) {
|
||
const event = get.event(),
|
||
filter = event._backup.filterCard;
|
||
for (const name of ["wuxie", "huogong"]) {
|
||
if (filter(get.autoViewAs({ name }, "unsure"), player, event)) return { name };
|
||
}
|
||
return null;
|
||
},
|
||
filterCard: () => false,
|
||
selectCard: -1,
|
||
prompt: function () {
|
||
const player = get.player();
|
||
const event = get.event(),
|
||
filter = event._backup.filterCard;
|
||
let str = "将牌堆顶的牌当【";
|
||
for (const name of ["wuxie", "huogong"]) {
|
||
if (filter({ name }, player, event)) {
|
||
str += get.translation(name);
|
||
break;
|
||
}
|
||
}
|
||
str += "】使用";
|
||
return str;
|
||
},
|
||
precontent() {
|
||
player.logSkill("jsrgwentian");
|
||
const cards = get.cards();
|
||
event.result.cards = cards;
|
||
delete event.result.skill;
|
||
game.cardsGotoOrdering(cards);
|
||
const color = event.result.card.name == "wuxie" ? "black" : "red";
|
||
if (get.color(cards, false) != color) {
|
||
player.tempBanSkill("jsrgwentian", "roundStart");
|
||
}
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgchushi: {
|
||
available(mode) {
|
||
return mode == "identity" || (mode == "versus" && (_status.mode == "four" || _status.mode == "guandu"));
|
||
},
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
filter(event, player) {
|
||
const zhu = get.zhu(player);
|
||
if (!zhu || !zhu.isZhu2() || !zhu.countCards("h")) return false;
|
||
return !player.isZhu2() && player.countCards("h");
|
||
},
|
||
async content(event, trigger, player) {
|
||
player
|
||
.chooseToDebate(
|
||
game.filterPlayer(current => {
|
||
return (current == player || current.isZhu2()) && current.countCards("h");
|
||
})
|
||
)
|
||
.set("callback", async event => {
|
||
const result = event.debateResult;
|
||
if (result.bool && result.opinion) {
|
||
const { opinion, targets } = result;
|
||
targets.sortBySeat();
|
||
if (opinion == "red") {
|
||
do {
|
||
for (const current of targets) {
|
||
await current.draw();
|
||
}
|
||
} while (
|
||
targets
|
||
.map(current => {
|
||
return current.countCards("h");
|
||
})
|
||
.reduce((p, c) => {
|
||
return p + c;
|
||
}, 0) < 7
|
||
);
|
||
} else {
|
||
player.addMark("jsrgchushi_add", 1, false);
|
||
player.addTempSkill("jsrgchushi_add", "roundStart");
|
||
}
|
||
}
|
||
});
|
||
},
|
||
subSkill: {
|
||
add: {
|
||
audio: "jsrgchushi",
|
||
trigger: { source: "damageBegin1" },
|
||
filter: function (event) {
|
||
return event.hasNature("linked");
|
||
},
|
||
forced: true,
|
||
charlotte: true,
|
||
onremove: true,
|
||
async content(_, trigger, player) {
|
||
trigger.num += player.countMark("jsrgchushi_add");
|
||
},
|
||
ai: {
|
||
damageBonus: true,
|
||
skillTagFilter: function (player, tag, arg) {
|
||
if (tag === "damageBonus") return arg && arg.card && game.hasNature(arg.card, "linked");
|
||
},
|
||
},
|
||
intro: {
|
||
content: "造成的属性伤害+#",
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgyinlve: {
|
||
audio: 2,
|
||
trigger: {
|
||
global: "damageBegin4",
|
||
},
|
||
filter: function (event, player) {
|
||
return event.player.isIn() && ["fire", "thunder"].some(n => !player.hasSkill(`jsrgyinlve_${n}`) && event.hasNature(n));
|
||
},
|
||
check: function (event, player) {
|
||
if (get.damageEffect(event.player, event.source, player, get.natureList(event.nature)) < -5) return true;
|
||
return false;
|
||
},
|
||
logTarget: "player",
|
||
async content(event, trigger, player) {
|
||
trigger.cancel();
|
||
const natures = ["fire", "thunder"];
|
||
let index;
|
||
if (natures.every(n => !player.hasSkill(`jsrgyinlve_${n}`) && trigger.hasNature(n))) {
|
||
const { result } = await player.chooseControl(["摸牌阶段", "弃牌阶段"]).set("prompt", "请选择要新回合内仅有的阶段");
|
||
index = result.index;
|
||
} else index = [0, 1].find(i => !player.hasSkill(`jsrgyinlve_${natures[i]}`) && trigger.hasNature(natures[i]));
|
||
player.addTempSkill(`jsrgyinlve_${natures[index]}`, "roundStart");
|
||
player.insertPhase().set("phaseList", [["phaseDraw", "phaseDiscard"][index]]);
|
||
},
|
||
subSkill: {
|
||
fire: { charlotte: true },
|
||
thunder: { charlotte: true },
|
||
},
|
||
},
|
||
//姜维
|
||
jsrgjinfa: {
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
filterCard: true,
|
||
position: "h",
|
||
discard: false,
|
||
lose: false,
|
||
delay: false,
|
||
check: function () {
|
||
return 1 + Math.random();
|
||
},
|
||
async content(event, trigger, player) {
|
||
await player.showCards(event.cards);
|
||
player
|
||
.chooseToDebate(
|
||
game.filterPlayer(current => {
|
||
return current.maxHp <= player.maxHp;
|
||
})
|
||
)
|
||
.set("callback", async event => {
|
||
const result = event.debateResult;
|
||
if (result.bool && result.opinion) {
|
||
const { cards: fixedCards } = event.getParent("jsrgjinfa");
|
||
const color = get.color(fixedCards);
|
||
const { opinion, targets } = result;
|
||
if (opinion == color) {
|
||
const { result } = await player
|
||
.chooseTarget("是否令至多两名参与议事的角色将手牌摸至体力上限?", [1, 2], (card, player, target) => {
|
||
return get.event("targets").includes(target);
|
||
})
|
||
.set("targets", targets)
|
||
.set("ai", target => {
|
||
const player = get.player();
|
||
const att = get.attitude(player, target);
|
||
if (att <= 0) return -1;
|
||
return att * Math.sqrt(Math.max(0.1, target.maxHp - target.countCards("h")));
|
||
});
|
||
if (result.bool) {
|
||
const targets = result.targets;
|
||
targets.sortBySeat();
|
||
player.line(targets, "green");
|
||
for (const current of targets) {
|
||
if (current.countCards("h") < current.maxHp) await current.drawTo(current.maxHp);
|
||
}
|
||
}
|
||
} else {
|
||
await player.gain(lib.card.ying.getYing(2), "gain2");
|
||
}
|
||
}
|
||
const { red, black } = result;
|
||
if ((red.length == 1 && red[0][0] == player) || (black.length == 1 && black[0][0] == player)) {
|
||
const list = lib.group.slice();
|
||
list.remove(player.group);
|
||
list.push("cancel2");
|
||
const {
|
||
result: { control },
|
||
} = await player
|
||
.chooseControl(list)
|
||
.set("prompt", "是否变更势力?")
|
||
.set("ai", () => {
|
||
if (!get.event("change")) return "cancel2";
|
||
const controls = get.event("controls");
|
||
const groups = ["wei", "shu"].filter(g => controls.includes(g));
|
||
if (groups.length) return groups.randomGet();
|
||
return controls.randomGet();
|
||
})
|
||
.set("change", ["wei", "shu"].includes(player.group) ? Math.random() < 0.5 : true);
|
||
if (control != "cancel2") {
|
||
player.popup(control + "2", get.groupnature(control, "raw"));
|
||
player.changeGroup(control);
|
||
}
|
||
}
|
||
});
|
||
},
|
||
ai: {
|
||
order: function (item, player) {
|
||
if (player.countCards("h") == 1) return 10;
|
||
return 1;
|
||
},
|
||
result: {
|
||
player: 1,
|
||
},
|
||
},
|
||
},
|
||
jsrgfumou: {
|
||
audio: 2,
|
||
trigger: { global: "chooseToDebateAfter" },
|
||
groupSkill: true,
|
||
forced: true,
|
||
locked: false,
|
||
filter: function (event, player) {
|
||
if (player.group != "wei") return false;
|
||
if (!event.targets.includes(player)) return false;
|
||
if (event.red.some(i => i[0] == player)) return event.black.length;
|
||
if (event.black.some(i => i[0] == player)) return event.red.length;
|
||
return false;
|
||
},
|
||
async content(event, trigger, player) {
|
||
const targets = [];
|
||
if (trigger.red.some(i => i[0] == player)) targets.addArray(trigger.black.map(i => i[0]));
|
||
if (trigger.black.some(i => i[0] == player)) targets.addArray(trigger.red.map(i => i[0]));
|
||
player.line(targets, "thunder");
|
||
targets.forEach(target => {
|
||
target.addTempSkill("jsrgfumou_forbid");
|
||
target.markAuto(
|
||
"jsrgfumou_forbid",
|
||
["red", "black"].filter(color => {
|
||
return trigger[color].some(i => i[0] == target);
|
||
})
|
||
);
|
||
});
|
||
game.broadcastAll(targets => {
|
||
lib.skill.jsrgfumou_backup.targets = targets;
|
||
}, targets);
|
||
const next = player.chooseToUse();
|
||
next.set("openskilldialog", `是否将一张【影】当【出其不意】对一名与你意见不同的角色使用?`);
|
||
next.set("norestore", true);
|
||
next.set("_backupevent", "jsrgfumou_backup");
|
||
next.set("custom", {
|
||
add: {},
|
||
replace: { window: function () {} },
|
||
});
|
||
next.backup("jsrgfumou_backup");
|
||
},
|
||
subSkill: {
|
||
backup: {
|
||
filterCard: function (card) {
|
||
return get.itemtype(card) == "card" && get.name(card) == "ying";
|
||
},
|
||
viewAs: {
|
||
name: "chuqibuyi",
|
||
},
|
||
selectCard: 1,
|
||
position: "hs",
|
||
log: false,
|
||
filterTarget: function (card, player, target) {
|
||
const targets = lib.skill.jsrgfumou_backup.targets;
|
||
if (!targets.includes(target) || ui.selected.targets.containsSome(targets)) return false;
|
||
return lib.filter.targetEnabled.apply(this, arguments);
|
||
},
|
||
ai1: function (card) {
|
||
return 6 - get.value(card);
|
||
},
|
||
precontent: function () {
|
||
delete event.result.skill;
|
||
},
|
||
},
|
||
forbid: {
|
||
charlotte: true,
|
||
onremove: true,
|
||
mod: {
|
||
cardEnabled: function (card, player) {
|
||
const color = get.color(card);
|
||
if (color != "unsure" && player.getStorage("jsrgfumou_forbid").includes(color)) return false;
|
||
},
|
||
cardRespondable: function (card, player) {
|
||
const color = get.color(card);
|
||
if (color != "unsure" && player.getStorage("jsrgfumou_forbid").includes(color)) return false;
|
||
},
|
||
cardSavable: function (card, player) {
|
||
const color = get.color(card);
|
||
if (color != "unsure" && player.getStorage("jsrgfumou_forbid").includes(color)) return false;
|
||
},
|
||
},
|
||
mark: true,
|
||
intro: {
|
||
content: "本回合不能使用或打出$牌",
|
||
},
|
||
},
|
||
},
|
||
ai: {
|
||
combo: "jsrgjinfa"
|
||
},
|
||
},
|
||
jsrgxuanfeng: {
|
||
audio: 2,
|
||
enable: "chooseToUse",
|
||
filterCard: { name: "ying" },
|
||
position: "hs",
|
||
groupSkill: true,
|
||
locked: false,
|
||
viewAs: {
|
||
name: "sha",
|
||
nature: "stab",
|
||
storage: { jsrgxuanfeng: true },
|
||
},
|
||
viewAsFilter(player) {
|
||
if (player.group != "shu") return false;
|
||
if (!player.countCards("hs", "ying")) return false;
|
||
},
|
||
prompt: "将一张【影】当无距离和次数限制的刺【杀】使用",
|
||
check(card) {
|
||
const val = get.value(card);
|
||
return 5 - val;
|
||
},
|
||
mod: {
|
||
targetInRange: function (card, player, target) {
|
||
if (card.storage && card.storage.jsrgxuanfeng) return true;
|
||
},
|
||
cardUsable: function (card) {
|
||
if (card.storage && card.storage.jsrgxuanfeng) return Infinity;
|
||
},
|
||
},
|
||
ai: {
|
||
order: 2,
|
||
combo: "jsrgjinfa"
|
||
},
|
||
},
|
||
//陆逊
|
||
jsrgyoujin: {
|
||
audio: 2,
|
||
trigger: { player: "phaseUseBegin" },
|
||
filter(event, player) {
|
||
return game.hasPlayer(current => {
|
||
return player.canCompare(current);
|
||
});
|
||
},
|
||
direct: true,
|
||
async content(event, trigger, player) {
|
||
const { result } = await player
|
||
.chooseTarget(get.prompt2("jsrgyoujin"), (card, player, target) => {
|
||
return player.canCompare(target);
|
||
})
|
||
.set("ai", target => {
|
||
if (!get.event("goon")) return 0;
|
||
return -get.attitude(get.player(), target);
|
||
})
|
||
.set("goon", player.countCards("hs", ["shan", "caochuan"]) || player.getHp() >= 3);
|
||
if (!result.bool) return;
|
||
const { targets } = result,
|
||
target = targets[0];
|
||
player.logSkill("jsrgyoujin", target);
|
||
const { result: result2 } = await player.chooseToCompare(target).set("small", true);
|
||
player.addTempSkill("jsrgyoujin_forbid");
|
||
player.markAuto("jsrgyoujin_forbid", [result2.num1]);
|
||
target.addTempSkill("jsrgyoujin_forbid");
|
||
target.markAuto("jsrgyoujin_forbid", [result2.num2]);
|
||
if (!result2.tie) {
|
||
const targets = [target, player];
|
||
if (result2.bool) targets.reverse();
|
||
const sha = new lib.element.VCard({ name: "sha" });
|
||
if (targets[0].canUse(sha, targets[1], false)) {
|
||
targets[0].useCard(sha, targets[1], false);
|
||
}
|
||
}
|
||
},
|
||
subSkill: {
|
||
forbid: {
|
||
charlotte: true,
|
||
onremove: true,
|
||
mod: {
|
||
cardEnabled2: function (card, player) {
|
||
if (get.itemtype(card) == "card" && player.getStorage("jsrgyoujin_forbid").some(num => num > get.number(card))) return false;
|
||
},
|
||
},
|
||
mark: true,
|
||
intro: {
|
||
content: "本回合不能使用或打出点数小于$的手牌",
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgdailao: {
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
filter(event, player) {
|
||
return !player.hasCard(card => {
|
||
return player.hasUseTarget(card, true, true);
|
||
});
|
||
},
|
||
async content(event, trigger, player) {
|
||
await player.showHandcards();
|
||
await player.draw(2);
|
||
const evt = event.getParent("phase");
|
||
if (evt) {
|
||
game.resetSkills();
|
||
_status.event = evt;
|
||
_status.event.finish();
|
||
_status.event.untrigger(true);
|
||
}
|
||
},
|
||
ai: {
|
||
order: 0.0001,
|
||
result: { player: 1 },
|
||
},
|
||
},
|
||
jsrgzhubei: {
|
||
audio: 2,
|
||
trigger: { source: "damageBegin1" },
|
||
forced: true,
|
||
init(player) {
|
||
player.addSkill("jsrgzhubei_record");
|
||
},
|
||
filter(event, player) {
|
||
return event.player.hasHistory("damage", evt => {
|
||
return evt.source == player;
|
||
});
|
||
},
|
||
logTarget: "player",
|
||
async content(event, trigger, player) {
|
||
trigger.num++;
|
||
},
|
||
subSkill: {
|
||
record: {
|
||
trigger: {
|
||
global: ["loseAfter", "equipAfter", "addJudgeAfter", "gainAfter", "loseAsyncAfter", "addToExpansionAfter"],
|
||
},
|
||
charlotte: true,
|
||
silent: true,
|
||
filter(event, player) {
|
||
return game.hasPlayer(current => {
|
||
if (current.countCards("h")) return false;
|
||
const evt = event.getl(current);
|
||
return evt && evt.hs && evt.hs.length;
|
||
});
|
||
},
|
||
async content(event, trigger, player) {
|
||
game.countPlayer(current => {
|
||
if (current.countCards("h")) return false;
|
||
const evt = trigger.getl(current);
|
||
if (evt && evt.hs && evt.hs.length) current.addTempSkill("jsrgzhubei_lost");
|
||
});
|
||
},
|
||
},
|
||
lost: { charlotte: true },
|
||
},
|
||
mod: {
|
||
cardUsableTarget(card, player, target) {
|
||
if (target.hasSkill("jsrgzhubei_lost")) return true;
|
||
},
|
||
},
|
||
},
|
||
//赵云
|
||
jsrglonglin: {
|
||
audio: 2,
|
||
trigger: {
|
||
global: "useCardToPlayered",
|
||
},
|
||
usable: 1,
|
||
filter(event, player) {
|
||
if (event.player == player) return false;
|
||
if (event.card.name != "sha") return false;
|
||
return event.isFirstTarget && event.player.isPhaseUsing();
|
||
},
|
||
direct: true,
|
||
async content(event, trigger, player) {
|
||
const juedou = new lib.element.VCard({ name: "juedou", storage: { jsrglonglin: true } });
|
||
const { result } = await player
|
||
.chooseToDiscard(get.prompt2("jsrglonglin"), "he")
|
||
.set("ai", card => {
|
||
if (get.event("goon")) return 5 - get.value(card);
|
||
return 0;
|
||
})
|
||
.set(
|
||
"goon",
|
||
(trigger.player.canUse(juedou, player) ? Math.max(0, get.effect(player, juedou, trigger.player, trigger.player)) : 0) +
|
||
trigger.targets
|
||
.map(target => {
|
||
return get.effect(target, trigger.card, trigger.player, player);
|
||
})
|
||
.reduce((p, c) => {
|
||
return p + c;
|
||
}, 0) <
|
||
-4
|
||
)
|
||
.set("logSkill", ["jsrglonglin", trigger.player]);
|
||
if (result.bool) {
|
||
trigger.excluded.addArray(trigger.targets);
|
||
game.asyncDelayx();
|
||
if (trigger.player.canUse(juedou, player)) {
|
||
const { result } = await trigger.player.chooseBool(`是否视为对${get.translation(player)}使用一张【决斗】?`).set("choice", get.effect(player, juedou, trigger.player, trigger.player) >= 0);
|
||
if (result.bool) {
|
||
player.addTempSkill("jsrglonglin_source");
|
||
trigger.player.useCard(juedou, player);
|
||
}
|
||
}
|
||
}
|
||
},
|
||
subSkill: {
|
||
source: {
|
||
trigger: { source: "damageSource" },
|
||
charlotte: true,
|
||
forced: true,
|
||
popup: false,
|
||
filter(event, player) {
|
||
return event.card && event.card.storage && event.card.storage.jsrglonglin;
|
||
},
|
||
async content(event, trigger, player) {
|
||
player.line(trigger.player);
|
||
trigger.player.addTempSkill("jsrglonglin_forbid", "phaseUseAfter");
|
||
},
|
||
},
|
||
forbid: {
|
||
mod: {
|
||
cardEnabled: function (card, player) {
|
||
if (!card.cards) return;
|
||
if (card.cards.some(cardx => get.position(cardx) == "h")) return false;
|
||
},
|
||
cardSavable: function (card, player) {
|
||
if (!card.cards) return;
|
||
if (card.cards.some(cardx => get.position(cardx) == "h")) return false;
|
||
},
|
||
},
|
||
charlotte: true,
|
||
mark: true,
|
||
intro: {
|
||
content: "不能使用手牌",
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgzhendan: {
|
||
audio: 2,
|
||
trigger: {
|
||
player: "damageEnd",
|
||
global: "roundStart",
|
||
},
|
||
filter(event, player) {
|
||
let count = 0;
|
||
let roundCount = 1 + (event.name != "damage");
|
||
const curLen = player.actionHistory.length;
|
||
for (let i = curLen - 1; i >= 0; i--) {
|
||
if (
|
||
roundCount == 1 &&
|
||
game.hasPlayer(current => {
|
||
const history = current.actionHistory[i];
|
||
if (!history.isMe || history.isSkipped) return false;
|
||
return true;
|
||
})
|
||
) {
|
||
count++;
|
||
}
|
||
if (player.actionHistory[i].isRound) roundCount--;
|
||
if (roundCount <= 0) break;
|
||
}
|
||
if (!player.storage.jsrgzhendan_mark && count > 0) return true;
|
||
return false;
|
||
},
|
||
forced: true,
|
||
locked: false,
|
||
group: "jsrgzhendan_viewas",
|
||
async content(event, trigger, player) {
|
||
let count = 0;
|
||
let roundCount = 1 + (trigger.name != "damage");
|
||
const curLen = player.actionHistory.length;
|
||
for (let i = curLen - 1; i >= 0; i--) {
|
||
if (
|
||
roundCount == 1 &&
|
||
game.hasPlayer(current => {
|
||
const history = current.actionHistory[i];
|
||
if (!history.isMe || history.isSkipped) return false;
|
||
return true;
|
||
})
|
||
) {
|
||
count++;
|
||
}
|
||
if (player.actionHistory[i].isRound) roundCount--;
|
||
if (roundCount <= 0) break;
|
||
}
|
||
count = Math.min(5, count);
|
||
await player.draw(count);
|
||
if (trigger.name == "damage") {
|
||
player.tempBanSkill("jsrgzhendan", "roundStart");
|
||
player.storage.jsrgzhendan_mark = true;
|
||
player
|
||
.when({ global: "roundStart" })
|
||
.assign({
|
||
lastDo: true,
|
||
})
|
||
.then(() => {
|
||
delete player.storage.jsrgzhendan_mark;
|
||
});
|
||
}
|
||
},
|
||
subSkill: {
|
||
viewas: {
|
||
audio: "jsrgzhendan",
|
||
enable: ["chooseToUse", "chooseToRespond"],
|
||
filter(event, player) {
|
||
if (event.type == "wuxie") return false;
|
||
if (
|
||
!_status.connectMode &&
|
||
!player.countCards("hs", card => {
|
||
return get.type2(card) != "basic";
|
||
})
|
||
)
|
||
return false;
|
||
return get.inpileVCardList(info => {
|
||
if (info[0] != "basic") return false;
|
||
return event.filterCard(get.autoViewAs({ name: info[2], nature: info[3] }, "unsure"), player, event);
|
||
}).length;
|
||
},
|
||
chooseButton: {
|
||
dialog(event, player) {
|
||
const vcards = get.inpileVCardList(info => {
|
||
if (info[0] != "basic") return false;
|
||
return event.filterCard(get.autoViewAs({ name: info[2], nature: info[3] }, "unsure"), player, event);
|
||
});
|
||
return ui.create.dialog("镇胆", [vcards, "vcard"]);
|
||
},
|
||
check(button) {
|
||
if (get.event().getParent().type != "phase") return 1;
|
||
return get.player().getUseValue({ name: button.link[2], nature: button.link[3] });
|
||
},
|
||
backup(links, player) {
|
||
return {
|
||
audio: "jsrgzhendan",
|
||
popname: true,
|
||
viewAs: { name: links[0][2], nature: links[0][3] },
|
||
filterCard(card, player) {
|
||
return get.type2(card) != "basic";
|
||
},
|
||
selectCard: 1,
|
||
position: "hs",
|
||
};
|
||
},
|
||
prompt(links, player) {
|
||
return "将一张非基本手牌当" + (get.translation(links[0][3]) || "") + get.translation(links[0][2]) + "使用或打出";
|
||
},
|
||
},
|
||
hiddenCard(player, name) {
|
||
return get.type(name) == "basic" && player.countCards("hs") > 0;
|
||
},
|
||
ai: {
|
||
respondSha: true,
|
||
respondShan: true,
|
||
skillTagFilter(player) {
|
||
return player.countCards("hs") > 0;
|
||
},
|
||
order: 0.5,
|
||
result: {
|
||
player(player) {
|
||
if (get.event().dying) {
|
||
return get.attitude(player, get.event().dying);
|
||
}
|
||
return 1;
|
||
},
|
||
},
|
||
},
|
||
},
|
||
viewas_backup: {},
|
||
},
|
||
},
|
||
//司马懿
|
||
jsrgyingshi: {
|
||
audio: 2,
|
||
trigger: { player: "turnOverAfter" },
|
||
async content(event, trigger, player) {
|
||
const number = game.dead.length > 2 ? 5 : 3;
|
||
const cards = get.bottomCards(number);
|
||
game.cardsGotoOrdering(cards);
|
||
const next = player.chooseToMove();
|
||
next.set("list", [["牌堆顶"], ["牌堆底", cards.reverse()]]);
|
||
next.set("prompt", "鹰眎:点击将牌移动到牌堆顶或牌堆底");
|
||
next.processAI = list => {
|
||
const cards = list[1][1],
|
||
player = _status.event.player;
|
||
const top = [];
|
||
const judges = player.getCards("j");
|
||
let stopped = false;
|
||
if (!player.hasWuxie()) {
|
||
for (let i = 0; i < judges.length; i++) {
|
||
const judge = get.judge(judges[i]);
|
||
cards.sort((a, b) => judge(b) - judge(a));
|
||
if (judge(cards[0]) < 0) {
|
||
stopped = true;
|
||
break;
|
||
} else {
|
||
top.unshift(cards.shift());
|
||
}
|
||
}
|
||
}
|
||
let bottom;
|
||
if (!stopped) {
|
||
cards.sort((a, b) => get.value(b, player) - get.value(a, player));
|
||
while (cards.length) {
|
||
if (get.value(cards[0], player) <= 5) break;
|
||
top.unshift(cards.shift());
|
||
}
|
||
}
|
||
bottom = cards;
|
||
return [top, bottom];
|
||
};
|
||
const {
|
||
result: { moved },
|
||
} = await next;
|
||
const top = moved[0];
|
||
const bottom = moved[1];
|
||
top.reverse();
|
||
game.cardsGotoPile(top.concat(bottom), ["top_cards", top], (event, card) => {
|
||
if (event.top_cards.includes(card)) return ui.cardPile.firstChild;
|
||
return null;
|
||
});
|
||
player.popup(get.cnNumber(top.length) + "上" + get.cnNumber(bottom.length) + "下");
|
||
game.log(player, "将" + get.cnNumber(top.length) + "张牌置于牌堆顶");
|
||
game.asyncDelayx();
|
||
},
|
||
},
|
||
jsrgtuigu: {
|
||
audio: 2,
|
||
trigger: { player: "phaseBegin" },
|
||
prompt2(event, player) {
|
||
const num = Math.floor(game.countPlayer() / 2);
|
||
return `你翻面,令你本回合的手牌上限+${num},摸${get.cnNumber(num)}张牌,视为使用一张【解甲归田】(目标角色不能使用这些牌直到其下回合结束)。`;
|
||
},
|
||
group: ["jsrgtuigu_insert", "jsrgtuigu_recover"],
|
||
async content(event, trigger, player) {
|
||
await player.turnOver();
|
||
const num = Math.floor(game.countPlayer() / 2);
|
||
player.addTempSkill("jsrgtuigu_handcard");
|
||
player.addMark("jsrgtuigu_handcard", num, false);
|
||
await player.draw(num);
|
||
const jiejia = new lib.element.VCard({ name: "jiejia", storage: { jsrgtuigu: true } });
|
||
if (player.hasUseTarget(jiejia)) {
|
||
player.addTempSkill("jsrgtuigu_block");
|
||
player.chooseUseTarget(jiejia, true);
|
||
}
|
||
},
|
||
subSkill: {
|
||
insert: {
|
||
audio: "jsrgtuigu",
|
||
trigger: { global: "roundStart" },
|
||
filter(event, player) {
|
||
const curLen = player.actionHistory.length;
|
||
if (curLen <= 2) return false;
|
||
for (let i = curLen - 2; i >= 0; i--) {
|
||
const history = player.actionHistory[i];
|
||
if (history.isMe && !history.isSkipped && !history._jsrgtuigu) return false;
|
||
if (history.isRound) break;
|
||
}
|
||
return true;
|
||
},
|
||
forced: true,
|
||
locked: false,
|
||
async content(event, trigger, player) {
|
||
const evt = trigger,
|
||
evtx = player.insertPhase();
|
||
player
|
||
.when("phaseBeforeStart")
|
||
.filter(evtt => evtt == evtx)
|
||
.then(() => {
|
||
game.players
|
||
.slice()
|
||
.concat(game.dead)
|
||
.forEach(current => {
|
||
current.getHistory()._jsrgtuigu = true;
|
||
current.getStat()._jsrgtuigu = true;
|
||
});
|
||
});
|
||
if (evt.player != player && !evt._finished) {
|
||
evt.finish();
|
||
evt._triggered = 5;
|
||
const evtxx = evt.player.insertPhase();
|
||
delete evtxx.skill;
|
||
}
|
||
},
|
||
},
|
||
recover: {
|
||
audio: "jsrgtuigu",
|
||
trigger: {
|
||
player: "loseAfter",
|
||
global: ["gainAfter", "equipAfter", "addJudgeAfter", "loseAsyncAfter", "addToExpansionAfter"],
|
||
},
|
||
filter(event, player) {
|
||
if (player.isHealthy()) return false;
|
||
const evt = event.getl(player);
|
||
return evt && evt.es && evt.es.length > 0;
|
||
},
|
||
forced: true,
|
||
locked: false,
|
||
async content(event, trigger, player) {
|
||
player.recover();
|
||
},
|
||
},
|
||
handcard: {
|
||
markimage: "image/card/handcard.png",
|
||
intro: {
|
||
content(storage, player) {
|
||
return "手牌上限+" + storage;
|
||
},
|
||
},
|
||
onremove: true,
|
||
charlotte: true,
|
||
mod: {
|
||
maxHandcard(player, num) {
|
||
return num + player.countMark("jsrgtuigu_handcard");
|
||
},
|
||
},
|
||
},
|
||
block: {
|
||
trigger: { global: "gainAfter" },
|
||
filter(event, player) {
|
||
if (event.getParent().name != "jiejia") return false;
|
||
const card = event.getParent(2).card;
|
||
if (card && card.storage && card.storage.jsrgtuigu) return true;
|
||
return false;
|
||
},
|
||
charlotte: true,
|
||
forced: true,
|
||
silent: true,
|
||
content() {
|
||
trigger.player.addGaintag(trigger.cards, "jsrgtuigu");
|
||
trigger.player.addTempSkill("jsrgtuigu_blocked", { player: "phaseAfter" });
|
||
},
|
||
},
|
||
blocked: {
|
||
mod: {
|
||
cardEnabled2(card) {
|
||
if (get.itemtype(card) == "card" && card.hasGaintag("jsrgtuigu")) return false;
|
||
},
|
||
},
|
||
charlotte: true,
|
||
forced: true,
|
||
popup: false,
|
||
onremove(player) {
|
||
player.removeGaintag("jsrgtuigu");
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//郭循
|
||
jsrgeqian: {
|
||
audio: 2,
|
||
trigger: { player: "useCardToPlayered" },
|
||
filter(event, player) {
|
||
if (!event.isFirstTarget || event.targets.length != 1 || event.target == player) return false;
|
||
if (event.card.name == "sha") return true;
|
||
return event.getParent(3).name == "xumou_jsrg";
|
||
},
|
||
prompt2(event, player) {
|
||
return `令${get.translation(event.card)}不计入次数限制,且你获得${get.translation(event.target)}一张牌,然后其可以令你本回合至其的距离+2`;
|
||
},
|
||
group: "jsrgeqian_prepare",
|
||
logTarget: "target",
|
||
async content(event, trigger, player) {
|
||
if (trigger.addCount !== false) {
|
||
trigger.addCount = false;
|
||
var stat = player.getStat().card,
|
||
name = trigger.card.name;
|
||
if (typeof stat[name] == "number") stat[name]--;
|
||
}
|
||
await player.gainPlayerCard(trigger.target, "he", true);
|
||
const {
|
||
result: { bool },
|
||
} = await trigger.target.chooseBool(`是否令${get.translation(player)}至你的距离于本回合内+2?`).set("ai", () => true);
|
||
if (bool) {
|
||
player.addTempSkill("jsrgeqian_distance");
|
||
if (!player.storage.jsrgeqian_distance) player.storage.jsrgeqian_distance = {};
|
||
const id = trigger.target.playerid;
|
||
if (typeof player.storage.jsrgeqian_distance[id] != "number") player.storage.jsrgeqian_distance[id] = 0;
|
||
player.storage.jsrgeqian_distance[id] += 2;
|
||
player.markSkill("jsrgeqian_distance");
|
||
}
|
||
},
|
||
subSkill: {
|
||
prepare: {
|
||
audio: "jsrgeqian",
|
||
trigger: { player: "phaseJieshuBegin" },
|
||
filter(event, player) {
|
||
return player.countCards("h") && !player.isDisabledJudge();
|
||
},
|
||
direct: true,
|
||
async content(event, trigger, player) {
|
||
while (player.countCards("h") > 0) {
|
||
const {
|
||
result: { bool, cards },
|
||
} = await player.chooseCard(get.prompt("jsrgeqian"), "你可以蓄谋任意次").set("ai", card => {
|
||
const player = get.player();
|
||
if (player.hasValueTarget(card)) return player.getUseValue(card);
|
||
return 0;
|
||
});
|
||
if (!bool) break;
|
||
await player.addJudge({ name: "xumou_jsrg" }, cards);
|
||
}
|
||
},
|
||
},
|
||
distance: {
|
||
onremove: true,
|
||
charlotte: true,
|
||
mod: {
|
||
globalFrom(player, target, distance) {
|
||
if (!player.storage.jsrgeqian_distance) return;
|
||
const dis = player.storage.jsrgeqian_distance[target.playerid];
|
||
if (typeof dis == "number") return distance + dis;
|
||
},
|
||
},
|
||
intro: {
|
||
content(storage, player) {
|
||
if (!storage) return;
|
||
const map = _status.connectMode ? lib.playerOL : game.playerMap;
|
||
let str = `你本回合:`;
|
||
for (const id in storage) {
|
||
str += "<li>至" + get.translation(map[id]) + "的距离+" + storage[id];
|
||
}
|
||
return str;
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgfusha: {
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
limited: true,
|
||
skillAnimation: true,
|
||
animationColor: "fire",
|
||
filter(event, player) {
|
||
return (
|
||
game.countPlayer(current => {
|
||
return player.inRange(current);
|
||
}) == 1
|
||
);
|
||
},
|
||
filterTarget(card, player, target) {
|
||
return player.inRange(target);
|
||
},
|
||
selectTarget: -1,
|
||
async content(event, trigger, player) {
|
||
player.awakenSkill("jsrgfusha");
|
||
event.target.damage(Math.min(game.countPlayer(), player.getAttackRange()));
|
||
},
|
||
ai: {
|
||
order: 1,
|
||
result: {
|
||
target: -2,
|
||
},
|
||
},
|
||
},
|
||
//大小虎
|
||
jsrgdaimou: {
|
||
audio: 2,
|
||
trigger: {
|
||
global: "useCardToPlayer",
|
||
},
|
||
filter(event, player) {
|
||
if (event.card.name != "sha") return false;
|
||
if (event.target != player) return !player.hasSkill("jsrgdaimou_other") && !player.isDisabledJudge();
|
||
return (
|
||
!player.hasSkill("jsrgdaimou_me") &&
|
||
player.hasCard(card => {
|
||
return (card.viewAs || card.name) == "xumou_jsrg" && lib.filter.cardDiscardable(card, player, "jsrgdaimou");
|
||
}, "j")
|
||
);
|
||
},
|
||
direct: true,
|
||
async content(event, trigger, player) {
|
||
if (trigger.target == player) {
|
||
player.logSkill("jsrgdaimou");
|
||
player.addTempSkill("jsrgdaimou_me");
|
||
const {
|
||
result: { bool, links },
|
||
} = await player
|
||
.chooseButton(
|
||
[
|
||
"殆谋:请弃置区域里的一张蓄谋牌",
|
||
player.getCards("j", card => {
|
||
return (card.viewAs || card.name) == "xumou_jsrg";
|
||
}),
|
||
],
|
||
true
|
||
)
|
||
.set("filterButton", button => {
|
||
return lib.filter.cardDiscardable(button.link, get.player(), "jsrgdaimou");
|
||
})
|
||
.set("ai", button => {
|
||
const player = get.player();
|
||
return 1 / Math.max(0.01, player.getUseValue(button.link));
|
||
});
|
||
if (bool) {
|
||
player.discard(links);
|
||
}
|
||
} else {
|
||
const {
|
||
result: { bool },
|
||
} = await player.chooseBool(get.prompt("jsrgdaimou"), "你可以用牌堆顶的牌蓄谋").set("ai", () => true);
|
||
if (bool) {
|
||
player.logSkill("jsrgdaimou");
|
||
player.addTempSkill("jsrgdaimou_other");
|
||
player.addJudge({ name: "xumou_jsrg" }, get.cards());
|
||
}
|
||
}
|
||
},
|
||
subSkill: {
|
||
me: { charlotte: true },
|
||
other: { charlotte: true },
|
||
},
|
||
},
|
||
jsrgfangjie: {
|
||
audio: 2,
|
||
trigger: { player: "phaseZhunbeiBegin" },
|
||
direct: true,
|
||
async content(event, trigger, player) {
|
||
if (
|
||
!player.hasCard(card => {
|
||
return (card.viewAs || card.name) == "xumou_jsrg";
|
||
}, "j")
|
||
) {
|
||
player.logSkill("jsrgfangjie");
|
||
await player.recover();
|
||
await player.draw();
|
||
} else {
|
||
const {
|
||
result: { bool, links },
|
||
} = await player
|
||
.chooseButton(
|
||
[
|
||
"是否弃置区域里的任意张蓄谋牌并失去〖芳洁〗?",
|
||
player.getCards("j", card => {
|
||
return (card.viewAs || card.name) == "xumou_jsrg";
|
||
}),
|
||
],
|
||
[1, Infinity]
|
||
)
|
||
.set("filterButton", button => {
|
||
return lib.filter.cardDiscardable(button.link, get.player(), "jsrgdaimou");
|
||
})
|
||
.set("ai", () => 0);
|
||
if (bool) {
|
||
player.logSkill("jsrgfangjie");
|
||
await player.discard(links);
|
||
player.removeSkills("jsrgfangjie");
|
||
}
|
||
}
|
||
},
|
||
},
|
||
//曹芳
|
||
jsrgzhaotu: {
|
||
audio: 2,
|
||
enable: "chooseToUse",
|
||
viewAs: { name: "lebu" },
|
||
position: "hes",
|
||
round: 1,
|
||
viewAsFilter(player) {
|
||
return player.countCards("hes");
|
||
},
|
||
filterCard(card, player) {
|
||
return get.color(card) == "red" && get.type2(card) != "trick";
|
||
},
|
||
onuse(result, player) {
|
||
player.tempBanSkill("jsrgzhaotu", null, false);
|
||
result.targets[0].insertPhase();
|
||
result.targets[0].addTempSkill("jsrgzhaotu_handcard", { player: "phaseAfter" });
|
||
result.targets[0].addMark("jsrgzhaotu_handcard", 2, false);
|
||
},
|
||
subSkill: {
|
||
handcard: {
|
||
intro: {
|
||
content(storage, player) {
|
||
return "手牌上限-" + storage;
|
||
},
|
||
},
|
||
charlotte: true,
|
||
onremove: true,
|
||
mod: {
|
||
maxHandcard(player, num) {
|
||
return num - player.countMark("jsrgzhaotu_handcard");
|
||
},
|
||
},
|
||
},
|
||
},
|
||
ai: {
|
||
order: 5,
|
||
result: {
|
||
target(player, target) {
|
||
let dis = 0.5 - 0.75 * target.needsToDiscard(2, null, true);
|
||
if (dis > 0) return dis;
|
||
if (player.hasSkill("jsrgjingju") && player.hasZhuSkill("jsrgweizhui") && get.attitude(player, target) > 0)
|
||
return game.countPlayer(current => {
|
||
if (current === player || current === target || current.group !== "wei") return false;
|
||
return player.hasZhuSkill("jsrgweizhui", current) && get.attitude(player, current) > 0;
|
||
});
|
||
return dis;
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgjingju: {
|
||
audio: 2,
|
||
enable: "chooseToUse",
|
||
filter(event, player) {
|
||
if (event.type == "wuxie" || event.jsrgjingju) return false;
|
||
if (
|
||
!player.canMoveCard(
|
||
null,
|
||
false,
|
||
game.filterPlayer(i => i != player),
|
||
player,
|
||
card => {
|
||
return get.position(card) == "j";
|
||
}
|
||
)
|
||
)
|
||
return false;
|
||
return get.inpileVCardList(info => {
|
||
if (info[0] != "basic") return false;
|
||
return event.filterCard(get.autoViewAs({ name: info[2], nature: info[3] }, "unsure"), player, event);
|
||
}).length;
|
||
},
|
||
chooseButton: {
|
||
dialog: function (event, player) {
|
||
const vcards = get.inpileVCardList(info => {
|
||
if (info[0] != "basic") return false;
|
||
return event.filterCard(get.autoViewAs({ name: info[2], nature: info[3] }, "unsure"), player, event);
|
||
});
|
||
return ui.create.dialog("惊惧", [vcards, "vcard"], "hidden");
|
||
},
|
||
check: function (button) {
|
||
let player = _status.event.player;
|
||
if (get.event().getParent().type != "phase") return 1;
|
||
return (
|
||
get.player().getUseValue({ name: button.link[2], nature: button.link[3] }) +
|
||
game.countPlayer(current => {
|
||
if (current === player || current.group !== "wei") return false;
|
||
return player.hasZhuSkill("jsrgweizhui", current) && get.attitude(player, current) > 0;
|
||
})
|
||
);
|
||
},
|
||
backup: function (links, player) {
|
||
return {
|
||
filterCard: () => false,
|
||
viewAs: {
|
||
name: links[0][2],
|
||
nature: links[0][3],
|
||
isCard: true,
|
||
},
|
||
selectCard: -1,
|
||
precontent() {
|
||
"step 0";
|
||
player
|
||
.moveCard(
|
||
`惊惧:将其他角色判定区里的牌移动至你的判定区`,
|
||
game.filterPlayer(i => i != player),
|
||
player,
|
||
card => {
|
||
return get.position(card) == "j";
|
||
}
|
||
)
|
||
.set("logSkill", "jsrgjingju");
|
||
("step 1");
|
||
if (result.bool) {
|
||
delete event.result.skill;
|
||
} else {
|
||
event.getParent().jsrgjingju = true;
|
||
event.getParent().goto(0);
|
||
delete event.getParent().openskilldialog;
|
||
event.finish();
|
||
}
|
||
("step 2");
|
||
game.delayx();
|
||
},
|
||
};
|
||
},
|
||
prompt: function (links, player) {
|
||
return "选择" + get.translation(links[0][3] || "") + "【" + get.translation(links[0][2]) + "】的目标";
|
||
},
|
||
},
|
||
ai: {
|
||
order: function () {
|
||
const player = get.player(),
|
||
event = _status.event;
|
||
if (
|
||
player.canMoveCard(null, false, game.filterPlayer(), player, card => {
|
||
return get.position(card) == "j";
|
||
})
|
||
) {
|
||
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) {
|
||
return player.canMoveCard(null, false, game.filterPlayer(), player, card => {
|
||
return get.position(card) == "j";
|
||
});
|
||
},
|
||
result: {
|
||
player: function (player) {
|
||
if (get.event().type == "dying") {
|
||
return get.attitude(player, get.event().dying);
|
||
}
|
||
return 1;
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgweizhui: {
|
||
audio: 2,
|
||
trigger: { global: "phaseJieshuBegin" },
|
||
zhuSkill: true,
|
||
direct: true,
|
||
filter(event, player) {
|
||
return player != event.player && event.player.group == "wei" && event.player.isIn() && player.hasZhuSkill("jsrgweizhui", event.player);
|
||
},
|
||
async content(event, trigger, player) {
|
||
const {
|
||
result: { bool, cards },
|
||
} = await trigger.player
|
||
.chooseCard(`是否响应${get.translation(player)}的主公技【危坠】?`, "将一张黑色手牌当【过河拆桥】对其使用", (card, player) => {
|
||
if (get.color(card) != "black") return false;
|
||
return player.canUse(get.autoViewAs({ name: "guohe" }, [card]), get.event("target"));
|
||
})
|
||
.set("target", player)
|
||
.set("ai", card => {
|
||
if (get.effect(get.event("target"), get.autoViewAs({ name: "guohe" }, [card]), player) <= 0) return 0;
|
||
return 7 - get.value(card);
|
||
});
|
||
if (bool) {
|
||
trigger.player.logSkill("jsrgweizhui", player);
|
||
trigger.player.useCard(get.autoViewAs({ name: "guohe" }, cards), cards, player);
|
||
}
|
||
},
|
||
},
|
||
//孙峻
|
||
jsrgyaoyan: {
|
||
audio: 2,
|
||
trigger: { player: "phaseZhunbeiBegin" },
|
||
prompt: "是否发动【邀宴】?",
|
||
logTarget: () => game.filterPlayer(),
|
||
async content(event, trigger, player) {
|
||
const targets = game.filterPlayer();
|
||
const toDebateList = [];
|
||
while (targets.length) {
|
||
const current = targets.shift();
|
||
const {
|
||
result: { bool },
|
||
} = await current.chooseBool(`是否响应${get.translation(player)}的【邀宴】,于回合结束参与议事?`).set("ai", () => Math.random() < 0.5);
|
||
if (bool) {
|
||
toDebateList.add(current);
|
||
current.popup("同意", "wood");
|
||
game.log(current, "#g同意", "参加", player, "的议事");
|
||
} else {
|
||
current.popup("拒绝", "fire");
|
||
game.log(current, "#r拒绝", "参加", player, "的议事");
|
||
}
|
||
}
|
||
if (toDebateList.length) {
|
||
player.addTempSkill("jsrgyaoyan_hold");
|
||
player.markAuto("jsrgyaoyan_hold", toDebateList);
|
||
}
|
||
},
|
||
subSkill: {
|
||
hold: {
|
||
trigger: { player: "phaseEnd" },
|
||
charlotte: true,
|
||
forced: true,
|
||
popup: false,
|
||
onremove: true,
|
||
filter(event, player) {
|
||
return player.getStorage("jsrgyaoyan_hold").some(i => i.isIn());
|
||
},
|
||
async content(event, trigger, player) {
|
||
player.chooseToDebate(player.getStorage("jsrgyaoyan_hold").filter(i => i.isIn())).set("callback", async event => {
|
||
const { bool, opinion, targets } = event.debateResult;
|
||
if (bool && opinion) {
|
||
if (opinion == "red") {
|
||
const notDebated = game.filterPlayer().removeArray(targets);
|
||
if (notDebated.length) {
|
||
const { result } = await player
|
||
.chooseTarget("获得任意名未议事的角色的各一张手牌", [1, Infinity], true, (card, player, target) => {
|
||
return get.event("targets").includes(target) && target.countGainableCards(player, "h");
|
||
})
|
||
.set("targets", notDebated)
|
||
.set("ai", target => {
|
||
const player = get.player();
|
||
const att = get.attitude(player, target);
|
||
return -att;
|
||
});
|
||
if (result.bool) {
|
||
const targets = result.targets;
|
||
targets.sortBySeat();
|
||
player.line(targets, "green");
|
||
for (const current of targets) {
|
||
await player.gainPlayerCard(current, "h", true);
|
||
}
|
||
}
|
||
}
|
||
} else {
|
||
const {
|
||
result: { bool, targets: targets2 },
|
||
} = await player
|
||
.chooseTarget("是否对一名议事的角色造成2点伤害?", (card, player, target) => {
|
||
return get.event("targets").includes(target);
|
||
})
|
||
.set("targets", targets)
|
||
.set("ai", target => {
|
||
const player = get.player();
|
||
const eff = get.damageEffect(target, player, player);
|
||
return eff;
|
||
});
|
||
if (bool) {
|
||
player.line(targets2[0]);
|
||
targets2[0].damage(2);
|
||
}
|
||
}
|
||
}
|
||
});
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgbazheng: {
|
||
audio: 2,
|
||
trigger: { global: "debateShowOpinion" },
|
||
filter(event, player) {
|
||
if (!event.targets.includes(player)) return false;
|
||
const damagedPlayers = player
|
||
.getHistory("sourceDamage")
|
||
.map(evt => evt.player)
|
||
.toUniqued();
|
||
let dissent;
|
||
const colors = ["red", "black"];
|
||
for (const color of colors) {
|
||
if (event[color].some(i => i[0] == player)) {
|
||
dissent = colors.find(i => i != color);
|
||
break;
|
||
}
|
||
}
|
||
return event[dissent].some(i => damagedPlayers.includes(i[0]));
|
||
},
|
||
forced: true,
|
||
locked: false,
|
||
direct: true,
|
||
async content(event, trigger, player) {
|
||
let myOpinion, dissent;
|
||
const colors = ["red", "black"];
|
||
for (const color of colors) {
|
||
if (trigger[color].some(i => i[0] == player)) {
|
||
myOpinion = color;
|
||
dissent = colors.find(i => i != color);
|
||
break;
|
||
}
|
||
}
|
||
const damagedPlayers = player
|
||
.getHistory("sourceDamage")
|
||
.map(evt => evt.player)
|
||
.toUniqued();
|
||
let dissident = [];
|
||
for (let i = 0; i < trigger[dissent].length; i++) {
|
||
const pair = trigger[dissent][i];
|
||
if (damagedPlayers.includes(pair[0])) {
|
||
dissident.push(pair[0]);
|
||
trigger[myOpinion].push(pair);
|
||
trigger[dissent].splice(i--, 1);
|
||
}
|
||
}
|
||
player.logSkill("jsrgbazheng", dissident);
|
||
},
|
||
ai: {
|
||
combo: "jsrgyaoyan"
|
||
},
|
||
},
|
||
//刘永
|
||
jsrgdanxin: {
|
||
audio: 2,
|
||
enable: "chooseToUse",
|
||
viewAs: {
|
||
name: "tuixinzhifu",
|
||
storage: { jsrgdanxin: true },
|
||
},
|
||
filterCard: true,
|
||
position: "hes",
|
||
precontent() {
|
||
player.addTempSkill("jsrgdanxin_effect");
|
||
},
|
||
subSkill: {
|
||
effect: {
|
||
audio: "jsrgdanxin",
|
||
trigger: {
|
||
global: "gainAfter",
|
||
},
|
||
filter(event, player) {
|
||
const level = event.player != player ? 1 : 2;
|
||
if (event.player != player && event.getParent(level).name != "tuixinzhifu") return false;
|
||
if (event.player == player && event.getParent(level).name != "tuixinzhifu") return false;
|
||
const card = event.getParent(level + 1).card;
|
||
return card && card.storage && card.storage.jsrgdanxin;
|
||
},
|
||
forced: true,
|
||
popup: false,
|
||
charlotte: true,
|
||
async content(event, trigger, player) {
|
||
const level = trigger.player != player ? 1 : 2;
|
||
const { targets } = trigger.getParent(level + 1);
|
||
await player.showCards(trigger.cards);
|
||
if (trigger.cards.some(card => get.suit(card) == "heart")) {
|
||
const owners = trigger.cards
|
||
.filter(card => get.suit(card) == "heart")
|
||
.map(card => get.owner(card))
|
||
.toUniqued();
|
||
for (const owner of owners) {
|
||
if (owner && owner.isIn()) await owner.recover();
|
||
}
|
||
}
|
||
if (trigger.player == player) return;
|
||
player.addTempSkill("jsrgdanxin_distance");
|
||
if (!player.storage.jsrgdanxin_distance) player.storage.jsrgdanxin_distance = {};
|
||
const id = targets[0].playerid;
|
||
if (typeof player.storage.jsrgdanxin_distance[id] != "number") player.storage.jsrgdanxin_distance[id] = 0;
|
||
player.storage.jsrgdanxin_distance[id]++;
|
||
player.markSkill("jsrgdanxin_distance");
|
||
},
|
||
},
|
||
distance: {
|
||
onremove: true,
|
||
charlotte: true,
|
||
mod: {
|
||
globalFrom(player, target, distance) {
|
||
if (!player.storage.jsrgdanxin_distance) return;
|
||
const dis = player.storage.jsrgdanxin_distance[target.playerid];
|
||
if (typeof dis == "number") return distance + dis;
|
||
},
|
||
},
|
||
intro: {
|
||
content(storage, player) {
|
||
if (!storage) return;
|
||
const map = _status.connectMode ? lib.playerOL : game.playerMap;
|
||
let str = `你本回合:`;
|
||
for (const id in storage) {
|
||
str += "<li>至" + get.translation(map[id]) + "的距离+" + storage[id];
|
||
}
|
||
return str;
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgfengxiang: {
|
||
audio: "fengxiang",
|
||
trigger: { player: "damageEnd" },
|
||
forced: true,
|
||
direct: true,
|
||
filter(event, player) {
|
||
return game.hasPlayer(current => {
|
||
return current.countCards("e");
|
||
});
|
||
},
|
||
async content(event, trigger, player) {
|
||
const {
|
||
result: { bool, targets },
|
||
} = await player
|
||
.chooseTarget(
|
||
"封乡:与一名其他角色交换装备区里的所有牌",
|
||
(card, player, target) => {
|
||
return target.countCards("e") + player.countCards("e") > 0 && player != target;
|
||
},
|
||
true
|
||
)
|
||
.set("ai", target => {
|
||
const player = get.player();
|
||
const att = get.attitude(player, target);
|
||
let delta = get.value(target.getCards("e"), player) - get.value(player.getCards("e"), player);
|
||
if (att > 0) {
|
||
if (delta < 0) delta += att / 3;
|
||
} else {
|
||
if (delta < 0) delta -= att / 3;
|
||
}
|
||
return delta;
|
||
});
|
||
if (bool) {
|
||
player.logSkill("jsrgfengxiang", targets[0]);
|
||
const num = player.countCards("e");
|
||
await player.swapEquip(targets[0]);
|
||
const delta = num - player.countCards("e");
|
||
if (delta > 0) player.draw(delta);
|
||
}
|
||
},
|
||
},
|
||
jsrgfuhai: {
|
||
audio: "xinfu_fuhai",
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
filter(event, player) {
|
||
return game.hasPlayer(current => {
|
||
return current.countCards("h") && current != player;
|
||
});
|
||
},
|
||
filterTarget(card, player, target) {
|
||
return target.countCards("h") && target != player;
|
||
},
|
||
selectTarget: -1,
|
||
multitarget: true,
|
||
multiline: true,
|
||
async content(event, trigger, player) {
|
||
const targets = event.targets.sortBySeat();
|
||
const next = player
|
||
.chooseCardOL(targets, "请展示一张手牌", true)
|
||
.set("ai", card => {
|
||
return -get.value(card);
|
||
})
|
||
.set("aiCard", target => {
|
||
const hs = target.getCards("h");
|
||
return { bool: true, cards: [hs.randomGet()] };
|
||
});
|
||
next._args.remove("glow_result");
|
||
const { result } = await next;
|
||
const cards = [];
|
||
const videoId = lib.status.videoId++;
|
||
for (let i = 0; i < targets.length; i++) {
|
||
cards.push(result[i].cards[0]);
|
||
game.log(targets[i], "展示了", result[i].cards[0]);
|
||
}
|
||
game.broadcastAll(
|
||
(targets, cards, id, player) => {
|
||
var dialog = ui.create.dialog(get.translation(player) + "发动了【浮海】", cards);
|
||
dialog.videoId = id;
|
||
const getName = target => {
|
||
if (target._tempTranslate) return target._tempTranslate;
|
||
var name = target.name;
|
||
if (lib.translate[name + "_ab"]) return lib.translate[name + "_ab"];
|
||
return get.translation(name);
|
||
};
|
||
for (let i = 0; i < targets.length; i++) {
|
||
dialog.buttons[i].querySelector(".info").innerHTML = getName(targets[i]) + "|" + get.strNumber(cards[i].number);
|
||
}
|
||
},
|
||
targets,
|
||
cards,
|
||
videoId,
|
||
player
|
||
);
|
||
await game.asyncDelay(4);
|
||
game.broadcastAll("closeDialog", videoId);
|
||
let clock = -1,
|
||
anticlock = -1;
|
||
for (let j = 0; j < 2; j++) {
|
||
let increase = -Infinity,
|
||
decrease = Infinity,
|
||
count = 0;
|
||
for (let i = 0; i < targets.length; i++) {
|
||
const number = get.number(cards[i], false);
|
||
let flag = false;
|
||
if (number > increase) {
|
||
increase = number;
|
||
flag = true;
|
||
} else increase = Infinity;
|
||
if (number < decrease) {
|
||
decrease = number;
|
||
flag = true;
|
||
} else decrease = -Infinity;
|
||
if (flag) count++;
|
||
else break;
|
||
}
|
||
targets.reverse();
|
||
cards.reverse();
|
||
if (j == 0) anticlock = Math.max(1, count);
|
||
else clock = Math.max(1, count);
|
||
}
|
||
const {
|
||
result: { index },
|
||
} = await player
|
||
.chooseControl(`↖顺时针(${clock})`, `逆时针(${anticlock})↗`)
|
||
.set("prompt", "请选择一个方向,摸对应数量的牌")
|
||
.set("ai", () => get.event("choice"))
|
||
.set("choice", clock > anticlock ? 0 : 1);
|
||
player.draw(index == 0 ? clock : anticlock);
|
||
},
|
||
ai: {
|
||
order: 8,
|
||
result: { player: 1 },
|
||
},
|
||
},
|
||
//张嫙
|
||
jsrgtongli: {
|
||
audio: "tongli",
|
||
trigger: { player: "useCardToPlayered" },
|
||
filter(event, player) {
|
||
if (!event.isFirstTarget) return false;
|
||
const type = get.type(event.card);
|
||
if (type != "basic" && type != "trick") return false;
|
||
const hs = player.getCards("h");
|
||
if (!hs.length) return false;
|
||
const evt = event.getParent("phaseUse");
|
||
if (!evt || evt.player != player) return false;
|
||
const num1 = player.getHistory("useCard", evtx => {
|
||
return evtx.getParent("phaseUse") == evt;
|
||
}).length;
|
||
if (hs.length < num1) return false;
|
||
const list = [];
|
||
for (const i of hs) list.add(get.suit(i, player));
|
||
return list.length == num1;
|
||
},
|
||
prompt2(event, player) {
|
||
let str = "展示所有手牌,额外结算一次";
|
||
if (event.card.name == "sha" && game.hasNature(event.card)) str += get.translation(event.card.nature);
|
||
return str + "【" + get.translation(event.card.name) + "】";
|
||
},
|
||
check(event, player) {
|
||
return !get.tag(event.card, "norepeat");
|
||
},
|
||
async content(event, trigger, player) {
|
||
await player.showHandcards();
|
||
trigger.getParent().effectCount++;
|
||
},
|
||
},
|
||
jsrgshezang: {
|
||
audio: "shezang",
|
||
round: 1,
|
||
trigger: { global: "dying" },
|
||
frequent: true,
|
||
filter(event, player) {
|
||
return event.player == player || player == _status.currentPhase;
|
||
},
|
||
async content(event, trigger, player) {
|
||
const cards = get.cards(4);
|
||
game.cardsGotoOrdering(cards);
|
||
const videoId = lib.status.videoId++;
|
||
game.broadcastAll(
|
||
(player, id, cards) => {
|
||
let str = "奢葬";
|
||
if (player == game.me && !_status.auto) {
|
||
str += ":获得任意张花色各不相同的牌";
|
||
}
|
||
const dialog = ui.create.dialog(str, cards);
|
||
dialog.videoId = id;
|
||
},
|
||
player,
|
||
videoId,
|
||
cards
|
||
);
|
||
const time = get.utc();
|
||
game.addVideo("showCards", player, ["奢葬", get.cardsInfo(event.cards)]);
|
||
game.addVideo("delay", null, 2);
|
||
const list = [];
|
||
for (const i of cards) list.add(get.suit(i, false));
|
||
const next = player.chooseButton([1, list.length]);
|
||
next.set("dialog", event.videoId);
|
||
next.set("filterButton", function (button) {
|
||
for (var i = 0; i < ui.selected.buttons.length; i++) {
|
||
if (get.suit(ui.selected.buttons[i].link) == get.suit(button.link)) return false;
|
||
}
|
||
return true;
|
||
});
|
||
next.set("ai", function (button) {
|
||
return get.value(button.link, _status.event.player);
|
||
});
|
||
const { result } = await next;
|
||
if (result.bool && result.links) {
|
||
const time2 = 1000 - (get.utc() - time);
|
||
if (time2 > 0) {
|
||
await game.asyncDelay(0, time2);
|
||
}
|
||
game.broadcastAll("closeDialog", videoId);
|
||
player.gain(result.links, "gain2");
|
||
}
|
||
},
|
||
},
|
||
jsrgchiying: {
|
||
audio: "dcchiying",
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
filterTarget: true,
|
||
async content(event, trigger, player) {
|
||
const target = event.target;
|
||
const targets = game.filterPlayer(current => target.inRange(current) && current != player).sortBySeat(player);
|
||
if (!targets.length) return;
|
||
while (targets.length) {
|
||
const current = targets.shift();
|
||
if (current.countCards("he")) await current.chooseToDiscard("驰应:请弃置一张牌", "he", true);
|
||
}
|
||
let cards = [];
|
||
game.getGlobalHistory("cardMove", evt => {
|
||
if (evt.getParent(3) == event) {
|
||
cards.addArray(evt.cards.filter(card => get.type(card) == "basic"));
|
||
}
|
||
});
|
||
if (cards.length <= target.getHp()) {
|
||
cards = cards.filterInD("d");
|
||
if (cards.length) target.gain(cards, "gain2");
|
||
}
|
||
},
|
||
ai: {
|
||
order: 6,
|
||
result: {
|
||
target(player, target) {
|
||
const targets = game.filterPlayer(current => target.inRange(current) && current != player);
|
||
let eff = 0;
|
||
for (const targetx of targets) {
|
||
let effx = get.effect(targetx, { name: "guohe_copy2" }, player, target);
|
||
if (get.attitude(player, targetx) < 0) effx /= 2;
|
||
eff += effx;
|
||
}
|
||
return eff * (get.attitude(player, target) <= 0 ? 0.75 : 1);
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//郭照
|
||
jsrgpianchong: {
|
||
audio: "pianchong",
|
||
trigger: { global: "phaseJieshuBegin" },
|
||
filter(event, player) {
|
||
return player.getHistory("lose").length;
|
||
},
|
||
frequent: true,
|
||
async content(event, trigger, player) {
|
||
const { result } = await player.judge();
|
||
let num = 0;
|
||
game.getGlobalHistory("cardMove", evt => {
|
||
if (evt.name != "cardsDiscard") {
|
||
if (evt.name != "lose" || evt.position != ui.discardPile) return false;
|
||
}
|
||
num += evt.cards.filter(i => get.color(i, false) == result.color).length;
|
||
});
|
||
if (num > 0) player.draw(num);
|
||
},
|
||
},
|
||
jsrgzunwei: {
|
||
audio: "zunwei",
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
filter(event, player) {
|
||
const storage = player.getStorage("jsrgzunwei");
|
||
return (
|
||
storage.length < 3 &&
|
||
game.hasPlayer(current => {
|
||
return (player.isDamaged() && current.getHp() > player.getHp() && !storage.includes(2)) || (current.countCards("h") > player.countCards("h") && !storage.includes(0)) || (current.countCards("e") > player.countCards("e") && !storage.includes(1));
|
||
})
|
||
);
|
||
},
|
||
chooseButton: {
|
||
dialog(event, player) {
|
||
const list = ["选择手牌数大于你的一名角色", "选择装备数大于你的一名角色", "选择体力值大于你的一名角色"];
|
||
const choiceList = ui.create.dialog("尊位:请选择一项", "forcebutton", "hidden");
|
||
choiceList.add([
|
||
list.map((item, i) => {
|
||
if (player.getStorage("jsrgzunwei").includes(i)) item = `<span style="text-decoration: line-through;">${item}</span>`;
|
||
return [i, item];
|
||
}),
|
||
"textbutton",
|
||
]);
|
||
return choiceList;
|
||
},
|
||
filter(button) {
|
||
const player = get.player();
|
||
if (player.getStorage("jsrgzunwei").includes(button.link)) return false;
|
||
if (button.link == 2) {
|
||
if (!player.isDamaged()) return false;
|
||
return game.hasPlayer(current => {
|
||
return current.getHp() > player.getHp();
|
||
});
|
||
}
|
||
if (button.link == 0) {
|
||
return game.hasPlayer(current => {
|
||
return current.countCards("h") > player.countCards("h");
|
||
});
|
||
}
|
||
if (button.link == 1) {
|
||
return game.hasPlayer(current => {
|
||
return current.countCards("e") > player.countCards("e");
|
||
});
|
||
}
|
||
},
|
||
backup(links) {
|
||
const next = get.copy(lib.skill.jsrgzunwei.backups[links[0]]);
|
||
next.audio = "zunwei";
|
||
next.filterCard = function () {
|
||
return false;
|
||
};
|
||
next.selectCard = -1;
|
||
return next;
|
||
},
|
||
check(button) {
|
||
const player = get.player();
|
||
switch (button.link) {
|
||
case 2: {
|
||
const target = game.findPlayer(function (current) {
|
||
return current.isMaxHp();
|
||
});
|
||
return (Math.min(target.hp, player.maxHp) - player.hp) * 2;
|
||
}
|
||
case 0: {
|
||
const target = game.findPlayer(function (current) {
|
||
return current.isMaxHandcard();
|
||
});
|
||
return Math.min(5, target.countCards("h") - player.countCards("h")) * 0.8;
|
||
}
|
||
case 1: {
|
||
const target = game.findPlayer(function (current) {
|
||
return current.isMaxEquip();
|
||
});
|
||
return (target.countCards("e") - player.countCards("e")) * 1.4;
|
||
}
|
||
}
|
||
},
|
||
prompt(links) {
|
||
return ["选择一名手牌数大于你的其他角色,将手牌数摸至与其相同(至多摸五张)", "选择一名装备区内牌数大于你的其他角色,将其装备区里的牌移至你的装备区,直到你装备数不小于其", "选择一名体力值大于你的其他角色,将体力值回复至与其相同"][links[0]];
|
||
},
|
||
},
|
||
backups: [
|
||
{
|
||
filterTarget(card, player, target) {
|
||
return target.countCards("h") > player.countCards("h");
|
||
},
|
||
async content(event, trigger, player) {
|
||
player.draw(Math.min(5, event.target.countCards("h") - player.countCards("h")));
|
||
if (!player.storage.jsrgzunwei) player.storage.jsrgzunwei = [];
|
||
player.storage.jsrgzunwei.add(0);
|
||
},
|
||
ai: {
|
||
order: 10,
|
||
result: {
|
||
player: function (player, target) {
|
||
return Math.min(5, target.countCards("h") - player.countCards("h"));
|
||
},
|
||
},
|
||
},
|
||
},
|
||
{
|
||
filterTarget(card, player, target) {
|
||
return target.countCards("e") > player.countCards("e");
|
||
},
|
||
async content(event, trigger, player) {
|
||
if (!player.storage.jsrgzunwei) player.storage.jsrgzunwei = [];
|
||
player.storage.jsrgzunwei.add(1);
|
||
const target = event.target;
|
||
do {
|
||
if (
|
||
!target.countCards("e", card => {
|
||
return player.canEquip(card);
|
||
})
|
||
)
|
||
break;
|
||
const {
|
||
result: { bool, links },
|
||
} = await player
|
||
.chooseButton([`尊位:将${get.translation(target)}的一张装备牌移至你的区域内`, target.getCards("e")], true)
|
||
.set("filterButton", button => {
|
||
return get.player().canEquip(button.link);
|
||
})
|
||
.set("ai", get.buttonValue);
|
||
if (bool) {
|
||
target.$give(links[0], player, false);
|
||
await player.equip(links[0]);
|
||
}
|
||
} while (player.countCards("e") < target.countCards("e"));
|
||
},
|
||
ai: {
|
||
order: 10,
|
||
result: {
|
||
player(player, target) {
|
||
return target.countCards("e") - player.countCards("e");
|
||
},
|
||
},
|
||
},
|
||
},
|
||
{
|
||
filterTarget(card, player, target) {
|
||
if (player.isHealthy()) return false;
|
||
return target.hp > player.hp;
|
||
},
|
||
async content(event, trigger, player) {
|
||
player.recover(event.target.hp - player.hp);
|
||
if (!player.storage.jsrgzunwei) player.storage.jsrgzunwei = [];
|
||
player.storage.jsrgzunwei.add(2);
|
||
},
|
||
ai: {
|
||
order: 10,
|
||
result: {
|
||
player: function (player, target) {
|
||
return Math.min(target.hp, player.maxHp) - player.hp;
|
||
},
|
||
},
|
||
},
|
||
},
|
||
],
|
||
ai: {
|
||
order: 10,
|
||
result: {
|
||
player: 1,
|
||
},
|
||
},
|
||
subSkill: {
|
||
backup: {},
|
||
},
|
||
},
|
||
//江山如故·转
|
||
//404郭嘉
|
||
jsrgqingzi: {
|
||
audio: 2,
|
||
trigger: { player: "phaseZhunbeiBegin" },
|
||
filter: function (event, player) {
|
||
return game.hasPlayer(current => {
|
||
if (current == player) return false;
|
||
return current.hasCard(card => {
|
||
return lib.filter.canBeDiscarded(card, player, current);
|
||
}, "e");
|
||
});
|
||
},
|
||
derivation: "xinshensu",
|
||
direct: true,
|
||
content: function () {
|
||
"step 0";
|
||
player
|
||
.chooseTarget(get.prompt("jsrgqingzi"), "弃置任意名其他角色装备区里的一张牌,然后令这些角色获得〖神速〗直到你的下回合开始", [1, Infinity], (card, player, target) => {
|
||
return (
|
||
target != player &&
|
||
target.hasCard(card => {
|
||
return lib.filter.canBeDiscarded(card, player, target);
|
||
}, "e")
|
||
);
|
||
})
|
||
.set("ai", target => {
|
||
var player = _status.event.player;
|
||
return target.hasCard(card => {
|
||
return (lib.filter.canBeDiscarded(card, player, target) && get.value(card, target) > 3) || (target.hp == 1 && get.value(card, target) > 0);
|
||
});
|
||
});
|
||
("step 1");
|
||
if (result.bool) {
|
||
var targets = result.targets.slice();
|
||
targets.sortBySeat();
|
||
event.targets = targets;
|
||
event.num = 0;
|
||
player.logSkill("jsrgqingzi", targets);
|
||
player.addSkill("jsrgqingzi_clear");
|
||
} else event.finish();
|
||
("step 2");
|
||
var target = targets[num];
|
||
if (
|
||
target.hasCard(card => {
|
||
return lib.filter.canBeDiscarded(card, player, target);
|
||
}, "e")
|
||
) {
|
||
player.discardPlayerCard(target, "e", true);
|
||
target.addAdditionalSkills("jsrgqingzi_" + player.playerid, "xinshensu");
|
||
player.markAuto("jsrgqingzi_clear", [target]);
|
||
}
|
||
event.num++;
|
||
if (event.num < targets.length) event.redo();
|
||
},
|
||
subSkill: {
|
||
clear: {
|
||
audio: "jsrgqingzi",
|
||
charlotte: true,
|
||
trigger: {
|
||
global: "die",
|
||
player: "phaseBegin",
|
||
},
|
||
forced: true,
|
||
popup: false,
|
||
forceDie: true,
|
||
onremove: true,
|
||
filter: function (event, player) {
|
||
if (event.name == "die") {
|
||
return player == event.player || player.getStorage("jsrgqingzi_clear").includes(event.player);
|
||
}
|
||
return player.getStorage("jsrgqingzi_clear").length > 0;
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
var targets = player.getStorage("jsrgqingzi_clear");
|
||
if (trigger.name == "die" && player == trigger.player) {
|
||
for (var target of targets) {
|
||
target.removeAdditionalSkill(`jsrgqingzi_${player.playerid}`);
|
||
}
|
||
player.removeSkill("jsrgqingzi_clear");
|
||
event.finish();
|
||
return;
|
||
}
|
||
if (trigger.name == "phase") event.targets = targets.slice(0).sortBySeat();
|
||
else event.targets = [trigger.player];
|
||
("step 1");
|
||
var target = targets.shift();
|
||
var storage = player.getStorage("jsrgqingzi_clear");
|
||
if (storage.includes(target)) {
|
||
storage.remove(target);
|
||
target.removeAdditionalSkill(`jsrgqingzi_${player.playerid}`);
|
||
}
|
||
if (targets.length > 0) {
|
||
event.redo();
|
||
} else if (!storage.length) {
|
||
player.removeSkill("jsrgqingzi_clear");
|
||
}
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgdingce: {
|
||
audio: 2,
|
||
trigger: { player: "damageEnd" },
|
||
filter: function (event, player) {
|
||
if (!event.source || !event.source.isIn()) return false;
|
||
return player.hasCard(card => {
|
||
return lib.filter.cardDiscardable(card, player, "jsrgdingce");
|
||
});
|
||
},
|
||
direct: true,
|
||
content: function () {
|
||
"step 0";
|
||
var target = trigger.source;
|
||
event.target = target;
|
||
player
|
||
.chooseToDiscard(get.prompt("jsrgdingce", target), "弃置你与其的各一张手牌。若这两张牌颜色相同,你视为使用一张【洞烛先机】。")
|
||
.set("ai", card => {
|
||
if (_status.event.goon) return 6 - get.value(card);
|
||
return 0;
|
||
})
|
||
.set(
|
||
"goon",
|
||
get.attitude(player, target) < 0 ||
|
||
player
|
||
.getCards("h")
|
||
.concat(target.getCards("h"))
|
||
.filter(card => {
|
||
return get.value(card) < 5.5;
|
||
}).length >= 2
|
||
)
|
||
.set("logSkill", ["jsrgdingce", target]);
|
||
("step 1");
|
||
if (result.bool) {
|
||
event.card = result.cards[0];
|
||
if (target.countDiscardableCards(player, "h")) {
|
||
var next = player.discardPlayerCard(target, "h", true);
|
||
if (target == player)
|
||
next.set("ai", button => {
|
||
var card = button.link;
|
||
return (get.color(card, false) == _status.event.color ? 7.5 : 5) - get.value(card);
|
||
}).set("color", get.color(event.card, false));
|
||
} else event.finish();
|
||
} else event.finish();
|
||
("step 2");
|
||
if (result.bool) {
|
||
var card = result.cards[0];
|
||
if (get.color(event.card, false) == get.color(card, false)) {
|
||
game.delayex();
|
||
player.chooseUseTarget("dongzhuxianji", true);
|
||
}
|
||
}
|
||
},
|
||
},
|
||
jsrgzhenfeng: {
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
locked: false,
|
||
filter: function (event, player) {
|
||
if (!event.jsrgzhenfeng) return false;
|
||
return event.jsrgzhenfeng.some(info =>
|
||
event.filterCard(
|
||
{
|
||
name: info[2],
|
||
nature: info[3],
|
||
storage: { jsrgzhenfeng: true },
|
||
isCard: true,
|
||
},
|
||
player,
|
||
event
|
||
)
|
||
);
|
||
},
|
||
onChooseToUse: function (event) {
|
||
if (!event.jsrgzhenfeng && !game.online) {
|
||
var str = "";
|
||
game.countPlayer(current => {
|
||
current.getSkills(null, false, false).forEach(skill => {
|
||
var info = get.info(skill);
|
||
if (!info || info.charlotte) return;
|
||
var translation = get.skillInfoTranslation(skill, current);
|
||
str += translation;
|
||
});
|
||
});
|
||
event.set("jsrgzhenfeng", lib.skill.jsrgzhenfeng.getInclusion(str, null, event.player));
|
||
}
|
||
},
|
||
getInclusion: function (str, checkCard, player) {
|
||
let list = [];
|
||
const names = Object.keys(lib.card);
|
||
for (const name of names) {
|
||
let type = get.type(name);
|
||
if (!["basic", "trick"].includes(type)) continue;
|
||
if (player && player.getStorage("jsrgzhenfeng_effect").includes(type)) continue;
|
||
const reg = `【${get.translation(name)}】`;
|
||
if (name == "sha") {
|
||
if (str.includes(reg)) {
|
||
if (checkCard && checkCard.name == name) return true;
|
||
list.push([type, "", name]);
|
||
}
|
||
for (let nature of lib.inpile_nature) {
|
||
const reg1 = `【${get.translation(nature) + get.translation(name)}】`,
|
||
reg2 = `${get.translation(nature)}【${get.translation(name)}】`;
|
||
if (str.includes(reg1) || str.includes(reg2)) {
|
||
if (checkCard && checkCard.name == name && checkCard.nature == nature) return true;
|
||
list.push([type, "", name, nature]);
|
||
}
|
||
}
|
||
} else {
|
||
if (!str.includes(reg)) continue;
|
||
if (checkCard && checkCard.name == name) return true;
|
||
list.push([type, "", name]);
|
||
}
|
||
}
|
||
if (checkCard) return false;
|
||
return list;
|
||
},
|
||
chooseButton: {
|
||
dialog: function (event, player) {
|
||
var list = event.jsrgzhenfeng.filter(info => {
|
||
return event.filterCard(
|
||
{
|
||
name: info[2],
|
||
nature: info[3],
|
||
storage: { jsrgzhenfeng: true },
|
||
isCard: true,
|
||
},
|
||
player,
|
||
event
|
||
);
|
||
});
|
||
return ui.create.dialog("针锋", [list, "vcard"]);
|
||
},
|
||
filter: function (button, player) {
|
||
return _status.event.getParent().filterCard(
|
||
{
|
||
name: button.link[2],
|
||
nature: button.link[3],
|
||
storage: { jsrgzhenfeng: true },
|
||
isCard: true,
|
||
},
|
||
player,
|
||
_status.event.getParent()
|
||
);
|
||
},
|
||
check: function (button) {
|
||
var player = _status.event.player;
|
||
var card = {
|
||
name: button.link[2],
|
||
nature: button.link[3],
|
||
storage: { jsrgzhenfeng: true },
|
||
isCard: true,
|
||
};
|
||
var eff = player.getUseValue(card);
|
||
if (["wugu", "zhulu_card", "yiyi", "lulitongxin", "lianjunshengyan", "diaohulishan"].includes(button.link[2])) eff /= 5;
|
||
var info = get.info(card);
|
||
if (info.toself) {
|
||
var str = player
|
||
.getSkills(null, false, false)
|
||
.map(skill => {
|
||
var info = get.info(skill);
|
||
if (!info || info.charlotte) return;
|
||
return get.skillInfoTranslation(skill, player);
|
||
})
|
||
.join("\n");
|
||
if (lib.skill.jsrgzhenfeng.getInclusion(str, card)) eff += get.damageEffect(player, player, player);
|
||
}
|
||
return eff;
|
||
},
|
||
backup: function (links, player) {
|
||
return {
|
||
audio: "jsrgzhenfeng",
|
||
filterCard: () => false,
|
||
selectCard: -1,
|
||
popname: true,
|
||
viewAs: {
|
||
name: links[0][2],
|
||
nature: links[0][3],
|
||
storage: { jsrgzhenfeng: true },
|
||
isCard: true,
|
||
},
|
||
precontent: function () {
|
||
delete event.result.skill;
|
||
player.logSkill("jsrgzhenfeng");
|
||
event.getParent().addCount = false;
|
||
player.addTempSkill("jsrgzhenfeng_effect", "phaseUseAfter");
|
||
player.markAuto("jsrgzhenfeng_effect", [get.type(event.result.card)]);
|
||
},
|
||
};
|
||
},
|
||
prompt: function (links, player) {
|
||
return "视为使用一张" + (get.translation(links[0][3]) || "") + get.translation(links[0][2]);
|
||
},
|
||
},
|
||
mod: {
|
||
cardUsable: function (card) {
|
||
if (card.storage && card.storage.jsrgzhenfeng) return Infinity;
|
||
},
|
||
targetInRange: function (card) {
|
||
if (card.storage && card.storage.jsrgzhenfeng) return true;
|
||
},
|
||
},
|
||
ai: {
|
||
order: 1,
|
||
result: {
|
||
player: 1,
|
||
},
|
||
},
|
||
subSkill: {
|
||
effect: {
|
||
audio: "jsrgzhenfeng",
|
||
trigger: {
|
||
global: "useCardToBegin",
|
||
},
|
||
charlotte: true,
|
||
forced: true,
|
||
onremove: true,
|
||
filter: function (event, player) {
|
||
if (!event.card.storage || !event.card.storage.jsrgzhenfeng) return false;
|
||
// debugger
|
||
var str = event.target
|
||
.getSkills(null, false, false)
|
||
.map(skill => {
|
||
var info = get.info(skill);
|
||
if (!info || info.charlotte) return;
|
||
return get.skillInfoTranslation(skill, event.target);
|
||
})
|
||
.join("\n");
|
||
return lib.skill.jsrgzhenfeng.getInclusion(str, event.card);
|
||
},
|
||
logTarget: "target",
|
||
content: function () {
|
||
trigger.target.damage();
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//张飞
|
||
jsrgbaohe: {
|
||
audio: 2,
|
||
trigger: { global: "phaseUseEnd" },
|
||
filter: function (event, player) {
|
||
return (
|
||
player.countCards("he") >= 2 &&
|
||
game.hasPlayer(current => {
|
||
return current.inRange(event.player) && player.canUse("sha", current, false);
|
||
})
|
||
);
|
||
},
|
||
direct: true,
|
||
content: function () {
|
||
"step 0";
|
||
player
|
||
.chooseToDiscard(get.prompt2("jsrgbaohe"), 2, "he")
|
||
.set("ai", card => {
|
||
var val = _status.event.val;
|
||
if (val > 20) return 6 - get.value(card);
|
||
if (val > 0) return 4 - get.value(card);
|
||
return 0;
|
||
})
|
||
.set(
|
||
"val",
|
||
game
|
||
.filterPlayer(current => {
|
||
return current.inRange(trigger.player) && player.canUse("sha", current, false);
|
||
})
|
||
.map(i => get.effect(i, { name: "sha" }, player, player))
|
||
.reduce((p, c) => {
|
||
return p + c;
|
||
}, 0)
|
||
)
|
||
.set("logSkill", "jsrgbaohe");
|
||
("step 1");
|
||
if (result.bool) {
|
||
var targets = game.filterPlayer(current => {
|
||
return current.inRange(trigger.player) && player.canUse("sha", current, false);
|
||
});
|
||
if (targets.length) {
|
||
game.delayex();
|
||
player.useCard({ name: "sha", isCard: true, storage: { jsrgbaohe: true } }, targets, false);
|
||
player.addTempSkill("jsrgbaohe_add");
|
||
}
|
||
}
|
||
},
|
||
subSkill: {
|
||
add: {
|
||
audio: "jsrgbaohe",
|
||
trigger: {
|
||
global: "useCard",
|
||
},
|
||
charlotte: true,
|
||
forced: true,
|
||
filter: function (event, player) {
|
||
let evt = event.getParent(3),
|
||
respondTo = event.respondTo;
|
||
if (evt.name != "useCard" || !Array.isArray(respondTo) || !respondTo[1].storage || !respondTo[1].storage.jsrgbaohe) return false;
|
||
return evt.targets.length > evt.num + 1;
|
||
},
|
||
logTarget: function (event) {
|
||
let evt = event.getParent(3);
|
||
return evt.targets.slice(evt.num + 1);
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
var evt = trigger.getParent(3);
|
||
var targets = evt.targets.slice(evt.num + 1);
|
||
var map = evt.customArgs;
|
||
for (var target of targets) {
|
||
var id = target.playerid;
|
||
if (!map[id]) map[id] = {};
|
||
if (typeof map[id].extraDamage != "number") {
|
||
map[id].extraDamage = 0;
|
||
}
|
||
map[id].extraDamage++;
|
||
}
|
||
game.delayx();
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgxushi: {
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
filterCard: true,
|
||
filterTarget: lib.filter.notMe,
|
||
selectCard: [1, Infinity],
|
||
selectTarget: [1, Infinity],
|
||
position: "he",
|
||
filterOk: function () {
|
||
return ui.selected.cards.length == ui.selected.targets.length;
|
||
},
|
||
check: function (card) {
|
||
var player = get.player();
|
||
if (
|
||
ui.selected.cards.length >=
|
||
game.countPlayer(current => {
|
||
return current != player && get.attitude(player, current) > 0;
|
||
})
|
||
)
|
||
return 0;
|
||
return 5 - get.value(card);
|
||
},
|
||
prompt: "按顺序选择卡牌和角色,并将卡牌交给对应顺序的角色。然后你获得两倍数量的【影】。",
|
||
complexSelect: true,
|
||
multitarget: true,
|
||
multiline: true,
|
||
discard: false,
|
||
lose: false,
|
||
delay: false,
|
||
contentBefore: function () {
|
||
event.getParent()._jsrgxushi_targets = targets.slice();
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
var targets = event.getParent()._jsrgxushi_targets;
|
||
var list = [];
|
||
for (var i = 0; i < targets.length; i++) {
|
||
var target = targets[i];
|
||
var card = cards[i];
|
||
list.push([target, card]);
|
||
player.line(target);
|
||
}
|
||
game.loseAsync({
|
||
gain_list: list,
|
||
player: player,
|
||
cards: cards,
|
||
giver: player,
|
||
animate: "giveAuto",
|
||
}).setContent("gaincardMultiple");
|
||
("step 1");
|
||
player.gain(lib.card.ying.getYing(2 * cards.length), "gain2");
|
||
},
|
||
ai: {
|
||
order: 2.5,
|
||
result: {
|
||
target: function (player, target) {
|
||
var card = ui.selected.cards[ui.selected.targets.length];
|
||
if (!card) return 0;
|
||
if (get.value(card) < 0) return -1;
|
||
if (get.value(card) < 1.5 && player.hasSkill("jsrgbaohe")) return (get.sgnAttitude(player, target) + 0.01) / 5;
|
||
return Math.sqrt(5 - Math.min(4, target.countCards("h")));
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgzhuiming: {
|
||
audio: 2,
|
||
trigger: {
|
||
player: "useCardToPlayered",
|
||
},
|
||
filter: function (event, player) {
|
||
if (event.card.name != "sha") return false;
|
||
return event.isFirstTarget && event.targets.length == 1 && event.target.isIn();
|
||
},
|
||
direct: true,
|
||
content: function* (event, map) {
|
||
var player = map.player,
|
||
trigger = map.trigger,
|
||
target = trigger.target;
|
||
var colors = Object.keys(lib.color).remove("none");
|
||
var result = yield player
|
||
.chooseControl(colors, "cancel2")
|
||
.set("prompt", get.prompt("jsrgzhuiming"))
|
||
.set("prompt2", `声明一种颜色并令${get.translation(trigger.target)}弃置任意张牌`)
|
||
.set("ai", () => {
|
||
var player = get.player(),
|
||
target = get.event("target"),
|
||
att = get.attitude(player, target) > 0 ? 1 : -1;
|
||
var list = get
|
||
.event("controls")
|
||
.map(i => [
|
||
i,
|
||
target
|
||
.getCards("he")
|
||
.map(get.value)
|
||
.reduce((p, c) => p + c, 0),
|
||
])
|
||
.sort((a, b) => {
|
||
return att * (a[1] - b[1]);
|
||
});
|
||
return list[0][0];
|
||
})
|
||
.set("target", target);
|
||
var color = result.control;
|
||
if (color == "cancel2") {
|
||
event.finish();
|
||
return;
|
||
}
|
||
player.logSkill("jsrgzhuiming", target);
|
||
player.popup(color, color == "red" ? "fire" : "thunder");
|
||
game.log(player, "声明了", color);
|
||
var prompt = `追命:${get.translation(player)}声明了${get.translation(color)}`,
|
||
prompt2 = `请弃置任意张牌,然后其展示你一张牌,若此牌颜色为${get.translation(color)},此【杀】不计入次数限制、不可被响应且伤害+1`;
|
||
yield target
|
||
.chooseToDiscard(prompt, prompt2, [1, Infinity], "he", true)
|
||
.set("ai", card => {
|
||
var color = get.event("color"),
|
||
player = get.player();
|
||
if (get.position(card) == "e" && get.color(card) == color) return 2;
|
||
if (player.getHp() <= 2 && get.color(card) == color) return Math.random() < 0.5;
|
||
return 0;
|
||
})
|
||
.set("color", color);
|
||
if (target.countCards("he"))
|
||
result = yield player
|
||
.choosePlayerCard(target, "he", true)
|
||
.set("ai", button => {
|
||
var color = get.event("color"),
|
||
att = get.event("att");
|
||
if (get.position(button.link) == "e" && get.color(button.link) == color) {
|
||
return 100 * att;
|
||
}
|
||
return 1 + Math.random();
|
||
})
|
||
.set("color", color)
|
||
.set("att", get.attitude(player, target) > 0 ? 1 : -1);
|
||
else {
|
||
event.finish();
|
||
return;
|
||
}
|
||
var card = result.cards[0];
|
||
player.showCards(card, `${get.translation(target)}因【追命】被展示`);
|
||
if (get.color(card) == color) {
|
||
trigger.directHit.addArray(game.players);
|
||
var evt = trigger.getParent();
|
||
if (evt.addCount !== false) {
|
||
evt.addCount = false;
|
||
player.getStat().card.sha--;
|
||
}
|
||
var map = trigger.getParent().customArgs;
|
||
var id = target.playerid;
|
||
if (!map[id]) map[id] = {};
|
||
if (typeof map[id].extraDamage != "number") {
|
||
map[id].extraDamage = 0;
|
||
}
|
||
map[id].extraDamage++;
|
||
game.log(trigger.card, "不计入次数限制、不可被响应、伤害+1");
|
||
}
|
||
},
|
||
},
|
||
//娄圭
|
||
jsrgshacheng: {
|
||
audio: 2,
|
||
trigger: { global: "useCardAfter" },
|
||
filter: function (event, player) {
|
||
if (event.card.name != "sha") return false;
|
||
return event.targets.some(i => i.isIn() && i.hasHistory("lose", evt => evt.cards2.length)) && player.getExpansions("jsrgshacheng").length;
|
||
},
|
||
direct: true,
|
||
group: "jsrgshacheng_build",
|
||
content: function () {
|
||
"step 0";
|
||
if (_status.connectMode)
|
||
game.broadcastAll(function () {
|
||
_status.noclearcountdown = true;
|
||
});
|
||
var targets = trigger.targets.filter(i => i.isIn() && i.hasHistory("lose", evt => evt.cards2.length));
|
||
player
|
||
.chooseTarget(get.prompt("jsrgshacheng"), "令一名目标角色摸X张牌,然后移去一张“城”(X为对应角色本回合失去过的牌数且至多为5)", (card, player, target) => {
|
||
return get.event("targets").includes(target);
|
||
})
|
||
.set("targets", targets)
|
||
.set("ai", target => {
|
||
return target == get.event("targetx") ? 1 : 0;
|
||
})
|
||
.set(
|
||
"targetx",
|
||
(() => {
|
||
let info = [];
|
||
targets.filter(target => {
|
||
let att = get.attitude(player, target);
|
||
if (att <= 0) return false;
|
||
if (Math.abs(att) > 1) att = Math.sign(att) * Math.sqrt(Math.abs(att));
|
||
info.push([
|
||
target,
|
||
att *
|
||
target
|
||
.getHistory("lose")
|
||
.map(evt => evt.cards2.length)
|
||
.reduce((p, c) => p + c, 0),
|
||
]);
|
||
return false;
|
||
});
|
||
if (!info.length) return null;
|
||
info = info.sort((a, b) => {
|
||
return b[1] - a[1];
|
||
})[0];
|
||
if (info[1] <= 0) return null;
|
||
return info[0];
|
||
})()
|
||
);
|
||
("step 1");
|
||
if (result.bool) {
|
||
event.target = result.targets[0];
|
||
var cards = player.getExpansions("jsrgshacheng");
|
||
if (cards.length == 1) event._result = { bool: true, links: cards };
|
||
else player.chooseButton([`沙城:移去一张“城”`, cards], true);
|
||
} else {
|
||
if (_status.connectMode) {
|
||
game.broadcastAll(function () {
|
||
delete _status.noclearcountdown;
|
||
game.stopCountChoose();
|
||
});
|
||
}
|
||
event.finish();
|
||
}
|
||
("step 2");
|
||
if (_status.connectMode) {
|
||
game.broadcastAll(function () {
|
||
delete _status.noclearcountdown;
|
||
game.stopCountChoose();
|
||
});
|
||
}
|
||
if (result.bool) {
|
||
player.logSkill("jsrgshacheng", target);
|
||
player.loseToDiscardpile(result.links);
|
||
target.draw(
|
||
Math.min(
|
||
5,
|
||
target
|
||
.getHistory("lose")
|
||
.map(evt => evt.cards2.length)
|
||
.reduce((p, c) => p + c, 0)
|
||
)
|
||
);
|
||
}
|
||
},
|
||
marktext: "城",
|
||
intro: {
|
||
content: "expansion",
|
||
markcount: "expansion",
|
||
},
|
||
onremove: function (player, skill) {
|
||
var cards = player.getExpansions(skill);
|
||
if (cards.length) player.loseToDiscardpile(cards);
|
||
},
|
||
subSkill: {
|
||
build: {
|
||
trigger: {
|
||
global: "phaseBefore",
|
||
player: "enterGame",
|
||
},
|
||
forced: true,
|
||
locked: false,
|
||
filter: function (event, player) {
|
||
return event.name != "phase" || game.phaseNumber == 0;
|
||
},
|
||
content: function () {
|
||
var cards = get.cards(2);
|
||
player.addToExpansion(cards, "gain2").gaintag.add("jsrgshacheng");
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgninghan: {
|
||
audio: 2,
|
||
init: player => {
|
||
game.addGlobalSkill("jsrgninghan_frozen");
|
||
},
|
||
onremove: player => {
|
||
if (!game.hasPlayer(current => current.hasSkill("jsrgninghan"), true)) game.removeGlobalSkill("jsrgninghan_frozen");
|
||
},
|
||
trigger: { global: "damageEnd" },
|
||
filter: function (event, player) {
|
||
if (!event.hasNature("ice")) return false;
|
||
return event.cards && event.cards.filterInD().length;
|
||
},
|
||
forced: true,
|
||
content: function () {
|
||
var cards = trigger.cards.filterInD();
|
||
player.addToExpansion(cards, "gain2").gaintag.add("jsrgshacheng");
|
||
},
|
||
subSkill: {
|
||
frozen: {
|
||
mod: {
|
||
cardnature: function (card, player) {
|
||
if (card.name === "sha" && get.suit(card) === "club") return "ice";
|
||
},
|
||
aiOrder: (player, card, num) => {
|
||
if (num && card.name === "sha" && game.hasNature(card, "ice")) {
|
||
let lg = game.findPlayer(current => current.hasSkill("jsrgninghan"));
|
||
if (lg) return num + 0.15 * Math.sign(get.attitude(player, lg));
|
||
}
|
||
},
|
||
},
|
||
trigger: { player: "dieAfter" },
|
||
filter: (event, player) => {
|
||
return !game.hasPlayer(current => !current.hasSkill("jsrgninghan"), true);
|
||
},
|
||
silent: true,
|
||
forceDie: true,
|
||
content: () => {
|
||
game.removeGlobalSkill("jsrgninghan_frozen");
|
||
},
|
||
},
|
||
},
|
||
ai: {
|
||
combo: "jsrgshacheng",
|
||
},
|
||
},
|
||
//张任
|
||
jsrgfuni: {
|
||
audio: 2,
|
||
trigger: { global: "roundStart" },
|
||
group: ["jsrgfuni_unlimit", "jsrgfuni_zero"],
|
||
forced: true,
|
||
direct: true,
|
||
content: function* (event, map) {
|
||
var player = map.player,
|
||
trigger = map.trigger;
|
||
var count = Math.ceil(game.countPlayer() / 2);
|
||
var result = yield player.chooseTarget(`伏匿:请选择至多${get.cnNumber(count)}名角色`, `令这些角色获得共计${get.cnNumber(count)}张【影】`, true, [1, count]).set("ai", target => {
|
||
return get.attitude(get.player(), target) + get.event().getRand(target.playerid);
|
||
});
|
||
if (result.bool) {
|
||
var targets = result.targets.slice().sortBySeat(_status.currentPhase);
|
||
player.logSkill("jsrgfuni", targets);
|
||
} else event.finish();
|
||
yield null;
|
||
var num = count / targets.length;
|
||
if (num == 1 || num == count) {
|
||
result = {
|
||
bool: true,
|
||
links: targets.map(current => {
|
||
return `${num}|${current.playerid}`;
|
||
}),
|
||
};
|
||
} else {
|
||
var dialog = ["伏匿:选择每名角色要获得的【影】数"];
|
||
var len = count - targets.length + 1;
|
||
for (var target of targets) {
|
||
dialog.addArray([
|
||
`<div class="text center">${get.translation(target)}</div>`,
|
||
[
|
||
Array.from({ length: len }).map((_, i) => {
|
||
return [`${i + 1}|${target.playerid}`, get.cnNumber(i + 1, true)];
|
||
}),
|
||
"tdnodes",
|
||
],
|
||
]);
|
||
}
|
||
result = yield player
|
||
.chooseButton(dialog, true)
|
||
.set("filterButton", button => {
|
||
var total = 0,
|
||
info = button.link.split("|");
|
||
var numFix = 0;
|
||
for (var buttonx of ui.selected.buttons) {
|
||
var infox = buttonx.link.split("|");
|
||
var num = parseInt(infox[0]);
|
||
total += num;
|
||
if (infox[1] == info[1]) numFix = num;
|
||
}
|
||
return total + parseInt(info[0]) - numFix <= get.event("count");
|
||
})
|
||
.set("count", count)
|
||
.set("filterOk", () => {
|
||
var total = 0;
|
||
for (var buttonx of ui.selected.buttons) {
|
||
total += parseInt(buttonx.link.split("|")[0]);
|
||
}
|
||
return total == get.event("count");
|
||
})
|
||
.set("selectButton", () => {
|
||
return [get.event("len"), Math.max(get.event("len"), ui.selected.buttons.length) + 1];
|
||
})
|
||
.set("len", targets.length)
|
||
.set("custom", {
|
||
add: {},
|
||
replace: {
|
||
button: function (button) {
|
||
if (!_status.event.isMine()) return;
|
||
if (button.classList.contains("selectable") == false) return;
|
||
if (button.classList.contains("selected")) {
|
||
ui.selected.buttons.remove(button);
|
||
button.classList.remove("selected");
|
||
if (_status.multitarget || _status.event.complexSelect) {
|
||
game.uncheck();
|
||
game.check();
|
||
}
|
||
} else {
|
||
var current = button.parentNode.querySelector(".selected");
|
||
if (current) {
|
||
ui.selected.buttons.remove(current);
|
||
current.classList.remove("selected");
|
||
}
|
||
button.classList.add("selected");
|
||
ui.selected.buttons.add(button);
|
||
}
|
||
game.check();
|
||
},
|
||
},
|
||
})
|
||
.set("processAI", () => {
|
||
return get.event("aiResult");
|
||
})
|
||
.set(
|
||
"aiResult",
|
||
(() => {
|
||
var result = targets.map(i => {
|
||
return [i == player ? 2 : 1, i.playerid];
|
||
});
|
||
var rest = count - targets.length - 1;
|
||
while (rest--) result[Math.floor(Math.random() * result.length)][0]++;
|
||
return {
|
||
bool: true,
|
||
links: result.map(i => `${i[0]}|${i[1]}`),
|
||
};
|
||
})()
|
||
);
|
||
}
|
||
if (result.bool) {
|
||
var links = result.links;
|
||
var list = [];
|
||
for (var link of links) {
|
||
var info = link.split("|");
|
||
var id = info[1];
|
||
var target = (_status.connectMode ? lib.playerOL : game.playerMap)[id];
|
||
player.line(target);
|
||
var yings = lib.card.ying.getYing(parseInt(info[0]));
|
||
list.push([target, yings]);
|
||
game.log(target, "获得了", yings);
|
||
}
|
||
game.loseAsync({
|
||
gain_list: list,
|
||
animate: "gain2",
|
||
}).setContent("gaincardMultiple");
|
||
}
|
||
},
|
||
subSkill: {
|
||
zero: {
|
||
priority: Infinity,
|
||
mod: {
|
||
attackRange: () => 0,
|
||
},
|
||
},
|
||
unlimit: {
|
||
audio: "jsrgfuni",
|
||
trigger: {
|
||
global: ["loseAfter", "loseAsyncAfter", "cardsDiscardAfter"],
|
||
},
|
||
filter: function (event, player) {
|
||
return event.getd().some(i => get.name(i, false) == "ying");
|
||
},
|
||
forced: true,
|
||
content: function () {
|
||
player.addTempSkill("jsrgfuni_buff");
|
||
},
|
||
},
|
||
buff: {
|
||
charlotte: true,
|
||
trigger: { player: "useCard1" },
|
||
forced: true,
|
||
popup: false,
|
||
content: function () {
|
||
trigger.directHit.addArray(game.players);
|
||
game.log(trigger.card, "不可被响应");
|
||
},
|
||
mark: true,
|
||
intro: {
|
||
content: "使用牌无距离限制且不能被响应",
|
||
},
|
||
mod: {
|
||
targetInRange: () => true,
|
||
},
|
||
},
|
||
},
|
||
ai: {
|
||
expose: 0.15,
|
||
halfneg: true,
|
||
},
|
||
},
|
||
jsrgchuanxin: {
|
||
audio: 2,
|
||
trigger: { global: "phaseJieshuBegin" },
|
||
filter: function (event, player) {
|
||
return (
|
||
player.countCards("hes") &&
|
||
game.hasPlayer(current =>
|
||
player.canUse(
|
||
{
|
||
name: "sha",
|
||
storage: { jsrgchuanxin: true },
|
||
},
|
||
current
|
||
)
|
||
)
|
||
);
|
||
},
|
||
direct: true,
|
||
content: function () {
|
||
var next = player.chooseToUse();
|
||
next.set("openskilldialog", `###${get.prompt("jsrgchuanxin")}###将一张牌当【杀】使用,且当一名角色受到此【杀】伤害时,此伤害+X(X为其本回合回复过的体力值)。`);
|
||
next.set("norestore", true);
|
||
next.set("_backupevent", "jsrgchuanxin_backup");
|
||
next.set("addCount", false);
|
||
next.set("logSkill", "jsrgchuanxin");
|
||
next.set("custom", {
|
||
add: {},
|
||
replace: { window: function () {} },
|
||
});
|
||
next.backup("jsrgchuanxin_backup");
|
||
},
|
||
subSkill: {
|
||
backup: {
|
||
filterCard: function (card) {
|
||
return get.itemtype(card) == "card";
|
||
},
|
||
viewAs: {
|
||
name: "sha",
|
||
storage: { jsrgchuanxin: true },
|
||
},
|
||
selectCard: 1,
|
||
position: "hes",
|
||
ai1: function (card) {
|
||
var player = get.player();
|
||
var maxVal = 5.5;
|
||
if (get.name(card, false) == "ying" && player.hasSkill("jsrgchuanxin")) maxVal -= 3;
|
||
return maxVal - get.value(card);
|
||
},
|
||
precontent: function () {
|
||
delete event.result.skill;
|
||
player.addTempSkill("jsrgchuanxin_add");
|
||
},
|
||
},
|
||
add: {
|
||
trigger: { global: "damageBegin3" },
|
||
filter: function (event, player) {
|
||
if (!event.card || !event.card.storage || !event.card.storage.jsrgchuanxin) return false;
|
||
if (event.getParent().type != "card") return false;
|
||
return game.hasGlobalHistory("changeHp", evt => {
|
||
return evt.getParent().name == "recover" && evt.player == event.player;
|
||
});
|
||
},
|
||
forced: true,
|
||
charlotte: true,
|
||
content: function () {
|
||
var num = game
|
||
.getGlobalHistory("changeHp", evt => {
|
||
return evt.getParent().name == "recover" && evt.player == trigger.player;
|
||
})
|
||
.map(evt => evt.num)
|
||
.reduce((p, c) => p + c, 0);
|
||
trigger.num += num;
|
||
game.log(trigger.card, "的伤害+" + num);
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//黄忠
|
||
jsrgcuifeng: {
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
limited: true,
|
||
skillAnimation: true,
|
||
animationColor: "orange",
|
||
locked: false,
|
||
chooseButton: {
|
||
dialog: function (event, player) {
|
||
var list = [];
|
||
for (var name of lib.inpile) {
|
||
var info = lib.card[name];
|
||
if (!info || info.notarget || (info.selectTarget && info.selectTarget != 1) || !get.tag({ name: name }, "damage")) continue;
|
||
if (name == "sha") {
|
||
list.push(["基本", "", "sha"]);
|
||
for (var nature of lib.inpile_nature) list.push(["基本", "", name, nature]);
|
||
} else if (get.type(name) == "trick") list.push(["锦囊", "", name]);
|
||
else if (get.type(name) == "basic") list.push(["基本", "", name]);
|
||
}
|
||
return ui.create.dialog("摧锋", [list, "vcard"]);
|
||
},
|
||
filter: function (button, player) {
|
||
return _status.event.getParent().filterCard(
|
||
{
|
||
name: button.link[2],
|
||
nature: button.link[3],
|
||
isCard: true,
|
||
storage: { jsrgcuifeng: true },
|
||
},
|
||
player,
|
||
_status.event.getParent()
|
||
);
|
||
},
|
||
check: function (button) {
|
||
var player = _status.event.player;
|
||
var effect = player.getUseValue({
|
||
name: button.link[2],
|
||
nature: button.link[3],
|
||
storage: { jsrgcuifeng: true },
|
||
});
|
||
if (effect > 0) return effect;
|
||
return 0;
|
||
},
|
||
backup: function (links, player) {
|
||
return {
|
||
audio: "jsrgcuifeng",
|
||
selectCard: -1,
|
||
filterCard: () => false,
|
||
popname: true,
|
||
viewAs: {
|
||
name: links[0][2],
|
||
nature: links[0][3],
|
||
isCard: true,
|
||
storage: { jsrgcuifeng: true },
|
||
},
|
||
precontent: function () {
|
||
player.logSkill("jsrgcuifeng");
|
||
player.awakenSkill("jsrgcuifeng");
|
||
delete event.result.skill;
|
||
if (!player.storage.jsrgcuifeng_check)
|
||
player
|
||
.when("phaseEnd")
|
||
.then(() => {
|
||
var num = 0;
|
||
player.checkHistory("sourceDamage", evt => {
|
||
if (evt.card.storage.jsrgcuifeng) num += evt.num;
|
||
});
|
||
if (num == 0 || num > 1) {
|
||
player.restoreSkill("jsrgcuifeng");
|
||
game.log(player, "重置了", "#g【摧锋】");
|
||
}
|
||
delete player.storage.jsrgcuifeng_check;
|
||
})
|
||
.translation("摧锋");
|
||
player.setStorage("jsrgcuifeng_check", true);
|
||
},
|
||
};
|
||
},
|
||
prompt: function (links, player) {
|
||
return "请选择" + (get.translation(links[0][3]) || "") + get.translation(links[0][2]) + "的目标";
|
||
},
|
||
},
|
||
mod: {
|
||
targetInRange: card => {
|
||
if (card.storage && card.storage.jsrgcuifeng) return true;
|
||
},
|
||
},
|
||
ai: {
|
||
order: 1.9,
|
||
result: {
|
||
player: 1,
|
||
},
|
||
},
|
||
},
|
||
jsrgdengnan: {
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
limited: true,
|
||
skillAnimation: true,
|
||
animationColor: "orange",
|
||
chooseButton: {
|
||
dialog: function (event, player) {
|
||
var list = [];
|
||
for (var name of lib.inpile) {
|
||
var info = lib.card[name];
|
||
if (!info || info.type != "trick" || info.notarget || get.tag({ name: name }, "damage")) continue;
|
||
list.push(["锦囊", "", name]);
|
||
}
|
||
return ui.create.dialog("登难", [list, "vcard"]);
|
||
},
|
||
filter: function (button, player) {
|
||
return _status.event.getParent().filterCard({ name: button.link[2], isCard: true }, player, _status.event.getParent());
|
||
},
|
||
check: function (button) {
|
||
var player = _status.event.player;
|
||
return player.getUseValue(button.link[2]);
|
||
},
|
||
backup: function (links, player) {
|
||
return {
|
||
audio: "jsrgdengnan",
|
||
selectCard: -1,
|
||
filterCard: () => false,
|
||
popname: true,
|
||
viewAs: {
|
||
name: links[0][2],
|
||
isCard: true,
|
||
storage: { jsrgdengnan: true },
|
||
},
|
||
precontent: function () {
|
||
player.logSkill("jsrgdengnan");
|
||
player.awakenSkill("jsrgdengnan");
|
||
delete event.result.skill;
|
||
if (!player.storage.jsrgdengnan_check)
|
||
player
|
||
.when("phaseEnd")
|
||
.then(() => {
|
||
var targets = [];
|
||
player.checkHistory("useCard", evt => {
|
||
if (evt.card.storage.jsrgdengnan) targets.addArray(evt.targets);
|
||
});
|
||
if (
|
||
targets.every(current => {
|
||
return current.hasHistory("damage");
|
||
})
|
||
) {
|
||
player.restoreSkill("jsrgdengnan");
|
||
game.log(player, "重置了", "#g【登难】");
|
||
}
|
||
delete player.storage.jsrgdengnan_check;
|
||
})
|
||
.translation("登难");
|
||
player.setStorage("jsrgdengnan_check", true);
|
||
},
|
||
};
|
||
},
|
||
prompt: function (links, player) {
|
||
return "请选择" + (get.translation(links[0][3]) || "") + get.translation(links[0][2]) + "的目标";
|
||
},
|
||
},
|
||
ai: {
|
||
order: 2,
|
||
result: {
|
||
player: 1,
|
||
},
|
||
},
|
||
},
|
||
//夏侯荣
|
||
jsrgfenjian: {
|
||
audio: 2,
|
||
enable: "chooseToUse",
|
||
locked: false,
|
||
filter: function (event, player) {
|
||
return ["juedou", "tao"].some(name => {
|
||
return (
|
||
!player.getStorage("jsrgfenjian_used").includes(name) &&
|
||
event.filterCard(
|
||
{
|
||
name: name,
|
||
isCard: true,
|
||
storage: { jsrgfenjian: true },
|
||
},
|
||
player,
|
||
event
|
||
)
|
||
);
|
||
});
|
||
},
|
||
hiddenCard: function (player, name) {
|
||
if (["juedou", "tao"].some(i => i == name && !player.getStorage("jsrgfenjian_used").includes(name))) return true;
|
||
return false;
|
||
},
|
||
chooseButton: {
|
||
dialog: function (event, player) {
|
||
var dialog = ui.create.dialog("奋剑", [["juedou", "tao"].filter(name => !player.getStorage("jsrgfenjian_used").includes(name)), "vcard"]);
|
||
dialog.direct = true;
|
||
return dialog;
|
||
},
|
||
filter: function (button, player) {
|
||
var evt = _status.event.getParent();
|
||
return evt.filterCard(
|
||
{
|
||
name: button.link[2],
|
||
isCard: true,
|
||
storage: { jsrgfenjian: true },
|
||
},
|
||
player,
|
||
evt
|
||
);
|
||
},
|
||
check: function (button) {
|
||
if (button.link[2] === "tao") {
|
||
let dying = _status.event.getParent(2).dying;
|
||
if (dying)
|
||
return get.effect(
|
||
dying,
|
||
{
|
||
name: "tao",
|
||
isCard: true,
|
||
storage: { jsrgfenjian: true },
|
||
},
|
||
_status.event.player
|
||
);
|
||
}
|
||
return _status.event.player.getUseValue({
|
||
name: button.link[2],
|
||
isCard: true,
|
||
storage: { jsrgfenjian: true },
|
||
});
|
||
},
|
||
backup: function (links) {
|
||
return {
|
||
audio: "jsrgfenjian",
|
||
viewAs: {
|
||
name: links[0][2],
|
||
isCard: true,
|
||
storage: { jsrgfenjian: true },
|
||
},
|
||
filterCard: () => false,
|
||
selectCard: -1,
|
||
precontent: function () {
|
||
player.logSkill("jsrgfenjian");
|
||
delete event.result.skill;
|
||
player.addTempSkill("jsrgfenjian_effect");
|
||
player.addMark("jsrgfenjian_effect", 1, false);
|
||
if (!player.storage.jsrgfenjian_used)
|
||
player.when({ global: "phaseAfter" }).then(() => {
|
||
delete player.storage.jsrgfenjian_used;
|
||
});
|
||
player.markAuto("jsrgfenjian_used", [event.result.card.name]);
|
||
},
|
||
};
|
||
},
|
||
prompt: function (links) {
|
||
return "奋剑:令你本回合受到的伤害+1,视为使用" + get.translation(links[0][2]);
|
||
},
|
||
},
|
||
mod: {
|
||
targetEnabled: function (card, player, target) {
|
||
if (player == target && card.storage && card.storage.jsrgfenjian) return false;
|
||
},
|
||
},
|
||
ai: {
|
||
order: function (item, player) {
|
||
return Math.max(get.order({ name: "juedou" }), get.order({ name: "tao" })) + 0.2;
|
||
},
|
||
result: {
|
||
player: player => {
|
||
if (_status.event.dying) return 2 * get.sgnAttitude(player, _status.event.dying);
|
||
return 1;
|
||
},
|
||
},
|
||
},
|
||
subSkill: {
|
||
effect: {
|
||
audio: "jsrgfenjian",
|
||
charlotte: true,
|
||
trigger: { player: "damageBegin3" },
|
||
forced: true,
|
||
onremove: true,
|
||
content: function () {
|
||
trigger.num += player.countMark("jsrgfenjian_effect");
|
||
},
|
||
intro: { content: "本回合受到的伤害+#" },
|
||
},
|
||
},
|
||
},
|
||
//孙尚香
|
||
jsrgguiji: {
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
filter: function (event, player) {
|
||
if (player.hasSkill("jsrgguiji_used")) return false;
|
||
return game.hasPlayer(current => lib.skill.jsrgguiji.filterTarget("keiki", player, current));
|
||
},
|
||
filterTarget: function (card, player, target) {
|
||
return target.countCards("h") < player.countCards("h") && target.hasSex("male");
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
player.swapHandcards(target);
|
||
player.addSkill("jsrgguiji_swapback");
|
||
player.markAuto("jsrgguiji_swapback", target);
|
||
player.addTempSkill("jsrgguiji_used");
|
||
},
|
||
ai: {
|
||
order: 6,
|
||
result: {
|
||
target: function (player, target) {
|
||
var val = player
|
||
.getCards("h")
|
||
.map(i => get.value(i))
|
||
.reduce((p, c) => p + c, 0);
|
||
var val2 = target
|
||
.getCards("h")
|
||
.map(i => get.value(i))
|
||
.reduce((p, c) => p + c, 0);
|
||
return val - val2;
|
||
},
|
||
},
|
||
},
|
||
subSkill: {
|
||
used: { charlotte: true },
|
||
swapback: {
|
||
audio: "jsrgguiji",
|
||
trigger: {
|
||
global: ["phaseUseEnd", "dieAfter"],
|
||
},
|
||
filter: function (event, player) {
|
||
return player.getStorage("jsrgguiji_swapback").includes(event.player);
|
||
},
|
||
charlotte: true,
|
||
direct: true,
|
||
check: function (event, player) {
|
||
return (
|
||
player
|
||
.getCards("h")
|
||
.map(i => get.value(i))
|
||
.reduce((p, c) => p + c, 0) <
|
||
event.player
|
||
.getCards("h")
|
||
.map(i => get.value(i))
|
||
.reduce((p, c) => p + c, 0) +
|
||
4 * Math.random()
|
||
);
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
player.unmarkAuto("jsrgguiji_swapback", [trigger.player]);
|
||
if (trigger.name == "phaseUse") {
|
||
player
|
||
.chooseBool(get.prompt("jsrgguiji_swapback", trigger.player), "与其交换手牌。")
|
||
.set("ai", () => {
|
||
return get.event("bool");
|
||
})
|
||
.set("bool", lib.skill.jsrgguiji_swapback.check(trigger, player) > 0);
|
||
} else {
|
||
event.finish();
|
||
}
|
||
("step 1");
|
||
if (result.bool) {
|
||
player.logSkill("jsrgguiji_swapback", trigger.player);
|
||
player.swapHandcards(trigger.player);
|
||
}
|
||
},
|
||
intro: {
|
||
content: "$的下个出牌阶段结束时,你可以与其交换手牌",
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgjiaohao: {
|
||
audio: 2,
|
||
trigger: { player: "phaseZhunbeiBegin" },
|
||
filter: function (event, player) {
|
||
return [1, 2, 3, 4, 5].some(i => player.countEmptySlot(i));
|
||
},
|
||
forced: true,
|
||
locked: false,
|
||
global: "jsrgjiaohao_g",
|
||
content: function () {
|
||
"step 0";
|
||
var count = Math.ceil([1, 2, 3, 4, 5].map(i => player.countEmptySlot(i)).reduce((p, c) => p + c, 0) / 2);
|
||
player.gain(lib.card.ying.getYing(count), "gain2");
|
||
},
|
||
subSkill: {
|
||
g: {
|
||
audio: "jsrgjiaohao",
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
filter: function (event, player) {
|
||
return game.hasPlayer(current => {
|
||
if (current == player || !current.hasSkill("jsrgjiaohao")) return false;
|
||
return player.hasCard(card => {
|
||
return get.type(card) == "equip" && current.canEquip(card);
|
||
});
|
||
});
|
||
},
|
||
filterTarget: function (card, player, target) {
|
||
if (target.isMin()) return false;
|
||
return target != player && target.hasSkill("jsrgjiaohao") && target.canEquip(card);
|
||
},
|
||
selectTarget: function () {
|
||
var num = game.countPlayer(current => {
|
||
return current.hasSkill("jsrgjiaohao");
|
||
});
|
||
return num > 1 ? 1 : -1;
|
||
},
|
||
filterCard: function (card) {
|
||
return get.type(card) == "equip";
|
||
},
|
||
check: function (card) {
|
||
var player = get.player();
|
||
if (player.countCards("he", { subtype: get.subtype(card) }) > 1) {
|
||
return 11 - get.equipValue(card);
|
||
}
|
||
return 6 - get.value(card);
|
||
},
|
||
prompt: function () {
|
||
var list = game.filterPlayer(current => {
|
||
return current.hasSkill("jsrgjiaohao");
|
||
});
|
||
return `将一张装备牌置于${get.translation(list)}${list.length > 1 ? "中的一人" : ""}的装备区`;
|
||
},
|
||
discard: false,
|
||
lose: false,
|
||
prepare: function (cards, player, targets) {
|
||
player.$give(cards, targets[0], false);
|
||
},
|
||
content: function () {
|
||
target.equip(cards[0]);
|
||
},
|
||
ai: {
|
||
order: 10,
|
||
result: {
|
||
target: function (player, target) {
|
||
var card = ui.selected.cards[0];
|
||
if (card) return get.effect(target, card, target, target);
|
||
return 0;
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//庞统
|
||
jsrgmanjuan: {
|
||
audio: 2,
|
||
trigger: {
|
||
player: "loseEnd",
|
||
global: ["equipEnd", "addJudgeEnd", "gainEnd", "loseAsyncEnd", "addToExpansionEnd"],
|
||
},
|
||
filter: function (event, player) {
|
||
return (player.countCards("h") == 0) ^ player.hasSkill("jsrgmanjuan_in");
|
||
},
|
||
forced: true,
|
||
locked: false,
|
||
firstDo: true,
|
||
silent: true,
|
||
content: function () {
|
||
"step 0";
|
||
if (!player.countCards("h")) {
|
||
var cards = [];
|
||
game.checkGlobalHistory("cardMove", evt => {
|
||
if ((evt.name == "lose" && evt.position == ui.discardPile) || evt.name == "cardsDiscard") {
|
||
cards.addArray(evt.cards.filterInD("d"));
|
||
}
|
||
});
|
||
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, "jsrgmanjuan");
|
||
player.addSkill("jsrgmanjuan_in");
|
||
} else {
|
||
player.removeSkill("jsrgmanjuan_in");
|
||
}
|
||
},
|
||
subSkill: {
|
||
in: {
|
||
audio: "jsrgmanjuan",
|
||
trigger: {
|
||
global: ["loseAfter", "loseAsyncAfter", "cardsDiscardAfter", "equipAfter"],
|
||
},
|
||
forced: true,
|
||
locked: false,
|
||
silent: true,
|
||
filter: function (event, player) {
|
||
var cards = event.getd();
|
||
return cards.length;
|
||
},
|
||
onremove: function (player) {
|
||
var cards2 = player.getCards("s", card => {
|
||
return card.hasGaintag("jsrgmanjuan");
|
||
});
|
||
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: ["jsrgmanjuan_use", "jsrgmanjuan_lose"],
|
||
content: function () {
|
||
var cards = [];
|
||
var idList = player.getCards("s", card => card.hasGaintag("jsrgmanjuan")).map(i => i._cardid);
|
||
game.checkGlobalHistory("cardMove", evt => {
|
||
if ((evt.name == "lose" && evt.position == ui.discardPile) || evt.name == "cardsDiscard") {
|
||
cards.addArray(evt.cards.filter(i => get.position(i, true) == "d" && !idList.includes(i.cardid)));
|
||
}
|
||
});
|
||
var cards2 = cards.map(card => {
|
||
var cardx = ui.create.card();
|
||
cardx.init(get.cardInfo(card));
|
||
cardx._cardid = card.cardid;
|
||
return cardx;
|
||
});
|
||
player.directgains(cards2, null, "jsrgmanjuan");
|
||
},
|
||
mod: {
|
||
cardEnabled2: function (card, player) {
|
||
if (get.itemtype(card) == "card" && card.hasGaintag("jsrgmanjuan") && player.getStorage("jsrgmanjuan_used").includes(get.number(card, false))) return false;
|
||
},
|
||
},
|
||
},
|
||
use: {
|
||
trigger: {
|
||
player: ["useCardBefore", "respondBefore"],
|
||
},
|
||
charlotte: true,
|
||
forced: true,
|
||
popup: false,
|
||
firstDo: true,
|
||
filter: function (event, player) {
|
||
var cards = player.getCards("s", card => card.hasGaintag("jsrgmanjuan") && card._cardid);
|
||
return (
|
||
event.cards &&
|
||
event.cards.some(card => {
|
||
return cards.includes(card);
|
||
})
|
||
);
|
||
},
|
||
content: function () {
|
||
var idList = player.getCards("s", card => card.hasGaintag("jsrgmanjuan")).map(i => i._cardid);
|
||
var cards = [];
|
||
game.checkGlobalHistory("cardMove", evt => {
|
||
if ((evt.name == "lose" && evt.position == ui.discardPile) || evt.name == "cardsDiscard") {
|
||
cards.addArray(evt.cards.filter(i => idList.includes(i.cardid)));
|
||
}
|
||
});
|
||
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();
|
||
if (!player.storage.jsrgmanjuan_used) {
|
||
player.when({ global: "phaseAfter" }).then(() => {
|
||
delete player.storage.jsrgmanjuan_used;
|
||
});
|
||
}
|
||
player.markAuto(
|
||
"jsrgmanjuan_used",
|
||
cards3.map(card => get.number(card, false))
|
||
);
|
||
},
|
||
},
|
||
lose: {
|
||
trigger: {
|
||
global: ["loseEnd", "equipEnd", "addJudgeEnd", "gainEnd", "loseAsyncEnd", "addToExpansionEnd", "cardsGotoOrderingBegin", "phaseAfter"],
|
||
},
|
||
charlotte: true,
|
||
forced: true,
|
||
popup: false,
|
||
firstDo: true,
|
||
filter: function (event, player) {
|
||
if (event.name == "phase") return true;
|
||
var idList = player.getCards("s", card => card.hasGaintag("jsrgmanjuan")).map(i => i._cardid);
|
||
return (
|
||
event.cards &&
|
||
event.cards.some(card => {
|
||
return idList.includes(card.cardid);
|
||
})
|
||
);
|
||
},
|
||
content: function () {
|
||
var cards2;
|
||
if (trigger.name == "phase") {
|
||
cards2 = player.getCards("s", card => {
|
||
return card.hasGaintag("jsrgmanjuan");
|
||
});
|
||
} else {
|
||
var idList = [];
|
||
game.checkGlobalHistory("cardMove", evt => {
|
||
if ((evt.name == "lose" && evt.position == ui.discardPile) || evt.name == "cardsDiscard") {
|
||
idList.addArray(evt.cards.filter(i => get.position(i, true) == "d").map(i => i.cardid));
|
||
}
|
||
});
|
||
cards2 = player.getCards("s", card => {
|
||
return card.hasGaintag("jsrgmanjuan") && !idList.includes(card._cardid);
|
||
});
|
||
}
|
||
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();
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgyangming: {
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
filter: function (event, player) {
|
||
return game.hasPlayer(current => {
|
||
return player.canCompare(current);
|
||
});
|
||
},
|
||
filterTarget: function (card, player, current) {
|
||
return player.canCompare(current);
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
target.addTempSkill("jsrgyangming_lose", "phaseUseAfter");
|
||
("step 1");
|
||
player.chooseToCompare(target).set(
|
||
"small",
|
||
get.attitude(player, target) > 0 &&
|
||
(player.countCards("h", card => {
|
||
return get.value(card) < 6;
|
||
}) <= 1 ||
|
||
target.countCards("h", card => {
|
||
return get.value(card) < 6;
|
||
}) <= 1)
|
||
);
|
||
("step 2");
|
||
if (result.winner != target) {
|
||
if (!player.canCompare(target)) event._result = { bool: false };
|
||
else
|
||
player
|
||
.chooseBool("是否与其重复此拼点流程?")
|
||
.set("ai", () => get.event("bool"))
|
||
.set("bool", get.effect(target, "jsrgyangming", player, player) > 0);
|
||
game.broadcastAll(target => {
|
||
target.storage.jsrgyangming_lose++;
|
||
}, target);
|
||
} else {
|
||
if (target.storage.jsrgyangming_lose) target.draw(target.storage.jsrgyangming_lose);
|
||
player.recover();
|
||
event.finish();
|
||
}
|
||
("step 3");
|
||
if (result.bool) {
|
||
event.goto(1);
|
||
}
|
||
},
|
||
ai: {
|
||
order: 1,
|
||
expose: 0.15,
|
||
result: {
|
||
target: function (player, target) {
|
||
var maxnum = 0;
|
||
var cards2 = target.getCards("h");
|
||
for (var i = 0; i < cards2.length; i++) {
|
||
if (get.number(cards2[i]) > maxnum) {
|
||
maxnum = get.number(cards2[i]);
|
||
}
|
||
}
|
||
if (maxnum > 10) maxnum = 10;
|
||
if (maxnum < 5 && cards2.length > 1) maxnum = 5;
|
||
var cards = player.getCards("h");
|
||
for (var i = 0; i < cards.length; i++) {
|
||
if (get.number(cards[i]) < maxnum) return 1;
|
||
}
|
||
return 0;
|
||
},
|
||
},
|
||
},
|
||
subSkill: {
|
||
lose: {
|
||
init(player, skill) {
|
||
player.storage[skill] = 0;
|
||
},
|
||
onremove: true,
|
||
charlotte: true,
|
||
},
|
||
},
|
||
},
|
||
//韩遂
|
||
jsrgniluan: {
|
||
audio: "niluan",
|
||
trigger: { player: "phaseZhunbeiBegin" },
|
||
direct: true,
|
||
content: function () {
|
||
"step 0";
|
||
var damaged = game.filterPlayer(current => {
|
||
return current.hasAllHistory("sourceDamage", evt => evt.player == player);
|
||
});
|
||
var undamaged = game.filterPlayer().removeArray(damaged);
|
||
player.chooseCardTarget({
|
||
prompt: get.prompt("jsrgniluan"),
|
||
prompt2: `${undamaged.length ? "选择一张牌弃置并选择一名未对你造成过伤害的角色,你对其造成1点伤害" : ""}${undamaged.length && damaged.length ? ";<br>或" : ""}${damaged.length ? "仅选择一名对你造成过伤害的角色,你令其摸两张牌" : ""}。`,
|
||
damaged: damaged,
|
||
aiTarget: (() => {
|
||
if (
|
||
undamaged.includes(player) &&
|
||
!undamaged.some(i => {
|
||
if (i === player) return false;
|
||
let att = get.attitude(player, i);
|
||
if (att > 0) return true;
|
||
return att < 0 && i.getHp(true) + i.hujia < 2;
|
||
}) &&
|
||
(player.hp > 2 || get.damageEffect(player, player, player) >= 0)
|
||
)
|
||
return player;
|
||
var info = game
|
||
.filterPlayer()
|
||
.map(current => {
|
||
let damage = undamaged.includes(current),
|
||
card = { name: damage ? "damage" : "draw" };
|
||
return [current, get.effect(current, card, player, player) * (damage ? 0.7 : 2)];
|
||
})
|
||
.sort((a, b) => b[1] - a[1])[0];
|
||
if (info[1] > 0) return info[0];
|
||
return null;
|
||
})(),
|
||
filterCard: lib.filter.cardDiscardable,
|
||
selectCard: function () {
|
||
if (get.event("damaged").length == 0) return 1;
|
||
if (get.event("damaged").length == game.countPlayer()) return 0;
|
||
return [0, 1];
|
||
},
|
||
position: "he",
|
||
filterTarget: function (card, player, target) {
|
||
var damaged = get.event("damaged");
|
||
return damaged.includes(target) ^ (ui.selected.cards.length > 0);
|
||
},
|
||
selectTarget: 1,
|
||
ai1: function (card) {
|
||
if (get.event("damaged").includes(get.event("aiTarget"))) return 0;
|
||
return 6 - get.value(card);
|
||
},
|
||
ai2: function (target) {
|
||
return target == get.event("aiTarget") ? 10 : 0;
|
||
},
|
||
});
|
||
("step 1");
|
||
if (result.bool) {
|
||
var cards = result.cards,
|
||
target = result.targets[0];
|
||
player.logSkill("jsrgniluan", target);
|
||
if (cards && cards.length) {
|
||
player.discard(cards);
|
||
game.delayex();
|
||
target.damage();
|
||
} else {
|
||
target.draw(2);
|
||
}
|
||
}
|
||
},
|
||
},
|
||
jsrghuchou: {
|
||
audio: 2,
|
||
trigger: { source: "damageBegin1" },
|
||
filter: function (event, player) {
|
||
const history = _status.globalHistory;
|
||
for (let i = history.length - 1; i >= 0; i--) {
|
||
let evts = history[i]["useCard"];
|
||
for (let j = evts.length - 1; j >= 0; j--) {
|
||
var evt = evts[j];
|
||
let card = evt.card,
|
||
targets = evt.targets;
|
||
if (!get.tag(card, "damage") || !targets.includes(player)) continue;
|
||
return event.player == evt.player;
|
||
}
|
||
}
|
||
return false;
|
||
},
|
||
forced: true,
|
||
content: function () {
|
||
trigger.num++;
|
||
},
|
||
ai: {
|
||
damageBonus: true,
|
||
skillTagFilter: (player, tag, arg) => {
|
||
if (tag === "damageBonus" && arg && arg.target) {
|
||
const history = _status.globalHistory;
|
||
for (let i = history.length - 1; i >= 0; i--) {
|
||
let evts = history[i]["useCard"];
|
||
for (let j = evts.length - 1; j >= 0; j--) {
|
||
var evt = evts[j];
|
||
let card = evt.card,
|
||
targets = evt.targets;
|
||
if (!get.tag(card, "damage") || !targets.includes(player)) continue;
|
||
return arg.target === evt.player;
|
||
}
|
||
}
|
||
return false;
|
||
}
|
||
},
|
||
effect: {
|
||
player: (card, player, target) => {
|
||
if (
|
||
get.tag(card, "damage") &&
|
||
target &&
|
||
lib.skill.jsrghuchou.ai.skillTagFilter(player, "damageBonus", {
|
||
card: card,
|
||
target: target,
|
||
}) &&
|
||
!target.hasSkillTag("filterDamage", null, {
|
||
player: player,
|
||
card: card,
|
||
})
|
||
)
|
||
return [1, 0, 2, 0];
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgjiemeng: {
|
||
audio: 2,
|
||
zhuSkill: true,
|
||
forced: true,
|
||
init: () => {
|
||
game.addGlobalSkill("jsrgjiemeng_effect");
|
||
},
|
||
onremove: () => {
|
||
if (!game.hasPlayer(i => i.hasSkill("jsrgjiemeng"), true)) game.removeGlobalSkill("jsrgjiemeng_effect");
|
||
},
|
||
subSkill: {
|
||
effect: {
|
||
mod: {
|
||
globalFrom: function (from, to, distance) {
|
||
if (from.group != "qun") return;
|
||
if (to.hasZhuSkill("jsrgjiemeng")) return;
|
||
return distance - game.countPlayer(current => current.group == "qun");
|
||
},
|
||
},
|
||
trigger: { player: "dieAfter" },
|
||
filter: () => {
|
||
return !game.hasPlayer(i => i.hasSkill("jsrgjiemeng"), true);
|
||
},
|
||
silent: true,
|
||
forceDie: true,
|
||
content: () => {
|
||
game.removeGlobalSkill("jsrgjiemeng_effect");
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//张楚
|
||
jsrghuozhong: {
|
||
audio: "dcjizhong",
|
||
global: "jsrghuozhong_g",
|
||
subSkill: {
|
||
g: {
|
||
audio: "dcjizhong",
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
filter: function (event, player) {
|
||
if (player.hasJudge("bingliang")) return false;
|
||
if (!game.hasPlayer(current => current.hasSkill("jsrghuozhong"))) return false;
|
||
return player.countCards("hes", card => get.color(card) == "black" && get.type2(card) != "trick") > 0;
|
||
},
|
||
viewAs: { name: "bingliang" },
|
||
position: "hes",
|
||
discard: false,
|
||
prompt: function () {
|
||
var list = game.filterPlayer(target => {
|
||
return target.hasSkill("jsrghuozhong");
|
||
});
|
||
return `将一张黑色非锦囊牌当【兵粮寸断】置于自己的判定区,然后令${get.translation(list)}${list.length > 1 ? "中的一人" : ""}摸两张牌。`;
|
||
},
|
||
filterCard: function (card, player, event) {
|
||
return get.color(card) == "black" && get.type2(card) != "trick" && player.canAddJudge({ name: "bingliang", cards: [card] });
|
||
},
|
||
selectTarget: -1,
|
||
filterTarget: function (card, player, target) {
|
||
return player == target;
|
||
},
|
||
check: function (card) {
|
||
return 6 - get.value(card);
|
||
},
|
||
precontent: function* (event, map) {
|
||
var player = map.player;
|
||
var targets = game.filterPlayer(current => current.hasSkill("jsrghuozhong"));
|
||
var result;
|
||
if (targets.length) result = { bool: true, targets: targets };
|
||
else
|
||
result = yield player
|
||
.chooseTarget("请选择一名传教士,发动其的【惑众】", true, (card, player, target) => {
|
||
return get.event("targets").includes(target);
|
||
})
|
||
.set("targets", targets);
|
||
if (result.bool) {
|
||
var target = result.targets[0];
|
||
player.logSkill("jsrghuozhong", target);
|
||
var next = game.createEvent("jsrghuozhong_draw", false);
|
||
next.set("player", player);
|
||
next.set("target", target);
|
||
event.next.remove(next);
|
||
event.getParent().after.push(next);
|
||
next.setContent(function () {
|
||
target.draw(2);
|
||
});
|
||
}
|
||
},
|
||
ai: {
|
||
result: {
|
||
player: function (player) {
|
||
if (game.hasPlayer(current => get.attitude(player, current) > 2 && current.hasSkill("jsrghuozhong"))) return 1;
|
||
return 0;
|
||
},
|
||
},
|
||
order: 9,
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgrihui: {
|
||
audio: "dcrihui",
|
||
locked: false,
|
||
trigger: { source: "damageSource" },
|
||
filter: function (event, player) {
|
||
return (
|
||
event.getParent().type == "card" &&
|
||
event.card &&
|
||
event.card.name == "sha" &&
|
||
game.hasPlayer(current => {
|
||
return current != player && current.countCards("j");
|
||
})
|
||
);
|
||
},
|
||
prompt: "是否发动【日彗】?",
|
||
prompt2: function (event, player) {
|
||
var list = game.filterPlayer(current => {
|
||
return current != player && current.countCards("j");
|
||
});
|
||
return `令${get.translation(list)}${list.length > 1 ? "各" : ""}摸一张牌。`;
|
||
},
|
||
logTarget: function (event, player) {
|
||
return game.filterPlayer(current => {
|
||
return current != player && current.countCards("j");
|
||
});
|
||
},
|
||
group: "jsrgrihui_sha",
|
||
content: function () {
|
||
game.asyncDraw(lib.skill.jsrgrihui.logTarget(trigger, player));
|
||
},
|
||
mod: {
|
||
cardUsableTarget: function (card, player, target) {
|
||
if (card.name == "sha" && !player.getStorage("jsrgrihui_targeted").includes(target)) return true;
|
||
},
|
||
},
|
||
subSkill: {
|
||
sha: {
|
||
trigger: { player: "useCardToPlayered" },
|
||
forced: true,
|
||
silent: true,
|
||
firstDo: true,
|
||
content: function () {
|
||
player.addTempSkill("jsrgrihui_targeted");
|
||
player.markAuto("jsrgrihui_targeted", trigger.target);
|
||
},
|
||
},
|
||
targeted: {
|
||
charlotte: true,
|
||
onremove: true,
|
||
},
|
||
},
|
||
},
|
||
//夏侯恩
|
||
jsrghujian: {
|
||
audio: "twfujian",
|
||
trigger: {
|
||
global: "phaseEnd",
|
||
},
|
||
filter: function (event, player) {
|
||
if (!Array.from(ui.discardPile.childNodes).some(i => i.name == "chixueqingfeng")) return false;
|
||
return game.hasGlobalHistory("everything", evt => ["useCard", "respond"].includes(evt.name) && evt.player.isIn());
|
||
},
|
||
popup: false,
|
||
forced: true,
|
||
locked: false,
|
||
group: "jsrghujian_begin",
|
||
content: function () {
|
||
"step 0";
|
||
var cards = Array.from(ui.discardPile.childNodes).filter(i => i.name == "chixueqingfeng");
|
||
if (cards.length) {
|
||
event.cards = cards;
|
||
var history = _status.globalHistory,
|
||
target = null;
|
||
for (var i = history.length - 1; i >= 0 && !target; i--) {
|
||
var evts = history[i]["everything"];
|
||
for (var j = evts.length - 1; j >= 0; j--) {
|
||
var evt = evts[j];
|
||
if (!["useCard", "respond"].includes(evt.name)) continue;
|
||
target = evt.player;
|
||
break;
|
||
}
|
||
}
|
||
if (target && target.isIn()) {
|
||
event.target = target;
|
||
target.chooseBool(`是否响应${get.translation(player)}的【护剑】?`, "获得弃牌堆里的【赤血青锋】。");
|
||
} else event.finish();
|
||
} else event.finish();
|
||
("step 1");
|
||
if (result.bool) {
|
||
player.logSkill("jsrghujian");
|
||
player.line(target);
|
||
target.gain(cards, "gain2");
|
||
}
|
||
},
|
||
subSkill: {
|
||
begin: {
|
||
audio: "twfujian",
|
||
trigger: {
|
||
global: "phaseBefore",
|
||
player: "enterGame",
|
||
},
|
||
forced: true,
|
||
locked: false,
|
||
filter: function (event, player) {
|
||
return event.name != "phase" || game.phaseNumber == 0;
|
||
},
|
||
content: function () {
|
||
player.gain(game.createCard2("chixueqingfeng", "spade", 6), "gain2");
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgshili: {
|
||
audio: "twjianwei",
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
viewAs: {
|
||
name: "juedou",
|
||
},
|
||
filterCard: { type: "equip" },
|
||
position: "hs",
|
||
viewAsFilter: function (player) {
|
||
return player.hasCard({ type: "equip" }, "hs");
|
||
},
|
||
check: function (card) {
|
||
return (get.name(card, false) == "chixueqingfeng" ? 20 : 12) - _status.event.player.getUseValue(card);
|
||
},
|
||
ai: {
|
||
order: 0.001,
|
||
},
|
||
},
|
||
//范疆张达
|
||
jsrgfushan: {
|
||
audio: 2,
|
||
trigger: { player: "phaseUseBegin" },
|
||
forced: true,
|
||
locked: false,
|
||
filter: function (event, player) {
|
||
return game.hasPlayer(i => i != player);
|
||
},
|
||
content: function* (event, map) {
|
||
var player = map.player,
|
||
trigger = map.trigger,
|
||
targets = game.filterPlayer(i => i != player);
|
||
var shas = player.mayHaveSha(target, "use", null, "count") - player.getCardUsable("sha", true);
|
||
for (var target of targets) {
|
||
var att = get.attitude(target, player);
|
||
var result = yield target
|
||
.chooseCard("he", `负山:是否交给${get.translation(player)}一张牌?`, `若如此做,其此阶段使用【杀】的次数上限+1`)
|
||
.set("att", att)
|
||
.set("ai", card => {
|
||
if (!get.event("goon")) return -get.value(card);
|
||
var isSha = get.name(card, get.event("target")) == "sha";
|
||
if (get.event("att") < 0) return (isSha ? 0 : 5) - get.value(card);
|
||
return (isSha ? 10 : 0) - get.value(card);
|
||
})
|
||
.set("goon", (att > 0 && shas >= 0) || (att < 0 && target.hp > player.getCardUsable("sha", true) && shas < -1 / Math.max(1, player.hp)))
|
||
.set("target", player);
|
||
if (result.bool) {
|
||
target.give(result.cards, player);
|
||
target.line(player);
|
||
player.addTempSkill("jsrgfushan_sha", "phaseAfter");
|
||
player.addMark("jsrgfushan_sha", 1, false);
|
||
player.markAuto("jsrgfushan_given", target);
|
||
}
|
||
}
|
||
player
|
||
.when("phaseUseAfter")
|
||
.filter(evt => evt == trigger)
|
||
.then(() => {
|
||
player.logSkill("jsrgfushan");
|
||
if (
|
||
player.getCardUsable("sha", true) >
|
||
player.getHistory("useCard", evt => {
|
||
return evt.getParent("phaseUse") == trigger && evt.card.name == "sha" && evt.addCount !== false;
|
||
}).length &&
|
||
player.storage.jsrgfushan_given &&
|
||
player.storage.jsrgfushan_given.every(i => i.isIn())
|
||
) {
|
||
player.loseHp(2);
|
||
} else {
|
||
player.drawTo(player.maxHp);
|
||
}
|
||
delete player.storage.jsrgfushan_given;
|
||
});
|
||
},
|
||
subSkill: {
|
||
sha: {
|
||
charlotte: true,
|
||
onremove: true,
|
||
marktext: "负",
|
||
intro: { content: "使用【杀】的次数上限+#" },
|
||
mod: {
|
||
cardUsable: function (card, player, num) {
|
||
if (card.name == "sha") return num + player.countMark("jsrgfushan_sha");
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//江山如故·承
|
||
//404孙策
|
||
jsrgduxing: {
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
viewAs: {
|
||
name: "juedou",
|
||
storage: { jsrgduxing: true },
|
||
isCard: true,
|
||
},
|
||
viewAsFilter: function (player) {
|
||
if (player.hasSkill("jsrgduxing_used")) return false;
|
||
},
|
||
filterCard: () => false,
|
||
selectCard: -1,
|
||
selectTarget: [1, Infinity],
|
||
precontent: function () {
|
||
player.logSkill("jsrgduxing");
|
||
delete event.result.skill;
|
||
var targets = event.result.targets;
|
||
for (var target of targets) {
|
||
target.addTempSkill("jsrgduxing_allsha");
|
||
}
|
||
player.addTempSkill("jsrgduxing_restore");
|
||
player.addTempSkill("jsrgduxing_used", "phaseUseAfter");
|
||
},
|
||
ai: {
|
||
order: 5,
|
||
result: {
|
||
player: function (player, target) {
|
||
var eff = Math.sign(get.effect(target, { name: "juedou" }, player, player));
|
||
if (
|
||
player.hasSkillTag(
|
||
"directHit_ai",
|
||
true,
|
||
{
|
||
target: target,
|
||
card: { name: "juedou" },
|
||
},
|
||
true
|
||
) ||
|
||
ui.selected.targets.concat(target).reduce((p, c) => {
|
||
return p + c.countCards("h");
|
||
}, 0) < player.countCards("h", "sha")
|
||
) {
|
||
return 0;
|
||
}
|
||
return -114514;
|
||
},
|
||
target: -1.5,
|
||
},
|
||
},
|
||
subSkill: {
|
||
allsha: {
|
||
charlotte: true,
|
||
mod: {
|
||
cardname: function (card, player, name) {
|
||
return "sha";
|
||
},
|
||
},
|
||
},
|
||
used: {
|
||
charlotte: true,
|
||
},
|
||
restore: {
|
||
charlotte: true,
|
||
trigger: {
|
||
global: "useCardAfter",
|
||
},
|
||
forced: true,
|
||
popup: false,
|
||
forceDie: true,
|
||
forceOut: true,
|
||
filter: function (event, player) {
|
||
return event.card.name == "juedou" && event.card.storage && event.card.storage.jsrgduxing;
|
||
},
|
||
content: function () {
|
||
game.countPlayer(current => {
|
||
current.removeSkill("jsrgduxing_allsha");
|
||
}, true);
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgzhiheng: {
|
||
audio: 2,
|
||
trigger: {
|
||
source: "damageBegin1",
|
||
},
|
||
forced: true,
|
||
filter: function (event, player) {
|
||
if (event.getParent().type != "card") return false;
|
||
var respondEvts = [];
|
||
respondEvts.addArray(event.player.getHistory("useCard")).addArray(event.player.getHistory("respond"));
|
||
respondEvts = respondEvts.filter(i => i.respondTo).map(evt => evt.respondTo);
|
||
return respondEvts.some(list => {
|
||
return list[0] == player;
|
||
});
|
||
},
|
||
content: function () {
|
||
trigger.num++;
|
||
},
|
||
},
|
||
jsrgzhasi: {
|
||
audio: 2,
|
||
trigger: {
|
||
player: "damageBegin4",
|
||
},
|
||
limited: true,
|
||
skillAnimation: true,
|
||
animationColor: "wood",
|
||
filter: function (event, player) {
|
||
return event.num >= player.getHp();
|
||
},
|
||
content: function () {
|
||
player.awakenSkill("jsrgzhasi");
|
||
trigger.cancel();
|
||
player.changeSkills(["rezhiheng"], ["jsrgzhiheng"]);
|
||
player.addSkill("jsrgzhasi_undist");
|
||
},
|
||
derivation: "rezhiheng",
|
||
subSkill: {
|
||
undist: {
|
||
group: "undist",
|
||
trigger: {
|
||
player: ["useCardAfter", "damageEnd"],
|
||
},
|
||
filter: function (event, player) {
|
||
if (event.name == "useCard")
|
||
return event.targets.some(target => {
|
||
return target != player;
|
||
});
|
||
return true;
|
||
},
|
||
forced: true,
|
||
popup: false,
|
||
charlotte: true,
|
||
content: function () {
|
||
player.removeSkill("jsrgzhasi_undist");
|
||
},
|
||
mark: true,
|
||
intro: {
|
||
content: "诈死中,不计入距离和座次的计算",
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgbashi: {
|
||
audio: 2,
|
||
trigger: { player: "chooseToRespondBefore" },
|
||
zhuSkill: true,
|
||
filter: function (event, player) {
|
||
if (event.responded) return false;
|
||
if (player.storage.jsrgbashiing) return false;
|
||
if (!player.hasZhuSkill("jsrgbashi")) return false;
|
||
if (!event.filterCard({ name: "sha" }, player, event) && !event.filterCard({ name: "shan" }, player, event)) return false;
|
||
return game.hasPlayer(function (current) {
|
||
return current != player && current.group == "wu";
|
||
});
|
||
},
|
||
check: function (event, player) {
|
||
if (get.damageEffect(player, event.player, player) >= 0) return false;
|
||
return true;
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
event.targets = game.filterPlayer();
|
||
("step 1");
|
||
var target = event.targets.shift();
|
||
event.target = target;
|
||
if (!target) event.finish();
|
||
else if (!target.isIn() || target == player) event.redo();
|
||
else if (target.group == "wu") {
|
||
if ((target == game.me && !_status.auto) || get.attitude(target, player) > 2 || target.isOnline()) {
|
||
player.storage.jsrgbashiing = true;
|
||
var list = ["sha", "shan"].filter(name => trigger.filterCard({ name: name }, player, trigger));
|
||
var names = list.map(i => "【" + get.translation(i) + "】").join("或");
|
||
var next = target.chooseToRespond("是否替" + get.translation(player) + "打出一张" + names + "?", { name: list });
|
||
next.set("ai", function () {
|
||
var event = _status.event;
|
||
return get.attitude(event.player, event.source) - 2;
|
||
});
|
||
next.set("skillwarn", "替" + get.translation(player) + "打出一张" + names);
|
||
next.autochoose = function () {
|
||
if (!lib.filter.autoRespondSha.apply(this, arguments)) return false;
|
||
return lib.filter.autoRespondShan.apply(this, arguments);
|
||
};
|
||
next.set("source", player);
|
||
}
|
||
}
|
||
("step 2");
|
||
delete player.storage.jsrgbashiing;
|
||
if (result.bool) {
|
||
event.finish();
|
||
var name = result.card.name;
|
||
trigger.result = { bool: true, card: { name: name, isCard: true } };
|
||
trigger.responded = true;
|
||
trigger.animate = false;
|
||
if (typeof target.ai.shown == "number" && target.ai.shown < 0.95) {
|
||
target.ai.shown += 0.3;
|
||
if (target.ai.shown > 0.95) target.ai.shown = 0.95;
|
||
}
|
||
} else {
|
||
event.goto(1);
|
||
}
|
||
},
|
||
ai: {
|
||
respondSha: true,
|
||
respondShan: true,
|
||
skillTagFilter: function (player, tag, arg) {
|
||
if (arg == "use") return false;
|
||
if (player.storage.jsrgbashiing) return false;
|
||
if (!player.hasZhuSkill("jsrgbashi")) return false;
|
||
return game.hasPlayer(function (current) {
|
||
return current != player && current.group == "wu";
|
||
});
|
||
},
|
||
},
|
||
},
|
||
//许攸
|
||
jsrglipan: {
|
||
forbid: ["guozhan"],
|
||
audio: 2,
|
||
trigger: {
|
||
player: "phaseEnd",
|
||
},
|
||
direct: true,
|
||
content: function () {
|
||
"step 0";
|
||
var list = lib.group.slice();
|
||
list.remove(player.group);
|
||
var getV = function (group) {
|
||
var val = 1;
|
||
if (group == "wei" || group == "qun") val++;
|
||
game.countPlayer(current => {
|
||
if (current.group != group) return false;
|
||
var att = get.attitude(player, current);
|
||
if (att > 0) val++;
|
||
else if (att == 0) val += 0.5;
|
||
else val--;
|
||
});
|
||
return val;
|
||
};
|
||
var maxGroup = list.slice().sort((a, b) => {
|
||
return getV(b) - getV(a);
|
||
})[0];
|
||
list.push("cancel2");
|
||
player
|
||
.chooseControl(list)
|
||
.set("prompt", get.prompt("jsrglipan"))
|
||
.set("prompt2", "变更为另一个势力")
|
||
.set("ai", () => {
|
||
return _status.event.choice;
|
||
})
|
||
.set("choice", maxGroup);
|
||
("step 1");
|
||
var group = result.control;
|
||
if (group == "cancel2") return;
|
||
player.logSkill("jsrglipan");
|
||
player.popup(group + "2", get.groupnature(group, "raw"));
|
||
player.changeGroup(group);
|
||
var num = game.countPlayer(current => {
|
||
return current.group == group && current != player;
|
||
});
|
||
if (num > 0) player.draw(num);
|
||
var next = player.phaseUse();
|
||
next.jsrglipan = true;
|
||
event.next.remove(next);
|
||
trigger.next.push(next);
|
||
player.addTempSkill("jsrglipan_backfire");
|
||
},
|
||
subSkill: {
|
||
backfire: {
|
||
trigger: {
|
||
player: "phaseUseEnd",
|
||
},
|
||
charlotte: true,
|
||
forced: true,
|
||
popup: false,
|
||
filter: function (event, player) {
|
||
return event.jsrglipan;
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
var targets = game.filterPlayer(current => {
|
||
return current.group == player.group;
|
||
});
|
||
targets.sortBySeat();
|
||
event.targets = targets;
|
||
("step 1");
|
||
var target = targets.shift();
|
||
event.target = target;
|
||
if (target && target.isIn() && target.canUse({ name: "juedou" }, player)) {
|
||
target.chooseCardTarget({
|
||
position: "hes",
|
||
prompt: "是否将一张牌当【决斗】对" + get.translation(player) + "使用?",
|
||
filterCard: function (card, player) {
|
||
return player.canUse(get.autoViewAs({ name: "juedou" }, [card]), _status.event.getParent().player);
|
||
},
|
||
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: "juedou" }, [card]);
|
||
return lib.filter.filterTarget.apply(this, arguments);
|
||
},
|
||
selectTarget: function () {
|
||
var card = get.card(),
|
||
player = get.player();
|
||
if (!card) return;
|
||
card = get.autoViewAs({ name: "juedou" }, [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: "juedou" }, [card]), player, player);
|
||
if (eff <= 0) 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: "juedou" }, _status.event.player);
|
||
},
|
||
});
|
||
}
|
||
("step 2");
|
||
if (result.bool) {
|
||
var cards = result.cards;
|
||
var cardx = get.autoViewAs({ name: "juedou" }, cards);
|
||
var targets = result.targets.filter(targetx => {
|
||
return target.canUse(cardx, targetx);
|
||
});
|
||
if (targets.length) target.useCard(cardx, cards, targets);
|
||
}
|
||
if (targets.length) event.goto(1);
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgqingxi: {
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
filter: function (event, player) {
|
||
if (player.group != "qun") return false;
|
||
return game.hasPlayer(current => lib.skill.jsrgqingxi.filterTarget("", player, current));
|
||
},
|
||
groupSkill: true,
|
||
filterTarget: function (card, player, target) {
|
||
if (target.countCards("h") >= player.countCards("h")) return false;
|
||
return !player.getStorage("jsrgqingxi_used").includes(target);
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
player.addTempSkill("jsrgqingxi_used", "phaseUseAfter");
|
||
player.markAuto("jsrgqingxi_used", [target]);
|
||
var num = player.countCards("h") - target.countCards("h");
|
||
if (num > 0) player.chooseToDiscard(num, true, "轻袭:弃置" + get.cnNumber(num) + "张手牌");
|
||
("step 1");
|
||
var card = {
|
||
name: "sha",
|
||
nature: "stab",
|
||
isCard: true,
|
||
};
|
||
if (player.canUse(card, target, false)) player.useCard(card, target, false);
|
||
},
|
||
ai: {
|
||
order: 8,
|
||
result: {
|
||
target: (player, target) => {
|
||
let num = player.countCards("h") - target.countCards("h"),
|
||
eff = get.effect(target, { name: "sha", nature: "stab" }, player, target),
|
||
val = 0,
|
||
ph = _status.event.getTempCache("jsrgqingxi_result", "ph");
|
||
if (!ph) {
|
||
ph = player.getCards("h").sort((a, b) => {
|
||
return get.value(a) - get.value(b);
|
||
});
|
||
_status.event.putTempCache("jsrgqingxi_result", "ph", ph);
|
||
}
|
||
ph.slice(0, num).forEach(i => {
|
||
val += get.value(i, player);
|
||
});
|
||
eff = Math.sign(eff) * Math.sqrt(Math.abs(eff));
|
||
if (val > 2 * Math.abs(eff)) return 0;
|
||
return eff / num;
|
||
},
|
||
},
|
||
},
|
||
subSkill: {
|
||
used: {
|
||
onremove: true,
|
||
charlotte: true,
|
||
},
|
||
},
|
||
},
|
||
jsrgjinmie: {
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
filter: function (event, player) {
|
||
if (player.group != "wei") return false;
|
||
return game.hasPlayer(current => current.countCards("h") > player.countCards("h"));
|
||
},
|
||
groupSkill: true,
|
||
filterTarget: function (card, player, target) {
|
||
return target.countCards("h") > player.countCards("h");
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
var card = {
|
||
name: "sha",
|
||
nature: "fire",
|
||
storage: { jsrgjinmie: target },
|
||
isCard: true,
|
||
};
|
||
if (player.canUse(card, target, false)) {
|
||
player.useCard(card, target, false);
|
||
player.addTempSkill("jsrgjinmie_effect");
|
||
}
|
||
},
|
||
ai: {
|
||
order: 0.5,
|
||
result: {
|
||
target: function (player, target) {
|
||
var eff = get.effect(target, { name: "sha", nature: "fire" }, player, target) / 30;
|
||
if (
|
||
!target.mayHaveShan(
|
||
player,
|
||
"use",
|
||
target.getCards("h", i => {
|
||
return i.hasGaintag("sha_notshan");
|
||
})
|
||
)
|
||
)
|
||
eff *= 2;
|
||
var del = target.countCards("h") - player.countCards("h") + 1.5;
|
||
eff *= Math.sqrt(del);
|
||
return eff;
|
||
},
|
||
},
|
||
},
|
||
subSkill: {
|
||
effect: {
|
||
trigger: {
|
||
source: "damageSource",
|
||
},
|
||
filter: function (event, player) {
|
||
return event.card && event.card.storage && event.card.storage.jsrgjinmie && event.card.storage.jsrgjinmie.isIn();
|
||
},
|
||
forced: true,
|
||
popup: false,
|
||
charlotte: true,
|
||
content: function () {
|
||
"step 0";
|
||
var target = trigger.card.storage.jsrgjinmie;
|
||
var del = target.countCards("h") - player.countCards("h");
|
||
if (del > 0) {
|
||
player.line(target);
|
||
player.discardPlayerCard(target, "h", true, del);
|
||
}
|
||
// else if(del<0){
|
||
// player.line(target);
|
||
// target.draw(-del);
|
||
// }
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//吕布
|
||
jsrgwuchang: {
|
||
forbid: ["guozhan"],
|
||
audio: 2,
|
||
trigger: {
|
||
player: "gainAfter",
|
||
global: "loseAsyncAfter",
|
||
},
|
||
forced: true,
|
||
filter: function (event, player) {
|
||
var cards = event.getg(player);
|
||
if (!cards.length) return false;
|
||
return game.hasPlayer(current => {
|
||
if (current == player) return false;
|
||
return event.getl(current).cards2.length;
|
||
});
|
||
},
|
||
group: "jsrgwuchang_add",
|
||
content: function () {
|
||
"step 0";
|
||
var targets = game.filterPlayer(current => {
|
||
if (current == player) return false;
|
||
return trigger.getl(current).cards2.length;
|
||
});
|
||
var target = targets[0];
|
||
player.changeGroup(target.group);
|
||
player.popup(target.group + "2", get.groupnature(target.group, "raw"));
|
||
},
|
||
subSkill: {
|
||
add: {
|
||
trigger: {
|
||
source: "damageBegin1",
|
||
},
|
||
filter: function (event, player) {
|
||
if (!event.card || !["sha", "juedou"].includes(event.card.name) || event.getParent().type != "card") return false;
|
||
return event.player.group == player.group;
|
||
},
|
||
forced: true,
|
||
content: function () {
|
||
"step 0";
|
||
trigger.num++;
|
||
var group = "qun";
|
||
player.changeGroup(group);
|
||
player.popup(group + "2", get.groupnature(group, "raw"));
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgqingjiao: {
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
filter: function (event, player) {
|
||
if (player.group != "qun") return false;
|
||
if (!player.countCards("hes")) return false;
|
||
return (
|
||
(!player.hasSkill("jsrgqingjiao_tuixinzhifu") &&
|
||
game.hasPlayer(current => {
|
||
return current.countCards("h") > player.countCards("h");
|
||
})) ||
|
||
(!player.hasSkill("jsrgqingjiao_chenghuodajie") &&
|
||
game.hasPlayer(current => {
|
||
return current.countCards("h") < player.countCards("h");
|
||
}))
|
||
);
|
||
},
|
||
groupSkill: true,
|
||
position: "hes",
|
||
filterCard: true,
|
||
selectCard: 1,
|
||
discard: false,
|
||
lose: false,
|
||
delay: false,
|
||
filterTarget: function (card, player, target) {
|
||
var mod = game.checkMod(ui.selected.cards[0], player, "unchanged", "cardEnabled2", player);
|
||
if (!mod) return false;
|
||
var del = target.countCards("h") - player.countCards("h");
|
||
if (del == 0) return false;
|
||
var name = del > 0 ? "tuixinzhifu" : "chenghuodajie";
|
||
if (player.hasSkill("jsrgqingjiao_" + name)) return false;
|
||
return player.canUse({ name: name, cards: ui.selected.cards }, target);
|
||
},
|
||
content: function () {
|
||
var del = target.countCards("h") - player.countCards("h");
|
||
var name = del > 0 ? "tuixinzhifu" : "chenghuodajie";
|
||
player.useCard({ name: name }, target, cards);
|
||
player.addTempSkill("jsrgqingjiao_" + name, "phaseUseAfter");
|
||
},
|
||
ai: {
|
||
order: 7,
|
||
result: {
|
||
player: function (player, target) {
|
||
var name = target.countCards("h") > player.countCards("h") ? "tuixinzhifu" : "chenghuodajie";
|
||
var list = [];
|
||
if (ui.selected.cards.length) list.addArray(ui.selected.cards);
|
||
var card = get.autoViewAs({ name: name }, list);
|
||
return get.effect(target, card, player, player);
|
||
},
|
||
},
|
||
},
|
||
subSkill: {
|
||
tuixinzhifu: {
|
||
charlotte: true,
|
||
},
|
||
chenghuodajie: {
|
||
charlotte: true,
|
||
},
|
||
},
|
||
},
|
||
jsrgchengxu: {
|
||
audio: 2,
|
||
trigger: { player: "useCard" },
|
||
forced: true,
|
||
locked: false,
|
||
filter: function (event, player) {
|
||
if (player.group != "shu") return false;
|
||
return game.hasPlayer(current => {
|
||
return current != player && current.group == player.group;
|
||
});
|
||
},
|
||
groupSkill: true,
|
||
content: function () {
|
||
trigger.directHit.addArray(
|
||
game.filterPlayer(current => {
|
||
return current != player && current.group == player.group;
|
||
})
|
||
);
|
||
},
|
||
ai: {
|
||
directHit_ai: true,
|
||
skillTagFilter: function (player, tag, arg) {
|
||
return player.group == "shu" && player.group == arg.target.group;
|
||
},
|
||
},
|
||
},
|
||
//张郃
|
||
jsrgqiongtu: {
|
||
audio: 2,
|
||
enable: "chooseToUse",
|
||
groupSkill: true,
|
||
viewAs: {
|
||
name: "wuxie",
|
||
suit: "none",
|
||
number: null,
|
||
isCard: true,
|
||
},
|
||
filter: function (event, player) {
|
||
if (!player.countCards("he", card => _status.connectMode || get.type(card) != "basic")) return false;
|
||
return player.group == "qun" && !player.hasSkill("jsrgqiongtu_check");
|
||
},
|
||
viewAsFilter: function (player) {
|
||
if (!player.countCards("he", card => _status.connectMode || get.type(card) != "basic")) return false;
|
||
return player.group == "qun" && !player.hasSkill("jsrgqiongtu_check");
|
||
},
|
||
filterCard: function (card) {
|
||
return get.type(card) != "basic";
|
||
},
|
||
position: "he",
|
||
popname: true,
|
||
ignoreMod: true,
|
||
precontent: function () {
|
||
"step 0";
|
||
player.logSkill("jsrgqiongtu");
|
||
delete event.result.skill;
|
||
var card = event.result.cards[0];
|
||
event.card = card;
|
||
event.result.card = {
|
||
name: event.result.card.name,
|
||
storage: { jsrgqiongtu: true },
|
||
isCard: true,
|
||
};
|
||
event.result.cards = [];
|
||
player.addToExpansion(card, player, "give").gaintag.add("jsrgqiongtu");
|
||
player.addTempSkill("jsrgqiongtu_check");
|
||
},
|
||
marktext: "途",
|
||
intro: {
|
||
content: "expansion",
|
||
markcount: "expansion",
|
||
},
|
||
onremove: function (player, skill) {
|
||
var cards = player.getExpansions(skill);
|
||
if (cards.length) player.loseToDiscardpile(cards);
|
||
delete player.storage[skill];
|
||
},
|
||
subSkill: {
|
||
check: {
|
||
trigger: {
|
||
global: "useCardAfter",
|
||
},
|
||
filter: function (event, player) {
|
||
return event.card.name == "wuxie" && event.card.storage && event.card.storage.jsrgqiongtu;
|
||
},
|
||
forced: true,
|
||
popup: false,
|
||
charlotte: true,
|
||
content: function () {
|
||
"step 0";
|
||
game.delayx();
|
||
var evt = trigger.getParent(4);
|
||
if (evt.name == "phaseJudge") {
|
||
state = evt.cancelled;
|
||
} else {
|
||
state = evt._neutralized;
|
||
}
|
||
if (state) {
|
||
player.draw();
|
||
} else {
|
||
player.changeGroup("wei");
|
||
var cards = player.getExpansions("jsrgqiongtu");
|
||
if (cards.length) player.gain(cards, "gain2");
|
||
}
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgxianzhu: {
|
||
audio: 2,
|
||
enable: "chooseToUse",
|
||
filter: function (event, player) {
|
||
return (
|
||
player.group == "wei" &&
|
||
player.hasCard(card => {
|
||
return _status.connectMode || get.type(card) == "trick";
|
||
}, "hs")
|
||
);
|
||
},
|
||
groupSkill: true,
|
||
locked: false,
|
||
viewAs: {
|
||
name: "sha",
|
||
storage: { jsrgxianzhu: true },
|
||
},
|
||
position: "hs",
|
||
filterCard: function (card) {
|
||
return get.type(card) == "trick";
|
||
},
|
||
check: function (card) {
|
||
var player = _status.event.player;
|
||
var cardx = {
|
||
name: "sha",
|
||
storage: { jsrgxianzhu: true },
|
||
cards: [card],
|
||
};
|
||
if (
|
||
game.hasPlayer(current => {
|
||
return player.canUse(cardx, current) && get.effect(current, card, player, player) > 0 && get.effect(current, cardx, player, player) > 0;
|
||
})
|
||
)
|
||
return 15 - get.value(card);
|
||
return 0;
|
||
},
|
||
onuse: function (links, player) {
|
||
player.addTempSkill("jsrgxianzhu_after");
|
||
},
|
||
mod: {
|
||
cardUsable: function (card) {
|
||
if (card.storage && card.storage.jsrgxianzhu) return Infinity;
|
||
},
|
||
},
|
||
subSkill: {
|
||
after: {
|
||
trigger: {
|
||
global: "damageSource",
|
||
},
|
||
filter: function (event, player) {
|
||
var targets = event.getParent(2).targets;
|
||
if (!targets || targets.length != 1) return false;
|
||
if (!event.card || !event.card.storage || !event.card.storage.jsrgxianzhu) return false;
|
||
var target = event.player,
|
||
card = event.cards[0];
|
||
if (!target.isIn()) return false;
|
||
if (get.type(card) != "trick") return false;
|
||
if (!player.canUse(card, target, false)) return false;
|
||
return true;
|
||
},
|
||
forced: true,
|
||
charlotte: true,
|
||
group: "jsrgxianzhu_inf",
|
||
content: function () {
|
||
var card = {
|
||
name: trigger.cards[0].name,
|
||
isCard: true,
|
||
};
|
||
player.useCard(card, trigger.player, false);
|
||
game.delayx();
|
||
},
|
||
},
|
||
inf: {
|
||
trigger: { player: "useCard1" },
|
||
forced: true,
|
||
popup: false,
|
||
firstDo: true,
|
||
filter: function (event, player) {
|
||
if (event.card.storage && event.card.storage.jsrgxianzhu && event.addCount !== false) return true;
|
||
return false;
|
||
},
|
||
content: function () {
|
||
trigger.addCount = false;
|
||
var stat = player.getStat().card,
|
||
name = trigger.card.name;
|
||
if (typeof stat[name] == "number") stat[name]--;
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//邹氏
|
||
jsrgguyin: {
|
||
audio: 2,
|
||
trigger: {
|
||
player: "phaseZhunbeiBegin",
|
||
},
|
||
check: function (event, player) {
|
||
return player.isTurnedOver() || game.countPlayer2(current => current.hasSex("male")) >= 2;
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
player.turnOver();
|
||
("step 1");
|
||
var targets = game.filterPlayer(current => current != player && current.hasSex("male"));
|
||
event.targets = targets;
|
||
player.line(targets);
|
||
game.delayx();
|
||
("step 2");
|
||
var target = targets.shift();
|
||
event.target = target;
|
||
target
|
||
.chooseBool("是否响应" + get.translation(player) + "的【孤吟】?", "你可以翻面。")
|
||
.set("ai", () => {
|
||
return _status.event.bool;
|
||
})
|
||
.set(
|
||
"bool",
|
||
(function () {
|
||
return target.isTurnedOver() || (get.attitude(target, player) > 0 && (game.countPlayer2(current => current.hasSex("male")) >= 3 || (target.getHp() <= 1 && player.hasSkill("jsrgzhangdeng"))));
|
||
})()
|
||
);
|
||
("step 3");
|
||
if (result.bool) {
|
||
target.turnOver();
|
||
}
|
||
if (targets.length) event.goto(2);
|
||
("step 4");
|
||
var targets = game.filterPlayer(current => {
|
||
return current == player || current.isTurnedOver();
|
||
});
|
||
event.targets = targets;
|
||
event.num = 0;
|
||
event.index = 0;
|
||
("step 5");
|
||
var target = targets[event.index];
|
||
if (target.isIn()) {
|
||
target.draw();
|
||
event.num++;
|
||
}
|
||
event.index++;
|
||
if (event.index >= targets.length) event.index = 0;
|
||
("step 6");
|
||
if (event.num >= game.countPlayer2(current => current.hasSex("male"))) event.finish();
|
||
else event.goto(5);
|
||
},
|
||
},
|
||
jsrgzhangdeng: {
|
||
audio: 2,
|
||
trigger: {
|
||
global: "logSkill",
|
||
},
|
||
filter: function (event, player) {
|
||
return (
|
||
event.player
|
||
.getHistory("useSkill", evt => {
|
||
return evt.skill == "jsrgzhangdeng_jiu";
|
||
})
|
||
.map(evt => evt.event)
|
||
.indexOf(event.log_event) == 1
|
||
);
|
||
},
|
||
global: "jsrgzhangdeng_jiu",
|
||
forced: true,
|
||
locked: false,
|
||
content: function () {
|
||
player.turnOver(false);
|
||
},
|
||
subSkill: {
|
||
jiu: {
|
||
audio: "jsrgzhangdeng",
|
||
enable: "chooseToUse",
|
||
filter: function (event, player) {
|
||
return (
|
||
player.isTurnedOver() &&
|
||
game.hasPlayer(current => {
|
||
return current.hasSkill("jsrgzhangdeng") && current.isTurnedOver();
|
||
})
|
||
);
|
||
},
|
||
viewAs: { name: "jiu", isCard: true },
|
||
viewAsFilter: function (player) {
|
||
return (
|
||
player.isTurnedOver() &&
|
||
game.hasPlayer(current => {
|
||
return current.hasSkill("jsrgzhangdeng") && current.isTurnedOver();
|
||
})
|
||
);
|
||
},
|
||
filterCard: () => false,
|
||
selectCard: -1,
|
||
precontent: function () {
|
||
player.logSkill("jsrgzhangdeng_jiu");
|
||
var targets = game.filterPlayer(current => {
|
||
return current.hasSkill("jsrgzhangdeng") && current.isTurnedOver();
|
||
});
|
||
player.line(targets[0]);
|
||
delete event.result.skill;
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//关羽
|
||
jsrgguanjue: {
|
||
audio: 2,
|
||
trigger: {
|
||
player: ["useCard", "respond"],
|
||
},
|
||
filter: function (event, player) {
|
||
return lib.suit.includes(get.suit(event.card));
|
||
},
|
||
forced: true,
|
||
content: function () {
|
||
"step 0";
|
||
var targets = game.filterPlayer(current => current != player);
|
||
var suit = get.suit(trigger.card);
|
||
for (var target of targets) {
|
||
target.addTempSkill("jsrgguanjue_ban");
|
||
target.markAuto("jsrgguanjue_ban", [suit]);
|
||
}
|
||
},
|
||
subSkill: {
|
||
ban: {
|
||
onremove: true,
|
||
charlotte: true,
|
||
mod: {
|
||
cardEnabled: function (card, player) {
|
||
if (player.getStorage("jsrgguanjue_ban").includes(get.suit(card))) return false;
|
||
},
|
||
cardRespondable: function (card, player) {
|
||
if (player.getStorage("jsrgguanjue_ban").includes(get.suit(card))) return false;
|
||
},
|
||
cardSavable: function (card, player) {
|
||
if (player.getStorage("jsrgguanjue_ban").includes(get.suit(card))) return false;
|
||
},
|
||
},
|
||
mark: true,
|
||
marktext: "绝",
|
||
intro: {
|
||
content: "本回合内不能使用或打出$的牌",
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgnianen: {
|
||
audio: 2,
|
||
enable: ["chooseToUse", "chooseToRespond"],
|
||
filter: function (event, player) {
|
||
if (!player.countCards("hes")) return false;
|
||
if (player.hasSkill("jsrgnianen_blocker")) return false;
|
||
for (var name of lib.inpile) {
|
||
if (get.type2(name) != "basic") continue;
|
||
var card = { name: name };
|
||
if (event.filterCard(get.autoViewAs(card, "unsure"), player, event)) return true;
|
||
if (name == "sha") {
|
||
for (var nature of lib.inpile_nature) {
|
||
card.nature = nature;
|
||
if (event.filterCard(get.autoViewAs(card, "unsure"), player, event)) return true;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
},
|
||
derivation: "mashu",
|
||
chooseButton: {
|
||
dialog: function (event, player) {
|
||
var list = [];
|
||
for (var name of lib.inpile) {
|
||
if (name == "sha") {
|
||
if (event.filterCard(get.autoViewAs({ name }, "unsure"), player, event)) list.push(["基本", "", "sha"]);
|
||
for (var nature of lib.inpile_nature) {
|
||
if (event.filterCard(get.autoViewAs({ name, nature }, "unsure"), player, event)) list.push(["基本", "", "sha", nature]);
|
||
}
|
||
} else if (get.type(name) == "basic" && event.filterCard(get.autoViewAs({ name }, "unsure"), player, event)) list.push(["基本", "", name]);
|
||
}
|
||
var dialog = ui.create.dialog("念恩", [list, "vcard"]);
|
||
dialog.direct = true;
|
||
return dialog;
|
||
},
|
||
filter: function (button, player) {
|
||
return _status.event.getParent().filterCard(get.autoViewAs({ name: button.link[2], nature: button.link[3] }, "unsure"), player, _status.event.getParent());
|
||
},
|
||
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;
|
||
return player.getUseValue({
|
||
name: button.link[2],
|
||
nature: button.link[3],
|
||
});
|
||
},
|
||
backup: function (links, player) {
|
||
return {
|
||
audio: "jsrgnianen",
|
||
filterCard: true,
|
||
popname: true,
|
||
check: function (card) {
|
||
return 8 - get.value(card);
|
||
},
|
||
position: "hes",
|
||
viewAs: { name: links[0][2], nature: links[0][3] },
|
||
precontent: function () {
|
||
player.logSkill("jsrgnianen");
|
||
delete event.result.skill;
|
||
var card = event.result.card;
|
||
if (get.color(card, player) != "red" || get.name(card) != "sha" || get.natureList(card).length) {
|
||
player.addTempSkill("jsrgnianen_blocker");
|
||
player.addAdditionalSkill("jsrgnianen_blocker", "mashu");
|
||
}
|
||
},
|
||
};
|
||
},
|
||
prompt: function (links, player) {
|
||
return "将一张牌当做" + (get.translation(links[0][3]) || "") + get.translation(links[0][2]) + "使用";
|
||
},
|
||
},
|
||
hiddenCard: function (player, name) {
|
||
if (!lib.inpile.includes(name)) return false;
|
||
var type = get.type2(name);
|
||
return type == "basic" && player.countCards("hes") > 0 && !player.hasSkill("jsrgnianen_blocker");
|
||
},
|
||
ai: {
|
||
fireAttack: true,
|
||
respondSha: true,
|
||
respondShan: true,
|
||
skillTagFilter: function (player) {
|
||
if (!player.countCards("hes") || player.hasSkill("jsrgnianen_blocker")) return false;
|
||
},
|
||
order: 1,
|
||
result: {
|
||
player: function (player) {
|
||
if (_status.event.dying) return get.attitude(player, _status.event.dying);
|
||
return 1;
|
||
},
|
||
},
|
||
},
|
||
subSkill: {
|
||
blocker: {
|
||
charlotte: true,
|
||
mark: true,
|
||
marktext: "恩",
|
||
intro: { content: "视为拥有〖马术〗" },
|
||
},
|
||
},
|
||
},
|
||
//生鱼片
|
||
jsrglunshi: {
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
filterTarget: function (card, player, target) {
|
||
return game.hasPlayer(current => {
|
||
return current.inRangeOf(target);
|
||
});
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
var num = game.countPlayer(current => {
|
||
return current.inRangeOf(target);
|
||
});
|
||
var len = target.countCards("h");
|
||
num = Math.max(0, Math.min(len + num, 5) - len);
|
||
if (num > 0) target.draw(num);
|
||
("step 1");
|
||
var num = game.countPlayer(current => {
|
||
return current.inRange(target);
|
||
});
|
||
if (num > 0) target.chooseToDiscard(num, "he", true, get.translation(player) + "对你发动了【论势】", "请弃置" + get.cnNumber(num) + "张牌");
|
||
},
|
||
ai: {
|
||
order: 6,
|
||
result: {
|
||
target: function (player, target) {
|
||
var num1 = game.countPlayer(current => {
|
||
return current.inRangeOf(target);
|
||
}),
|
||
num2 = game.countPlayer(current => {
|
||
return current.inRange(target);
|
||
});
|
||
var len = target.countCards("h");
|
||
num1 = Math.max(0, Math.min(len + num1, 5) - len);
|
||
return (num1 - num2 + 1) / 2;
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgguitu: {
|
||
audio: 2,
|
||
trigger: {
|
||
player: "phaseZhunbeiBegin",
|
||
},
|
||
direct: true,
|
||
filter: function (event, player) {
|
||
return (
|
||
game.countPlayer(current => {
|
||
return current.getEquips(1).length;
|
||
}) >= 2
|
||
);
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
player
|
||
.chooseTarget(
|
||
get.prompt2("jsrgguitu"),
|
||
(card, player, target) => {
|
||
return target.getEquips(1).length;
|
||
},
|
||
[1, 2]
|
||
)
|
||
.set("filterOk", () => {
|
||
var num = 0;
|
||
for (var target of ui.selected.targets) {
|
||
num += target.getEquips(1).length;
|
||
}
|
||
return num >= 2;
|
||
})
|
||
.set("ai", target => {
|
||
var sign = -1;
|
||
var val = 0;
|
||
if (ui.selected.targets.length) {
|
||
sign = 1;
|
||
var targetx = ui.selected.targets[0];
|
||
var cards = targetx.getEquips(1);
|
||
var list = cards.map(card => {
|
||
return [card, get.value(card, targetx)];
|
||
});
|
||
list.sort((a, b) => {
|
||
return b[1] - a[1];
|
||
});
|
||
val = get.attitude(_status.event.player, targetx) * list[0][1];
|
||
}
|
||
var cards = target.getEquips(1);
|
||
var list = cards.map(card => {
|
||
return [card, get.value(card, target)];
|
||
});
|
||
list.sort((a, b) => {
|
||
return b[1] - a[1];
|
||
});
|
||
return get.attitude(_status.event.player, target) * list[0][1] * sign - val;
|
||
});
|
||
("step 1");
|
||
if (result.bool) {
|
||
var targets = result.targets.slice();
|
||
targets.sortBySeat();
|
||
event.targets = targets;
|
||
player.logSkill("jsrgguitu", targets);
|
||
event.rangeList = targets.map(target => {
|
||
return target.getAttackRange();
|
||
});
|
||
var weapons = [];
|
||
for (var target of targets) {
|
||
weapons.addArray(target.getEquips(1));
|
||
}
|
||
if (weapons.length > 2) {
|
||
var list = ["诡图:选择要交换的武器牌"];
|
||
for (var target of targets) {
|
||
list.addArray(['<div class="text center">' + get.translation(target) + "的武器牌</div>", target.getEquips(1)]);
|
||
}
|
||
player
|
||
.chooseButton(list, true, 2)
|
||
.set("filterButton", button => {
|
||
var count = _status.event.count;
|
||
if (count == 1) return true;
|
||
for (var i = 0; i < ui.selected.buttons.length; i++) {
|
||
if (get.owner(button.link) == get.owner(ui.selected.buttons[i].link)) return false;
|
||
}
|
||
return true;
|
||
})
|
||
.set("count", targets.length)
|
||
.set("ai", button => {
|
||
var player = _status.event.player;
|
||
var card = button.link;
|
||
var owner = get.owner(card);
|
||
var att = get.attitude(player, owner);
|
||
var val = -get.value(card) * att;
|
||
return val;
|
||
});
|
||
} else event._result = { bool: true, links: weapons };
|
||
} else event.finish();
|
||
("step 2");
|
||
if (result.bool) {
|
||
var links = result.links;
|
||
var list = [];
|
||
for (var target of targets) {
|
||
var weapons = target.getEquips(1);
|
||
weapons = weapons.filter(i => links.includes(i));
|
||
if (weapons.length) {
|
||
list.push([target, weapons]);
|
||
}
|
||
}
|
||
if (list.length == 2) {
|
||
event.players = list.map(i => i[0]);
|
||
event.cards = list.map(i => i[1]);
|
||
} else {
|
||
event.players = [list[0][0], list[0][0]];
|
||
event.cards = list[0][1];
|
||
}
|
||
game.loseAsync({
|
||
player: event.players[0],
|
||
target: event.players[1],
|
||
cards1: event.cards[0],
|
||
cards2: event.cards[1],
|
||
}).setContent("swapHandcardsx");
|
||
} else event.finish();
|
||
("step 3");
|
||
for (var i = 0; i < event.cards[1].length; i++) {
|
||
if (get.position(event.cards[1][i], true) == "o") event.players[0].equip(event.cards[1][i]);
|
||
}
|
||
for (var i = 0; i < event.cards[0].length; i++) {
|
||
if (get.position(event.cards[0][i], true) == "o") event.players[1].equip(event.cards[0][i]);
|
||
}
|
||
("step 4");
|
||
var rangeList = targets.map(target => {
|
||
return target.getAttackRange();
|
||
});
|
||
for (var i = 0; i < targets.length; i++) {
|
||
if (rangeList[i] < event.rangeList[i]) {
|
||
targets[i].recover();
|
||
}
|
||
}
|
||
},
|
||
},
|
||
//甄宓
|
||
jsrgjixiang: {
|
||
audio: 2,
|
||
trigger: {
|
||
global: ["chooseToUseBegin", "chooseToRespondBegin"],
|
||
},
|
||
filter: function (event, player) {
|
||
if (player != _status.currentPhase) return false;
|
||
if (player == event.player) return false;
|
||
if (!player.countCards("he")) return false;
|
||
for (var name of lib.inpile) {
|
||
if (get.type(name) != "basic") continue;
|
||
if (player.getStorage("jsrgjixiang_used").includes(name)) continue;
|
||
var card = { name: name, isCard: true };
|
||
if (event.filterCard(card, event.player, event)) return true;
|
||
if (name == "sha") {
|
||
for (var nature of lib.inpile_nature) {
|
||
card.nature = nature;
|
||
if (event.filterCard(card, event.player, event)) return true;
|
||
}
|
||
}
|
||
}
|
||
return false;
|
||
},
|
||
direct: true,
|
||
global: "jsrgjixiang_save",
|
||
content: function () {
|
||
"step 0";
|
||
var list = [];
|
||
for (var name of lib.inpile) {
|
||
if (get.type(name) != "basic") continue;
|
||
var card = { name: name };
|
||
if (trigger.filterCard(card, trigger.player, trigger)) list.push(name);
|
||
}
|
||
var listx = [];
|
||
for (var name of list) {
|
||
if (player.getStorage("jsrgjixiang_used").includes(name)) continue;
|
||
listx.push([get.type2(name), "", name]);
|
||
if (name == "sha") {
|
||
for (var nature of lib.inpile_nature) {
|
||
if (trigger.filterCard({ name: name, nature: nature }, player, trigger)) {
|
||
listx.push([get.type2(name), "", name, nature]);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
var evt = trigger.getParent();
|
||
var names = "";
|
||
for (var i = 0; i < list.length; i++) {
|
||
names += "【" + get.translation(list[i]) + "】";
|
||
names += i < list.length - 2 ? "、" : "或";
|
||
}
|
||
names = names.slice(0, names.length - 1);
|
||
var reason = trigger.name == "chooseToUse" ? "使用" : "打出";
|
||
var used = player.getStorage("jsrgjixiang_used").filter(name => list.includes(name));
|
||
var str = get.translation(trigger.player) + (evt.card ? "因" + get.translation(evt.card) : "") + "需要" + reason + "一张" + names + ",是否弃置一张牌视为其" + reason + "之" + (used.length ? "(你不能以此法令其" + reason + get.translation(used) + ")" : "") + "?若如此做,你摸一张牌并令〖称贤〗此阶段可发动次数上限+1。";
|
||
event.str = str;
|
||
if (!listx.length) event.finish();
|
||
else if (listx.length == 1) event._result = { bool: true, links: listx };
|
||
else {
|
||
event.asked = true;
|
||
player.chooseButton(["###" + get.prompt("jsrgjixiang", trigger.player) + '###<div class="text center">' + str + "</div>", [listx, "vcard"]]).set("ai", () => Math.random() + 1);
|
||
}
|
||
event.list = list;
|
||
("step 1");
|
||
if (result.bool) {
|
||
var name = result.links[0][2],
|
||
nature = result.links[0][3];
|
||
var card = { name: name, nature: nature, isCard: true };
|
||
event.card = card;
|
||
var evt = trigger.getParent();
|
||
var reason = trigger.name == "chooseToUse" ? "使用" : "打出";
|
||
var prompt = event.asked ? "济乡:是否弃置一张牌" + (trigger.filterTarget ? "并选择目标角色" : "") + "?" : get.prompt("jsrgjixiang", trigger.player);
|
||
var str = event.asked ? "若如此做,视为" + get.translation(trigger.player) + reason + get.translation(card) + ",然后你摸一张牌并令〖称贤〗此阶段可发动次数上限+1。" : event.str;
|
||
var next = player.chooseCardTarget({
|
||
prompt: prompt,
|
||
prompt2: str,
|
||
filterCard: lib.filter.cardDiscardable,
|
||
position: "he",
|
||
goon: get.attitude(player, trigger.player) > 1 && (evt.card ? get.effect(trigger.player, evt.card, evt.player, player) < 0 : get.effect(trigger.player, { name: event.list[0] }, trigger.player, player) > 0),
|
||
ai1: function (card) {
|
||
if (_status.event.goon) return 6 - get.value(card);
|
||
return 0;
|
||
},
|
||
_get_card: card,
|
||
});
|
||
var keys = ["filterTarget", "selectTarget", "ai2"];
|
||
for (var key of keys) delete next[key];
|
||
for (var i in trigger) {
|
||
if (!(i in next)) next[i] = trigger[i];
|
||
}
|
||
next.filterTargetx = trigger.filterTarget || (() => false);
|
||
next.filterTarget = function (card, player, target) {
|
||
var filter = this.filterTargetx;
|
||
if (typeof filter != "function") filter = () => filter;
|
||
card = _status.event._get_card;
|
||
player = _status.event.getTrigger().player;
|
||
return this.filterTargetx.apply(this, arguments);
|
||
};
|
||
if (typeof next.selectTarget != "number" && typeof next.selectTarget != "function" && get.itemtype(next.selectTarget) != "select") next.selectTarget = -1;
|
||
} else event.finish();
|
||
("step 2");
|
||
if (result.bool) {
|
||
var cardx = result.cards[0];
|
||
var targets = result.targets || [];
|
||
event.targets = targets;
|
||
player.logSkill("jsrgjixiang", trigger.player);
|
||
player.addTempSkill("jsrgjixiang_used");
|
||
player.markAuto("jsrgjixiang_used", [card.name]);
|
||
player.discard(cardx);
|
||
trigger.untrigger();
|
||
trigger.set("responded", true);
|
||
var result = {
|
||
bool: true,
|
||
card: card,
|
||
};
|
||
if (targets.length) result.targets = targets;
|
||
trigger.result = result;
|
||
player.draw();
|
||
var phaseName;
|
||
for (var name of lib.phaseName) {
|
||
var evt = trigger.getParent(name);
|
||
if (!evt || evt.name != name) continue;
|
||
phaseName = name;
|
||
break;
|
||
}
|
||
if (phaseName) {
|
||
player.addTempSkill("jsrgjixiang_add", phaseName + "After");
|
||
player.addMark("jsrgjixiang_add", 1, false);
|
||
}
|
||
}
|
||
},
|
||
subSkill: {
|
||
used: {
|
||
charlotte: true,
|
||
onremove: true,
|
||
mark: true,
|
||
marktext: "乡",
|
||
intro: {
|
||
content: "已触发过牌名:$",
|
||
},
|
||
},
|
||
add: {
|
||
charlotte: true,
|
||
onremove: true,
|
||
mark: true,
|
||
intro: {
|
||
markcount: (storage, player) => 2 + (storage || 0),
|
||
content: (storage, player) => "〖称贤〗剩余可发动次数为" + (2 + (storage || 0)),
|
||
},
|
||
},
|
||
save: {
|
||
charlotte: true,
|
||
ai: {
|
||
save: true,
|
||
skillTagFilter: function (player, arg, target) {
|
||
return _status.currentPhase && _status.currentPhase != player && _status.currentPhase.hasSkill("jsrgjixiang") && _status.currentPhase.countCards("he");
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgchengxian: {
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
filter: function (event, player) {
|
||
if (!player.countCards("hs")) return false;
|
||
if (2 + player.countMark("jsrgjixiang_add") <= 0) return false;
|
||
for (var name of lib.inpile) {
|
||
if (get.type(name) != "trick") continue;
|
||
if (player.getStorage("jsrgchengxian_used").includes(name)) continue;
|
||
if (event.filterCard({ name: name }, player, event)) return true;
|
||
}
|
||
return false;
|
||
},
|
||
chooseButton: {
|
||
dialog: function (event, player) {
|
||
var list = [];
|
||
for (var name of lib.inpile) {
|
||
if (player.getStorage("jsrgchengxian_used").includes(name)) continue;
|
||
var info = get.info({ name: name });
|
||
if (!info || info.type != "trick") continue;
|
||
if (info.notarget) continue;
|
||
if (!info.selectTarget) continue;
|
||
if (get.type(name) == "trick" && event.filterCard({ name: name }, player, event)) list.push(["锦囊", "", name]);
|
||
}
|
||
var dialog = ui.create.dialog("称贤", [list, "vcard"]);
|
||
return dialog;
|
||
},
|
||
filter: function (button, player) {
|
||
return _status.event.getParent().filterCard({ name: button.link[2], nature: button.link[3] }, player, _status.event.getParent());
|
||
},
|
||
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;
|
||
return player.getUseValue({
|
||
name: button.link[2],
|
||
nature: button.link[3],
|
||
});
|
||
},
|
||
backup: function (links, player) {
|
||
return {
|
||
audio: "jsrgchengxian",
|
||
filterCard: function (card, player) {
|
||
var num = game.countPlayer(current => {
|
||
return player.canUse(card, current);
|
||
});
|
||
if (!num) return false;
|
||
var cardx = get.copy(lib.skill.jsrgchengxian_backup.viewAs);
|
||
cardx.cards = [card];
|
||
var num2 = game.countPlayer(current => {
|
||
return player.canUse(cardx, current);
|
||
});
|
||
return num == num2;
|
||
},
|
||
popname: true,
|
||
check: function (card) {
|
||
return 8 - get.value(card);
|
||
},
|
||
position: "hs",
|
||
viewAs: { name: links[0][2] },
|
||
precontent: function () {
|
||
player.logSkill("jsrgchengxian");
|
||
player.addTempSkill("jsrgjixiang_add");
|
||
if (typeof player.storage.jsrgjixiang_add != "number") player.storage.jsrgjixiang_add = 0;
|
||
player.storage.jsrgjixiang_add--;
|
||
player.addTempSkill("jsrgchengxian_used");
|
||
player.markAuto("jsrgchengxian_used", [event.result.card.name]);
|
||
delete event.result.skill;
|
||
},
|
||
};
|
||
},
|
||
prompt: function (links, player) {
|
||
return "将一张合法目标数与" + (get.translation(links[0][3]) || "") + get.translation(links[0][2]) + "相同的手牌当此牌使用";
|
||
},
|
||
},
|
||
//理解错了,下面这个不用了
|
||
getNumber: function (card, player) {
|
||
var rangex = null;
|
||
var info = get.info(card);
|
||
if (!info) return null;
|
||
if (info.notarget) return null;
|
||
if (info.selectTarget != undefined) {
|
||
var select = get.select(info.selectTarget);
|
||
if (select[0] < 0) {
|
||
if (!info.toself) {
|
||
var count = game.countPlayer(current => {
|
||
return lib.filter.targetEnabled(card, player, current);
|
||
});
|
||
} else count = 1;
|
||
rangex = [count, count];
|
||
} else rangex = select;
|
||
}
|
||
return rangex;
|
||
},
|
||
ai: {
|
||
order: 1,
|
||
result: {
|
||
player: function (player) {
|
||
if (_status.event.dying) return get.attitude(player, _status.event.dying);
|
||
return 1;
|
||
},
|
||
},
|
||
},
|
||
subSkill: {
|
||
used: {
|
||
charlotte: true,
|
||
onremove: true,
|
||
mark: true,
|
||
intro: {
|
||
content: "已使用过$",
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//张辽
|
||
jsrgzhengbing: {
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
usable: 3,
|
||
filter: function (event, player) {
|
||
return player.group == "qun";
|
||
},
|
||
filterCard: lib.filter.cardRecastable,
|
||
check: function (card) {
|
||
var player = _status.event.player,
|
||
val = 5 + ["shan", "tao"].includes(get.name(card)) * 1.5;
|
||
if (player.needsToDiscard() > 2 && get.name(card) == "sha" && player.countCards("hs", "sha") > 1) val += 0.5;
|
||
return val - get.value(card);
|
||
},
|
||
position: "he",
|
||
groupSkill: true,
|
||
lose: false,
|
||
discard: false,
|
||
delay: false,
|
||
content: function () {
|
||
"step 0";
|
||
player.recast(cards);
|
||
switch (get.name(cards[0])) {
|
||
case "sha":
|
||
player.addTempSkill("jsrgzhengbing_sha");
|
||
player.addMark("jsrgzhengbing_sha", 2, false);
|
||
break;
|
||
case "shan":
|
||
player.draw();
|
||
break;
|
||
case "tao":
|
||
player.changeGroup("wei");
|
||
}
|
||
},
|
||
ai: {
|
||
order: 7,
|
||
result: { player: 1 },
|
||
},
|
||
subSkill: {
|
||
sha: {
|
||
charlotte: true,
|
||
onremove: true,
|
||
mod: {
|
||
maxHandcard: function (player, num) {
|
||
return num + player.countMark("jsrgzhengbing_sha");
|
||
},
|
||
},
|
||
intro: {
|
||
content: "手牌上限+#",
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgtuwei: {
|
||
audio: 2,
|
||
trigger: {
|
||
player: "phaseUseBegin",
|
||
},
|
||
filter: function (event, player) {
|
||
return (
|
||
player.group == "wei" &&
|
||
game.hasPlayer(current => {
|
||
return player.inRange(current) && current.countGainableCards(player, "he") > 0;
|
||
})
|
||
);
|
||
},
|
||
groupSkill: true,
|
||
direct: true,
|
||
content: function () {
|
||
"step 0";
|
||
player
|
||
.chooseTarget(
|
||
get.prompt("jsrgtuwei"),
|
||
"获得攻击范围内任意名角色的各一张牌。然后回合结束时这些角色中未受过伤害的角色依次获得你的一张牌。",
|
||
(card, player, target) => {
|
||
return player.inRange(target) && target.countGainableCards(player, "he") > 0;
|
||
},
|
||
[1, Infinity]
|
||
)
|
||
.set("ai", target => {
|
||
var player = _status.event.player;
|
||
return get.effect(target, { name: "shunshou_copy2" }, player, player);
|
||
});
|
||
("step 1");
|
||
if (result.bool) {
|
||
var targets = result.targets.slice();
|
||
targets.sortBySeat();
|
||
player.logSkill("jsrgtuwei", targets);
|
||
player.gainMultiple(result.targets, "he");
|
||
player.addTempSkill("jsrgtuwei_backfire");
|
||
player.markAuto("jsrgtuwei_backfire", targets);
|
||
}
|
||
},
|
||
subSkill: {
|
||
backfire: {
|
||
audio: "jsrgtuwei",
|
||
trigger: {
|
||
player: "phaseEnd",
|
||
},
|
||
charlotte: true,
|
||
onremove: true,
|
||
forced: true,
|
||
filter: function (event, player) {
|
||
return player.getStorage("jsrgtuwei_backfire").some(target => {
|
||
return !target.getHistory("damage").length && target.isIn();
|
||
});
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
var targets = player.getStorage("jsrgtuwei_backfire").filter(target => {
|
||
return !target.getHistory("damage").length && target.isIn();
|
||
});
|
||
event.targets = targets.sortBySeat();
|
||
("step 1");
|
||
var target = targets.shift();
|
||
if (target.isIn() && player.countGainableCards(target, "he")) {
|
||
target.line(player);
|
||
target.gainPlayerCard(player, true, "he");
|
||
}
|
||
if (player.countCards("he") && targets.length) event.redo();
|
||
},
|
||
ai: {
|
||
effect: {
|
||
player: function (card, player, target) {
|
||
if (player != target && get.tag(card, "damage") && target && player.getStorage("jsrgtuwei_backfire").includes(target) && !target.getHistory("damage").length) return [1, 1, 1, 0];
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//许贡
|
||
jsrgbiaozhao: {
|
||
audio: 2,
|
||
trigger: { player: "phaseZhunbeiBegin" },
|
||
filter: function (event, player) {
|
||
return game.countPlayer(current => current != player) >= 2;
|
||
},
|
||
direct: true,
|
||
content: function () {
|
||
"step 0";
|
||
player
|
||
.chooseTarget(get.prompt2("jsrgbiaozhao"), lib.filter.notMe, 2)
|
||
.set("ai", target => {
|
||
var player = _status.event.player;
|
||
var att = get.attitude(player, target);
|
||
if (!ui.selected.targets.length) return att * (Math.sqrt(target.countCards("hs")) + 0.1);
|
||
return -att / Math.sqrt(target.countCards("hs") + 0.1);
|
||
})
|
||
.set("targetprompt", ["用牌无限制", "打你变疼"]);
|
||
("step 1");
|
||
if (result.bool) {
|
||
var targets = result.targets;
|
||
player.logSkill("jsrgbiaozhao", targets);
|
||
player.addTempSkill("jsrgbiaozhao_syujin", { player: ["phaseBegin", "die"] });
|
||
if (!player.storage.jsrgbiaozhao_syujin) player.storage.jsrgbiaozhao_syujin = [];
|
||
player.storage.jsrgbiaozhao_syujin.push(targets);
|
||
targets[0].addSkill("jsrgbiaozhao_A");
|
||
targets[0].markAuto("jsrgbiaozhao_A", [targets[1]]);
|
||
targets[1].addSkill("jsrgbiaozhao_B");
|
||
targets[1].addMark("jsrgbiaozhao_B" + player.playerid, 1, false);
|
||
targets[1].markAuto("jsrgbiaozhao_B", [player]);
|
||
}
|
||
},
|
||
subSkill: {
|
||
syujin: {
|
||
charlotte: true,
|
||
onremove: function (player, skill) {
|
||
var list = player.storage.jsrgbiaozhao_syujin;
|
||
for (var targets of list) {
|
||
targets[0].unmarkAuto("jsrgbiaozhao_A", [targets[1]]);
|
||
targets[1].unmarkAuto("jsrgbiaozhao_B", [player]);
|
||
delete targets[1].storage["jsrgbiaozhao_B" + player.playerid];
|
||
if (!targets[0].getStorage("jsrgbiaozhao_A")) targets[0].removeSkill("jsrgbiaozhao_A");
|
||
if (!targets[1].getStorage("jsrgbiaozhao_B")) targets[1].removeSkill("jsrgbiaozhao_B");
|
||
}
|
||
delete player.storage.jsrgbiaozhao_syujin;
|
||
},
|
||
},
|
||
A: {
|
||
charlotte: true,
|
||
onremove: true,
|
||
mark: true,
|
||
marktext: "表",
|
||
intro: {
|
||
content: "对$使用牌无次数和距离限制",
|
||
},
|
||
mod: {
|
||
targetInRange: function (card, player, target) {
|
||
if (player.getStorage("jsrgbiaozhao_A").includes(target)) return true;
|
||
},
|
||
cardUsableTarget: function (card, player, target) {
|
||
if (player.getStorage("jsrgbiaozhao_A").includes(target)) return true;
|
||
},
|
||
},
|
||
},
|
||
B: {
|
||
trigger: {
|
||
source: "damageBegin1",
|
||
},
|
||
charlotte: true,
|
||
forced: true,
|
||
onremove: function (player, skill) {
|
||
for (var i in player.storage) {
|
||
if (i.indexOf("jsrgbiaozhao_B") == 0) delete player.storage[i];
|
||
}
|
||
},
|
||
filter: function (event, player) {
|
||
return event.card && player.getStorage("jsrgbiaozhao_B").includes(event.player);
|
||
},
|
||
content: function () {
|
||
trigger.num += player.countMark("jsrgbiaozhao_B" + trigger.player.playerid) || 1;
|
||
},
|
||
mark: true,
|
||
marktext: "召",
|
||
intro: {
|
||
content: function (storage, player) {
|
||
var str = "";
|
||
for (var target of storage) {
|
||
str += "对" + get.translation(target) + "使用牌造成的伤害+" + player.countMark("jsrgbiaozhao_B" + target.playerid);
|
||
}
|
||
return str;
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgyechou: {
|
||
audio: 2,
|
||
trigger: { player: "die" },
|
||
forceDie: true,
|
||
direct: true,
|
||
skillAnimation: true,
|
||
animationColor: "wood",
|
||
content: function () {
|
||
"step 0";
|
||
player.chooseTarget(get.prompt2("jsrgyechou"), lib.filter.notMe).set("ai", target => {
|
||
var player = _status.event.player;
|
||
return -get.attitude(player, target);
|
||
});
|
||
("step 1");
|
||
if (result.bool) {
|
||
var target = result.targets[0];
|
||
player.logSkill("jsrgyechou", target);
|
||
target.addSkill("jsrgyechou_effect");
|
||
target.addMark("jsrgyechou_effect", 1, false);
|
||
}
|
||
},
|
||
subSkill: {
|
||
effect: {
|
||
trigger: {
|
||
player: "damageBegin3",
|
||
},
|
||
filter: function (event, player) {
|
||
return event.num >= player.getHp();
|
||
},
|
||
forced: true,
|
||
charlotte: true,
|
||
onremove: true,
|
||
content: function () {
|
||
trigger.num *= 2 * player.countMark("jsrgyechou_effect");
|
||
},
|
||
mark: true,
|
||
marktext: "仇",
|
||
intro: {
|
||
content: "当你受到伤害值不小于体力值的伤害时,此伤害翻&倍",
|
||
},
|
||
ai: {
|
||
effect: {
|
||
target: function (card, player, target) {
|
||
if (get.tag(card, "damage")) {
|
||
if (player.hasSkillTag("jueqing", false, target)) return [1, -2];
|
||
if (target.hp == 1) return 2;
|
||
}
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//淳于琼
|
||
jsrgcangchu: {
|
||
audio: "recangchu",
|
||
trigger: {
|
||
global: "phaseJieshuBegin",
|
||
},
|
||
filter: function (event, player) {
|
||
if (player.hasSkill("jsrgshishou_blocker")) return false;
|
||
return player.getHistory("gain").length;
|
||
},
|
||
direct: true,
|
||
content: function () {
|
||
"step 0";
|
||
var num = 0;
|
||
player.getHistory("gain", evt => {
|
||
num += evt.cards.length;
|
||
});
|
||
event.num = num;
|
||
player.chooseTarget(get.prompt("jsrgcangchu"), "令至多" + get.cnNumber(num) + "名角色各摸" + get.cnNumber(num > game.countPlayer() ? 2 : 1) + "张牌", [1, num]).set("ai", target => {
|
||
var player = _status.event.player;
|
||
return get.attitude(player, target) / Math.sqrt(target.countCards("hs") + 1);
|
||
});
|
||
("step 1");
|
||
if (result.bool) {
|
||
var targets = result.targets.slice();
|
||
targets.sortBySeat();
|
||
player.logSkill("jsrgcangchu", targets);
|
||
game.asyncDraw(targets, num > game.countPlayer() ? 2 : 1);
|
||
game.delayex();
|
||
}
|
||
},
|
||
},
|
||
jsrgshishou: {
|
||
audio: "reshishou",
|
||
trigger: {
|
||
player: "useCard",
|
||
},
|
||
forced: true,
|
||
filter: function (event, player) {
|
||
return event.card.name == "jiu";
|
||
},
|
||
group: "jsrgshishou_burn",
|
||
content: function () {
|
||
"step 0";
|
||
player.draw(3);
|
||
player.addTempSkill("jsrgshishou_nouse");
|
||
},
|
||
mod: {
|
||
aiOrder: function (player, card, num) {
|
||
if (card.name == "jiu") return 0.01;
|
||
},
|
||
},
|
||
ai: {
|
||
halfneg: true,
|
||
effect: {
|
||
player_use(card, player, target) {
|
||
if (card.name == "jiu") return [1, 1];
|
||
},
|
||
},
|
||
},
|
||
subSkill: {
|
||
nouse: {
|
||
charlotte: true,
|
||
mod: {
|
||
cardEnabled: function (card, player) {
|
||
return false;
|
||
},
|
||
cardUsable: function (card, player) {
|
||
return false;
|
||
},
|
||
cardSavable: function (card, player) {
|
||
return false;
|
||
},
|
||
},
|
||
mark: true,
|
||
marktext: "失",
|
||
intro: {
|
||
content: "喝醉了,不能再使用牌",
|
||
},
|
||
},
|
||
burn: {
|
||
audio: "reshishou",
|
||
trigger: {
|
||
player: "damageEnd",
|
||
},
|
||
forced: true,
|
||
filter: function (event, player) {
|
||
return event.hasNature("fire");
|
||
},
|
||
content: function () {
|
||
player.addTempSkill("jsrgshishou_blocker", { player: "phaseEnd" });
|
||
},
|
||
},
|
||
blocker: {
|
||
charlotte: true,
|
||
mark: true,
|
||
marktext: "守",
|
||
intro: {
|
||
content: "〖仓储〗失效直到下回合结束",
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//江山如故·起
|
||
sbyingmen: {
|
||
trigger: {
|
||
global: "phaseBefore",
|
||
player: "enterGame",
|
||
},
|
||
forced: true,
|
||
filter: function (event, player) {
|
||
return event.name != "phase" || game.phaseNumber == 0;
|
||
},
|
||
content: function () {
|
||
if (!_status.characterlist) lib.skill.pingjian.initList();
|
||
var characters = _status.characterlist.randomRemove(4);
|
||
lib.skill.sbyingmen.addVisitors(characters, player);
|
||
game.delayx();
|
||
},
|
||
ai: {
|
||
combo: "sbpingjian",
|
||
},
|
||
group: "sbyingmen_reload",
|
||
subSkill: {
|
||
reload: {
|
||
trigger: { player: "phaseBegin" },
|
||
forced: true,
|
||
locked: false,
|
||
filter: function (event, player) {
|
||
return player.getStorage("sbyingmen").length < 4;
|
||
},
|
||
content: function () {
|
||
if (!_status.characterlist) lib.skill.pingjian.initList();
|
||
var characters = _status.characterlist.randomRemove(4 - player.getStorage("sbyingmen").length);
|
||
lib.skill.sbyingmen.addVisitors(characters, player);
|
||
game.delayx();
|
||
},
|
||
},
|
||
},
|
||
getSkills: function (characters, player) {
|
||
var skills = [];
|
||
for (var name of characters) {
|
||
if (Array.isArray(lib.character[name].skills)) {
|
||
for (var skill of lib.character[name].skills) {
|
||
var list = get.skillCategoriesOf(skill, player);
|
||
list.remove("锁定技");
|
||
if (list.length > 0) continue;
|
||
var info = get.info(skill);
|
||
if (info && (!info.unique || info.gainable)) {
|
||
// lib.skill.rehuashen.createAudio(name,skill,'jsrg_xushao');
|
||
skills.add(skill);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return skills;
|
||
},
|
||
addVisitors: function (characters, player) {
|
||
player.addSkillBlocker("sbyingmen");
|
||
game.log(player, "将", "#y" + get.translation(characters), "加入了", "#g“访客”");
|
||
game.broadcastAll(
|
||
function (player, characters) {
|
||
player.tempname.addArray(characters);
|
||
player.$draw(
|
||
characters.map(function (name) {
|
||
var cardname = "huashen_card_" + name;
|
||
lib.card[cardname] = {
|
||
fullimage: true,
|
||
image: "character:" + name,
|
||
};
|
||
lib.translate[cardname] = get.rawName2(name);
|
||
return game.createCard(cardname, " ", " ");
|
||
}),
|
||
"nobroadcast"
|
||
);
|
||
},
|
||
player,
|
||
characters
|
||
);
|
||
player.markAuto("sbyingmen", characters);
|
||
var storage = player.getStorage("sbyingmen");
|
||
var skills = lib.skill.sbyingmen.getSkills(storage, player);
|
||
player.addInvisibleSkill(skills);
|
||
},
|
||
removeVisitors: function (characters, player) {
|
||
var skills = lib.skill.sbyingmen.getSkills(characters, player);
|
||
var characters2 = player.getStorage("sbyingmen").slice(0);
|
||
characters2.removeArray(characters);
|
||
skills.removeArray(lib.skill.sbyingmen.getSkills(characters2, player));
|
||
game.broadcastAll((player, characters) => player.tempname.removeArray(characters), player, characters);
|
||
player.unmarkAuto("sbyingmen", characters);
|
||
_status.characterlist.addArray(characters);
|
||
player.removeInvisibleSkill(skills);
|
||
},
|
||
onremove: function (player, skill) {
|
||
lib.skill.sbyingmen.removeVisitors(player.getStorage("sbyingmen"), player);
|
||
player.removeSkillBlocker("sbyingmen");
|
||
},
|
||
skillBlocker: function (skill, player) {
|
||
if (!player.invisibleSkills.includes(skill) || skill == "sbpingjian" || skill == "sbpingjian") return false;
|
||
return !player.hasSkill("sbpingjian");
|
||
},
|
||
marktext: "客",
|
||
intro: {
|
||
name: "访客",
|
||
mark: function (dialog, storage, player) {
|
||
if (!storage || !storage.length) return "当前没有“访客”";
|
||
dialog.addSmall([storage, "character"]);
|
||
var skills = lib.skill.sbyingmen.getSkills(storage, player);
|
||
if (skills.length) dialog.addText("<li>当前可用技能:" + get.translation(skills), false);
|
||
},
|
||
},
|
||
},
|
||
sbpingjian: {
|
||
trigger: { player: ["useSkill", "logSkillBegin"] },
|
||
forced: true,
|
||
locked: false,
|
||
filter: function (event, player) {
|
||
var skill = event.sourceSkill || event.skill;
|
||
return player.invisibleSkills.includes(skill) && lib.skill.sbyingmen.getSkills(player.getStorage("sbyingmen"), player).includes(skill);
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
var visitors = player.getStorage("sbyingmen").slice(0);
|
||
var drawers = visitors.filter(function (name) {
|
||
return lib.character[name].skills && lib.character[name].skills.includes(trigger.sourceSkill);
|
||
});
|
||
event.drawers = drawers;
|
||
if (visitors.length == 1) event._result = { bool: true, links: visitors };
|
||
else {
|
||
var dialog = ["评鉴:请选择移去一张“访客”"];
|
||
if (drawers.length) dialog.push('<div class="text center">如果移去' + get.translation(drawers) + ",则你摸一张牌</div>");
|
||
dialog.push([visitors, "character"]);
|
||
player.chooseButton(dialog, true);
|
||
}
|
||
("step 1");
|
||
if (result.bool) {
|
||
lib.skill.sbyingmen.removeVisitors(result.links, player);
|
||
game.log(player, "移去了", "#y" + get.translation(result.links[0]));
|
||
if (event.drawers.includes(result.links[0])) {
|
||
player.addTempSkill("sbpingjian_draw");
|
||
player.storage.sbpingjian_draw.push(trigger.skill);
|
||
}
|
||
}
|
||
},
|
||
group: "sbpingjian_trigger",
|
||
subSkill: {
|
||
draw: {
|
||
charlotte: true,
|
||
init: function (player, skill) {
|
||
if (!player.storage[skill]) player.storage[skill] = [];
|
||
},
|
||
onremove: true,
|
||
trigger: { player: ["useSkillAfter", "logSkill"] },
|
||
forced: true,
|
||
popup: false,
|
||
filter: function (event, player) {
|
||
return player.getStorage("sbpingjian_draw").includes(event.skill);
|
||
},
|
||
content: function () {
|
||
player.storage.sbpingjian_draw.remove(trigger.skill);
|
||
player.draw();
|
||
if (!player.storage.sbpingjian_draw.length) player.removeSkill("sbpingjian_draw");
|
||
},
|
||
},
|
||
trigger: {
|
||
trigger: { player: "triggerInvisible" },
|
||
forced: true,
|
||
forceDie: true,
|
||
popup: false,
|
||
charlotte: true,
|
||
priority: 10,
|
||
filter: function (event, player) {
|
||
if (event.revealed) return false;
|
||
var info = get.info(event.skill);
|
||
if (info.charlotte) return false;
|
||
var skills = lib.skill.sbyingmen.getSkills(player.getStorage("sbyingmen"), player);
|
||
game.expandSkills(skills);
|
||
return skills.includes(event.skill);
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
if (get.info(trigger.skill).silent) {
|
||
event.finish();
|
||
} else {
|
||
var info = get.info(trigger.skill);
|
||
var event = trigger,
|
||
trigger = event._trigger;
|
||
var str;
|
||
var check = info.check;
|
||
if (info.prompt) str = info.prompt;
|
||
else {
|
||
if (typeof info.logTarget == "string") {
|
||
str = get.prompt(event.skill, trigger[info.logTarget], player);
|
||
} else if (typeof info.logTarget == "function") {
|
||
var logTarget = info.logTarget(trigger, player, trigger.triggername, trigger.indexedData);
|
||
if (get.itemtype(logTarget).indexOf("player") == 0) str = get.prompt(event.skill, logTarget, player);
|
||
} else {
|
||
str = get.prompt(event.skill, null, player);
|
||
}
|
||
}
|
||
if (typeof str == "function") {
|
||
str = str(trigger, player, trigger.triggername, trigger.indexedData);
|
||
}
|
||
var next = player.chooseBool("评鉴:" + str);
|
||
next.set("yes", !info.check || info.check(trigger, player, trigger.triggername, trigger.indexedData));
|
||
next.set("hsskill", event.skill);
|
||
next.set("forceDie", true);
|
||
next.set("ai", function () {
|
||
return _status.event.yes;
|
||
});
|
||
if (typeof info.prompt2 == "function") {
|
||
next.set("prompt2", info.prompt2(trigger, player, trigger.triggername, trigger.indexedData));
|
||
} else if (typeof info.prompt2 == "string") {
|
||
next.set("prompt2", info.prompt2);
|
||
} else if (info.prompt2 != false) {
|
||
if (lib.dynamicTranslate[event.skill]) next.set("prompt2", lib.dynamicTranslate[event.skill](player, event.skill));
|
||
else if (lib.translate[event.skill + "_info"]) next.set("prompt2", lib.translate[event.skill + "_info"]);
|
||
}
|
||
if (trigger.skillwarn) {
|
||
if (next.prompt2) {
|
||
next.set("prompt2", '<span class="thundertext">' + trigger.skillwarn + "。</span>" + next.prompt2);
|
||
} else {
|
||
next.set("prompt2", trigger.skillwarn);
|
||
}
|
||
}
|
||
}
|
||
("step 1");
|
||
if (result.bool) {
|
||
if (!get.info(trigger.skill).cost) {
|
||
trigger.revealed = true;
|
||
}
|
||
} else {
|
||
trigger.untrigger();
|
||
trigger.cancelled = true;
|
||
}
|
||
},
|
||
},
|
||
},
|
||
ai: {
|
||
combo: "sbyingmen",
|
||
},
|
||
},
|
||
jsrgchaozheng: {
|
||
audio: 2,
|
||
trigger: { player: "phaseZhunbeiBegin" },
|
||
logTarget: function (event, player) {
|
||
return game.filterPlayer(i => i != player);
|
||
},
|
||
prompt: "是否发动【朝争】?",
|
||
content: function () {
|
||
player.chooseToDebate(game.filterPlayer(i => i != player)).set("callback", lib.skill.jsrgchaozheng.callback);
|
||
},
|
||
callback: function () {
|
||
var result = event.debateResult;
|
||
if (result.bool && result.opinion) {
|
||
var opinion = result.opinion,
|
||
targets = result.red.map(i => i[0]);
|
||
targets.sortBySeat();
|
||
targets.forEach(i => i[opinion == "red" ? "recover" : "loseHp"]());
|
||
if (targets.length == 0 || result.black.length == 0) player.draw(result.targets.length);
|
||
}
|
||
},
|
||
},
|
||
jsrgshenchong: {
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
limited: true,
|
||
filterTarget: lib.filter.notMe,
|
||
skillAnimation: true,
|
||
animationColor: "soil",
|
||
content: function () {
|
||
"step 0";
|
||
player.awakenSkill("jsrgshenchong");
|
||
target.addSkillLog("jsrgfeiyang");
|
||
target.addSkillLog("jsrgbahu");
|
||
("step 1");
|
||
player.addSkill("jsrgshenchong_die");
|
||
player.markAuto("jsrgshenchong_die", [target]);
|
||
},
|
||
ai: {
|
||
order: 1,
|
||
result: { target: 1 },
|
||
},
|
||
subSkill: {
|
||
die: {
|
||
audio: "jsrgshenchong",
|
||
trigger: { player: "die" },
|
||
charlotte: true,
|
||
forced: true,
|
||
forceDie: true,
|
||
filter: function (event, player) {
|
||
return player.getStorage("jsrgshenchong_die").length;
|
||
},
|
||
content: function () {
|
||
var targets = player.getStorage("jsrgshenchong_die");
|
||
player.line(targets);
|
||
targets.sortBySeat().forEach(current => {
|
||
current.clearSkills(true);
|
||
current.chooseToDiscard(current.countCards("h"), "h", true);
|
||
});
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgfeiyang: {
|
||
trigger: { player: "phaseJudgeBegin" },
|
||
direct: true,
|
||
filter: function (event, player) {
|
||
return player.countCards("j") && player.countCards("h") > 1;
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
player
|
||
.chooseToDiscard("h", 2, get.prompt("jsrgfeiyang"), "弃置两张手牌并弃置判定区里的一张牌")
|
||
.set("logSkill", "jsrgfeiyang")
|
||
.set("ai", function (card) {
|
||
if (_status.event.goon) return 6 - get.value(card);
|
||
return 0;
|
||
})
|
||
.set(
|
||
"goon",
|
||
(() => {
|
||
if (player.hasSkillTag("rejudge") && player.countCards("j") < 2) return false;
|
||
return player.hasCard(function (card) {
|
||
if (get.tag(card, "damage") && get.damageEffect(player, player, _status.event.player, get.natureList(card)) >= 0) return false;
|
||
return (
|
||
get.effect(
|
||
player,
|
||
{
|
||
name: card.viewAs || card.name,
|
||
cards: [card],
|
||
},
|
||
player,
|
||
player
|
||
) < 0
|
||
);
|
||
}, "j");
|
||
})()
|
||
);
|
||
("step 1");
|
||
if (result.bool) {
|
||
player.discardPlayerCard(player, "j", true);
|
||
}
|
||
},
|
||
},
|
||
jsrgbahu: {
|
||
trigger: { player: "phaseZhunbeiBegin" },
|
||
forced: true,
|
||
content: function () {
|
||
player.draw();
|
||
},
|
||
mod: {
|
||
cardUsable: function (card, player, num) {
|
||
if (card.name == "sha") return num + 1;
|
||
},
|
||
},
|
||
},
|
||
jsrgjulian: {
|
||
audio: 2,
|
||
trigger: { player: "phaseJieshuBegin" },
|
||
filter: function (event, player) {
|
||
return player.hasZhuSkill("jsrgjulian") && lib.skill.jsrgjulian.logTarget(null, player).length;
|
||
},
|
||
prompt: "是否发动【聚敛】?",
|
||
prompt2: "你可以获得其他所有群势力角色的各一张牌",
|
||
logTarget: function (event, player) {
|
||
return game.filterPlayer(current => {
|
||
return current.group == "qun" && current.countGainableCards(player, "he") > 0 && current != player;
|
||
});
|
||
},
|
||
content: function () {
|
||
game.filterPlayer(current => {
|
||
return current.group == "qun" && current != player;
|
||
})
|
||
.sortBySeat()
|
||
.forEach(i => {
|
||
player.gainPlayerCard(i, "he", true);
|
||
});
|
||
},
|
||
group: "jsrgjulian_draw",
|
||
zhuSkill: true,
|
||
subSkill: {
|
||
draw: {
|
||
audio: "jsrgjulian",
|
||
trigger: { global: "gainAfter" },
|
||
filter: function (event, player) {
|
||
var source = event.player;
|
||
if (source == player || source.group != "qun") return false;
|
||
var evt = event.getParent("phaseDraw");
|
||
return (!evt || evt.player != source) && event.getParent().name == "draw" && event.getParent(2).name != "jsrgjulian_draw" && player.hasZhuSkill("jsrgjulian", event.player);
|
||
},
|
||
direct: true,
|
||
usable: 2,
|
||
content: function () {
|
||
"step 0";
|
||
var source = trigger.player;
|
||
event.source = source;
|
||
source.chooseBool("是否响应" + get.translation(player) + "的【聚敛】摸一张牌?");
|
||
("step 1");
|
||
if (result.bool) {
|
||
source.logSkill("jsrgjulian_draw", player);
|
||
source.draw();
|
||
} else player.storage.counttrigger.jsrgjulian_draw--;
|
||
},
|
||
},
|
||
give: {
|
||
charlotte: true,
|
||
onremove: true,
|
||
},
|
||
},
|
||
},
|
||
//何进
|
||
jsrgzhaobing: {
|
||
audio: 2,
|
||
trigger: { player: "phaseJieshuBegin" },
|
||
direct: true,
|
||
filter: function (event, player) {
|
||
var hs = player.getCards("h");
|
||
if (!hs.length) return false;
|
||
for (var i of hs) {
|
||
if (!lib.filter.cardDiscardable(i, player, "jsrgzhaobing")) return false;
|
||
}
|
||
return true;
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
var cards = player.getCards("h");
|
||
var num = cards.length;
|
||
var prompt2 = "弃置所有手牌,令至多" + get.cnNumber(num) + "名其他角色依次选择一项:1.正面向上交给你一张【杀】;2.失去1点体力";
|
||
player
|
||
.chooseTarget(get.prompt("jsrgzhaobing"), prompt2, [1, num], lib.filter.notMe)
|
||
.set("ai", target => {
|
||
if (!_status.event.goon) return 0;
|
||
return 2 - get.attitude(_status.event.player, target);
|
||
})
|
||
.set(
|
||
"goon",
|
||
num / 2 <
|
||
game.countPlayer(current => {
|
||
return 2 - get.attitude(player, current) > 0;
|
||
})
|
||
);
|
||
("step 1");
|
||
if (result.bool) {
|
||
player.logSkill("jsrgzhaobing", result.targets);
|
||
event.targets = result.targets;
|
||
event.targets.sortBySeat();
|
||
player.chooseToDiscard(true, "h", player.countCards("h"));
|
||
} else event.finish();
|
||
("step 2");
|
||
var target = targets.shift();
|
||
event.target = target;
|
||
target
|
||
.chooseCard("诏兵:交给" + get.translation(player) + "一张【杀】,或失去1点体力", card => {
|
||
return get.name(card) == "sha";
|
||
})
|
||
.set("ai", card => {
|
||
if (_status.event.goon) return 0;
|
||
return 6 - get.value(card);
|
||
})
|
||
.set("goon", get.effect(target, { name: "losehp" }, target, target) >= 0);
|
||
("step 3");
|
||
if (result.bool) target.give(result.cards, player, true);
|
||
else target.loseHp();
|
||
if (targets.length) event.goto(2);
|
||
},
|
||
ai: {
|
||
expose: 0.2,
|
||
},
|
||
},
|
||
jsrgzhuhuan: {
|
||
audio: "mouzhu",
|
||
trigger: { player: "phaseZhunbeiBegin" },
|
||
filter: function (event, player) {
|
||
var hs = player.getCards("h", "sha");
|
||
if (!hs.length) return false;
|
||
for (var i of hs) {
|
||
if (!lib.filter.cardDiscardable(i, player, "jsrgzhuhuan")) return false;
|
||
}
|
||
return true;
|
||
},
|
||
direct: true,
|
||
content: function () {
|
||
"step 0";
|
||
player.chooseTarget(get.prompt2("jsrgzhuhuan"), lib.filter.notMe).set("ai", 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("jsrgzhuhuan", target);
|
||
var hs = player.getCards("h", "sha");
|
||
event.num = hs.length;
|
||
player.discard(hs);
|
||
} else event.finish();
|
||
("step 2");
|
||
target
|
||
.chooseToDiscard(get.translation(player) + "对你发动了【诛宦】", "弃置" + get.cnNumber(num) + "张牌并失去1点体力;或点击“取消”令其回复1点体力且其摸" + get.cnNumber(num) + "张牌")
|
||
.set("ai", card => {
|
||
if (_status.event.goon) return 0;
|
||
return 5.5 - get.value(card);
|
||
})
|
||
.set("goon", target.hp <= 2 || get.attitude(target, player) >= 0 || player.isHealthy());
|
||
("step 3");
|
||
if (result.bool) {
|
||
target.loseHp();
|
||
} else {
|
||
player.draw(num);
|
||
player.recover();
|
||
}
|
||
},
|
||
ai: {
|
||
expose: 0.2,
|
||
},
|
||
},
|
||
jsrgyanhuo: {
|
||
inherit: "spyanhuo",
|
||
forced: true,
|
||
},
|
||
//孙坚
|
||
jsrgpingtao: {
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
filterTarget: lib.filter.notMe,
|
||
content: function () {
|
||
"step 0";
|
||
var att = get.attitude(target, player);
|
||
target
|
||
.chooseCard(get.translation(player) + "对你发动了【平讨】", "交给其一张牌并令其此回合使用【杀】的次数上限+1;或点击“取消”令其视为对你使用一张【杀】", "he")
|
||
.set("ai", card => {
|
||
if (_status.event.give) {
|
||
if (card.name == "sha" || card.name == "tao" || card.name == "jiu") return 0;
|
||
return 8 - get.value(card);
|
||
}
|
||
if (_status.event.att < 0 && card.name == "sha") return -1;
|
||
return 4 - get.value(card);
|
||
})
|
||
.set("give", (att >= 0 || (target.hp == 1 && target.countCards("hs", "shan") <= 1)) && get.effect(target, { name: "sha" }, player, target) < 0)
|
||
.set("att", att);
|
||
("step 1");
|
||
if (result.bool) {
|
||
target.give(result.cards, player);
|
||
player.addTempSkill("jsrgpingtao_sha");
|
||
player.addMark("jsrgpingtao_sha", 1, false);
|
||
} else if (player.canUse("sha", target, false)) {
|
||
player.useCard({ name: "sha", isCard: true }, target, false);
|
||
}
|
||
},
|
||
ai: {
|
||
expose: 0.15,
|
||
order: 5,
|
||
result: { target: -1 },
|
||
},
|
||
subSkill: {
|
||
sha: {
|
||
charlotte: true,
|
||
onremove: true,
|
||
marktext: "讨",
|
||
intro: {
|
||
content: "本回合使用【杀】的次数上限+#",
|
||
},
|
||
mod: {
|
||
cardUsable: function (card, player, num) {
|
||
if (card.name == "sha") return num + player.countMark("jsrgpingtao_sha");
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgjuelie: {
|
||
audio: 2,
|
||
trigger: { player: "useCardToPlayered" },
|
||
filter: function (event, player) {
|
||
return player.countCards("he") && event.card.name == "sha";
|
||
},
|
||
direct: true,
|
||
content: function () {
|
||
"step 0";
|
||
player
|
||
.chooseToDiscard(get.prompt("jsrgjuelie", trigger.target), "当你使用【杀】指定一名角色为目标后,你可以弃置任意张牌,然后弃置其等量的牌", [1, Infinity], "he")
|
||
.set("ai", card => {
|
||
if (ui.selected.cards.length >= _status.event.max) return 0;
|
||
if (_status.event.goon) return 4.5 - get.value(card);
|
||
return 0;
|
||
})
|
||
.set("max", trigger.target.countDiscardableCards(player, "he"))
|
||
.set("goon", get.attitude(player, trigger.target) < 0)
|
||
.set("logSkill", ["jsrgjuelie", trigger.target]);
|
||
("step 1");
|
||
if (result.bool) {
|
||
var num = result.cards.length;
|
||
if (trigger.target.countDiscardableCards(player, "he")) player.discardPlayerCard("平讨:弃置" + get.translation(trigger.target) + get.cnNumber(num) + "张牌", num, "he", trigger.target, true);
|
||
}
|
||
/*
|
||
else event.finish();
|
||
'step 2'
|
||
if(player.isMinHandcard()||player.isMinHp()){
|
||
var id=trigger.target.playerid;
|
||
var map=trigger.getParent().customArgs;
|
||
if(!map[id]) map[id]={};
|
||
if(typeof map[id].extraDamage!='number'){
|
||
map[id].extraDamage=0;
|
||
}
|
||
map[id].extraDamage++;
|
||
}
|
||
*/
|
||
},
|
||
shaRelated: true,
|
||
ai: {
|
||
unequip_ai: true,
|
||
skillTagFilter: function (player, tag, arg) {
|
||
if (!arg || !arg.name || arg.name != "sha") return false;
|
||
if (!arg.target) return false;
|
||
var card = arg.target.getEquip(2);
|
||
return (
|
||
card &&
|
||
get.value(card) > 0 &&
|
||
player.hasCard(cardx => {
|
||
return lib.filter.cardDiscardable(cardx, player, "jsrgjuelie_discard") && get.value(cardx) < 5;
|
||
})
|
||
);
|
||
},
|
||
},
|
||
group: "jsrgjuelie_pojun",
|
||
subSkill: {
|
||
pojun: {
|
||
trigger: { source: "damageBegin1" },
|
||
filter: function (event, player) {
|
||
if (!player.isMinHandcard() && !player.isMinHp()) return false;
|
||
return event.getParent().name == "sha";
|
||
},
|
||
forced: true,
|
||
locked: false,
|
||
logTarget: "player",
|
||
content: function () {
|
||
trigger.num++;
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//皇甫嵩
|
||
jsrgguanhuo: {
|
||
audio: 2,
|
||
trigger: { player: "useCardAfter" },
|
||
filter: function (event, player) {
|
||
return (
|
||
event.card.storage &&
|
||
event.card.storage.jsrgguanhuo &&
|
||
!game.hasPlayer2(current => {
|
||
return current.hasHistory("damage", evt => evt.card == event.card);
|
||
})
|
||
);
|
||
},
|
||
forced: true,
|
||
locked: false,
|
||
group: "jsrgguanhuo_viewas",
|
||
content: function () {
|
||
"step 0";
|
||
var count = player.getHistory("useSkill", evt => {
|
||
return evt.skill == "jsrgguanhuo_viewas" && evt.event.getParent("phaseUse") === trigger.getParent("phaseUse");
|
||
}).length;
|
||
if (count == 1) {
|
||
player.addTempSkill("jsrgguanhuo_ex", "phaseUseAfter");
|
||
player.addMark("jsrgguanhuo_ex", 1, false);
|
||
trigger.targets.forEach(i => i.removeSkill("huogong2"));
|
||
} else {
|
||
player.removeSkills("jsrgguanhuo");
|
||
}
|
||
},
|
||
ai: {
|
||
effect: {
|
||
player: function (card, player) {
|
||
if (
|
||
_status.event.getParent().skill == "jsrgguanhuo_viewas" &&
|
||
player.getHistory("useSkill", evt => {
|
||
return evt.skill == "jsrgguanhuo_viewas" && evt.event.getParent("phaseUse") === _status.event.getParent("phaseUse");
|
||
}).length == 1
|
||
)
|
||
return "zeroplayertarget";
|
||
if (
|
||
_status.event.type == "phase" &&
|
||
_status.event.skill == "jsrgguanhuo_viewas" &&
|
||
player.getHistory("useSkill", evt => {
|
||
return evt.skill == "jsrgguanhuo_viewas" && evt.event.getParent("phaseUse") === _status.event.getParent("phaseUse");
|
||
}).length > 1 &&
|
||
player.countCards("h") <= 3
|
||
)
|
||
return [0, 0];
|
||
},
|
||
},
|
||
},
|
||
subSkill: {
|
||
viewas: {
|
||
audio: "jsrgguanhuo",
|
||
enable: "phaseUse",
|
||
viewAs: {
|
||
name: "huogong",
|
||
isCard: true,
|
||
storage: {
|
||
jsrgguanhuo: true,
|
||
},
|
||
},
|
||
filterCard: () => false,
|
||
selectCard: -1,
|
||
prompt: "视为使用一张【火攻】",
|
||
ai: {
|
||
order: function (item, player) {
|
||
return get.order({ name: "huogong" }) + 0.01;
|
||
},
|
||
},
|
||
},
|
||
ex: {
|
||
trigger: { source: "damageBegin1" },
|
||
filter: function (event, player) {
|
||
return event.card && event.card.name == "huogong" && event.getParent().type == "card";
|
||
},
|
||
forced: true,
|
||
charlotte: true,
|
||
onremove: true,
|
||
intro: { content: "当你造成渠道为【火攻】的伤害时,此伤害+#" },
|
||
content: function () {
|
||
trigger.num += player.countMark("jsrgguanhuo_ex");
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgjuxia: {
|
||
audio: 2,
|
||
trigger: { target: "useCardToTargeted" },
|
||
usable: 1,
|
||
countSkill: function (player) {
|
||
return player.getSkills(null, false, false).filter(function (skill) {
|
||
var info = get.info(skill);
|
||
if (!info || info.charlotte) return false;
|
||
if (info.zhuSkill) return player.hasZhuSkill(skill);
|
||
return true;
|
||
}).length;
|
||
},
|
||
filter: function (event, player) {
|
||
return event.player != player && lib.skill.jsrgjuxia.countSkill(event.player) > lib.skill.jsrgjuxia.countSkill(player);
|
||
},
|
||
direct: true,
|
||
content: function () {
|
||
"step 0";
|
||
var goon = get.effect(player, trigger.card, trigger.player, trigger.player) < 1;
|
||
if (goon && !event.isMine() && !event.isOnline()) game.delayx();
|
||
trigger.player
|
||
.chooseBool("是否对" + get.translation(player) + "发动【居下】?", "令" + get.translation(trigger.card) + "对其无效,然后其摸两张牌")
|
||
.set("ai", () => {
|
||
return _status.event.goon;
|
||
})
|
||
.set("goon", goon);
|
||
("step 1");
|
||
if (result.bool) {
|
||
trigger.player.logSkill("jsrgjuxia", player);
|
||
trigger.excluded.add(player);
|
||
player.draw(2);
|
||
} else player.storage.counttrigger.jsrgjuxia--;
|
||
},
|
||
ai: {
|
||
effect: {
|
||
target_use(card, player, target) {
|
||
if (lib.skill.jsrgjuxia.countSkill(target) >= lib.skill.jsrgjuxia.countSkill(player)) return;
|
||
if (card && (card.cards || card.isCard) && get.attitude(target, player) > 0 && (!target.storage.counttrigger || !target.storage.counttrigger.jsrgjuxia)) return [0, 0.5, 0, 0.5];
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//许劭
|
||
jsrgyingmen: {
|
||
audio: 2,
|
||
trigger: {
|
||
global: "phaseBefore",
|
||
player: ["enterGame", "phaseBegin"],
|
||
},
|
||
forced: true,
|
||
filter: function (event, player, name) {
|
||
if (player.getStorage("jsrgyingmen").length >= 4) return false;
|
||
if (name == "phaseBefore") return game.phaseNumber == 0;
|
||
return event.name != "phase" || event.player == player;
|
||
},
|
||
update: function (player) {
|
||
var id = player.playerid;
|
||
var characters = player.getStorage("jsrgyingmen");
|
||
var skillName = "jsrgpingjian_" + id;
|
||
var skillsx = [],
|
||
skillsx2 = [];
|
||
var map = {};
|
||
var skillsy = lib.skill[skillName] ? lib.skill[skillName].group : [];
|
||
for (var name of characters) {
|
||
var skills = lib.character[name][3].slice();
|
||
skills = skills.filter(skill => {
|
||
var list = get.skillCategoriesOf(skill, player);
|
||
list.removeArray(["锁定技", "Charlotte"]);
|
||
if (list.length) return false;
|
||
var info = get.info(skill);
|
||
return info && (!info.unique || info.gainable);
|
||
});
|
||
game.expandSkills(skills);
|
||
for (var i = 0; i < skills.length; i++) {
|
||
var skill = skills[i];
|
||
var info = get.info(skill);
|
||
if (info.silent || info.charlotte) continue;
|
||
if (!info.forced && !info.frequent && (!info.mod || (info.charlotte && info.mod))) continue;
|
||
var infox = get.copy(info);
|
||
var newname = skill + "_" + id;
|
||
map[newname] = infox;
|
||
if (info.audio) infox.audio = typeof info.audio != "number" ? info.audio : skill;
|
||
// if(infox.group) delete infox.group;
|
||
if (infox.frequent) delete infox.frequent;
|
||
if (infox.forceDie) delete infox.forceDie;
|
||
var popup = infox.popup;
|
||
if (infox.forced && infox.direct) {
|
||
delete infox.direct;
|
||
infox.popup = false;
|
||
}
|
||
if (infox.forced && !infox.prompt2) {
|
||
var skillx = skill;
|
||
while (true) {
|
||
var prompt2 = lib.translate[skillx + "_info"];
|
||
if (prompt2 && prompt2.length) {
|
||
infox.prompt2 = prompt2;
|
||
break;
|
||
}
|
||
var ind = skillx.lastIndexOf("_");
|
||
if (ind == -1) break;
|
||
skillx = skillx.slice(0, ind);
|
||
}
|
||
}
|
||
if (popup != false && !infox.silent) infox.forced = false;
|
||
if (!infox.charlotte && infox.mod) delete infox.mod;
|
||
skillsx2.add(skill);
|
||
skills[i] = newname;
|
||
}
|
||
if (skills.length) {
|
||
skillsx.addArray(skills);
|
||
}
|
||
}
|
||
var skillsRemoving = skillsy.removeArray(skillsx);
|
||
player.removeSkill(skillsRemoving);
|
||
game.broadcastAll(
|
||
function (name, skillsx, skillsx2, id, map) {
|
||
for (var i in map) lib.skill[i] = map[i];
|
||
lib.skill[name] = {
|
||
unique: true,
|
||
group: skillsx,
|
||
};
|
||
lib.translate[name] = "评鉴";
|
||
for (var i of skillsx2) {
|
||
lib.translate[i + "_" + id] = lib.translate[i];
|
||
lib.translate[i + "_" + id + "_info"] = lib.translate[i + "_info"];
|
||
}
|
||
},
|
||
skillName,
|
||
skillsx,
|
||
skillsx2,
|
||
id,
|
||
map
|
||
);
|
||
player.addSkill(skillName);
|
||
player.addSkill("jsrgpingjian_blocker");
|
||
player.addSkillTrigger(skillName);
|
||
},
|
||
bannedList: ["zishu", "weishu", "xinfu_zhanji", "kyouko_rongzhu"],
|
||
content: function () {
|
||
"step 0";
|
||
if (!_status.characterlist) lib.skill.pingjian.initList();
|
||
var num = player.getStorage("jsrgyingmen").length;
|
||
var list = [];
|
||
_status.characterlist.randomSort();
|
||
for (var i = 0; i < _status.characterlist.length; i++) {
|
||
var name = _status.characterlist[i];
|
||
var skills = lib.character[name][3].slice();
|
||
if (
|
||
skills.some(skill => {
|
||
return lib.skill.jsrgyingmen.bannedList.includes(skill);
|
||
})
|
||
)
|
||
continue;
|
||
list.push(name);
|
||
_status.characterlist.remove(name);
|
||
if (list.length >= 4 - num) break;
|
||
}
|
||
if (list.length) {
|
||
player.markAuto("jsrgyingmen", list);
|
||
if (player.hasSkill("jsrgpingjian", null, false, false)) lib.skill.jsrgyingmen.update(player);
|
||
game.log(player, "将", "#g" + get.translation(list), "置为", "#y访客");
|
||
game.broadcastAll(
|
||
function (player, list) {
|
||
var cards = [];
|
||
for (var i = 0; i < list.length; i++) {
|
||
var cardname = "huashen_card_" + list[i];
|
||
lib.card[cardname] = {
|
||
fullimage: true,
|
||
image: "character:" + list[i],
|
||
};
|
||
lib.translate[cardname] = get.rawName2(list[i]);
|
||
cards.push(game.createCard(cardname, "", ""));
|
||
}
|
||
player.$draw(cards, "nobroadcast");
|
||
},
|
||
player,
|
||
list
|
||
);
|
||
}
|
||
},
|
||
ai: {
|
||
combo: "jsrgpingjian",
|
||
},
|
||
marktext: "客",
|
||
intro: {
|
||
name: "访客(盈门/评鉴)",
|
||
mark: function (dialog, storage, player) {
|
||
dialog.addText("剩余“访客”");
|
||
if (storage) dialog.addSmall([storage, "character"]);
|
||
else dialog.addText("无");
|
||
},
|
||
},
|
||
},
|
||
jsrgpingjian: {
|
||
audio: 2,
|
||
trigger: { player: ["logSkill", "useSkillAfter"] },
|
||
forced: true,
|
||
locked: false,
|
||
onremove: function (player) {
|
||
player.removeSkill("jsrgpingjian_" + player.playerid);
|
||
},
|
||
filter: function (event, player) {
|
||
var skill = event.skill,
|
||
name = event.event ? event.event.name : "";
|
||
var visitors = player.getStorage("jsrgyingmen");
|
||
for (var visitor of visitors) {
|
||
var skills = lib.character[visitor][3].slice();
|
||
game.expandSkills(skills);
|
||
var info = get.info(skill);
|
||
if (info && (info.charlotte || info.silent)) continue;
|
||
if (
|
||
skills.some(skillx => {
|
||
return skill.indexOf(skillx) == 0 || name.indexOf(skillx + "_" + player.playerid) == 0;
|
||
})
|
||
)
|
||
return true;
|
||
}
|
||
return false;
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
var current;
|
||
var skill = trigger.skill,
|
||
name = trigger.event ? trigger.event.name : "";
|
||
var visitors = player.getStorage("jsrgyingmen");
|
||
for (var visitor of visitors) {
|
||
var skills = lib.character[visitor][3].slice();
|
||
game.expandSkills(skills);
|
||
var info = get.info(skill);
|
||
if (info && info.charlotte) continue;
|
||
if (
|
||
skills.some(skillx => {
|
||
return skill.indexOf(skillx) == 0 || name.indexOf(skillx + "_" + player.playerid) == 0;
|
||
})
|
||
) {
|
||
current = visitor;
|
||
break;
|
||
}
|
||
}
|
||
event.current = current;
|
||
player
|
||
.chooseButton(['###评鉴:移去一名访客###<div class="text center">若移去的访客为' + get.translation(current) + ",则你摸一张牌</div>", [player.getStorage("jsrgyingmen"), "character"]], true)
|
||
.set("ai", button => {
|
||
if (button.link == _status.event.toremove) return 1;
|
||
return Math.random();
|
||
})
|
||
.set(
|
||
"toremove",
|
||
(function () {
|
||
var list = player.getStorage("jsrgyingmen");
|
||
var rand = Math.random();
|
||
if (rand < 0.33) return list[0];
|
||
if (rand < 0.66) return current;
|
||
return list.randomGet();
|
||
})()
|
||
);
|
||
("step 1");
|
||
if (result.bool) {
|
||
var visitor = result.links[0];
|
||
game.log(player, "从", "#y访客", "中移去了", "#g" + get.translation(visitor));
|
||
player.popup(visitor);
|
||
player.unmarkAuto("jsrgyingmen", [visitor]);
|
||
_status.characterlist.add(visitor);
|
||
if (visitor == event.current) player.draw();
|
||
lib.skill.jsrgyingmen.update(player);
|
||
}
|
||
},
|
||
subSkill: {
|
||
blocker: {
|
||
init: function (player, skill) {
|
||
player.addSkillBlocker(skill);
|
||
},
|
||
onremove: function (player, skill) {
|
||
player.removeSkillBlocker(skill);
|
||
},
|
||
charlotte: true,
|
||
locked: true,
|
||
skillBlocker: function (skill, player) {
|
||
if (skill != "jsrgpingjian_" + player.playerid) return false;
|
||
if (player._jsrgpingjian_blockerChecking) return;
|
||
player._jsrgpingjian_blockerChecking = true;
|
||
var own = player.hasSkill("jsrgpingjian");
|
||
delete player._jsrgpingjian_blockerChecking;
|
||
return !own;
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//董白
|
||
jsrgshichong: {
|
||
audio: 2,
|
||
zhuanhuanji: true,
|
||
trigger: { player: "useCardToPlayered" },
|
||
direct: true,
|
||
filter: function (event, player) {
|
||
return event.target != player && event.targets.length == 1 && event.target.isIn() && event.target.countCards("h");
|
||
},
|
||
mark: true,
|
||
marktext: "☯",
|
||
intro: {
|
||
content: function (storage, player) {
|
||
var str = "转换技。当你使用牌指定其他角色为唯一目标后,";
|
||
if (storage) return str + "目标角色可以交给你一张手牌。";
|
||
return str + "你可以获得目标角色一张手牌。";
|
||
},
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
if (!player.storage.jsrgshichong) {
|
||
player
|
||
.chooseBool(get.prompt("jsrgshichong", trigger.target), "你可以获得该角色的一张手牌")
|
||
.set("ai", () => {
|
||
return _status.event.bool;
|
||
})
|
||
.set("bool", get.attitude(player, trigger.target) <= 0);
|
||
} else {
|
||
trigger.target
|
||
.chooseCard("是否发动" + get.translation(player) + "的【恃宠】?", "你可以选择一张手牌,并交给该角色")
|
||
.set("ai", card => {
|
||
if (_status.event.goon) return 5 - get.value(card);
|
||
return 0 - get.value(card);
|
||
})
|
||
.set("goon", get.attitude(trigger.target, player) > 2);
|
||
}
|
||
("step 1");
|
||
if (result.bool) {
|
||
if (!player.storage.jsrgshichong) {
|
||
player.logSkill("jsrgshichong", trigger.target);
|
||
player.gainPlayerCard(trigger.target, "h", true);
|
||
} else {
|
||
trigger.target.logSkill("jsrgshichong", player);
|
||
trigger.target.give(result.cards, player);
|
||
}
|
||
player.changeZhuanhuanji("jsrgshichong");
|
||
}
|
||
},
|
||
},
|
||
jsrglianzhu: {
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
filterCard: { color: "black" },
|
||
position: "h",
|
||
filterTarget: lib.filter.notMe,
|
||
lose: false,
|
||
discard: false,
|
||
delay: false,
|
||
content: function () {
|
||
"step 0";
|
||
player.showCards(cards, get.translation(player) + "发动了【连诛】");
|
||
("step 1");
|
||
player.give(cards, target);
|
||
("step 2");
|
||
event.targets = game
|
||
.filterPlayer(current => {
|
||
return current.group == target.group && current != player;
|
||
})
|
||
.sortBySeat();
|
||
game.delayx();
|
||
("step 3");
|
||
var target = targets.shift();
|
||
if (player.canUse("guohe", target)) {
|
||
player.useCard({ name: "guohe", isCard: true }, target);
|
||
}
|
||
if (targets.length) event.redo();
|
||
},
|
||
ai: {
|
||
order: 4,
|
||
result: {
|
||
target: function (player, target) {
|
||
var targets = game.filterPlayer(current => {
|
||
return current.group == target.group && current != player;
|
||
});
|
||
var eff = targets.reduce((p, c) => {
|
||
return p + get.effect(c, { name: "guohe" }, player, player);
|
||
}, 0);
|
||
if (ui.selected.cards.length) eff += get.value(ui.selected.cards[0], target);
|
||
return eff;
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//桥玄
|
||
jsrgjuezhi: {
|
||
audio: 2,
|
||
trigger: { source: "damageBegin1" },
|
||
filter: function (event, player) {
|
||
if (_status.currentPhase != player || player.hasSkill("jsrgjuezhi_used", null, null, false)) return false;
|
||
return event.card && event.getParent().type == "card" && lib.skill.jsrgjuezhi.getNum(event.player, player) > 0;
|
||
},
|
||
forced: true,
|
||
locked: false,
|
||
getNum: function (target, player) {
|
||
return target.countCards("e", card => {
|
||
var subtype = get.subtypes(card);
|
||
for (var i of subtype) {
|
||
if (player.hasDisabledSlot(i)) return true;
|
||
}
|
||
return false;
|
||
});
|
||
},
|
||
group: "jsrgjuezhi_disable",
|
||
content: function () {
|
||
player.addTempSkill("jsrgjuezhi_used", ["phaseZhunbeiAfter", "phaseJudgeAfter", "phaseDrawAfter", "phaseUseAfter", "phaseDiscardAfter", "phaseJieshuAfter"]);
|
||
trigger.num += lib.skill.jsrgjuezhi.getNum(trigger.player, player);
|
||
},
|
||
subSkill: {
|
||
disable: {
|
||
audio: "jsrgjuezhi",
|
||
trigger: {
|
||
player: "loseAfter",
|
||
global: ["equipAfter", "addJudgeAfter", "gainAfter", "loseAsyncAfter", "addToExpansionAfter"],
|
||
},
|
||
direct: true,
|
||
filter: function (event, player) {
|
||
var evt = event.getl(player);
|
||
return evt && evt.es && evt.es.length > 0;
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
event.cards = trigger.getl(player).es;
|
||
("step 1");
|
||
var card = cards.shift(),
|
||
subtypes = get.subtypes(card).filter(slot => player.hasEnabledSlot(slot));
|
||
event.subtypes = subtypes;
|
||
if (subtypes.length > 0) {
|
||
player.chooseBool(get.prompt("jsrgjuezhi_disable"), "废除你的" + get.translation(subtypes) + "栏").set("ai", () => 1);
|
||
} else event._result = { bool: false };
|
||
("step 2");
|
||
if (result.bool) {
|
||
player.logSkill("jsrgjuezhi_disable");
|
||
player.disableEquip(event.subtypes);
|
||
}
|
||
if (cards.length > 0) event.goto(1);
|
||
},
|
||
},
|
||
used: { charlotte: true },
|
||
},
|
||
},
|
||
jsrgjizhao: {
|
||
audio: 2,
|
||
trigger: { player: ["phaseZhunbeiBegin", "phaseJieshuBegin"] },
|
||
direct: true,
|
||
content: function () {
|
||
"step 0";
|
||
player.chooseTarget(get.prompt2("jsrgjizhao")).set("ai", target => {
|
||
var player = _status.event.player;
|
||
if (player.countCards("j")) return player == target ? 10 : 0.1;
|
||
return 6 - get.attitude(player, target);
|
||
});
|
||
("step 1");
|
||
if (result.bool) {
|
||
var target = result.targets[0];
|
||
event.target = target;
|
||
player.logSkill("jsrgjizhao", target);
|
||
target.chooseToUse({
|
||
filterCard: function (card, player, event) {
|
||
if (get.itemtype(card) != "card" || (get.position(card) != "h" && get.position(card) != "s")) return false;
|
||
return lib.filter.filterCard.apply(this, arguments);
|
||
},
|
||
prompt: "急召:使用一张手牌,否则" + get.translation(player) + "可以移动你区域里的一张牌",
|
||
addCount: false,
|
||
goon: target != player || !player.countCards("j"),
|
||
ai1: function (card) {
|
||
if (_status.event.goon) return get.order(card);
|
||
return 0;
|
||
},
|
||
});
|
||
} else {
|
||
event.finish();
|
||
return;
|
||
}
|
||
("step 2");
|
||
if (result.bool) {
|
||
event.finish();
|
||
return;
|
||
}
|
||
var targets = game.filterPlayer(current => {
|
||
if (current == target) return false;
|
||
var hs = target.getCards("h");
|
||
if (hs.length) return true;
|
||
var js = target.getCards("j");
|
||
for (var i = 0; i < js.length; i++) {
|
||
if (current.canAddJudge(js[i])) return true;
|
||
}
|
||
if (current.isMin()) return false;
|
||
var es = target.getCards("e");
|
||
for (var i = 0; i < es.length; i++) {
|
||
if (current.canEquip(es[i])) return true;
|
||
}
|
||
return false;
|
||
});
|
||
if (targets.length) {
|
||
var next = player.chooseTarget(function (card, player, target) {
|
||
return _status.event.targets.includes(target);
|
||
});
|
||
next.set("from", target);
|
||
next.set("targets", targets);
|
||
next.set("ai", function (target) {
|
||
var player = _status.event.player;
|
||
var att = get.attitude(player, target);
|
||
var sgnatt = get.sgn(att);
|
||
var from = _status.event.from;
|
||
var es = from.getCards("e");
|
||
var i;
|
||
var att2 = get.sgn(get.attitude(player, from));
|
||
for (i = 0; i < es.length; i++) {
|
||
if (sgnatt != 0 && att2 != 0 && sgnatt != att2 && get.sgn(get.value(es[i], from)) == -att2 && get.sgn(get.effect(target, es[i], player, target)) == sgnatt && target.canEquip(es[i])) {
|
||
return Math.abs(att);
|
||
}
|
||
}
|
||
if (
|
||
i == es.length &&
|
||
(!from.countCards("j", function (card) {
|
||
return target.canAddJudge(card);
|
||
}) ||
|
||
att2 <= 0)
|
||
) {
|
||
if (from.countCards("h") > 0) return att;
|
||
return 0;
|
||
}
|
||
return -att * att2;
|
||
});
|
||
next.set("targetprompt", "移动目标");
|
||
next.set("prompt", "急召:是否移动" + get.translation(target) + "的一张牌?");
|
||
} else event.finish();
|
||
("step 3");
|
||
if (result.bool) {
|
||
var target2 = result.targets[0];
|
||
event.targets = [target, target2];
|
||
player.line2(event.targets, "green");
|
||
} else {
|
||
event.finish();
|
||
}
|
||
("step 4");
|
||
game.delay();
|
||
("step 5");
|
||
if (targets.length == 2) {
|
||
player
|
||
.choosePlayerCard(
|
||
"hej",
|
||
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;
|
||
if (get.position(button.link) == "h") return 10;
|
||
return get.value(button.link) * get.effect(targets1, button.link, player, targets1);
|
||
}
|
||
},
|
||
targets[0]
|
||
)
|
||
.set("targets0", targets[0])
|
||
.set("targets1", targets[1])
|
||
.set("filterButton", function (button) {
|
||
var targets1 = _status.event.targets1;
|
||
if (get.position(button.link) == "h") {
|
||
return true;
|
||
} else if (get.position(button.link) == "j") {
|
||
return targets1.canAddJudge(button.link);
|
||
} else {
|
||
return targets1.canEquip(button.link);
|
||
}
|
||
});
|
||
} else {
|
||
event.finish();
|
||
}
|
||
("step 6");
|
||
if (result.bool && result.links.length) {
|
||
var link = result.links[0];
|
||
if (get.position(link) == "h") event.targets[1].gain(link, event.targets[0], "giveAuto");
|
||
else {
|
||
event.targets[0].$give(link, event.targets[1], false);
|
||
if (get.position(link) == "e") event.targets[1].equip(link);
|
||
else if (link.viewAs) event.targets[1].addJudge({ name: link.viewAs }, [link]);
|
||
else event.targets[1].addJudge(link);
|
||
}
|
||
game.log(event.targets[0], "的", get.position(link) == "h" ? "一张手牌" : link, "被移动给了", event.targets[1]);
|
||
game.delay();
|
||
}
|
||
},
|
||
ai: {
|
||
effect: {
|
||
target: function (card, player, target, current) {
|
||
if (get.type(card) == "delay" && current < 0) {
|
||
if (target.countCards("j")) return;
|
||
return "zerotarget";
|
||
}
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//杨彪
|
||
jsrgzhaohan: {
|
||
audio: "zhaohan",
|
||
trigger: { player: "phaseZhunbeiBegin" },
|
||
forced: true,
|
||
//locked:false,
|
||
filter: function (event, player) {
|
||
if (game.shuffleNumber == 0) return player.isDamaged();
|
||
return true;
|
||
},
|
||
content: function () {
|
||
player[game.shuffleNumber > 0 ? "loseHp" : "recover"]();
|
||
},
|
||
},
|
||
jsrgrangjie: {
|
||
audio: "rangjie",
|
||
trigger: { player: "damageEnd" },
|
||
filter: function (event, player) {
|
||
return player.canMoveCard();
|
||
},
|
||
check: function (event, player) {
|
||
return player.canMoveCard(true);
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
event.num = trigger.num;
|
||
("step 1");
|
||
event.num--;
|
||
if (player.canMoveCard()) player.moveCard(true);
|
||
("step 2");
|
||
if (result.bool) {
|
||
var card = result.card;
|
||
var suit = get.suit(card, false);
|
||
var cards = Array.from(ui.discardPile.childNodes);
|
||
var gains = [];
|
||
var history = game.getGlobalHistory("cardMove", evt => {
|
||
if (evt.name == "lose") return evt.position == ui.discardPile;
|
||
return evt.name == "cardsDiscard";
|
||
});
|
||
for (var i = history.length - 1; i >= 0; i--) {
|
||
var evt = history[i];
|
||
var cards2 = evt.cards.filter(card => {
|
||
return cards.includes(card) && get.suit(card, false) == suit;
|
||
});
|
||
if (cards2.length) {
|
||
gains.addArray(cards2);
|
||
cards.removeArray(cards2);
|
||
}
|
||
if (!cards.length) break;
|
||
}
|
||
if (gains.length) {
|
||
player.chooseButton(["让节:是否获得一张" + get.translation(suit) + "牌?", gains]).set("ai", get.buttonValue);
|
||
} else event._result = { bool: false };
|
||
}
|
||
("step 3");
|
||
if (result.bool) {
|
||
player.gain(result.links, "gain2");
|
||
}
|
||
("step 4");
|
||
if (event.num > 0 && player.hasSkill("jsrgrangjie")) {
|
||
player
|
||
.chooseBool(get.prompt2("jsrgrangjie"))
|
||
.set("ai", () => _status.event.bool)
|
||
.set("bool", lib.skill.jsrgrangjie.check(trigger, player));
|
||
} else event.finish();
|
||
("step 5");
|
||
if (result.bool) {
|
||
player.logSkill("jsrgrangjie");
|
||
event.goto(1);
|
||
}
|
||
},
|
||
ai: {
|
||
maixie: true,
|
||
maixie_hp: true,
|
||
effect: {
|
||
target: function (card, player, target) {
|
||
if (get.tag(card, "damage")) {
|
||
if (player.hasSkillTag("jueqing", false, target)) return [1, -2];
|
||
if (target._jsrgrangjie_aiChecking) return;
|
||
target._jsrgrangjie_aiChecking = true;
|
||
var moveCard = target.canMoveCard(true);
|
||
delete target._jsrgrangjie_aiChecking;
|
||
if (!moveCard || !target.hasFriend()) return;
|
||
var num = 1;
|
||
if (get.attitude(player, target) > 0) {
|
||
if (player.needsToDiscard()) num = 0.5;
|
||
else num = 0.3;
|
||
}
|
||
if (target.hp >= 4) return [1, num * 2];
|
||
if (target.hp == 3) return [1, num * 1.5];
|
||
if (target.hp == 2) return [1, num * 0.5];
|
||
}
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgyizheng: {
|
||
audio: "yizheng",
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
filter: function (event, player) {
|
||
return game.hasPlayer(function (current) {
|
||
return current.countCards("h") > player.countCards("h") && player.canCompare(current);
|
||
});
|
||
},
|
||
filterTarget: function (card, player, current) {
|
||
return current.countCards("h") > player.countCards("h") && player.canCompare(current);
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
player.chooseToCompare(target);
|
||
("step 1");
|
||
if (result.bool) {
|
||
target.skip("phaseDraw");
|
||
target.addTempSkill("yizheng2", { player: "phaseDrawSkipped" });
|
||
event.finish();
|
||
} else {
|
||
target
|
||
.chooseControl("1", "2", "cancel")
|
||
.set("prompt", "是否对" + get.translation(player) + "造成至多2点伤害?")
|
||
.set("ai", () => {
|
||
return _status.event.choice;
|
||
})
|
||
.set("choice", get.damageEffect(player, target, target) > 0 ? (get.attitude(target, player) > 0 ? 0 : 1) : "cancel2");
|
||
}
|
||
("step 2");
|
||
if (result.control != "cancel2") {
|
||
var num = result.index + 1;
|
||
target.line(player);
|
||
player.damage(target, num);
|
||
}
|
||
},
|
||
ai: {
|
||
order: 1,
|
||
result: {
|
||
target: function (player, target) {
|
||
if (target.skipList.includes("phaseDraw") || target.hasSkill("pingkou")) return 0;
|
||
var hs = player.getCards("h").sort(function (a, b) {
|
||
return b.number - a.number;
|
||
});
|
||
var ts = target.getCards("h").sort(function (a, b) {
|
||
return b.number - a.number;
|
||
});
|
||
if (!hs.length || !ts.length) return 0;
|
||
if (hs[0].number > ts[0].number) return -1;
|
||
return 0;
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//孔融
|
||
jsrglirang: {
|
||
audio: "splirang",
|
||
trigger: { global: "phaseDrawBegin" },
|
||
direct: true,
|
||
filter: function (event, player) {
|
||
return event.player != player && !player.hasSkill("jsrglirang_used") && player.countCards("he") > 1;
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
player
|
||
.chooseCard(get.prompt("jsrglirang", trigger.player), "你可以选择两张牌,将这些牌交给该角色。若如此做,你获得其本回合弃牌阶段弃置的所有牌。", 2, "he")
|
||
.set("ai", card => {
|
||
if (!_status.event.give) return 0;
|
||
var player = _status.event.player,
|
||
target = _status.event.target;
|
||
return target.getUseValue(card) - player.getUseValue(card) + 0.5;
|
||
})
|
||
.set("give", get.attitude(player, trigger.player) > 0)
|
||
.set("target", trigger.player);
|
||
("step 1");
|
||
if (result.bool) {
|
||
player.logSkill("jsrglirang", trigger.player);
|
||
var cards = result.cards;
|
||
player.give(cards, trigger.player);
|
||
player.addTempSkill("jsrglirang_used", "roundStart");
|
||
player.addTempSkill("jsrglirang_given");
|
||
player.markAuto("jsrglirang_used", [trigger.player]);
|
||
}
|
||
},
|
||
subSkill: {
|
||
used: {
|
||
charlotte: true,
|
||
onremove: true,
|
||
intro: { content: "本轮〖礼让〗目标:$" },
|
||
},
|
||
given: {
|
||
audio: "splirang",
|
||
trigger: { global: "phaseDiscardEnd" },
|
||
filter: function (event, player) {
|
||
return event.player.hasHistory("lose", evt => {
|
||
return evt.type == "discard" && evt.getParent("phaseDiscard") == event && evt.cards2.filterInD("d").length > 0;
|
||
});
|
||
},
|
||
charlotte: true,
|
||
prompt2: function (event, player) {
|
||
var cards = [];
|
||
event.player.getHistory("lose", evt => {
|
||
if (evt.type == "discard" && evt.getParent("phaseDiscard") == event) cards.addArray(evt.cards2.filterInD("d"));
|
||
});
|
||
return "获得" + get.translation(cards);
|
||
},
|
||
content: function () {
|
||
var cards = [];
|
||
trigger.player.getHistory("lose", evt => {
|
||
if (evt.type == "discard" && evt.getParent("phaseDiscard") == trigger) cards.addArray(evt.cards2.filterInD("d"));
|
||
});
|
||
player.gain(cards, "gain2");
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgzhengyi: {
|
||
audio: 2,
|
||
trigger: { player: "damageBegin4" },
|
||
filter: function (event, player) {
|
||
var list = player.getStorage("jsrglirang_used");
|
||
if (!list.length) return false;
|
||
return !player.getHistory("damage").length && list[0].isIn();
|
||
},
|
||
direct: true,
|
||
content: function () {
|
||
"step 0";
|
||
var target = player.getStorage("jsrglirang_used")[0];
|
||
event.target = target;
|
||
target
|
||
.chooseBool("是否对" + get.translation(player) + "发动【争义】?", "将此" + (trigger.source ? "来源为" + get.translation(trigger.source) : "无来源") + "的" + trigger.num + "点伤害转移给你")
|
||
.set("ai", () => {
|
||
return _status.event.bool;
|
||
})
|
||
.set("bool", get.damageEffect(player, trigger.source, target) > get.damageEffect(target, trigger.source, target));
|
||
("step 1");
|
||
if (result.bool) {
|
||
target.logSkill("jsrgzhengyi", player);
|
||
trigger.cancel();
|
||
target.damage(trigger.source, trigger.nature, trigger.num).set("card", trigger.card).set("cards", trigger.cards);
|
||
}
|
||
},
|
||
ai: {
|
||
combo: "jsrglirang",
|
||
},
|
||
},
|
||
//朱儁
|
||
jsrgfendi: {
|
||
audio: 2,
|
||
trigger: { player: "useCardToPlayered" },
|
||
filter: function (event, player) {
|
||
return event.targets.length == 1 && event.card.name == "sha" && event.targets[0].countCards("h") > 0;
|
||
},
|
||
usable: 1,
|
||
logTarget: "target",
|
||
content: function () {
|
||
"step 0";
|
||
var target = trigger.target;
|
||
event.target = target;
|
||
player
|
||
.choosePlayerCard(target, "h", true, [1, Infinity], "分敌:展示" + get.translation(target) + "的任意张手牌")
|
||
.set("ai", button => {
|
||
if (_status.event.all) return 1;
|
||
if (ui.selected.buttons.length) return 0;
|
||
return Math.random();
|
||
})
|
||
.set(
|
||
"all",
|
||
!target.mayHaveShan(
|
||
player,
|
||
"use",
|
||
target.getCards("h", i => {
|
||
return i.hasGaintag("sha_notshan");
|
||
})
|
||
) && Math.random() < 0.75
|
||
)
|
||
.set("forceAuto", true);
|
||
("step 1");
|
||
if (result.bool) {
|
||
var cards = result.cards;
|
||
target.showCards(cards, get.translation(player) + "对" + get.translation(target) + "发动了【分敌】");
|
||
target.addGaintag(cards, "jsrgfendi_tag");
|
||
target.addTempSkill("jsrgfendi_blocker");
|
||
player.addTempSkill("jsrgfendi_gain");
|
||
if (!trigger.card.storage) trigger.card.storage = {};
|
||
trigger.card.storage.jsrgfendi = cards.slice();
|
||
player.storage.jsrgfendi_gain = target;
|
||
} else player.storage.counttrigger.jsrgfendi--;
|
||
},
|
||
subSkill: {
|
||
blocker: {
|
||
trigger: {
|
||
player: ["damageBefore", "damageCancelled", "damageZero"],
|
||
target: ["shaMiss", "useCardToExcluded", "useCardToEnd"],
|
||
global: ["useCardEnd"],
|
||
},
|
||
forced: true,
|
||
popup: false,
|
||
charlotte: true,
|
||
content: function () {
|
||
player.removeSkill("jsrgfendi_blocker");
|
||
},
|
||
mod: {
|
||
cardEnabled: function (card, player) {
|
||
if (card.cards) {
|
||
for (var i of card.cards) {
|
||
if (!i.hasGaintag("jsrgfendi_tag")) return false;
|
||
}
|
||
} else if (get.itemtype(card) == "card") {
|
||
if (!card.hasGaintag("jsrgfendi_tag")) return false;
|
||
}
|
||
},
|
||
cardRespondable: function (card, player) {
|
||
return lib.skill.jsrgfendi.cardEnabled.apply(this, arguments);
|
||
},
|
||
cardSavable: function (card, player) {
|
||
return lib.skill.jsrgfendi.cardEnabled.apply(this, arguments);
|
||
},
|
||
},
|
||
},
|
||
gain: {
|
||
trigger: { global: "damageSource" },
|
||
charlotte: true,
|
||
forced: true,
|
||
direct: true,
|
||
onremove: true,
|
||
filter: function (event, player) {
|
||
if (!event.card || !event.card.storage) return false;
|
||
var cards = event.card.storage.jsrgfendi;
|
||
var target = player.storage.jsrgfendi_gain;
|
||
if (!cards || !target || !target.isIn()) return false;
|
||
var cardsx = target.getCards("h");
|
||
cardsx.addArray(Array.from(ui.discardPile));
|
||
return cards.some(i => cardsx.includes(i));
|
||
//target.hasCard(card=>{
|
||
// return card.hasGaintag('jsrgfendi_tag');
|
||
//},'h');
|
||
},
|
||
content: function () {
|
||
var target = player.storage.jsrgfendi_gain;
|
||
player.logSkill("jsrgfendi_gain", target);
|
||
var cardsx = target.getCards("h");
|
||
cardsx.addArray(Array.from(ui.discardPile));
|
||
var cards = trigger.card.storage.jsrgfendi.filter(i => cardsx.includes(i));
|
||
player.gain(cards, "give");
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgjuxiang: {
|
||
audio: 2,
|
||
trigger: {
|
||
player: "gainAfter",
|
||
global: "loseAsyncAfter",
|
||
},
|
||
filter: function (event, player) {
|
||
var evt = event.getParent("phaseDraw");
|
||
if (evt && evt.name == "phaseDraw") return false;
|
||
var hs = player.getCards("h");
|
||
var cards = event.getg(player).filter(i => hs.includes(i));
|
||
if (!cards.length) return false;
|
||
for (var card of cards) {
|
||
if (!lib.filter.cardDiscardable(card, player, "jsrgjuxiang")) return false;
|
||
}
|
||
return true;
|
||
},
|
||
check: function (event, player) {
|
||
var target = _status.currentPhase;
|
||
if (!target || get.attitude(player, target) <= 0) return false;
|
||
var evt = event.getParent("phaseDiscard"),
|
||
evt2 = event.getParent("phaseJieshu");
|
||
if ((evt && evt.name == "phaseDiscard") || (evt2 && evt.name == "phaseJieshu")) return false;
|
||
if (target.getCardUsable({ name: "sha" }) >= target.countCards("hs", "sha")) return false;
|
||
if (!target.hasValueTarget({ name: "sha" })) return false;
|
||
var hs = player.getCards("h");
|
||
var cards = event.getg(player).filter(i => hs.includes(i));
|
||
var val = 0;
|
||
for (var i of cards) val += get.value(i);
|
||
if (val < 10) return true;
|
||
return false;
|
||
},
|
||
prompt2: function (event, player) {
|
||
var hs = player.getCards("h");
|
||
var cards = event.getg(player).filter(i => hs.includes(i));
|
||
var target = _status.currentPhase;
|
||
var str = "弃置" + get.translation(cards);
|
||
if (target && target.isIn()) {
|
||
var list = [];
|
||
for (var card of cards) {
|
||
list.add(get.suit(card, player));
|
||
}
|
||
var num = list.length;
|
||
str += ",然后令" + get.translation(target) + "于此回合额定的出牌阶段内使用【杀】的次数上限+" + num;
|
||
}
|
||
return str;
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
var hs = player.getCards("h");
|
||
var cards = trigger.getg(player).filter(i => hs.includes(i));
|
||
var list = [];
|
||
for (var card of cards) {
|
||
list.add(get.suit(card, player));
|
||
}
|
||
event.num = list.length;
|
||
player.discard(cards);
|
||
("step 1");
|
||
var target = _status.currentPhase;
|
||
if (target && target.isIn()) {
|
||
target.addTempSkill("jsrgjuxiang_sha");
|
||
target.addMark("jsrgjuxiang_sha", num, false);
|
||
var evt = trigger.getParent("phaseUse");
|
||
if (evt && evt.name == "phaseUse" && !evt.skill) {
|
||
evt.player.addTempSkill("jsrgjuxiang_buff", "phaseUseAfter");
|
||
evt.player.addMark("jsrgjuxiang_buff", num, false);
|
||
}
|
||
}
|
||
},
|
||
subSkill: {
|
||
sha: {
|
||
trigger: { global: "phaseUseBegin" },
|
||
filter: function (event, player) {
|
||
return !event.skill;
|
||
},
|
||
silent: true,
|
||
charlotte: true,
|
||
forced: true,
|
||
onremove: true,
|
||
content: function () {
|
||
trigger.player.addTempSkill("jsrgjuxiang_buff", "phaseUseAfter");
|
||
trigger.player.addMark("jsrgjuxiang_buff", player.countMark("jsrgjuxiang_sha"), false);
|
||
},
|
||
},
|
||
buff: {
|
||
charlotte: true,
|
||
intro: { content: "使用【杀】的次数上限+#" },
|
||
onremove: true,
|
||
mod: {
|
||
cardUsable: function (card, player, num) {
|
||
if (card.name == "sha") return num + player.countMark("jsrgjuxiang_buff");
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
//刘备
|
||
jsrgjishan: {
|
||
audio: 2,
|
||
trigger: { global: "damageBegin4" },
|
||
usable: 1,
|
||
filter: function (event, player) {
|
||
return player.hp > 0;
|
||
},
|
||
logTarget: "player",
|
||
onremove: true,
|
||
prompt2: "失去1点体力并防止此伤害,然后你与其各摸一张牌",
|
||
check: function (event, player) {
|
||
return get.damageEffect(event.player, event.source, _status.event.player, event.nature) * event.num < get.effect(player, { name: "losehp" }, player, _status.event.player) + get.effect(player, { name: "draw" }, player, _status.event.player) + get.effect(event.player, { name: "draw" }, player, _status.event.player) / 2;
|
||
},
|
||
group: "jsrgjishan_recover",
|
||
content: function () {
|
||
"step 0";
|
||
trigger.cancel();
|
||
player.loseHp();
|
||
player.markAuto("jsrgjishan", [trigger.player]);
|
||
("step 1");
|
||
if (player.isIn() && trigger.player.isIn()) {
|
||
var targets = [player, trigger.player];
|
||
targets.sortBySeat(_status.currentPhase);
|
||
targets[0].draw("nodelay");
|
||
targets[1].draw();
|
||
}
|
||
},
|
||
intro: { content: "已帮助$抵挡过伤害" },
|
||
ai: { expose: 0.2 },
|
||
subSkill: {
|
||
recover: {
|
||
audio: "jsrgjishan",
|
||
trigger: { source: "damageSource" },
|
||
filter: function (event, player) {
|
||
return game.hasPlayer(current => {
|
||
return current.isMinHp() && player.getStorage("jsrgjishan").includes(current);
|
||
});
|
||
},
|
||
usable: 1,
|
||
direct: true,
|
||
content: function () {
|
||
"step 0";
|
||
player
|
||
.chooseTarget(get.prompt("jsrgjishan_recover"), "令一名体力值最小且你对其发动过〖积善①〗的角色回复1点体力", (card, player, target) => {
|
||
return target.isMinHp() && player.getStorage("jsrgjishan").includes(target);
|
||
})
|
||
.set("ai", target => {
|
||
return get.recoverEffect(target, _status.event.player, _status.event.player);
|
||
});
|
||
("step 1");
|
||
if (result.bool) {
|
||
var target = result.targets[0];
|
||
player.logSkill("jsrgjishan_recover", target);
|
||
target.recover();
|
||
} else player.storage.counttrigger.jsrgjishan_recover--;
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgzhenqiao: {
|
||
audio: 2,
|
||
trigger: { player: "useCardToTargeted" },
|
||
forced: true,
|
||
shaRelated: true,
|
||
filter: function (event, player) {
|
||
return event.isFirstTarget && event.card.name == "sha" && player.hasEmptySlot(1);
|
||
},
|
||
content: function () {
|
||
// trigger.getParent().targets=trigger.getParent().targets.concat(trigger.targets);
|
||
// trigger.getParent().triggeredTargets4=trigger.getParent().triggeredTargets4.concat(trigger.targets);
|
||
trigger.getParent().effectCount++;
|
||
},
|
||
mod: {
|
||
attackRange: function (player, num) {
|
||
return num + 1;
|
||
},
|
||
aiOrder: (player, card, num) => {
|
||
if (num > 0 && get.itemtype(card) === "card" && get.subtype(card) === "equip1" && !player.getEquip(1)) {
|
||
if (
|
||
card.name !== "zhuge" ||
|
||
player.getCardUsable("sha") ||
|
||
!player.needsToDiscard() ||
|
||
player.countCards("hs", i => {
|
||
return get.name(i) === "sha" && lib.filter.cardEnabled(i, player);
|
||
}) < 2
|
||
)
|
||
return 0;
|
||
}
|
||
},
|
||
aiValue: (player, card, num) => {
|
||
if (num > 0 && get.itemtype(card) === "card" && card.name !== "zhuge" && get.subtype(card) === "equip1" && !player.getEquip(1)) return 0.01 * num;
|
||
},
|
||
aiUseful: function () {
|
||
return lib.skill.jsrgzhenqiao.mod.aiValue.apply(this, arguments);
|
||
},
|
||
},
|
||
},
|
||
//王允
|
||
jsrgshelun: {
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
filter: function (event, player) {
|
||
return game.hasPlayer(current => player.inRange(current));
|
||
},
|
||
filterTarget: function (card, player, target) {
|
||
return player.inRange(target);
|
||
},
|
||
content: function () {
|
||
var num = player.countCards("h");
|
||
var targets = game.filterPlayer(current => {
|
||
return current.countCards("h") <= num && current != target;
|
||
});
|
||
player
|
||
.chooseToDebate(targets)
|
||
.set("callback", function () {
|
||
var result = event.debateResult;
|
||
if (result.bool && result.opinion) {
|
||
var opinion = result.opinion;
|
||
var target = event.getParent(2).target;
|
||
if (opinion == "red") player.discardPlayerCard(target, "he", true);
|
||
else target.damage();
|
||
}
|
||
})
|
||
.set("ai", card => {
|
||
var player = _status.event.player;
|
||
var color = player == _status.event.source || get.damageEffect(_status.event.getParent(2).target, player, player) > 0 ? "black" : "red";
|
||
var val = 5 - get.value(card);
|
||
if (get.color(card) == color) val += 10;
|
||
return val;
|
||
})
|
||
.set("aiCard", target => {
|
||
var color = target == _status.event.source || get.damageEffect(_status.event.getParent(2).target, target, target) > 0 ? "black" : "red";
|
||
var hs = target.getCards("h", { color: color });
|
||
if (!hs.length) hs = target.getCards("h");
|
||
return { bool: true, cards: [hs.randomGet()] };
|
||
})
|
||
.set("target", target);
|
||
},
|
||
ai: {
|
||
order: 8,
|
||
expose: 0.2,
|
||
result: { target: -1 },
|
||
},
|
||
},
|
||
jsrgfayi: {
|
||
audio: 2,
|
||
trigger: { global: "chooseToDebateAfter" },
|
||
filter: function (event, player) {
|
||
if (!event.targets.includes(player)) return false;
|
||
if (event.red.map(i => i[0]).includes(player)) return event.black.length;
|
||
if (event.black.map(i => i[0]).includes(player)) return event.red.length;
|
||
return false;
|
||
},
|
||
direct: true,
|
||
content: function () {
|
||
"step 0";
|
||
var targets = [];
|
||
if (trigger.red.map(i => i[0]).includes(player)) targets = trigger.black;
|
||
if (trigger.black.map(i => i[0]).includes(player)) targets = trigger.red;
|
||
player
|
||
.chooseTarget(get.prompt("jsrgfayi"), "对一名与你意见不同的角色造成1点伤害", (card, player, target) => {
|
||
return _status.event.targets.includes(target);
|
||
})
|
||
.set(
|
||
"targets",
|
||
targets.map(i => i[0])
|
||
)
|
||
.set("ai", target => {
|
||
var player = _status.event.player;
|
||
return get.damageEffect(target, player, player);
|
||
});
|
||
("step 1");
|
||
if (result.bool) {
|
||
var target = result.targets[0];
|
||
player.logSkill("jsrgfayi", target);
|
||
target.damage();
|
||
}
|
||
},
|
||
ai: {
|
||
combo: "jsrgshelun"
|
||
},
|
||
},
|
||
jsrgtushe: {
|
||
audio: "xinfu_tushe",
|
||
mod: {
|
||
aiOrder(player, card, num) {
|
||
if (get.tag(card, "multitarget")) {
|
||
if (player.countCards("h", { type: "basic" })) return num / 10;
|
||
return num * 10;
|
||
}
|
||
if (get.type(card) === "basic") return num + 10;
|
||
},
|
||
aiValue(player, card, num) {
|
||
if (card.name === "zhangba") {
|
||
let fact = n => {
|
||
if (n > 1) return n * fact(n - 1);
|
||
return 1;
|
||
},
|
||
basic = 0;
|
||
return fact(
|
||
Math.min(
|
||
player.countCards("hs", i => {
|
||
if (get.tag(i, "multitarget")) return 2;
|
||
if (!["shan", "tao", "jiu"].includes(card.name)) return 1;
|
||
basic++;
|
||
}) /
|
||
(1 + basic),
|
||
player.getCardUsable("sha")
|
||
)
|
||
);
|
||
}
|
||
if (["shan", "tao", "jiu"].includes(card.name)) {
|
||
if (player.getEquip("zhangba") && player.countCards("hs") > 1) return 0.01;
|
||
return num / 2;
|
||
}
|
||
if (get.tag(card, "multitarget")) return num + game.players.length;
|
||
},
|
||
aiUseful(player, card, num) {
|
||
if (get.name(card, player) === "shan") {
|
||
if (
|
||
player.countCards("hs", i => {
|
||
if (card === i || (card.cards && card.cards.includes(i))) return false;
|
||
return get.name(i, player) === "shan";
|
||
})
|
||
)
|
||
return -1;
|
||
return num / Math.pow(Math.max(1, player.hp), 2);
|
||
}
|
||
},
|
||
},
|
||
trigger: {
|
||
player: "useCardToPlayered",
|
||
},
|
||
filter: function (event, player) {
|
||
if (get.type(event.card) == "equip") return false;
|
||
if (event.getParent().triggeredTargets3.length > 1) return false;
|
||
return event.targets.length > 0;
|
||
},
|
||
check: function (event, player) {
|
||
return !player.countCards("h", { type: "basic" });
|
||
},
|
||
locked: false,
|
||
content: function () {
|
||
"step 0";
|
||
player.showHandcards();
|
||
("step 1");
|
||
if (player.countCards("h", { type: "basic" })) event.finish();
|
||
else player.chooseBool("图射:是否摸" + get.cnNumber(trigger.targets.length) + "张牌?").set("ai", () => 1);
|
||
("step 2");
|
||
if (result.bool) {
|
||
player.draw(trigger.targets.length);
|
||
}
|
||
},
|
||
ai: {
|
||
presha: true,
|
||
pretao: true,
|
||
threaten: 1.8,
|
||
effect: {
|
||
player_use(card, player, target) {
|
||
if (
|
||
typeof card === "object" &&
|
||
card.name !== "shan" &&
|
||
get.type(card) !== "equip" &&
|
||
!player.countCards("h", i => {
|
||
if (card === i || (card.cards && card.cards.includes(i))) return false;
|
||
return get.type(i) === "basic";
|
||
})
|
||
) {
|
||
let targets = [],
|
||
evt = _status.event.getParent("useCard");
|
||
targets.addArray(ui.selected.targets);
|
||
if (evt && evt.card == card) targets.addArray(evt.targets);
|
||
if (targets.length) return [1, targets.length];
|
||
if (get.tag(card, "multitarget")) return [1, game.players.length - 1];
|
||
return [1, 1];
|
||
}
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgtongjue: {
|
||
audio: 2,
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
zhuSkill: true,
|
||
filter: function (event, player) {
|
||
return player.hasZhuSkill("jsrgtongjue") && game.hasPlayer(current => current != player && current.group == "qun");
|
||
},
|
||
filterCard: true,
|
||
selectCard: [1, Infinity],
|
||
filterTarget: function (card, player, target) {
|
||
return target != player && target.group == "qun";
|
||
},
|
||
selectTarget: [1, Infinity],
|
||
filterOk: function () {
|
||
return ui.selected.cards.length == ui.selected.targets.length;
|
||
},
|
||
check: function (card) {
|
||
var player = _status.event.player;
|
||
if (
|
||
player.hasCard(card => {
|
||
return player.hasValueTarget(card);
|
||
}, "hs")
|
||
) {
|
||
return 3 - player.getUseValue(card);
|
||
}
|
||
return 3 - get.value(card);
|
||
},
|
||
multiline: true,
|
||
multitarget: true,
|
||
delay: false,
|
||
discard: false,
|
||
lose: false,
|
||
content: function () {
|
||
"step 0";
|
||
var list = [];
|
||
for (var i = 0; i < targets.length; i++) {
|
||
var target = targets[i];
|
||
var card = cards[i];
|
||
list.push([target, card]);
|
||
}
|
||
game.loseAsync({
|
||
gain_list: list,
|
||
player: player,
|
||
cards: cards,
|
||
giver: player,
|
||
animate: "giveAuto",
|
||
}).setContent("gaincardMultiple");
|
||
("step 1");
|
||
player.addTempSkill("jsrgtongjue_blocker");
|
||
player.markAuto("jsrgtongjue_blocker", targets);
|
||
},
|
||
ai: {
|
||
order: 5,
|
||
result: {
|
||
target: 1,
|
||
},
|
||
},
|
||
subSkill: {
|
||
blocker: {
|
||
charlotte: true,
|
||
onremove: true,
|
||
mod: {
|
||
playerEnabled: function (card, player, target) {
|
||
if (player.getStorage("jsrgtongjue_blocker").includes(target)) return false;
|
||
},
|
||
},
|
||
mark: true,
|
||
intro: { content: "$已经立牧自居,不可接近" },
|
||
},
|
||
},
|
||
},
|
||
//404曹操
|
||
jsrgzhenglve: {
|
||
audio: 2,
|
||
trigger: { global: "phaseEnd" },
|
||
filter: function (event, player) {
|
||
var zhu = get.zhu(player) || game.findPlayer(current => current.getSeatNum() == 1);
|
||
return event.player == zhu;
|
||
},
|
||
locked: false,
|
||
group: "jsrgzhenglve_damage",
|
||
prompt2: function (event, player) {
|
||
var num = Math.min(
|
||
event.player.getHistory("sourceDamage").length > 0 ? 1 : 2,
|
||
game.countPlayer(current => {
|
||
return !current.hasMark("jsrgzhenglve_mark");
|
||
})
|
||
);
|
||
if (num == 0) return "你可以摸一张牌";
|
||
return "你可以摸一张牌并令" + get.cnNumber(num) + "名角色获得“猎”标记";
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
player.draw();
|
||
("step 1");
|
||
var damaged = trigger.player.getHistory("sourceDamage").length > 0;
|
||
var num = damaged ? 1 : 2;
|
||
var targets = game.filterPlayer(current => {
|
||
return !current.hasMark("jsrgzhenglve_mark");
|
||
});
|
||
if (!targets.length) event.finish();
|
||
else if (targets.length <= num) event._result = { bool: true, targets: targets };
|
||
else
|
||
player
|
||
.chooseTarget("令" + (num > 1 ? "至多" : "") + get.cnNumber(num) + "名角色获得“猎”标记", true, [1, num], (card, player, target) => {
|
||
return !target.hasMark("jsrgzhenglve_mark");
|
||
})
|
||
.set("ai", target => {
|
||
var att = get.attitude(_status.event.player, target);
|
||
return 100 - att;
|
||
});
|
||
("step 2");
|
||
if (result.bool) {
|
||
var targets = result.targets;
|
||
player.line(targets);
|
||
targets.forEach(i => i.addMark("jsrgzhenglve_mark", 1));
|
||
}
|
||
},
|
||
mod: {
|
||
cardUsableTarget: function (card, player, target) {
|
||
if (target.hasMark("jsrgzhenglve_mark")) return true;
|
||
},
|
||
targetInRange: function (card, player, target) {
|
||
if (target.hasMark("jsrgzhenglve_mark")) return true;
|
||
},
|
||
},
|
||
subSkill: {
|
||
damage: {
|
||
audio: "jsrgzhenglve",
|
||
trigger: { source: "damageSource" },
|
||
usable: 1,
|
||
filter: function (event, player) {
|
||
return event.player.hasMark("jsrgzhenglve_mark");
|
||
},
|
||
prompt2: function (event, player) {
|
||
var cards = event.cards || [];
|
||
return "摸一张牌" + (cards.filterInD().length ? "并获得" + get.translation(event.cards.filterInD()) : "");
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
player.draw();
|
||
var cards = trigger.cards;
|
||
if (cards && cards.filterInD().length) {
|
||
player.gain(cards.filterInD(), "gain2");
|
||
}
|
||
},
|
||
},
|
||
mark: {
|
||
marktext: "猎",
|
||
intro: {
|
||
name: "猎(政略)",
|
||
name2: "猎",
|
||
markcount: () => 0,
|
||
content: "已拥有“猎”标记",
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrghuilie: {
|
||
audio: 2,
|
||
trigger: { player: "phaseZhunbeiBegin" },
|
||
juexingji: true,
|
||
forced: true,
|
||
skillAnimation: true,
|
||
animationColor: "thunder",
|
||
derivation: ["jsrgpingrong", "feiying"],
|
||
filter: function (event, player) {
|
||
return game.countPlayer(current => current.hasMark("jsrgzhenglve_mark")) > 2;
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
player.awakenSkill("jsrghuilie");
|
||
player.loseMaxHp();
|
||
("step 1");
|
||
player.addSkills(["jsrgpingrong", "feiying"]);
|
||
},
|
||
ai: {
|
||
combo: "jsrgzhenglve",
|
||
},
|
||
},
|
||
jsrgpingrong: {
|
||
audio: 2,
|
||
trigger: { global: "phaseEnd" },
|
||
filter: function (event, player) {
|
||
return !player.hasSkill("jsrgpingrong_used") && game.hasPlayer(current => current.hasMark("jsrgzhenglve_mark"));
|
||
},
|
||
direct: true,
|
||
content: function () {
|
||
"step 0";
|
||
player
|
||
.chooseTarget(get.prompt("jsrghuilie"), "移去一名角色的“猎”,然后你执行一个额外回合。若你在此额外回合内未造成伤害,则你失去1点体力。", (card, player, target) => {
|
||
return target.hasMark("jsrgzhenglve_mark");
|
||
})
|
||
.set("ai", target => {
|
||
return get.attitude(_status.event.player, target);
|
||
});
|
||
("step 1");
|
||
if (result.bool) {
|
||
var target = result.targets[0];
|
||
player.logSkill("jsrgpingrong", target);
|
||
player.addTempSkill("jsrgpingrong_used", "roundStart");
|
||
target.removeMark("jsrgzhenglve_mark", target.countMark("jsrgzhenglve_mark"));
|
||
player.insertPhase();
|
||
player.addSkill("jsrgpingrong_check");
|
||
}
|
||
},
|
||
subSkill: {
|
||
used: { charlotte: true },
|
||
check: {
|
||
audio: "jsrgpingrong",
|
||
trigger: { player: "phaseAfter" },
|
||
charlotte: true,
|
||
forced: true,
|
||
filter: function (event, player) {
|
||
return event.skill == "jsrgpingrong" && !player.getHistory("sourceDamage").length;
|
||
},
|
||
content: function () {
|
||
player.loseHp();
|
||
},
|
||
},
|
||
},
|
||
ai: {
|
||
combo: "jsrgzhenglve",
|
||
},
|
||
},
|
||
//南华老仙
|
||
jsrgshoushu: {
|
||
audio: 2,
|
||
forced: true,
|
||
trigger: {
|
||
//player:'enterGame',
|
||
//global:'phaseBefore',
|
||
global: "roundStart",
|
||
},
|
||
filter: function (event, player) {
|
||
if (
|
||
game.hasPlayer(function (current) {
|
||
return current.countCards("hej", "taipingyaoshu");
|
||
})
|
||
)
|
||
return false;
|
||
return true;
|
||
//return event.name!='phase'||game.phaseNumber==0;
|
||
},
|
||
direct: true,
|
||
group: "jsrgshoushu_destroy",
|
||
content: function () {
|
||
"step 0";
|
||
player
|
||
.chooseTarget(get.prompt("jsrgshoushu"), "将【太平要术】置入一名角色的装备区", (card, player, target) => {
|
||
var card = { name: "taipingyaoshu" };
|
||
return target.canEquip(card, true);
|
||
})
|
||
.set("ai", target => {
|
||
return target.getUseValue({ name: "taipingyaoshu" }) * get.attitude(_status.event.player, target);
|
||
});
|
||
("step 1");
|
||
if (result.bool) {
|
||
var target = result.targets[0];
|
||
event.target = target;
|
||
player.logSkill("jsrgshoushu", target);
|
||
if (!lib.inpile.includes("taipingyaoshu")) {
|
||
lib.inpile.push("taipingyaoshu");
|
||
}
|
||
event.card = game.createCard2("taipingyaoshu", "heart", 3);
|
||
} else event.finish();
|
||
("step 2");
|
||
if (card) target.equip(card);
|
||
},
|
||
subSkill: {
|
||
destroy: {
|
||
audio: "jsrgshoushu",
|
||
trigger: {
|
||
global: ["loseEnd", "equipEnd", "addJudgeEnd", "gainEnd", "loseAsyncEnd", "addToExpansionEnd"],
|
||
},
|
||
forced: true,
|
||
filter: function (event, player) {
|
||
return game.hasPlayer(current => {
|
||
var evt = event.getl(current);
|
||
if (evt && evt.es) return evt.es.some(i => i.name == "taipingyaoshu");
|
||
return false;
|
||
});
|
||
},
|
||
content: function () {
|
||
var cards = [];
|
||
game.countPlayer(current => {
|
||
var evt = trigger.getl(current);
|
||
if (evt && evt.es) return cards.addArray(evt.es.filter(i => i.name == "taipingyaoshu"));
|
||
});
|
||
game.cardsGotoSpecial(cards);
|
||
game.log(cards, "被销毁了");
|
||
},
|
||
},
|
||
},
|
||
},
|
||
jsrgxundao: {
|
||
audio: 2,
|
||
trigger: { player: "judge" },
|
||
filter: function (event, player) {
|
||
return game.hasPlayer(current => current.countCards("he"));
|
||
},
|
||
direct: true,
|
||
content: function () {
|
||
"step 0";
|
||
var prompt2 = get.translation(player) + "(你)的" + (trigger.judgestr || "") + "判定为" + get.translation(player.judging[0]) + "," + "是否令至多两名角色依次弃置一张牌,然后选择其中一张作为新判定牌?";
|
||
player
|
||
.chooseTarget(get.prompt("jsrgxundao"), prompt2, [1, 2], (card, player, target) => {
|
||
return target.countCards("he");
|
||
})
|
||
.set("ai", target => {
|
||
var player = _status.event.player;
|
||
if (!_status.event.todiscard) return 0;
|
||
if (_status.event.todiscard != "all") {
|
||
if (target == _status.event.todiscard) return 100;
|
||
}
|
||
return get.effect(target, { name: "guohe_copy2" }, player, player) / 2;
|
||
})
|
||
.set(
|
||
"todiscard",
|
||
(function () {
|
||
if (trigger.judgestr == "闪电" && get.damageEffect(player, null, player, "thunder") >= 0) return "all";
|
||
var friends = game.filterPlayer(i => get.attitude(i, player) > 0);
|
||
for (var friend of friends) {
|
||
var cardsx = friend.getCards("he", card => trigger.judge(card) > 0);
|
||
cardsx.sort((a, b) => {
|
||
return get.value(a) - get.value(b);
|
||
});
|
||
if (cardsx.length) {
|
||
var card = cardsx[0];
|
||
if (trigger.judge(player.judging[0]) >= 0) {
|
||
if (get.value(card) > 4) return false;
|
||
}
|
||
return get.owner(card);
|
||
}
|
||
}
|
||
return "all";
|
||
})()
|
||
);
|
||
("step 1");
|
||
if (result.bool) {
|
||
var targets = result.targets;
|
||
targets.sortBySeat(_status.currentPhase);
|
||
event.targets = targets;
|
||
player.logSkill("jsrgxundao", targets);
|
||
event.cards = [];
|
||
} else event.finish();
|
||
("step 2");
|
||
var target = targets.shift();
|
||
target.chooseToDiscard("寻道:请弃置一张牌" + (target == player ? "" : ",可能被作为新判定牌"), "he", true).set("ai", card => {
|
||
var trigger = _status.event.getTrigger();
|
||
var player = _status.event.player;
|
||
var judging = _status.event.judging;
|
||
var result = trigger.judge(card) - trigger.judge(judging);
|
||
var attitude = get.attitude(player, trigger.player);
|
||
if (attitude == 0 || result == 0) return 0.1;
|
||
if (attitude > 0) {
|
||
return result + 0.01;
|
||
} else {
|
||
return 0.01 - result;
|
||
}
|
||
});
|
||
("step 3");
|
||
if (result.bool) {
|
||
event.cards.addArray(result.cards);
|
||
}
|
||
if (targets.length) event.goto(2);
|
||
("step 4");
|
||
var cards = event.cards.filterInD("d");
|
||
if (cards.length) {
|
||
player.chooseButton(["寻道:选择一张作为新判定牌", cards], true).set("ai", button => {
|
||
return trigger.judge(button.link);
|
||
});
|
||
} else event.finish();
|
||
("step 5");
|
||
if (result.bool) {
|
||
var card = result.links[0];
|
||
event.card = card;
|
||
game.cardsGotoOrdering(card).relatedEvent = trigger;
|
||
} else event.finish();
|
||
("step 6");
|
||
if (player.judging[0].clone) {
|
||
game.broadcastAll(
|
||
function (card, card2, player) {
|
||
if (card.clone) {
|
||
card.clone.classList.remove("thrownhighlight");
|
||
}
|
||
var node = player.$throwordered(card2.copy(), true);
|
||
node.classList.add("thrownhighlight");
|
||
ui.arena.classList.add("thrownhighlight");
|
||
},
|
||
player.judging[0],
|
||
card,
|
||
player
|
||
);
|
||
game.addVideo("deletenode", player, get.cardsInfo([player.judging[0].clone]));
|
||
}
|
||
game.cardsDiscard(player.judging[0]);
|
||
player.judging[0] = card;
|
||
trigger.orderingCards.add(card);
|
||
game.log(player, "的判定牌改为", card);
|
||
game.delay(2);
|
||
},
|
||
ai: {
|
||
rejudge: true,
|
||
tag: {
|
||
rejudge: 1,
|
||
},
|
||
},
|
||
},
|
||
jsrglinghua: {
|
||
audio: 2,
|
||
trigger: {
|
||
player: ["phaseZhunbeiBegin", "phaseJieshuBegin"],
|
||
},
|
||
prompt2: function (event, player) {
|
||
var zhunbei = event.name == "phaseZhunbei";
|
||
return "进行目标为你" + (zhunbei ? "" : "且效果反转") + "的【闪电】判定。若你未因此受到伤害,你可以" + (zhunbei ? "令一名角色回复1点体力" : "对一名角色造成1点雷电伤害");
|
||
},
|
||
check: function (event, player) {
|
||
var e2 = player.getEquip(2);
|
||
if (e2 && e2.name == "taipingyaoshu") return true;
|
||
if (
|
||
event.name == "phaseZhunbei" &&
|
||
game.hasPlayer(current => {
|
||
return get.recoverEffect(current, player, player) >= 0;
|
||
})
|
||
)
|
||
return true;
|
||
if (
|
||
event.name == "phaseJieshu" &&
|
||
game.hasPlayer(current => {
|
||
return get.damageEffect(current, player, player, "thunder") >= 0;
|
||
}) &&
|
||
player.hasSkillTag("rejudge") &&
|
||
player.hasCard(card => {
|
||
return lib.card.shandian.judge(card) < 0;
|
||
}, "he")
|
||
)
|
||
return true;
|
||
return false;
|
||
},
|
||
content: function () {
|
||
"step 0";
|
||
var next = (event.executeDelayCardEffect = player.executeDelayCardEffect("shandian"));
|
||
if (event.triggername != "phaseJieshuBegin") return;
|
||
next.judge = card => -lib.card.shandian.judge(card) - 4;
|
||
next.judge2 = result => !lib.card.shandian.judge2(result);
|
||
("step 1");
|
||
var executeDelayCardEffect = event.executeDelayCardEffect;
|
||
if (!player.hasHistory("damage", evt => evt.getParent(2) == executeDelayCardEffect)) {
|
||
if (trigger.name == "phaseZhunbei") {
|
||
player.chooseTarget("灵化:是否令一名角色回复1点体力?").set("ai", target => {
|
||
var player = _status.event.player;
|
||
return get.recoverEffect(target, player, player);
|
||
});
|
||
} else {
|
||
player.chooseTarget("灵化:是否对一名角色造成1点雷电伤害?").set("ai", target => {
|
||
var player = _status.event.player;
|
||
return get.damageEffect(target, player, player, "thunder");
|
||
});
|
||
}
|
||
} else event.finish();
|
||
("step 2");
|
||
if (result.bool) {
|
||
var target = result.targets[0];
|
||
player.line(target);
|
||
if (trigger.name == "phaseZhunbei") target.recover();
|
||
else target.damage("thunder");
|
||
}
|
||
},
|
||
ai: {
|
||
threaten: 2.8,
|
||
},
|
||
},
|
||
};
|
||
|
||
export default skills;
|