noname/character/extra/skill.js

8540 lines
246 KiB
JavaScript
Raw Normal View History

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) {
2024-06-02 08:50:12 +00:00
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) {
2024-06-02 08:50:12 +00:00
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) {
2024-06-02 08:50:12 +00:00
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) {
2024-06-02 08:50:12 +00:00
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) {
2024-06-02 08:50:12 +00:00
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);
2024-06-02 08:50:12 +00:00
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: {
2024-05-31 16:34:46 +00:00
effect: {
player(card, player, target) {
if (
!get.tag(card, "damage") ||
player.countMark("dcxianjin") % 2 ||
2024-06-01 05:29:32 +00:00
!player.hasSkillTag("jueqing", false, target)
2024-05-31 16:34:46 +00:00
) 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: {
2024-05-11 07:47:03 +00:00
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: {
2024-05-18 13:15:19 +00:00
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: {
2024-05-11 07:47:03 +00:00
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>";
2024-05-18 13:35:19 +00:00
str += "<li>锁定技。若你因〖驭衡〗获得过〖观潮〗〖决堰〗〖澜疆〗,则当你成为自己使用的装备牌的目标后,你将此牌置于弃牌堆,然后使用一张与此装备牌副类别相同的【长安大舰】。";
return str;
},
},
},
},
2024-05-28 13:16:44 +00:00
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;
},
},
2024-06-09 13:08:20 +00:00
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: {
2024-05-11 07:47:03 +00:00
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: {
2024-05-11 07:47:03 +00:00
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: {
2024-05-11 07:47:03 +00:00
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",
},
},
2024-05-20 14:52:10 +00:00
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) => {
2024-05-31 05:08:47 +00:00
if (!target.hasFriend()) return;
let rec = get.tag(card, "recover"), damage = get.tag(card, "damage");
if (!rec && !damage) return;
2024-06-01 05:29:32 +00:00
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++;
2024-05-31 05:08:47 +00:00
if (temp > die[1]) die = [i, temp];
else if (temp === die[1]) {
if (!die[0]) die = [i, temp];
2024-05-31 05:08:47 +00:00
else if (get.attitude(target, i) < get.attitude(target, die[0])) die = [i, temp];
}
});
2024-05-31 05:08:47 +00:00
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");
},
2024-05-19 15:51:55 +00:00
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: {
2024-05-19 15:51:55 +00:00
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;
2024-05-31 05:08:47 +00:00
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,
2024-05-07 07:37:29 +00:00
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;