noname/character/extra/skill.js

8540 lines
246 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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