Merge pull request #1391 from mengxinzxz/PR-Branch

裴秀、蔡瑁、鄂焕;bugfix
This commit is contained in:
Spmario233 2024-05-25 18:56:02 +08:00 committed by GitHub
commit 1afa55ecac
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 336 additions and 8 deletions

View File

@ -19,6 +19,7 @@ const characterReplaces = {
zhoubuyi: ["zhoubuyi", "yj_zhoubuyi"],
xianglang: ["xianglang", "mb_xianglang"],
miheng: ["re_miheng", "miheng"],
peixiu: ["ol_peixiu", "peixiu"],
};
export default characterReplaces;

View File

@ -563,7 +563,8 @@ const translates = {
miheng_prefix: "手杀",
re_gaoshun: "手杀界高顺",
re_gaoshun_prefix: "手杀界",
peixiu: "裴秀",
peixiu: "手杀裴秀",
peixiu_prefix: "手杀",
xingtu: "行图",
xingtu1: "倍数",
xingtu2: "约数",

View File

@ -1,4 +1,5 @@
const characters = {
yj_ehuan: ["male", "qun", 4, ["psdiwan", "pssuiluan", "psconghan"], ["doublegroup:shu:qun"]],
yj_zhouji: ["female", "wu", 3, ["psyanmou", "pszhanyan", "psyuhuo"]],
drag_guanyu: ["male", "shu", 4, ["dragchaojue", "dragjunshen"]],
drag_caoren: ["male", "wei", 4, ["draglizhong", "dragjuesui"]],

View File

@ -1,4 +1,5 @@
const characterIntro = {
ehuan: "鄂焕,古典文学名著《三国演义》人物,为蜀将高定部将,身长九尺,面目狰狞,使一只方天戟,有万夫不当之勇。于孔明征朱褒、雍闿时粉墨登场,与魏延大战不分胜负,后中计被魏延、王平、张翼联手擒获,孔明以礼相待,成功离间高定与朱、雍二人。后高定派鄂焕斩朱褒、平雍闿,二人一起归蜀,鄂焕遂因其功而被封为牙门将。",
zhouji: "三国杀集换式卡牌游戏《阵面对决》中的权倾系列卡牌。游卡桌游官方的三国时期女性角色,原型是周妃(又名周彻)。周瑜之女。",
lvchang: "吕常161—221年荆州南阳博望今河南省南阳市方城县博望镇汉末至三国时期曹魏将领。吕常曾担任曹魏横海将军、章陵太守为武猛都尉厉节中郎将裨将军封关内侯。常以中勇显名州司试守雉长执戈秉戎慎守易兵不顿于敌国坠不侵于四邻拜武猛都尉厉节中郎将裨将军封关内侯。王师南征与充军从奄有江汉舍爵册勋封阴德亭侯领郡。鸠集荒散为民统纪三考有成转拜平狄将军改封卢亭侯莅国赋政十有三年。会蜀将关羽猖獗为寇常御之羽不能克。文帝加其庸转拜横海将军徙封西鄂都乡侯食邑并七百户。年六十一黄初二年正月卒。",
huangjinleishi: "黄巾军中负责施法的女祭司二人组。",

View File

@ -2,7 +2,114 @@ import { lib, game, ui, get, ai, _status } from "../../noname.js";
/** @type { importCharacterConfig['skill'] } */
const skills = {
//线下E系列肘击
//线下E系列
//鄂焕
psdiwan: {
trigger: { player: "useCardToPlayered" },
filter(event, player) {
return event.card.name == "sha" && event.isFirstTarget;
},
frequent: true,
usable: 1,
content() {
player.draw(trigger.targets.length);
},
},
pssuiluan: {
trigger: { player: "useCard2" },
filter(event, player) {
if (player.group != "qun" || event.card.name != "sha") return false;
return (
game.countPlayer(target => {
return !event.targets.includes(target) && lib.filter.targetEnabled2(event.card, player, target) && lib.filter.targetInRange(event.card, player, target);
}) > 1
);
},
groupSkill: true,
async cost(event, trigger, player) {
event.result = await player
.chooseTarget(
get.prompt2("pssuiluan"),
(card, player, target) => {
const event = get.event().getTrigger();
return !event.targets.includes(target) && lib.filter.targetEnabled2(event.card, player, target) && lib.filter.targetInRange(event.card, player, target);
},
2
)
.set("ai", target => {
const player = get.event("player"),
event = get.event().getTrigger();
return get.effect(target, event.card, player);
})
.forResult();
},
async content(event, trigger, player) {
trigger.targets.addArray(event.targets);
player.addTempSkill("pssuiluan_effect");
trigger.card.pssuiluan = true;
},
subSkill: {
effect: {
charlotte: true,
trigger: { player: ["useCardAfter", "damageEnd"] },
filter(event, player) {
if (event.name == "damage") {
return player.group != "shu" && event.getParent(4).name == "pssuiluan_effect";
}
return event.card.pssuiluan && (event.targets || []).some(i => i.isIn());
},
forced: true,
popup: false,
forceDie: true,
async content(event, trigger, player) {
if (trigger.name == "damage") {
await player.changeGroup("shu");
return;
}
const targets = trigger.targets.filter(i => i.isIn()).sortBySeat();
for (const target of targets) {
await target
.chooseToUse(function (card, player, event) {
if (get.name(card) != "sha") return false;
return lib.filter.filterCard.apply(this, arguments);
}, "随乱:是否对" + get.translation(player) + "使用一张【杀】?")
.set("filterTarget", function (card, player, target) {
if (target != _status.event.sourcex && !ui.selected.targets.includes(_status.event.sourcex)) return false;
return lib.filter.filterTarget.apply(this, arguments);
})
.set("targetRequired", true)
.set("complexSelect", true)
.set("sourcex", player);
}
},
},
},
},
psconghan: {
trigger: { global: "damageSource" },
filter(event, player) {
if (player.group != "shu" || !event.source || !event.player.isIn()) return false;
return event.source.getSeatNum() == 1 && (player.hasSha() || (_status.connectMode && player.countCards("hs")));
},
direct: true,
groupSkill: true,
content() {
player
.chooseToUse(function (card, player, event) {
if (get.name(card) != "sha") return false;
return lib.filter.filterCard.apply(this, arguments);
}, get.prompt2("psconghan", trigger.player))
.set("filterTarget", function (card, player, target) {
if (target != _status.event.sourcex && !ui.selected.targets.includes(_status.event.sourcex)) return false;
return lib.filter.filterTarget.apply(this, arguments);
})
.set("targetRequired", true)
.set("complexSelect", true)
.set("logSkill", ["psconghan", trigger.player])
.set("sourcex", trigger.player);
},
},
//肘击
psyanmou: {
getCards(event, player) {
let cards = [];

View File

@ -5,7 +5,7 @@ const characterSort = {
offline_luanwu: ["ns_lijue", "ns_zhangji", "ns_fanchou"],
offline_yongjian: ["ns_chendao", "yj_caoang", "yj_caocao", "yj_liru", "yj_caohong", "yj_zhangfei", "yongjian_ganning", "yj_dongzhuo", "yj_xuyou", "yj_jiaxu", "yj_zhenji"],
offline_piracyE_zy: ["shen_jiaxu", "pe_wangyun", "pe_zhonghui", "pe_sunchen", "pe_mengda", "pe_wenqin", "ns_caoanmin", "jiangqing", "kongrong", "jiling", "tianfeng", "mateng"],
offline_piracyE: ["yj_zhouji"],
offline_piracyE: ["yj_zhouji", "yj_ehuan"],
offline_piracyS: ["ns_jiaxu", "longyufei", "ps_guanyu", "ps1059_guojia", "ps2070_guojia", "ps2063_zhaoyun", "ps2067_zhaoyun", "ps1062_zhouyu", "ps2080_zhouyu", "ps_caozhi", "ps_jin_simayi", "ps_caopi", "ps_simayi", "ps2068_simayi", "ps_machao", "ps_zhugeliang", "ps2066_zhugeliang", "ps_jiaxu", "ps_lvbu", "ps_shen_machao", "jsp_liubei"],
offline_piracyK: ["pk_sp_duyu"],
offline_vtuber: ["vtb_xiaosha", "vtb_xiaoshan", "vtb_xiaotao", "vtb_xiaole", "vtb_xiaojiu"],

View File

@ -404,8 +404,7 @@ const translates = {
drag_guanyu_prefix: "龙",
drag_caoren: "龙曹仁",
drag_caoren_prefix: "龙",
drag_lvchang: "龙吕常",
drag_lvchang_prefix: "龙",
drag_lvchang: "吕常",
dragchaojue: "超绝",
dragchaojue_info: "准备阶段,你可以弃置一张手牌,然后令所有其他角色本回合不能使用或打出此花色的牌,然后这些角色依次选择一项:①正面朝上交给你一张牌;②本回合非锁定技失效。",
dragjunshen: "军神",
@ -425,6 +424,13 @@ const translates = {
pszhanyan_info: "出牌阶段限一次你可以令你攻击范围内的所有角色依次选择一项①受到你对其造成的1点火属性伤害②将手牌或弃牌堆中的一张【火攻】或火【杀】置于牌堆顶。然后你摸X张牌X为本次选择次数较小的选项的被选择次数。",
psyuhuo: "驭火",
psyuhuo_info: "锁定技。①防止你受到的火属性伤害。②你的【火攻】和火【杀】不计入手牌上限。",
yj_ehuan: "鄂焕",
psdiwan: "敌万",
psdiwan_info: "每回合限一次当你使用【杀】指定第一个目标后你可以摸X张牌X为此牌指定的目标数。",
pssuiluan: "随乱",
pssuiluan_info: "群势力技。你使用【杀】可以额外指定两个目标,若如此做,此牌结算完毕后,所有目标角色可依次对你使用一张【杀】,你以此法受到伤害后,将势力变更至蜀。",
psconghan: "从汉",
psconghan_info: "蜀势力技。一号位造成伤害后,你可以对受伤角色使用一张【杀】。",
};
export default translates;

View File

@ -313,7 +313,7 @@ const skills = {
.chooseToUse(function (card, player, event) {
if (get.name(card) != "sha") return false;
return lib.filter.filterCard.apply(this, arguments);
}, "眩惑:对" + get.translation(player) + "使用一张【杀】,或令" + get.translation(player) + "你的手牌并获得你的两张牌")
}, "眩惑:对" + get.translation(target2) + "使用一张【杀】,或令" + get.translation(player) + "你的手牌并获得你的两张牌")
.set("filterTarget", function (card, player, target) {
if (target != _status.event.sourcex && !ui.selected.targets.includes(_status.event.sourcex)) return false;
return lib.filter.targetEnabled.apply(this, arguments);

View File

@ -714,6 +714,9 @@ window.noname_character_rank = {
"sb_gongsunzan",
],
bp: [
"ol_peixiu",
"caimao",
"yj_ehuan",
"xin_huojun",
"chess_diaochan",
"chess_huangzhong",
@ -2287,6 +2290,8 @@ window.noname_character_rank = {
"zhugemengxue",
"ol_sb_taishici",
"clan_wuqiao",
"caimao",
"yj_ehuan",
"xin_huojun",
"muludawang",
"mb_huban",
@ -2782,6 +2787,7 @@ window.noname_character_rank = {
"sb_gongsunzan",
],
junk: [
"ol_peixiu",
"ol_sb_guanyu",
"junk_guanyu",
"sunshao",

View File

@ -1,4 +1,6 @@
const characters = {
caimao: ["male", "wei", 4, ["olzuolian", "oljingzhou"]],
ol_peixiu: ["male", "wei", 3, ["olmaozhu", "oljinlan"]],
yadan: ["male", "qun", 4, ["olqingya", "oltielun"]],
sp_sunce: ["male", "qun", 4, ["olliantao"]],
ol_liupi: ["male", "qun", 4, ["olyicheng"]],

View File

@ -1,4 +1,5 @@
const characterIntro = {
caimao: "蔡瑁字德珪生卒年不详。襄阳蔡州人东汉末年荆州名士。少年时与曹操交好。初平元年公元190年刘表为荆州刺史。时宗贼猖獗蔡瑁协助刘表诛杀宗贼平定荆州之地蔡瑁因此得刘表重用并在刘表任镇南将军时担任他的军师。刘表病亡后蔡瑁拥护刘表幼子刘琮继位并逼迫他投降南征的曹操。蔡瑁在曹操麾下历任从事中郎、司马、长水校尉受封汉阳亭侯。",
yadan: "雅丹《三国演义》虚构人物西羌丞相。诸葛亮伐魏时魏大都督曹真驰书赴羌西羌国王彻里吉任命雅丹与元帅越吉起兵15万前去增援中了诸葛亮之计被伏兵所困。",
liupan: "刘磐(生卒年不详),山阳高平人,荆州牧刘表从子。与南阳人黄忠共守长沙攸县。为人骁勇,数次为寇于艾、西安诸县。江东孙策于是分海昏、建昌为左右六县,以东莱太史慈为建昌都尉,治海昏,并督诸将共拒刘磐。于是刘磐绝迹不复为寇。",
guotu: "郭图205年字公则颍川治今河南省禹州市人。东汉末年袁绍帐下谋士。韩馥统冀州时郭图与荀谌等人奉袁绍之命说服韩馥让位。袁绍统一河北后郭图与审配等人力劝袁绍统率大军攻打曹操。袁绍死后袁尚继位。郭图与辛评为袁谭效力挑唆袁谭攻击袁尚。建安十年205年郭图和袁谭一同被曹操所杀。",

View File

@ -2,6 +2,197 @@ import { lib, game, ui, get, ai, _status } from "../../noname.js";
/** @type { importCharacterConfig['skill'] } */
const skills = {
//蔡瑁
olzuolian: {
audio: 2,
enable: "phaseUse",
filter(event, player) {
return player.getHp() > 0 && game.hasPlayer(target => target.countCards("h"));
},
filterTarget(card, player, target) {
return target.countCards("h");
},
selectTarget() {
return [1, get.event("player").getHp()];
},
usable: 1,
multitarget: true,
multiline: true,
async content(event, trigger, player) {
const targets = event.targets.sortBySeat();
const cards = targets.slice().map(i => i.getCards("h").randomGet());
const videoId = lib.status.videoId++;
game.broadcastAll(
(targets, cards, id, player) => {
let dialog = ui.create.dialog(get.translation(player) + "发动了【佐练】", cards);
dialog.videoId = id;
const getName = target => {
if (target._tempTranslate) return target._tempTranslate;
var name = target.name;
if (lib.translate[name + "_ab"]) return lib.translate[name + "_ab"];
return get.translation(name);
};
for (let i = 0; i < targets.length; i++) {
dialog.buttons[i].querySelector(".info").innerHTML = getName(targets[i]);
}
},
targets,
cards,
videoId,
player
);
await game.asyncDelay(3);
game.broadcastAll("closeDialog", videoId);
const cards_cardPile = Array.from(ui.cardPile.childNodes).filter(i => i.name == "sha" && get.nature(i, false));
const cards_discardPile = Array.from(ui.discardPile.childNodes).filter(i => i.name == "sha" && get.nature(i, false));
if (!Boolean(cards_cardPile.length + cards_discardPile.length)) {
player.popup("杯具");
player.chat("我属性【杀】呢?!");
game.log("但牌堆和弃牌堆都没有属性【杀】!");
return;
}
const result = await player
.chooseToMove("佐练:选择交换展示牌和牌堆或弃牌堆中的属性【杀】")
.set(
"list",
(function (cards, cardPile, discardPile) {
let list = [["展示手牌", cards, "olzuolian_tag"]];
if (cardPile.length) {
list.push(["牌堆", cardPile]);
}
if (discardPile.length) {
list.push(["弃牌堆", discardPile]);
}
return list;
})(cards, cards_cardPile, cards_discardPile)
)
.set("filterMove", (from, to, moved) => {
if (typeof to == "number") return false;
const cards=get.event("cards");
if(cards.includes(from.link)==cards.includes(to.link)) return false;
for(const pl of [[from.link,to.link],[to.link,from.link]]){
if(cards.includes(pl[0])&&moved[0].includes(pl[1])&&cards.indexOf(pl[0])!=moved[0].indexOf(pl[1])) return false;
}
return true;
})
.set("processAI", list => {
return list.map(i => i[1]);
})
.set("cards", cards)
.forResult();
if (result.bool) {
const cardsx = result.moved[0];
for (let i = 0; i < cardsx.length; i++) {
const current = targets[i],
card = cardsx[i];
if (!cards.includes(card)) {
if (cards_cardPile.includes(card)) {
current.$throw([cards[i]], 1000);
await current
.lose([cards[i]], ui.cardPile)
.set("insert_index", () => {
return ui.cardPile.childNodes[get.event("num")];
})
.set("num", cards_cardPile.indexOf(card));
} else if (cards_discardPile.includes(card)) {
await current.loseToDiscardpile(cards[i]);
}
await current.gain(card, "gain2");
}
}
}
},
ai: {
order: 10,
result: {
target(player, target) {
//插个眼等PZ157拯救此AI
return 0.5 - Math.random();
},
},
},
},
oljingzhou: {
audio: 2,
trigger: { player: "damageBegin3" },
filter(event, player) {
return player.getHp() > 0;
},
async cost(event, trigger, player) {
event.result = await player
.chooseTarget(get.prompt2("oljingzhou"), [1, player.getHp()])
.set("ai", target => {
const player = get.event("player"),
trigger = get.event().getTrigger();
if (trigger.hasNature() && target == player) {
return -get.effect(target, { name: "tiesuo" }, player, player);
}
return get.effect(target, { name: "tiesuo" }, player, player);
})
.forResult();
},
async content(event, trigger, player) {
for (const i of event.targets) {
await i.link(!i.isLinked());
}
},
},
//裴秀
//我们三国杀也有属于自己的爽文.jpg
olmaozhu: {
audio: 2,
trigger: { source: "damageBegin1" },
filter(event, player) {
const count = lib.skill.olmaozhu.countSkill;
if (!player.isPhaseUsing() || count(player) <= count(event.player)) return false;
const evtx = event.getParent("phaseUse");
return !player.getHistory("sourceDamage", evt => {
return evt.getParent("phaseUse") == evtx && count(player) > count(evt.player);
}).length;
},
forced: true,
logTarget: "player",
content() {
trigger.increase("num");
},
countSkill(player) {
return player.getSkills(null, false, false).filter(i => {
const info = get.info(i);
return !info || !info.charlotte;
}).length;
},
mod: {
cardUsable(card, player, num) {
if (card.name == "sha") return num + lib.skill.olmaozhu.countSkill(player);
},
maxHandcard(player, num) {
return num + lib.skill.olmaozhu.countSkill(player);
},
},
},
oljinlan: {
audio: 2,
enable: "phaseUse",
filter(event, player) {
const count = lib.skill.olmaozhu.countSkill;
return player.countCards("h") < Math.max(...game.filterPlayer().map(i => count(i)));
},
filterCard: () => false,
selectCard: [0, 1],
prompt() {
const count = lib.skill.olmaozhu.countSkill;
return "将手牌数摸至" + get.cnNumber(Math.max(...game.filterPlayer().map(i => count(i)))) + "张";
},
usable: 1,
content() {
const count = lib.skill.olmaozhu.countSkill;
player.drawTo(Math.max(...game.filterPlayer().map(i => count(i))));
},
ai: {
order: 0.000000114514191981,
result: { player: 1 },
},
},
//鸭蛋
olqingya: {
audio: 2,

View File

@ -12,7 +12,7 @@ const characterSort = {
sp_zhongdan: ["cuiyan", "huangfusong"],
sp_guozhan2: ["sp_dongzhuo", "liqueguosi", "zhangren"],
sp_others: ["hanba", "caiyang"],
sp_waitforsort: ["ol_luyusheng", "ol_tw_zhangji", "ol_liwan", "ol_liuyan"],
sp_waitforsort: ["ol_luyusheng", "ol_tw_zhangji", "ol_liwan", "ol_liuyan", "ol_peixiu", "caimao"],
};
const characterSortTranslate = {

View File

@ -1244,6 +1244,17 @@ const translates = {
olqingya_info: "当你使用【杀】指定唯一目标后,你可从逆时针方向和顺时针方向中选择一个你与其之间角色最少的方向。你弃置该方向下你与其之间的角色各一张手牌,然后你可以于本回合下个阶段结束时使用其中一张牌。",
oltielun: "铁轮",
oltielun_info: "锁定技。你计算与其他角色的距离-XX为你本轮使用的牌数。",
ol_peixiu: "裴秀",
olmaozhu: "茂著",
olmaozhu_info: "锁定技。①你的手牌上限和使用【杀】的额定次数+XX为你拥有的技能数。②当你于出牌阶段首次对技能数小于你的角色造成伤害时此伤害+1。",
oljinlan: "尽览",
oljinlan_info: "出牌阶段限一次你可以将手牌数摸至Y张Y为场上技能数最多的角色的技能数。",
caimao: "蔡瑁",
olzuolian: "佐练",
olzuolian_tag: "展示牌",
olzuolian_info: "出牌阶段限一次你可以选择至多X名有牌的角色X为你的体力值你随机展示这些角色的各一张牌然后你可以将这些牌与牌堆和弃牌堆中的属性【杀】进行交换。",
oljingzhou: "精舟",
oljingzhou_info: "当你受到伤害时你可以选择至多X名角色X为你的体力值这些角色中处于/未处于连环状态的角色重置/横置武将牌。",
};
export default translates;

View File

@ -274,7 +274,7 @@ const skills = {
let max = 0,
names = ["huogong", "tiesuo", "wuzhong"].filter(name => {
if (player.getStorage("twcairu_used").includes(name)) return false;
return event.filterCard({ name }, player, event);
return player.hasValueTarget(name ,true, true);
});
if (!names.length) return 0;
names = names.map(namex => ({ name: namex }));

BIN
image/character/caimao.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB