mirror of
https://github.com/Shu-Ying/noname-shuying.git
synced 2026-10-22 15:19:59 +08:00
1764 lines
44 KiB
JavaScript
1764 lines
44 KiB
JavaScript
import { lib, game, ui, get, ai, _status, getTianshuDifficulty } from "../../shared.js";
|
||
|
||
const skills = {
|
||
//孟婆 over
|
||
aotang_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: {
|
||
player: "phaseBegin",
|
||
},
|
||
forced: true,
|
||
locked: true,
|
||
filter(event, player) {
|
||
return player.getEnemies(null, false).some(target => {
|
||
if (!target.isIn()) return false;
|
||
|
||
return target.getStockSkills(false, true).some(skill => {
|
||
const info = get.info(skill);
|
||
return info && !info.charlotte && !info.temp && !info.sub;
|
||
});
|
||
});
|
||
},
|
||
async content(event, trigger, player) {
|
||
const difficulty = getTianshuDifficulty();
|
||
const enemies = player.getEnemies(null, false).filter(target => {
|
||
if (!target.isIn()) return false;
|
||
|
||
return target.getStockSkills(false, true).some(skill => {
|
||
const info = get.info(skill);
|
||
return info && !info.charlotte && !info.temp && !info.sub;
|
||
});
|
||
});
|
||
if (!enemies.length) return;
|
||
|
||
const targetNum = difficulty == "nightmare" ? 2 : 1;
|
||
const targets = enemies.randomGets(Math.min(targetNum, enemies.length));
|
||
const disableKey = `aotang_shuying_${player.playerid}`;
|
||
|
||
player.addSkill("aotang_shuying_clear");
|
||
player.storage.aotang_shuying_disabled = [];
|
||
|
||
for (const target of targets) {
|
||
let skills = target.getStockSkills(false, true).filter(skill => {
|
||
const info = get.info(skill);
|
||
return info && !info.charlotte && !info.temp && !info.sub;
|
||
});
|
||
if (!skills.length) continue;
|
||
|
||
if (difficulty == "normal") {
|
||
skills = [skills.randomGet()];
|
||
}
|
||
|
||
player.line(target);
|
||
target.disableSkill(disableKey, skills);
|
||
player.storage.aotang_shuying_disabled.push({
|
||
target,
|
||
disableKey,
|
||
});
|
||
|
||
if (!Array.isArray(target.storage.aotang_shuying_mark)) {
|
||
target.storage.aotang_shuying_mark = [];
|
||
}
|
||
target.storage.aotang_shuying_mark.push({
|
||
source: player,
|
||
disableKey,
|
||
skills: skills.slice(),
|
||
});
|
||
target.addSkill("aotang_shuying_mark");
|
||
target.markSkill("aotang_shuying_mark");
|
||
|
||
game.log(
|
||
target,
|
||
"暂时遗忘了技能",
|
||
`#g${get.translation(skills)}`
|
||
);
|
||
}
|
||
},
|
||
onremove(player) {
|
||
player.removeSkill("aotang_shuying_clear");
|
||
},
|
||
ai: {
|
||
threaten: 2,
|
||
},
|
||
subSkill: {
|
||
clear: {
|
||
charlotte: true,
|
||
forced: true,
|
||
forceDie: true,
|
||
popup: false,
|
||
firstDo: true,
|
||
priority: 100,
|
||
trigger: {
|
||
player: ["phaseBegin", "dieAfter"],
|
||
},
|
||
async content(event, trigger, player) {
|
||
player.removeSkill("aotang_shuying_clear");
|
||
},
|
||
onremove(player) {
|
||
for (const record of player.getStorage("aotang_shuying_disabled")) {
|
||
const target = record.target;
|
||
if (!target) continue;
|
||
|
||
target.enableSkill(record.disableKey);
|
||
const records = target
|
||
.getStorage("aotang_shuying_mark")
|
||
.filter(current => current.disableKey != record.disableKey);
|
||
if (records.length) {
|
||
target.storage.aotang_shuying_mark = records;
|
||
target.markSkill("aotang_shuying_mark");
|
||
} else {
|
||
delete target.storage.aotang_shuying_mark;
|
||
target.removeSkill("aotang_shuying_mark");
|
||
}
|
||
}
|
||
delete player.storage.aotang_shuying_disabled;
|
||
},
|
||
},
|
||
mark: {
|
||
charlotte: true,
|
||
mark: true,
|
||
marktext: "忘",
|
||
intro: {
|
||
content(storage, player) {
|
||
const records = player.getStorage("aotang_shuying_mark");
|
||
if (!records.length) return "没有因【熬汤】遗忘技能";
|
||
|
||
return records
|
||
.map(record => {
|
||
const source = record.source
|
||
? get.translation(record.source)
|
||
: "未知角色";
|
||
return `${source}令你暂时遗忘:${get.translation(
|
||
record.skills
|
||
)}`;
|
||
})
|
||
.join("<br>");
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
yunju_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: {
|
||
global: "phaseEnd",
|
||
},
|
||
forced: true,
|
||
locked: true,
|
||
logTarget: "player",
|
||
filter(event, player) {
|
||
return (
|
||
event.player?.isIn() &&
|
||
event.player.countCards("h") > 0 &&
|
||
player.getEnemies(null, false).includes(event.player)
|
||
);
|
||
},
|
||
async content(event, trigger, player) {
|
||
const difficulty = getTianshuDifficulty();
|
||
let num = 1;
|
||
|
||
if (difficulty == "hard") {
|
||
num = 2;
|
||
} else if (difficulty == "nightmare") {
|
||
num = 3;
|
||
}
|
||
|
||
player.line(trigger.player);
|
||
await trigger.player.randomDiscard(num, "h");
|
||
},
|
||
ai: {
|
||
threaten: 1.5,
|
||
},
|
||
},
|
||
guimei_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
forced: true,
|
||
locked: true,
|
||
group: [
|
||
"guimei_shuying_turn",
|
||
"guimei_shuying_redirect",
|
||
],
|
||
subSkill: {
|
||
turn: {
|
||
audio: "guimei_shuying",
|
||
trigger: {
|
||
player: "turnOverBefore",
|
||
},
|
||
forced: true,
|
||
locked: true,
|
||
filter(event, player) {
|
||
return (
|
||
getTianshuDifficulty() == "nightmare" &&
|
||
!player.isTurnedOver()
|
||
);
|
||
},
|
||
async content(event, trigger, player) {
|
||
trigger.cancel();
|
||
},
|
||
},
|
||
redirect: {
|
||
audio: "guimei_shuying",
|
||
trigger: {
|
||
global: "useCardToPlayer",
|
||
},
|
||
forced: true,
|
||
locked: true,
|
||
usable: 1,
|
||
filter(event, player) {
|
||
return (
|
||
getTianshuDifficulty() == "nightmare" &&
|
||
event.player != player &&
|
||
event.target == player &&
|
||
event.isFirstTarget &&
|
||
event.targets?.length == 1
|
||
);
|
||
},
|
||
async content(event, trigger, player) {
|
||
const source = trigger.player;
|
||
const originalTarget = trigger.target;
|
||
let targets;
|
||
|
||
if (get.type(trigger.card) == "delay") {
|
||
targets = game.filterPlayer(target => {
|
||
return lib.filter.judge(trigger.card, source, target);
|
||
});
|
||
} else {
|
||
targets = game.filterPlayer(target => {
|
||
return (
|
||
lib.filter.targetEnabled2(trigger.card, source, target) &&
|
||
lib.filter.targetInRange(trigger.card, source, target)
|
||
);
|
||
});
|
||
}
|
||
|
||
targets.add(originalTarget);
|
||
const target = targets.randomGet();
|
||
|
||
trigger.targets.remove(originalTarget);
|
||
trigger.getParent().triggeredTargets1?.remove(originalTarget);
|
||
trigger.getParent().triggeredTargets2?.remove(originalTarget);
|
||
trigger.untrigger();
|
||
trigger.targets.add(target);
|
||
|
||
source.line(target, "thunder");
|
||
game.log(trigger.card, "的目标被改为了", target);
|
||
|
||
if (target == player) {
|
||
await source.loseHp();
|
||
} else {
|
||
await player.recover();
|
||
}
|
||
},
|
||
},
|
||
},
|
||
ai: {
|
||
threaten: 1.8,
|
||
effect: {
|
||
target(card, source, target) {
|
||
if (
|
||
getTianshuDifficulty() == "nightmare" &&
|
||
source != target
|
||
) {
|
||
return [1, 0.5];
|
||
}
|
||
},
|
||
},
|
||
},
|
||
},
|
||
|
||
//豹尾 over
|
||
eli_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: {
|
||
source: "damageBegin1",
|
||
},
|
||
forced: true,
|
||
locked: true,
|
||
usable(skill, player) {
|
||
return getTianshuDifficulty() == "nightmare" ? Infinity : 1;
|
||
},
|
||
filter(event, player) {
|
||
return (
|
||
event.num > 0 &&
|
||
event.player?.isIn() &&
|
||
player.getEnemies(null, false).includes(event.player)
|
||
);
|
||
},
|
||
async content(event, trigger, player) {
|
||
const difficulty = getTianshuDifficulty();
|
||
const result = await player.judge(card => {
|
||
return get.color(card) == "red" ? 2 : 1;
|
||
}).forResult();
|
||
|
||
if (result.color == "red") {
|
||
trigger.num++;
|
||
return;
|
||
}
|
||
|
||
if (difficulty == "nightmare") {
|
||
await player.draw();
|
||
}
|
||
player.addTempSkill("wansha", {
|
||
global: "phaseAfter",
|
||
});
|
||
},
|
||
ai: {
|
||
threaten: 1.7,
|
||
damageBonus: true,
|
||
},
|
||
},
|
||
yinsha_shuying: {
|
||
mode: ["boss"],
|
||
audio: false,
|
||
forced: true,
|
||
locked: true,
|
||
mod: {
|
||
targetEnabled(card, source, target) {
|
||
if (
|
||
getTianshuDifficulty() != "normal" &&
|
||
source != target &&
|
||
!source.inRange(target)
|
||
) {
|
||
return false;
|
||
}
|
||
},
|
||
},
|
||
group: "yinsha_shuying_response",
|
||
subSkill: {
|
||
response: {
|
||
audio: "yinsha_shuying",
|
||
trigger: {
|
||
player: "useCard",
|
||
},
|
||
forced: true,
|
||
locked: true,
|
||
filter(event, player) {
|
||
return (
|
||
getTianshuDifficulty() != "normal" &&
|
||
game.hasPlayer(target => {
|
||
return target != player && !target.inRange(player);
|
||
})
|
||
);
|
||
},
|
||
async content(event, trigger, player) {
|
||
const targets = game.filterPlayer(target => {
|
||
return target != player && !target.inRange(player);
|
||
});
|
||
|
||
trigger.directHit.addArray(targets);
|
||
game.log(targets, "不能响应", player, "使用的", trigger.card);
|
||
},
|
||
},
|
||
},
|
||
ai: {
|
||
threaten: 1.8,
|
||
},
|
||
},
|
||
|
||
//鸟嘴 over
|
||
suoxue_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: {
|
||
player: "useCardToPlayered",
|
||
},
|
||
usable(skill, player) {
|
||
const difficulty = getTianshuDifficulty();
|
||
|
||
if (difficulty == "nightmare") return 3;
|
||
if (difficulty == "hard") return 2;
|
||
return 1;
|
||
},
|
||
filter(event, player) {
|
||
if (
|
||
!event.target?.isIn() ||
|
||
event.targets?.length != 1 ||
|
||
!get.tag(event.card, "damage") ||
|
||
!player.getEnemies(null, false).includes(event.target)
|
||
) {
|
||
return false;
|
||
}
|
||
|
||
const playerCount = player.countCards("h");
|
||
const targetCount = event.target.countCards("h");
|
||
|
||
if (targetCount > playerCount) return true;
|
||
if (targetCount >= playerCount) return false;
|
||
|
||
return player.hasCard(card => {
|
||
return lib.filter.cardDiscardable(card, player);
|
||
}, "h");
|
||
},
|
||
async cost(event, trigger, player) {
|
||
const target = trigger.target;
|
||
const playerCount = player.countCards("h");
|
||
const targetCount = target.countCards("h");
|
||
|
||
if (targetCount > playerCount) {
|
||
const num = Math.min(5, targetCount - playerCount);
|
||
const result = await player
|
||
.chooseBool(
|
||
get.prompt(event.skill, target),
|
||
`将手牌摸至与${get.translation(target)}相同,至多摸${get.cnNumber(num)}张牌`
|
||
)
|
||
.set("ai", () => true)
|
||
.forResult();
|
||
|
||
if (result.bool) {
|
||
result.cost_data = "draw";
|
||
}
|
||
event.result = result;
|
||
return;
|
||
}
|
||
|
||
const result = await player
|
||
.chooseToDiscard(
|
||
"h",
|
||
1,
|
||
get.prompt(event.skill, target),
|
||
`弃置一张手牌,令${get.translation(trigger.card)}不能被${get.translation(target)}响应`
|
||
)
|
||
.set("filterCard", lib.filter.cardDiscardable)
|
||
.set("ai", card => {
|
||
const player = get.player();
|
||
const trigger = get.event().getTrigger();
|
||
|
||
if (
|
||
get.damageEffect(
|
||
trigger.target,
|
||
player,
|
||
player
|
||
) <= 0
|
||
) {
|
||
return 0;
|
||
}
|
||
return 7 - get.value(card);
|
||
})
|
||
.forResult();
|
||
|
||
if (result.bool) {
|
||
result.cost_data = "directHit";
|
||
}
|
||
event.result = result;
|
||
},
|
||
async content(event, trigger, player) {
|
||
const target = trigger.target;
|
||
player.line(target);
|
||
|
||
if (event.cost_data == "draw") {
|
||
const num = Math.min(
|
||
5,
|
||
target.countCards("h") - player.countCards("h")
|
||
);
|
||
if (num > 0) {
|
||
await player.draw(num);
|
||
}
|
||
return;
|
||
}
|
||
|
||
trigger.getParent().directHit.add(target);
|
||
game.log(target, "不能响应", trigger.card);
|
||
},
|
||
ai: {
|
||
threaten: 1.4,
|
||
},
|
||
},
|
||
bingyi_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: {
|
||
player: "loseAfter",
|
||
global: [
|
||
"equipAfter",
|
||
"addJudgeAfter",
|
||
"gainAfter",
|
||
"loseAsyncAfter",
|
||
"addToExpansionAfter",
|
||
],
|
||
},
|
||
usable: 1,
|
||
forced: true,
|
||
locked: true,
|
||
filter(event, player) {
|
||
if (
|
||
getTianshuDifficulty() == "normal" ||
|
||
player.countCards("h") > 0
|
||
) {
|
||
return false;
|
||
}
|
||
|
||
const evt = event.getl(player);
|
||
return evt?.player == player && evt.hs?.length > 0;
|
||
},
|
||
async content(event, trigger, player) {
|
||
const num = getTianshuDifficulty() == "nightmare" ? 8 : 5;
|
||
await player.draw(num);
|
||
},
|
||
ai: {
|
||
threaten: 1.5,
|
||
effect: {
|
||
target(card, source, target) {
|
||
if (
|
||
get.tag(card, "loseCard") &&
|
||
target.countCards("h") == 1
|
||
) {
|
||
return [1, 0.6];
|
||
}
|
||
},
|
||
},
|
||
},
|
||
},
|
||
|
||
//黑白无常 over
|
||
mizui_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: { source: "damageEnd" },
|
||
forced: true,
|
||
filter(event, player) {
|
||
return event.player?.isIn() && event.player.countDiscardableCards(player, "he") > 0 && event.card && get.is.damageCard(event.card);
|
||
},
|
||
async content(event, trigger, player) {
|
||
const num = getTianshuDifficulty() == "normal" ? 1 : 2;
|
||
|
||
player.line(trigger.player);
|
||
await player.discardPlayerCard(trigger.player, num, "he", true);
|
||
},
|
||
ai: { expose: 0.2 },
|
||
},
|
||
qiangzheng_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: { global: "phaseEnd" },
|
||
forced: true,
|
||
logTarget: "player",
|
||
filter(event, player) {
|
||
let num = 2;
|
||
if (getTianshuDifficulty() == "hard") num = 4;
|
||
if (getTianshuDifficulty() == "nightmare") num = 6;
|
||
|
||
return event.player?.isIn() && player.getEnemies(null, false).includes(event.player) && event.player.countCards("h") > 0 && event.player.countCards("h") < num;
|
||
},
|
||
async content(event, trigger, player) {
|
||
player.line(trigger.player);
|
||
await player.gain(trigger.player.getCards("h"), trigger.player, "giveAuto");
|
||
},
|
||
},
|
||
xixing_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: { player: "phaseZhunbeiBegin" },
|
||
forced: true,
|
||
filter(event, player) {
|
||
return player.getEnemies(null, false).some(target => target.isIn());
|
||
},
|
||
async content(event, trigger, player) {
|
||
const difficulty = getTianshuDifficulty();
|
||
const enemies = player.getEnemies(null, false).filter(target => target.isIn());
|
||
|
||
if (difficulty == "nightmare") {
|
||
for (const target of enemies) {
|
||
player.line(target, "thunder");
|
||
await target.damage(2, "thunder", player);
|
||
}
|
||
} else {
|
||
const max = Math.max(...enemies.map(target => target.hp));
|
||
const target = enemies.filter(target => target.hp == max).randomGet();
|
||
player.line(target, "thunder");
|
||
await target.damage(2, "thunder", player);
|
||
}
|
||
|
||
await player.recover(2);
|
||
},
|
||
},
|
||
taiping_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: { player: "damageEnd" },
|
||
forced: true,
|
||
locked: true,
|
||
logTarget: "source",
|
||
filter(event, player) {
|
||
return (
|
||
event.num > 0 &&
|
||
event.source?.isIn() &&
|
||
player.getEnemies(null, false).includes(event.source)
|
||
);
|
||
},
|
||
async content(event, trigger, player) {
|
||
const source = trigger.source;
|
||
player.line(source);
|
||
|
||
const result = await source
|
||
.chooseToDiscard("h", 2, `太平:弃置两张花色不同的手牌,否则失去1点体力`, card => {
|
||
const cards = ui.selected.cards;
|
||
return !cards.some(cardx => get.suit(cardx) == get.suit(card));
|
||
})
|
||
.set("ai", card => {
|
||
const player = get.player();
|
||
if (player.hp <= 1) return 8 - get.value(card);
|
||
return 6 - get.value(card);
|
||
})
|
||
.forResult();
|
||
|
||
if (!result.bool) {
|
||
await source.loseHp();
|
||
}
|
||
},
|
||
ai: {
|
||
maixie_defend: true,
|
||
effect: {
|
||
target(card, player, target) {
|
||
if (get.tag(card, "damage") && target.getEnemies(null, false).includes(player)) {
|
||
if (player.countCards("h") < 2) return [1, -1];
|
||
return [1, 0.4];
|
||
}
|
||
},
|
||
},
|
||
},
|
||
},
|
||
|
||
//牛头马面 over
|
||
manji_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: {
|
||
player: "useCardToPlayered",
|
||
},
|
||
filter(event, player) {
|
||
return (
|
||
event.card.name == "sha" &&
|
||
event.targets?.length == 1 &&
|
||
event.target?.isIn() &&
|
||
player.getEnemies(null, false).includes(event.target) &&
|
||
event.target.countDiscardableCards(player, "h") > 0
|
||
);
|
||
},
|
||
async cost(event, trigger, player) {
|
||
const difficulty = getTianshuDifficulty();
|
||
const target = trigger.target;
|
||
let num = 1;
|
||
|
||
if (difficulty == "hard") {
|
||
num = 2;
|
||
} else if (difficulty == "nightmare") {
|
||
num = 3;
|
||
}
|
||
|
||
num = Math.min(
|
||
num,
|
||
target.countDiscardableCards(player, "h")
|
||
);
|
||
|
||
event.result = await player
|
||
.discardPlayerCard(
|
||
target,
|
||
"h",
|
||
get.prompt2(event.skill, target),
|
||
num
|
||
)
|
||
.set("chooseonly", true)
|
||
.set("ai", button => {
|
||
const card = button.link;
|
||
if (get.name(card, false) == "sha") {
|
||
return 12 - get.value(card);
|
||
}
|
||
return 6 - get.value(card);
|
||
})
|
||
.forResult();
|
||
},
|
||
async content(event, trigger, player) {
|
||
const target = trigger.target;
|
||
const cards = event.cards;
|
||
|
||
player.line(target);
|
||
await target.modedDiscard(cards, player);
|
||
|
||
if (!cards.some(card => get.name(card, false) == "sha")) {
|
||
return;
|
||
}
|
||
|
||
trigger.getParent().baseDamage++;
|
||
|
||
if (getTianshuDifficulty() == "nightmare") {
|
||
player.addTempSkill(
|
||
"manji_shuying_sha",
|
||
"phaseUseAfter"
|
||
);
|
||
player.addMark("manji_shuying_sha", 1, false);
|
||
}
|
||
},
|
||
ai: {
|
||
threaten: 1.5,
|
||
},
|
||
subSkill: {
|
||
sha: {
|
||
charlotte: true,
|
||
onremove: true,
|
||
mark: true,
|
||
marktext: "杀",
|
||
intro: {
|
||
content: "本阶段使用【杀】的次数上限+#",
|
||
},
|
||
mod: {
|
||
cardUsable(card, player, num) {
|
||
if (card.name == "sha") {
|
||
return num + player.countMark("manji_shuying_sha");
|
||
}
|
||
},
|
||
},
|
||
},
|
||
},
|
||
},
|
||
shiyv_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: {
|
||
player: "phaseDrawBegin1",
|
||
},
|
||
forced: true,
|
||
locked: true,
|
||
async content(event, trigger, player) {
|
||
trigger.changeToZero();
|
||
|
||
const pileCards = Array.from(ui.cardPile.childNodes);
|
||
const cards = [];
|
||
|
||
for (const suit of lib.suit) {
|
||
const list = pileCards.filter(card => {
|
||
return get.suit(card, false) == suit;
|
||
});
|
||
if (list.length) {
|
||
cards.push(list.randomGet());
|
||
}
|
||
}
|
||
|
||
if (cards.length) {
|
||
await player.gain(cards, "gain2");
|
||
}
|
||
},
|
||
ai: {
|
||
threaten: 1.4,
|
||
},
|
||
},
|
||
xiaoshou_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: {
|
||
player: "phaseZhunbeiBegin",
|
||
},
|
||
forced: true,
|
||
locked: true,
|
||
filter(event, player) {
|
||
return (
|
||
getTianshuDifficulty() != "normal" &&
|
||
player.getEnemies(null, false).some(target => target.isIn())
|
||
);
|
||
},
|
||
async content(event, trigger, player) {
|
||
const enemies = player
|
||
.getEnemies(null, false)
|
||
.filter(target => target.isIn());
|
||
if (!enemies.length) return;
|
||
|
||
const target = enemies.randomGet();
|
||
const num = getTianshuDifficulty() == "nightmare" ? 3 : 2;
|
||
|
||
player.line(target);
|
||
await target.damage(num, player);
|
||
},
|
||
ai: {
|
||
threaten: 1.8,
|
||
},
|
||
},
|
||
guizhao_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: {
|
||
player: "useCard",
|
||
},
|
||
forced: true,
|
||
locked: true,
|
||
filter(event, player) {
|
||
if (
|
||
getTianshuDifficulty() != "nightmare" ||
|
||
_status.currentPhase != player
|
||
) {
|
||
return false;
|
||
}
|
||
|
||
const type = get.type2(event.card, false);
|
||
return !player.getHistory("useCard").some(evt => {
|
||
return (
|
||
evt !== event &&
|
||
get.type2(evt.card, false) == type
|
||
);
|
||
});
|
||
},
|
||
async content(event, trigger, player) {
|
||
await player.draw();
|
||
},
|
||
ai: {
|
||
threaten: 1.3,
|
||
},
|
||
},
|
||
|
||
//鱼鳃 over
|
||
anchao_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
forced: true,
|
||
locked: true,
|
||
group: ["anchao_shuying_gain", "anchao_shuying_start"],
|
||
marktext: "潮",
|
||
intro: {
|
||
name: "暗潮",
|
||
content: "mark",
|
||
},
|
||
subSkill: {
|
||
gain: {
|
||
audio: "anchao_shuying",
|
||
trigger: { global: "phaseJieshuBegin" },
|
||
forced: true,
|
||
logTarget: "player",
|
||
filter(event, player) {
|
||
return (
|
||
event.player?.isIn() &&
|
||
!player.getEnemies(null, false).includes(event.player) &&
|
||
!event.player.getHistory("sourceDamage", evt => evt.num > 0).length
|
||
);
|
||
},
|
||
async content(event, trigger, player) {
|
||
trigger.player.addMark("anchao_shuying", 1);
|
||
},
|
||
},
|
||
start: {
|
||
audio: "anchao_shuying",
|
||
trigger: { global: "phaseBegin" },
|
||
forced: true,
|
||
logTarget: "player",
|
||
filter(event, player) {
|
||
return (
|
||
event.player?.isIn() &&
|
||
!player.getEnemies(null, false).includes(event.player) &&
|
||
event.player.countMark("anchao_shuying") > 0
|
||
);
|
||
},
|
||
async content(event, trigger, player) {
|
||
const target = trigger.player;
|
||
target.storage.anchao_shuying_effect = target.countMark("anchao_shuying");
|
||
target.addTempSkill("anchao_shuying_effect", { player: "phaseAfter" });
|
||
},
|
||
},
|
||
effect: {
|
||
charlotte: true,
|
||
group: ["anchao_shuying_draw", "anchao_shuying_damage"],
|
||
onremove(player) {
|
||
delete player.storage.anchao_shuying_effect;
|
||
},
|
||
},
|
||
draw: {
|
||
audio: "anchao_shuying",
|
||
trigger: { player: "phaseDrawBegin2" },
|
||
forced: true,
|
||
filter(event, player) {
|
||
return !event.numFixed && player.storage.anchao_shuying_effect > 0;
|
||
},
|
||
async content(event, trigger, player) {
|
||
trigger.num += player.storage.anchao_shuying_effect;
|
||
},
|
||
},
|
||
damage: {
|
||
audio: "anchao_shuying",
|
||
trigger: { source: "damageBegin1" },
|
||
forced: true,
|
||
filter(event, player) {
|
||
return (
|
||
player.storage.anchao_shuying_effect > 0 &&
|
||
event.player?.isIn() &&
|
||
player.getEnemies(null, false).includes(event.player)
|
||
);
|
||
},
|
||
async content(event, trigger, player) {
|
||
trigger.num += player.storage.anchao_shuying_effect;
|
||
},
|
||
},
|
||
},
|
||
ai: {
|
||
threaten: 2,
|
||
},
|
||
},
|
||
guixi_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: { player: "damageEnd" },
|
||
forced: true,
|
||
locked: true,
|
||
filter(event, player) {
|
||
return event.num > 0;
|
||
},
|
||
async content(event, trigger, player) {
|
||
const num = getTianshuDifficulty() == "nightmare" ? 2 : 1;
|
||
const result = await player
|
||
.judge(card => get.color(card) == "red" ? 2 : 0)
|
||
.set("judge2", result => result.bool)
|
||
.forResult();
|
||
|
||
if (result.bool && player.isDamaged()) {
|
||
await player.recover();
|
||
}
|
||
else {
|
||
await player.draw(num);
|
||
}
|
||
},
|
||
ai: {
|
||
maixie: true,
|
||
maixie_hp: true,
|
||
effect: {
|
||
target(card, player, target) {
|
||
if (get.tag(card, "damage")) {
|
||
if (player.hasSkillTag("jueqing", false, target)) return [1, -1];
|
||
return [1, 0.7];
|
||
}
|
||
},
|
||
},
|
||
},
|
||
},
|
||
|
||
//黄蜂 over
|
||
mingchong_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: { player: "die" },
|
||
forced: true,
|
||
locked: true,
|
||
forceDie: true,
|
||
logTarget: "source",
|
||
filter(event, player) {
|
||
return event.source?.isIn() && event.source.countDiscardableCards(player, "he") > 0;
|
||
},
|
||
async content(event, trigger, player) {
|
||
const source = trigger.source;
|
||
player.line(source);
|
||
|
||
const cards = source
|
||
.getCards("he")
|
||
.filter(card => lib.filter.cardDiscardable(card, source, "mingchong_shuying"));
|
||
|
||
if (cards.length) {
|
||
if (getTianshuDifficulty() == "nightmare") {
|
||
await source.discard(cards);
|
||
}
|
||
else {
|
||
await source.discard(cards.randomGets(Math.ceil(cards.length / 2)));
|
||
}
|
||
}
|
||
},
|
||
ai: {
|
||
threaten: 0.8,
|
||
effect: {
|
||
target(card, player, target) {
|
||
if (get.tag(card, "damage") && target.hp <= 1 && player.countCards("he") > 2) {
|
||
return [1, -0.8];
|
||
}
|
||
},
|
||
},
|
||
},
|
||
},
|
||
duzhen_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: { player: "useCardToPlayered" },
|
||
forced: true,
|
||
locked: true,
|
||
logTarget: "target",
|
||
filter(event, player) {
|
||
return (
|
||
event.targets?.length == 1 &&
|
||
event.target?.isIn() &&
|
||
player.getEnemies(null, false).includes(event.target) &&
|
||
event.target.countDiscardableCards(player, "he") > 0
|
||
);
|
||
},
|
||
async content(event, trigger, player) {
|
||
const target = trigger.target;
|
||
const num = getTianshuDifficulty() == "nightmare" ? 2 : 1;
|
||
const cards = [];
|
||
|
||
player.line(target);
|
||
|
||
const equips = target
|
||
.getCards("e")
|
||
.filter(card => lib.filter.cardDiscardable(card, target, "duzhen_shuying"))
|
||
.randomGets(num);
|
||
cards.addArray(equips);
|
||
|
||
if (cards.length < num) {
|
||
const hands = target
|
||
.getCards("h")
|
||
.filter(card => lib.filter.cardDiscardable(card, target, "duzhen_shuying"))
|
||
.randomGets(num - cards.length);
|
||
cards.addArray(hands);
|
||
}
|
||
|
||
if (cards.length) {
|
||
await target.discard(cards);
|
||
}
|
||
},
|
||
ai: {
|
||
threaten: 1.8,
|
||
effect: {
|
||
player_use(card, player, target) {
|
||
if (target && player.getEnemies(null, false).includes(target) && target.countCards("he") > 0) {
|
||
return [1, 0.5];
|
||
}
|
||
},
|
||
},
|
||
},
|
||
},
|
||
|
||
//日夜游神 over
|
||
huiyun_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
enable: "phaseUse",
|
||
usable: 1,
|
||
filter(event, player) {
|
||
return player.getEnemies(null, false).some(target => target.isIn() && target.countCards("h") > 0);
|
||
},
|
||
filterTarget(card, player, target) {
|
||
return target.isIn() && player.getEnemies(null, false).includes(target) && target.countCards("h") > 0;
|
||
},
|
||
async content(event, trigger, player) {
|
||
const target = event.targets[0];
|
||
const hs = target.getCards("h");
|
||
player.line(target);
|
||
await target.showCards(hs, `${get.translation(player)}对${get.translation(target)}发动了【${get.translation(event.name)}】`);
|
||
|
||
const result = await player
|
||
.choosePlayerCard(target, "h", [1, 2], `弃置${get.translation(target)}至多两张手牌`)
|
||
.set("filterButton", button => {
|
||
const player = get.player();
|
||
const target = get.event().target;
|
||
return lib.filter.canBeDiscarded(button.link, player, target);
|
||
})
|
||
.set("ai", button => {
|
||
const card = button.link;
|
||
const player = get.player();
|
||
const target = get.event().target;
|
||
let value = get.value(card, target);
|
||
if (get.name(card, target) == "tao") value += 3;
|
||
if (get.name(card, target) == "shan") value += 1;
|
||
return value;
|
||
})
|
||
.set("target", target)
|
||
.forResult();
|
||
|
||
if (!result.bool || !result.cards?.length) return;
|
||
|
||
const names = result.cards.map(card => get.name(card, target)).unique();
|
||
await target.discard(result.cards);
|
||
|
||
if (!target.isIn()) return;
|
||
|
||
const result2 = await player
|
||
.chooseToDiscard("he", `是否弃置一张同名牌,对${get.translation(target)}造成2点伤害?`, card => {
|
||
return get.event().names.includes(get.name(card));
|
||
})
|
||
.set("names", names)
|
||
.set("ai", card => {
|
||
const player = get.player();
|
||
const target = get.event().target;
|
||
if (!player.getEnemies(null, false).includes(target)) return 0;
|
||
const effect = get.damageEffect(target, player, player);
|
||
if (effect <= 0) return 0;
|
||
return effect * 3 - get.value(card);
|
||
})
|
||
.set("target", target)
|
||
.forResult();
|
||
|
||
if (result2.bool) {
|
||
const num = getTianshuDifficulty() == "normal" ? 1 : 2
|
||
|
||
player.line(target);
|
||
await target.damage(num, player);
|
||
}
|
||
},
|
||
ai: {
|
||
order: 5,
|
||
result: {
|
||
target(player, target) {
|
||
if (!player.getEnemies(null, false).includes(target)) return 0;
|
||
return -Math.min(2, target.countCards("h"));
|
||
},
|
||
},
|
||
threaten: 1.6,
|
||
},
|
||
},
|
||
yezhong_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: { player: "phaseJieshuBegin" },
|
||
forced: true,
|
||
locked: true,
|
||
async content(event, trigger, player) {
|
||
const result = await player
|
||
.judge(card => get.color(card) == "black" ? 2 : -1)
|
||
.set("judge2", result => result.bool)
|
||
.forResult();
|
||
|
||
if (result.card) {
|
||
await player.gain(result.card, "gain2");
|
||
}
|
||
|
||
if (result.bool) {
|
||
let num = 1;
|
||
if (getTianshuDifficulty() == "hard") num = 2;
|
||
if (getTianshuDifficulty() == "nightmare") num = 3;
|
||
|
||
const targets = player.getEnemies(null, false).filter(target => target.isIn() && target.countCards("h") > 0);
|
||
for (const target of targets) {
|
||
player.line(target);
|
||
const cards = target
|
||
.getCards("h")
|
||
.filter(card => lib.filter.cardDiscardable(card, target, "yezhong_shuying"))
|
||
.randomGets(num);
|
||
|
||
if (cards.length) {
|
||
await target.discard(cards);
|
||
}
|
||
}
|
||
}
|
||
},
|
||
ai: {
|
||
threaten: 1.8,
|
||
},
|
||
},
|
||
zhoucha_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: { player: "phaseZhunbeiBegin" },
|
||
forced: true,
|
||
locked: true,
|
||
async content(event, trigger, player) {
|
||
const result = await player
|
||
.judge(card => get.color(card) == "red" ? 2 : -1)
|
||
.set("judge2", result => result.bool)
|
||
.forResult();
|
||
|
||
if (result.card) {
|
||
await player.gain(result.card, "gain2");
|
||
}
|
||
|
||
if (result.bool) {
|
||
player.addTempSkill("zhoucha_shuying_effect", { player: "phaseAfter" });
|
||
}
|
||
},
|
||
subSkill: {
|
||
effect: {
|
||
charlotte: true,
|
||
mod: {
|
||
cardUsable(card, player, num) {
|
||
let number = 1;
|
||
if (getTianshuDifficulty() == "hard") number = 2;
|
||
if (getTianshuDifficulty() == "nightmare") number = 3;
|
||
|
||
if (card.name == "sha") return num + number;
|
||
},
|
||
},
|
||
},
|
||
},
|
||
ai: {
|
||
threaten: 1.4,
|
||
},
|
||
},
|
||
duane_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: { global: "phaseDiscardEnd" },
|
||
forced: true,
|
||
locked: true,
|
||
logTarget: "player",
|
||
filter(event, player) {
|
||
const target = event.player;
|
||
return (
|
||
target?.isIn() &&
|
||
player.getEnemies(null, false).includes(target) &&
|
||
target.getHistory("lose", evt => {
|
||
return (
|
||
evt.type == "discard" &&
|
||
evt.getParent("phaseDiscard") == event &&
|
||
evt.cards2?.some(card => get.color(card, target) == "black")
|
||
);
|
||
}).length
|
||
);
|
||
},
|
||
async content(event, trigger, player) {
|
||
const target = trigger.player;
|
||
player.line(target);
|
||
await target.loseHp(2);
|
||
},
|
||
ai: {
|
||
threaten: 1.5,
|
||
},
|
||
},
|
||
|
||
//鬼王 over
|
||
jizhou_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: {
|
||
global: "phaseUseBegin",
|
||
},
|
||
forced: true,
|
||
locked: true,
|
||
logTarget: "player",
|
||
filter(event, player) {
|
||
return (
|
||
event.player?.isIn() &&
|
||
player.getEnemies(null, false).includes(event.player)
|
||
);
|
||
},
|
||
async content(event, trigger, player) {
|
||
const target = trigger.player;
|
||
const difficulty = getTianshuDifficulty();
|
||
const num = difficulty == "nightmare" ? 2 : 1;
|
||
const result = await player.judge().forResult();
|
||
const judgeNumber = result.number;
|
||
|
||
const cards = target.getCards("he", card => {
|
||
return lib.filter.cardDiscardable(card, target);
|
||
});
|
||
const canDiscard =
|
||
cards.reduce((sum, card) => {
|
||
return sum + get.number(card, false);
|
||
}, 0) > judgeNumber;
|
||
|
||
let discarded = false;
|
||
|
||
if (canDiscard) {
|
||
const discardResult = await target
|
||
.chooseToDiscard(
|
||
"he",
|
||
`疾咒:弃置任意张点数之和大于${get.cnNumber(judgeNumber)}的牌,或取消并失去${get.cnNumber(num)}点体力`
|
||
)
|
||
.set("complexCard", true)
|
||
.set("judgeNumber", judgeNumber)
|
||
.set("selectCard", () => {
|
||
const sum = ui.selected.cards.reduce((total, card) => {
|
||
return total + get.number(card, false);
|
||
}, 0);
|
||
|
||
if (sum > get.event().judgeNumber) {
|
||
return ui.selected.cards.length;
|
||
}
|
||
return ui.selected.cards.length + 1;
|
||
})
|
||
.set("ai", card => {
|
||
const target = get.player();
|
||
const selected = ui.selected.cards.reduce((sum, current) => {
|
||
return sum + get.number(current, false);
|
||
}, 0);
|
||
|
||
if (selected > get.event().judgeNumber) return 0;
|
||
|
||
const urgency = target.hp <= num ? 4 : target.hp <= 2 ? 2 : 1;
|
||
return get.number(card, false) * urgency - get.value(card);
|
||
})
|
||
.set("num", num)
|
||
.forResult();
|
||
|
||
discarded = discardResult.bool;
|
||
}
|
||
|
||
if (discarded) {
|
||
target.line(player);
|
||
player.addMark("jizhou_shuying", num, false);
|
||
} else {
|
||
player.line(target);
|
||
await target.loseHp(num);
|
||
}
|
||
},
|
||
marktext: "噬",
|
||
intro: {
|
||
name: "噬",
|
||
content: "mark",
|
||
},
|
||
ai: {
|
||
threaten: 1.7,
|
||
},
|
||
},
|
||
danshi_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: {
|
||
player: "damageBegin1",
|
||
},
|
||
forced: true,
|
||
locked: true,
|
||
filter(event, player) {
|
||
return event.num > 0;
|
||
},
|
||
async content(event, trigger, player) {
|
||
const difficulty = getTianshuDifficulty();
|
||
let num = 1;
|
||
|
||
if (difficulty == "hard") {
|
||
num = 2;
|
||
} else if (difficulty == "nightmare") {
|
||
num = 3;
|
||
}
|
||
|
||
trigger.num++;
|
||
await player.draw(num);
|
||
|
||
if (player.countMark("jizhou_shuying") > 0) {
|
||
player.removeMark("jizhou_shuying", 1, false);
|
||
}
|
||
},
|
||
ai: {
|
||
threaten: 0.8,
|
||
maixie: true,
|
||
effect: {
|
||
target(card, source, target) {
|
||
if (get.tag(card, "damage")) {
|
||
return [1, -1.3, 0, 0.4];
|
||
}
|
||
},
|
||
},
|
||
},
|
||
},
|
||
chihu_shuying: {
|
||
mode: ["boss"],
|
||
audio: false,
|
||
forced: true,
|
||
locked: true,
|
||
group: [
|
||
"chihu_shuying_draw",
|
||
"chihu_shuying_damage",
|
||
],
|
||
subSkill: {
|
||
draw: {
|
||
audio: "chihu_shuying",
|
||
trigger: {
|
||
player: "phaseDrawBegin2",
|
||
},
|
||
forced: true,
|
||
locked: true,
|
||
filter(event, player) {
|
||
return (
|
||
getTianshuDifficulty() == "nightmare" &&
|
||
!event.numFixed &&
|
||
!player.isMaxHandcard()
|
||
);
|
||
},
|
||
async content(event, trigger, player) {
|
||
trigger.num += 4;
|
||
},
|
||
},
|
||
damage: {
|
||
audio: "chihu_shuying",
|
||
trigger: {
|
||
source: "damageBegin1",
|
||
},
|
||
forced: true,
|
||
locked: true,
|
||
filter(event, player) {
|
||
return (
|
||
getTianshuDifficulty() == "nightmare" &&
|
||
event.num > 0 &&
|
||
event.player?.isIn() &&
|
||
player.getEnemies(null, false).includes(event.player) &&
|
||
!player.isMaxHp()
|
||
);
|
||
},
|
||
async content(event, trigger, player) {
|
||
trigger.num++;
|
||
},
|
||
},
|
||
},
|
||
ai: {
|
||
threaten: 1.8,
|
||
},
|
||
},
|
||
|
||
//阎罗王 over
|
||
dianwei_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: {
|
||
player: "phaseZhunbeiBegin",
|
||
},
|
||
forced: true,
|
||
locked: true,
|
||
filter(event, player) {
|
||
return player.getEnemies(null, false).some(target => target.isIn());
|
||
},
|
||
async content(event, trigger, player) {
|
||
let enemies = player
|
||
.getEnemies(null, false)
|
||
.filter(target => target.isIn());
|
||
|
||
const sha = {
|
||
name: "sha",
|
||
isCard: true,
|
||
};
|
||
const shaTargets = enemies.filter(target => {
|
||
return (
|
||
target.countCards("e") == 0 &&
|
||
player.canUse(sha, target, false)
|
||
);
|
||
});
|
||
|
||
if (shaTargets.length) {
|
||
await player.useCard(sha, shaTargets, false);
|
||
}
|
||
|
||
enemies = player
|
||
.getEnemies(null, false)
|
||
.filter(target => {
|
||
return target.isIn() && target.countCards("e") > 0;
|
||
});
|
||
|
||
for (const target of enemies) {
|
||
player.line(target);
|
||
await target.randomDiscard("e", player);
|
||
}
|
||
},
|
||
ai: {
|
||
threaten: 1.7,
|
||
},
|
||
},
|
||
xingpan_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:1",
|
||
trigger: {
|
||
player: "phaseUseBegin",
|
||
},
|
||
forced: true,
|
||
locked: true,
|
||
filter(event, player) {
|
||
return player.getEnemies(null, false).some(target => target.isIn());
|
||
},
|
||
async content(event, trigger, player) {
|
||
const enemies = player
|
||
.getEnemies(null, false)
|
||
.filter(target => target.isIn());
|
||
if (!enemies.length) return;
|
||
|
||
const result = await player.judge().forResult();
|
||
|
||
if (result.color == "red") {
|
||
const target = enemies.find(current => {
|
||
return enemies.every(other => {
|
||
return (
|
||
other == current ||
|
||
other.countCards("h") < current.countCards("h")
|
||
);
|
||
});
|
||
});
|
||
if (!target) return;
|
||
|
||
const num = Math.floor(target.countCards("h") / 2);
|
||
if (num <= 0) return;
|
||
|
||
target.line(player);
|
||
await target
|
||
.chooseToGive(
|
||
player,
|
||
"h",
|
||
num,
|
||
true,
|
||
`刑判:将${get.cnNumber(num)}张手牌交给${get.translation(player)}`
|
||
)
|
||
.set("ai", card => 7 - get.value(card));
|
||
return;
|
||
}
|
||
|
||
const target = enemies.find(current => {
|
||
return enemies.every(other => {
|
||
return (
|
||
other == current ||
|
||
other.getHp() < current.getHp()
|
||
);
|
||
});
|
||
});
|
||
if (!target) return;
|
||
|
||
player.line(target);
|
||
await target.loseHp();
|
||
},
|
||
ai: {
|
||
threaten: 1.6,
|
||
},
|
||
},
|
||
zhennu_shuying: {
|
||
mode: ["boss"],
|
||
audio: false,
|
||
trigger: {
|
||
player: "changeHp",
|
||
},
|
||
forced: true,
|
||
locked: true,
|
||
silent: true,
|
||
popup: false,
|
||
mark: true,
|
||
filter(event, player) {
|
||
return (
|
||
getTianshuDifficulty() != "normal" &&
|
||
!player.storage.zhennu_shuying_used &&
|
||
event.changedHp < 0 &&
|
||
event.originalHp > event.originalMaxHp / 2 &&
|
||
event.originalHp + event.changedHp <= event.originalMaxHp / 2
|
||
);
|
||
},
|
||
async content(event, trigger, player) {
|
||
player.storage.zhennu_shuying_used = true;
|
||
player.storage.zhennu_shuying_pending = true;
|
||
player.storage.zhennu_shuying_pending_type = trigger.getParent()?.name;
|
||
trigger.zhennu_shuying_pending = true;
|
||
player.markSkill("zhennu_shuying");
|
||
},
|
||
group: "zhennu_shuying_takeover",
|
||
subSkill: {
|
||
takeover: {
|
||
charlotte: true,
|
||
forced: true,
|
||
silent: true,
|
||
popup: false,
|
||
forceDie: true,
|
||
trigger: {
|
||
player: [
|
||
"changeHpAfter",
|
||
"damageAfter",
|
||
"loseHpAfter",
|
||
"dyingAfter",
|
||
],
|
||
},
|
||
filter(event, player, name) {
|
||
if (
|
||
!player.storage.zhennu_shuying_pending ||
|
||
!player.isIn() ||
|
||
player.hp <= 0
|
||
) {
|
||
return false;
|
||
}
|
||
|
||
if (name == "dyingAfter") return true;
|
||
if (name == "changeHpAfter") {
|
||
return (
|
||
event.zhennu_shuying_pending === true &&
|
||
!["damage", "loseHp"].includes(
|
||
player.storage.zhennu_shuying_pending_type
|
||
)
|
||
);
|
||
}
|
||
|
||
return (
|
||
(name == "damageAfter" &&
|
||
player.storage.zhennu_shuying_pending_type ==
|
||
"damage") ||
|
||
(name == "loseHpAfter" &&
|
||
player.storage.zhennu_shuying_pending_type ==
|
||
"loseHp")
|
||
);
|
||
},
|
||
async content(event, trigger, player) {
|
||
delete player.storage.zhennu_shuying_pending;
|
||
delete player.storage.zhennu_shuying_pending_type;
|
||
player.logSkill("zhennu_shuying");
|
||
|
||
const phase = event.getParent("phase");
|
||
const phaseLoop = event.getParent("phaseLoop");
|
||
if (phase && phaseLoop) {
|
||
player.insertPhase("zhennu_shuying");
|
||
phaseLoop.player = player;
|
||
|
||
let activeChild = event;
|
||
let current = event.getParent();
|
||
while (current && current != phaseLoop) {
|
||
const pendingEvents = [
|
||
...(current.next || []),
|
||
...(current.after || []),
|
||
];
|
||
for (const pendingEvent of pendingEvents) {
|
||
if (pendingEvent == activeChild) continue;
|
||
pendingEvent.finish();
|
||
pendingEvent.untrigger(true);
|
||
}
|
||
|
||
current.finish();
|
||
current.untrigger(true);
|
||
if (current == phase) break;
|
||
activeChild = current;
|
||
current = current.getParent();
|
||
}
|
||
}
|
||
|
||
await player.draw(4);
|
||
if (!phase || !phaseLoop) {
|
||
player.insertPhase("zhennu_shuying", true);
|
||
}
|
||
},
|
||
},
|
||
},
|
||
intro: {
|
||
content(storage, player) {
|
||
return player.storage.zhennu_shuying_used
|
||
? "本局游戏已经发动"
|
||
: "本局游戏尚未发动";
|
||
},
|
||
},
|
||
ai: {
|
||
threaten: 1.8,
|
||
},
|
||
},
|
||
xuanpan_shuying: {
|
||
mode: ["boss"],
|
||
audio: "ext:术樱包/pve/audio/skill/驱鬼逐邪:2",
|
||
trigger: {
|
||
global: "phaseAfter",
|
||
},
|
||
filter(event, player) {
|
||
if (
|
||
getTianshuDifficulty() != "nightmare" ||
|
||
!event.player?.isIn() ||
|
||
!player.getEnemies(null, false).includes(event.player)
|
||
) {
|
||
return false;
|
||
}
|
||
|
||
const target = event.player;
|
||
const damage = target
|
||
.getHistory("sourceDamage", evt => {
|
||
return evt.player == player;
|
||
})
|
||
.reduce((sum, evt) => sum + evt.num, 0);
|
||
|
||
const draw = target
|
||
.getHistory("gain", evt => {
|
||
return evt.getParent()?.name == "draw";
|
||
})
|
||
.reduce((sum, evt) => sum + evt.cards.length, 0);
|
||
|
||
const recover = game
|
||
.getGlobalHistory("changeHp", evt => {
|
||
return (
|
||
evt.player == target &&
|
||
evt.getParent()?.name == "recover"
|
||
);
|
||
})
|
||
.reduce((sum, evt) => sum + evt.num, 0);
|
||
|
||
const discard = player
|
||
.getHistory("lose", evt => {
|
||
return (
|
||
evt.type == "discard" &&
|
||
evt.position == ui.discardPile &&
|
||
evt.getlx !== false
|
||
);
|
||
})
|
||
.reduce((sum, evt) => sum + (evt.cards2?.length || 0), 0);
|
||
|
||
return (
|
||
damage >= 4 ||
|
||
draw >= 8 ||
|
||
recover >= 3 ||
|
||
discard >= 4
|
||
);
|
||
},
|
||
async cost(event, trigger, player) {
|
||
const target = trigger.player;
|
||
const data = {
|
||
damage:
|
||
target
|
||
.getHistory("sourceDamage", evt => {
|
||
return evt.player == player;
|
||
})
|
||
.reduce((sum, evt) => sum + evt.num, 0) >= 4,
|
||
draw:
|
||
target
|
||
.getHistory("gain", evt => {
|
||
return evt.getParent()?.name == "draw";
|
||
})
|
||
.reduce((sum, evt) => sum + evt.cards.length, 0) >= 8,
|
||
recover:
|
||
game
|
||
.getGlobalHistory("changeHp", evt => {
|
||
return (
|
||
evt.player == target &&
|
||
evt.getParent()?.name == "recover"
|
||
);
|
||
})
|
||
.reduce((sum, evt) => sum + evt.num, 0) >= 3,
|
||
discard:
|
||
player
|
||
.getHistory("lose", evt => {
|
||
return (
|
||
evt.type == "discard" &&
|
||
evt.position == ui.discardPile &&
|
||
evt.getlx !== false
|
||
);
|
||
})
|
||
.reduce((sum, evt) => {
|
||
return sum + (evt.cards2?.length || 0);
|
||
}, 0) >= 4,
|
||
};
|
||
|
||
const list = [];
|
||
if (data.damage) list.push("对其造成1至3点伤害");
|
||
if (data.draw) list.push("随机摸1至4张牌");
|
||
if (data.recover) list.push("随机回复1至3点体力");
|
||
if (data.discard) list.push(`令其随机弃置1至3张手牌`);
|
||
|
||
const result = await player
|
||
.chooseBool(
|
||
get.prompt(event.skill, target),
|
||
`依次执行:${list.join(";")}`
|
||
)
|
||
.set("ai", () => true)
|
||
.forResult();
|
||
|
||
if (result.bool) {
|
||
result.cost_data = data;
|
||
}
|
||
event.result = result;
|
||
},
|
||
async content(event, trigger, player) {
|
||
const target = trigger.player;
|
||
const data = event.cost_data;
|
||
|
||
if (data.damage && target.isIn()) {
|
||
player.line(target);
|
||
await target.damage(get.rand(1, 3), player);
|
||
}
|
||
|
||
if (data.draw && player.isIn()) {
|
||
await player.draw(get.rand(1, 4));
|
||
}
|
||
|
||
if (data.recover && player.isIn() && player.isDamaged()) {
|
||
await player.recover(get.rand(1, 3));
|
||
}
|
||
|
||
if (
|
||
data.discard &&
|
||
target.isIn() &&
|
||
target.countCards("h") > 0
|
||
) {
|
||
player.line(target);
|
||
await target.randomDiscard(get.rand(1, 3), "h");
|
||
}
|
||
},
|
||
ai: {
|
||
threaten: 1.5,
|
||
},
|
||
},
|
||
};
|
||
|
||
export default skills;
|