Merge pull request #1417 from xizifu/PR-Branch

部分新武将;素材补充
This commit is contained in:
Spmario233 2024-06-02 12:12:11 +08:00 committed by GitHub
commit c672136bcb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 448 additions and 3 deletions

View File

@ -1,4 +1,7 @@
const characters = {
dc_sp_zhurong: ["female", "qun", 4, ["dcmanhou"]],
matie: ["male", "qun", 4, ["dczhuiwang", "dcquxian"]],
hansong: ["male", "qun", 3, ["dcyinbi", "dcshuaiyan"]],
yue_zhugeguo: ["female", "shu", 3, ["dcxidi", "dcchengyan"]],
yue_zoushi: ["female", "qun", 3, ["dcyunzheng", "dchuoxin"]],
zhupeilan: ["female", "wu", 3, ["dccilv", "dctongdao"]],

View File

@ -2,6 +2,261 @@ import { lib, game, ui, get, ai, _status } from "../../noname.js";
/** @type { importCharacterConfig['skill'] } */
const skills = {
//群祝融
dcmanhou: {
audio: 2,
enable: "phaseUse",
usable: 1,
chooseButton: {
dialog(event, player) {
return ui.create.dialog("###蛮后###选择一个数字,你可以摸等量张牌并执行等量项");
},
chooseControl(event, player) {
var list = Array.from({
length: 4,
}).map((_, i) => get.cnNumber(i + 1, true));
list.push("cancel2");
return list;
},
check(event, player) {
var list = Array.from({
length: 4,
}).map((_, i) => get.cnNumber(i + 1, true));
console.log(list);
if (get.effect(player, { name: "losehp" }, player, player) > 4 || player.countCards("hs", card => player.canSaveCard(card, player)) > 0 || player.hp > 2) return "四";
return "二";
},
backup(result, player) {
return {
num: result.control,
audio: "dcmanhou",
filterCard: () => false,
selectCard: -1,
async content(event, trigger, player) {
var num =
Array.from({
length: 4,
})
.map((_, i) => get.cnNumber(i + 1, true))
.indexOf(lib.skill.dcmanhou_backup.num) + 1;
await player.draw(num);
if (num >= 1) await player.removeSkills("dctanluan");
if (num >= 2 && player.countCards("h")) await player.chooseToDiscard("h", true);
if (num >= 3) await player.loseHp();
if (num >= 4) {
if (player.countCards("he")) await player.chooseToDiscard("he", true);
await player.addSkills("dctanluan");
}
},
};
},
},
ai: {
order: 8,
result: {
player: 1,
},
},
derivation: "dctanluan",
subSkill: {
backup: {},
},
},
dctanluan: {
audio: 2,
trigger: {
player: "useCardToPlayered",
},
filter(event, player) {
return event.isFirstTarget;
},
locked: true,
async cost(event, trigger, player) {
const num = trigger.targets.length,
num1 = game.filterPlayer(current => !trigger.targets.includes(current)).length;
if (num >= num1 && trigger.targets.some(current => current.countDiscardableCards(player, "ej"))) {
event.result = await player
.chooseTarget(get.prompt("dctanluan"), (card, player, target) => {
const evt = _status.event.getTrigger();
return evt.targets.includes(target) && target.countDiscardableCards(player, "ej");
})
.set("ai", target => {
const player = get.player();
const att = get.attitude(player, target);
if (
att > 0 &&
(target.countCards("j") > 0 ||
target.countCards("e", card => {
return get.value(card, target) < 0;
}))
)
return 2;
if (att < 0 && target.countCards("e") > 0 && !target.hasSkillTag("noe")) return -1;
return 0;
})
.forResult();
} else {
event.result = {
bool: true,
};
}
},
async content(event, trigger, player) {
if (event.targets && event.targets.length) await player.discardPlayerCard(event.targets[0], "ej", `弃置${get.translation(event.targets[0])}场上的一张牌`, true);
else player.addTempSkill("dctanluan_add");
},
subSkill: {
add: {
trigger: {
player: "useCard2",
},
async cost(event, trigger, player) {
player.removeSkill("dctanluan_add");
var goon = false;
var info = get.info(trigger.card);
if (!["basic", "trick"].includes(get.type(trigger.card))) return;
if (trigger.targets && !info.multitarget) {
if (
game.hasPlayer(function (current) {
return !trigger.targets.includes(current) && lib.filter.targetEnabled2(trigger.card, player, current);
})
) {
goon = true;
}
}
if (!goon) return;
event.result = await player
.chooseTarget("是否发动【探乱】?", `${get.translation(trigger.card)}添加一个目标`, (card, player, target) => {
const evt = _status.event.getTrigger();
return !evt.targets.includes(target) && lib.filter.targetEnabled2(evt.card, player, target);
})
.set("ai", target => {
return get.effect(target, _status.event.getTrigger().card, get.player());
})
.forResult();
},
async content(event, trigger, player) {
const targets = event.targets;
player.line(targets, "green");
trigger.targets.addArray(targets);
},
},
},
},
//马铁
dczhuiwang: {
mod: {
globalFrom(from, to) {
if (from.hp >= to.hp) return -Infinity;
},
},
},
dcquxian: {
audio: 2,
trigger: {
player: "phaseUseBegin",
},
async cost(event, trigger, player) {
event.result = await player
.chooseTarget(get.prompt("dcquxian"), "选择一名角色,攻击范围内包含其的角色可以对其使用【杀】")
.set("ai", target => {
const player = get.player();
return -get.attitude(player, target);
})
.forResult();
},
async content(event, trigger, player) {
const target = event.targets[0],
targets = game.filterPlayer(current => current.inRange(target)).sortBySeat();
if (!targets.length) return;
const sha = [],
nosha = [];
while (targets.length) {
const current = targets.shift();
const bool = await current
.chooseToUse(function (card, player, event) {
if (get.name(card) != "sha") return false;
return lib.filter.filterCard.apply(this, arguments);
}, "驱险:是否对" + get.translation(target) + "使用一张杀?")
.set("targetRequired", true)
.set("complexSelect", true)
.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);
})
.set("sourcex", target)
.set("addCount", false)
.forResultBool();
if (bool) sha.push(current);
else nosha.push(current);
}
if (!target.hasHistory("damage", evt => evt.getParent().type == "card" && evt.getParent(4) == event) && sha.length && nosha.length) {
for (const i of nosha) await i.loseHp(sha.length);
}
},
},
//韩嵩
dcyinbi: {
mod: {
targetInRange(card, player) {
if (!game.hasPlayer(current => current != player && current.countCards("h") == player.countCards("h"))) return true;
},
cardUsable(card, player) {
if (!game.hasPlayer(current => current != player && current.countCards("h") == player.countCards("h"))) return Infinity;
},
maxHandcardBase(player) {
if (_status.dcyinbi) return;
_status.dcyinbi = true;
const num = Math.max(...game.filterPlayer().map(target => target.getHandcardLimit()));
delete _status.dcyinbi;
return num;
},
},
},
dcshuaiyan: {
audio: 2,
trigger: {
global: ["loseAfter", "equipAfter", "addJudgeAfter", "gainAfter", "loseAsyncAfter", "addToExpansionAfter"],
},
filter(event, player, name, target) {
return target && target.countCards("h") == player.countCards("h");
},
getIndex(event, player) {
return game
.filterPlayer(target => {
if (target == player) return false;
if (event.getg && event.getg(target) && event.getg(target).length && target.countCards("h") == player.countCards("h")) return true;
const evt = event.getl(target);
if (evt && evt.hs && evt.hs.length && target.countCards("h") == player.countCards("h")) return true;
return false;
})
.sortBySeat();
},
logTarget(event, player, triggername, target) {
return target;
},
forced: true,
async content(event, trigger, player) {
const target = event.targets[0],
goon = target.countDiscardableCards(player, "he");
let result;
if (goon)
result = await player
.chooseControl()
.set("choiceList", ["弃置" + get.translation(target) + "的一张牌", "摸一张牌"])
.set("ai", () => {
const player = get.player();
const eff1 = get.effect(get.event("target"), { name: "guohe_copy2" }, player, player);
const eff2 = get.effect(player, { name: "draw" }, player, player);
return eff1 > eff2 ? 0 : 1;
})
.set("target", target)
.forResult();
else result = { index: 1 };
if (result.index == 0) player.discardPlayerCard(target, "he", true);
else player.draw();
},
},
//乐诸葛果
dcxidi: {
audio: 2,

View File

@ -10,9 +10,9 @@ const characterSort = {
sp_yanhan: ["dc_lifeng", "dc_liuba", "dc_huangquan", "furongfuqian", "xianglang", "dc_huojun", "gaoxiang", "dc_wuban", "jiangfei"],
sp_jishi: ["dc_jiben", "zhenghun", "dc_sunhanhua", "liuchongluojun", "wupu"],
sp_raoting: ["dc_huanghao", "dc_sunziliufang", "dc_sunchen", "dc_jiachong"],
sp_yijun: ["gongsundu", "mengyou", "dc_sp_menghuo", "gongsunxiu"],
sp_yijun: ["gongsundu", "mengyou", "dc_sp_menghuo", "gongsunxiu", "dc_sp_zhurong"],
sp_zhengyin: ["yue_caiwenji", "yue_zhoufei", "yue_caiyong", "yue_xiaoqiao", "yue_daqiao", "yue_miheng", "yue_zoushi", "yue_zhugeguo"],
huicui_waitforsort: ["chezhou", "zhupeilan"],
huicui_waitforsort: ["chezhou", "zhupeilan", "hansong", "matie"],
};
const characterSortTranslate = {

View File

@ -562,6 +562,21 @@ const translates = {
dcxidi_info: "锁定技。①游戏开始时你将所有手牌标记为“笛”。②你的“笛”牌不计入手牌上限。③准备阶段若你的手牌中有“笛”则你观看牌堆顶X张牌然后将这些牌以任意顺序置于牌堆顶和牌堆底X为你手牌中的“笛”数且X至多为5。",
dcchengyan: "乘烟",
dcchengyan_info: "当你于出牌阶段使用【杀】或普通锦囊牌指定其他角色为目标后,你可以亮出牌堆顶的一张牌,若此牌为【杀】或可指定目标的普通锦囊牌,你将此牌对其的结算方式改为此牌牌名的结算方式;若此牌不为【杀】和普通锦囊牌,你获得此牌并将此牌标记为“笛”。",
hansong: "韩嵩",
dcyinbi: "隐避",
dcyinbi_info: "锁定技。①你的手牌上限与场上手牌上限最多的角色相同。②若没有角色手牌数与你相等,你使用牌无距离和次数限制。",
dcshuaiyan: "率言",
dcshuaiyan_info: "锁定技,其他角色手牌数变化后,若与你相等,你弃置其一张牌或摸一张牌。",
matie: "马铁",
dczhuiwang: "追亡",
dczhuiwang_info: "锁定技你计算体力值小于等于你的角色的距离视为1。",
dcquxian: "驱险",
dcquxian_info: "出牌阶段开始时你可以选择一名角色若其在其他角色的攻击范围内这些角色可依次对其使用一张【杀】。然后若其未以此法受到伤害未使用【杀】的角色各失去X点体力X为以此法使用【杀】的角色数量。",
dc_sp_zhurong: "群祝融",
dcmanhou: "蛮后",
dcmanhou_info: "出牌阶段限一次你可以摸任意张牌并依次执行以下等量项至多为4 1失去〖探乱〗;2弃置一张手牌; 3失去1点体力; 4弃置一张牌并获得〖探乱〗。",
dctanluan: "探乱",
dctanluan_info: "锁定技,你使用牌指定目标后,若目标角色数大于等于非目标角色数,你可以弃置其中一个目标角色场上的一张牌;若目标角色数小于非目标角色数,则本回合你使用下一张牌的目标数+1。",
};
export default translates;

View File

@ -397,6 +397,7 @@ window.noname_character_rank = {
"yj_xuangongzhu",
"ol_sb_pangtong",
"dc_sb_zhugejin",
"matie",
"dc_sb_caoang",
"dc_sb_guanping",
],
@ -1145,6 +1146,9 @@ window.noname_character_rank = {
"mb_simafu",
],
b: [
"star_zhangzhao",
"dc_sp_zhurong",
"hansong",
"yue_zhugeguo",
"std_dc_yanghu",
"std_re_dengzhi",
@ -2282,6 +2286,9 @@ window.noname_character_rank = {
"ol_sb_pangtong",
"dc_sb_zhugejin",
"yue_miheng",
"hansong",
"star_zhangzhao",
"dc_sp_zhurong",
],
rare: [
"dc_sb_caoang",
@ -2808,6 +2815,7 @@ window.noname_character_rank = {
"mb_simafu",
"sb_handang",
"sb_gongsunzan",
"matie",
],
junk: [
"ol_peixiu",

View File

@ -1,4 +1,5 @@
const characters = {
star_zhangzhao: ["male", "wu", 3, ["starzhongyan", "starjinglun"]],
star_sunjian: ["male", "qun", "4/5", ["starruijun", "stargangyi"]],
liqueguosi: ["male", "qun", 4, ["xiongsuan"]],
star_zhangchunhua: ["female", "wei", 3, ["starliangyan", "starminghui"]],

View File

@ -2,6 +2,163 @@ import { lib, game, ui, get, ai, _status } from "../../noname.js";
/** @type { importCharacterConfig['skill'] } */
const skills = {
//星张昭
starzhongyan: {
audio: 2,
enable: "phaseUse",
usable: 1,
filter(event, player) {
return game.hasPlayer(current => get.info("starzhongyan").filterTarget(null, player, current));
},
filterTarget(card, player, target) {
return target.countCards("h");
},
async content(event, trigger, player) {
const target = event.targets[0],
topCards = get.cards(3);
await game.cardsGotoOrdering(topCards);
await player.showCards(topCards, get.translation(player) + "发动了【忠言】");
if (!target.countCards("h")) return;
const result = await target
.chooseToMove("忠言:交换其中一张牌")
.set("list", [
["牌堆顶", topCards],
["你的手牌", target.getCards("h")],
])
.set("filterMove", (from, to, moved) => {
if (typeof to == "number") return false;
var player = _status.event.player;
var hs = player.getCards("h");
var changed = hs.filter(function (card) {
return !moved[1].includes(card);
});
var changed2 = moved[1].filter(function (card) {
return !hs.includes(card);
});
if (changed.length < 1) return true;
var pos1 = moved[0].includes(from.link) ? 0 : 1,
pos2 = moved[0].includes(to.link) ? 0 : 1;
if (pos1 == pos2) return true;
if (pos1 == 0) {
if (changed.includes(from.link)) return true;
return changed2.includes(to.link);
}
if (changed2.includes(from.link)) return true;
return changed.includes(to.link);
})
.set("filterOk", moved => {
return moved[0].filter(card => get.owner(card)).length == 1;
})
.set("processAI", function (list) {
var cards1 = list[0][1].slice(),
cards2 = list[1][1].slice();
var card1 = cards1.sort((a, b) => get.value(b) - get.value(a))[0];
var card2 = cards2.sort((a, b) => get.value(a) - get.value(b))[0];
if (card1 && card2 && get.value(card1) > get.value(card2)) {
cards1.remove(card1);
cards2.remove(card2);
cards1.push(card2);
cards2.push(card1);
}
return [cards1, cards2];
})
.forResult();
if (result.bool) {
const lose = result.moved[0].slice();
const gain = result.moved[1].slice().filter(i => !get.owner(i));
if (lose.some(i => get.owner(i)))
await target.lose(
lose.filter(i => get.owner(i)),
ui.special
);
for (let i = lose.length - 1; i--; i >= 0) {
ui.cardPile.insertBefore(lose[i], ui.cardPile.firstChild);
}
game.updateRoundNumber();
if (gain.length) await target.gain(gain, "draw");
if (lose.map(card => get.color(card)).toUniqued().length == 1) {
const chosen = [],
list = player != target ? [target, player] : [target];
for (const current of list) {
const goon = game.hasPlayer(i => i.countGainableCards(current, "ej"));
const choices = [];
const choiceList = ["回复1点体力", "获得场上一张牌"];
if (current.isDamaged() && !chosen.includes("选项一")) choices.push("选项一");
else choiceList[0] = '<span style="opacity:0.5">' + choiceList[0] + "</span>";
if (goon && !chosen.includes("选项二")) choices.push("选项二");
else choiceList[1] = '<span style="opacity:0.5">' + choiceList[1] + "</span>";
if (!choices.length) continue;
const control =
choices.length == 1
? choices[0]
: await current
.chooseControl(choices)
.set("choiceList", choiceList)
.set("prompt", "忠言:请选择一项")
.set("ai", () => {
const player = get.player();
const eff2 = get.recoverEffect(player, player, player);
return eff2 ? 0 : 1;
})
.forResultControl();
chosen.push(control);
if (control == "选项一") {
await current.recover();
} else {
const targets = await current
.chooseTarget("获得一名角色场上的一张牌", true, (card, player, target) => {
const targetx = get.event("targetx");
return target.countGainableCards(targetx, "ej") > 0;
})
.set("ai", target => {
const player = get.player();
let att = get.attitude(player, target);
if (att < 0) att = -Math.sqrt(-att);
else att = Math.sqrt(att);
return att * lib.card.shunshou.ai.result.target(player, target);
})
.set("targetx", current)
.forResultTargets();
await current.gainPlayerCard(targets[0], "ej", true);
}
}
}
} else {
for (let i = topCards.length - 1; i--; i >= 0) {
ui.cardPile.insertBefore(topCards[i], ui.cardPile.firstChild);
}
game.updateRoundNumber();
}
},
ai: {
order: 8,
result: {
player: 1,
target: 1,
},
},
},
starjinglun: {
audio: 2,
trigger: {
global: "damageSource",
},
filter(event, player) {
const target = event.source;
return target && target.isIn() && get.distance(player, target) <= 1;
},
check(event, player) {
return get.attitude(player, event.source) > 0;
},
usable:1,
logTarget: "source",
async content(event, trigger, player) {
const target = trigger.source,
num = target.countCards("e");
if (num) await target.draw(num);
await player.useSkill("starzhongyan", [target]);
},
},
//星孙坚
starruijun: {
audio: 2,

View File

@ -14,7 +14,7 @@ const characterSort = {
sp_xuzhou: ["re_taoqian", "caosong", "zhangmiao", "qiuliju"],
sp_zhongyuan: ["re_hucheer", "re_zoushi", "caoanmin", "re_dongcheng"],
sp_xiaohu: ["haomeng", "yanfuren", "yanrou", "dc_zhuling"],
sp_star: ["star_caoren", "star_yuanshu", "star_dongzhuo", "star_yuanshao", "star_zhangchunhua", "star_sunjian"],
sp_star: ["star_caoren", "star_yuanshu", "star_dongzhuo", "star_yuanshao", "star_zhangchunhua", "star_sunjian", "star_zhangzhao"],
mini_qixian: ["mp_liuling"],
sp2_waitforsort: ["caobuxing", "re_maliang", "dc_jikang"],
};

View File

@ -580,6 +580,12 @@ const translates = {
starruijun_info: "当你于出牌阶段首次使用牌指定其他角色为目标后若目标角色数为1你可以摸X张牌X为你已损失的体力值+1。直到此阶段结束所有不为其的其他角色均不在你的攻击范围内且当你对其造成伤害时此伤害值改为YY为你本回合上一次对其造成过的伤害值+1至多为5。",
stargangyi: "刚毅",
stargangyi_info: "锁定技。①你的回合内,若你本回合没有造成过伤害,你不能使用【桃】。②当你处于濒死状态时,以你为目标的【桃】或【酒】的回复值+1。",
star_zhangzhao: "星张昭",
star_zhangzhao_prefix: "星",
starzhongyan: "忠言",
starzhongyan_info: "出牌阶段限一次你可展示牌堆顶三张牌然后令一名角色将一张手牌与其中一张牌交换。然后若这些牌颜色相同其回复1点体力或获得场上一张牌。然后若该角色不为你你执行其未执行的一项。",
starjinglun: "经纶",
starjinglun_info: "每回合限一次当你距离1以内的角色造成伤害后你可以令其摸X张牌并对其发动〖忠言〗X为其装备区的牌数。",
};
export default translates;

BIN
image/character/hansong.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB

BIN
image/character/matie.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 55 KiB