diff --git a/card/huodong.js b/card/huodong.js index 2255be3394..bbf0db6c22 100644 --- a/card/huodong.js +++ b/card/huodong.js @@ -282,18 +282,18 @@ game.import("card", function () { toself: true, modTarget: true, async content(event, trigger, player) { - event.cards ??= []; + const cards = []; const { target } = event; - const result = await target - .chooseControl("black", "red") - .set("prompt", `好运:选择一种颜色,然后开始判定。如果颜色为你选择的颜色,你获得此牌且重复此流程。`) - .set("ai", () => (Math.random() > 0.4 ? "black" : "red")) - .forResult(); - if (result?.control) { - const color = result.control; - game.log(player, "选择了", "#y" + color); - player.popup(color); - while (true) { + while (true) { + const result = await target + .chooseControl("black", "red") + .set("prompt", `好运:选择一种颜色,然后开始判定。如果颜色为你选择的颜色,你获得此牌且重复此流程。`) + .set("ai", () => (Math.random() > 0.4 ? "black" : "red")) + .forResult(); + if (result?.control) { + const color = result.control; + game.log(player, "选择了", "#y" + color); + player.popup(color); const judgeEvent = target.judge(card => { if (get.color(card) == get.event().haoyun_color) { return 1.5; @@ -302,27 +302,22 @@ game.import("card", function () { }); judgeEvent.set("haoyun_color", color); judgeEvent.judge2 = result => result.bool; - if (!player.hasSkillTag("rejudge")) { - judgeEvent.set("callback", async event => { - if (event.judgeResult.color == event.getParent().haoyun_color && get.position(event.card, true) == "o") { - await event.player.gain(event.card, "gain2"); - } - }); - } else { - judgeEvent.set("callback", async event => { - if (event.judgeResult.color == event.getParent().haoyun_color) { - event.getParent().orderingCards.remove(event.card); - } - }); - } - const result = await judgeEvent.forResult(); - if (result?.bool && result?.card) { - event.cards.push(result.card); + judgeEvent.set("callback", async event => { + if (event.judgeResult.color == event.getParent().haoyun_color) { + event.getParent().orderingCards.remove(event.card); + } + }); + const resultx = await judgeEvent.forResult(); + if (resultx?.bool && resultx?.card) { + cards.push(resultx.card); } else { break; } } } + if (cards.length) { + await player.gain(cards, "gain2"); + } }, ai: { wuxie(target, card, player, viewer) { @@ -914,7 +909,7 @@ game.import("card", function () { ai: { order: 6, useful: 1.2, - value: 8, + value: 7, result: { target(player, target) { const list = []; @@ -1060,12 +1055,14 @@ game.import("card", function () { ) .set("addCount", false);*/ if (!result?.bool) { - const damage = game.filterPlayer(current => current != target).sortBySeat(); + const damage = game.filterPlayer2(current => current != target).sortBySeat(); if (damage.length) { while (damage.length && target.isIn()) { const current = damage.shift(); - current.line(target, "yellow"); - await target.damage(current); + if (current.isIn()) { + current.line(target, "yellow"); + await target.damage(current); + } } } break; @@ -1098,8 +1095,8 @@ game.import("card", function () { async content(event, trigger, player) { player.$skill(get.translation(event.name), null, "thunder", null, "shen_jiaxu"); await game.delayx(); - const targets = game.filterPlayer(target => target != player).sortBySeat(); - player.line(targets); + const targets = game.filterPlayer2(target => target != player).sortBySeat(); + player.line(targets.filter(target => target.isIn())); game.broadcastAll(event => { if (!_status.nisiwohuo) { _status.nisiwohuo = []; @@ -1332,7 +1329,7 @@ game.import("card", function () { ai: { order: 7, useful: 3.5, - value: 9, + value: 8, tag: { draw: 2, }, diff --git a/character/collab/card.js b/character/collab/card.js index aa792bca40..73202e0ee8 100644 --- a/character/collab/card.js +++ b/character/collab/card.js @@ -3,9 +3,11 @@ import { lib, game, ui, get, ai, _status } from "../../noname.js"; const cards = { olhuaquan_heavy: { fullskin: true, + noname: true, }, olhuaquan_light: { fullskin: true, + noname: true, }, ruyijingubang: { fullskin: true, diff --git a/character/collab/skill.js b/character/collab/skill.js index 57d35bb5c0..ee200f8aa9 100644 --- a/character/collab/skill.js +++ b/character/collab/skill.js @@ -16,7 +16,7 @@ const skills = { ["", "", "olhuaquan_light"], ]; const result = await player - .chooseButton([`###花拳###${get.skillInfoTranslation(event.skill)}`, [list, "vcard"]], true) + .chooseButton([`###花拳###${get.skillInfoTranslation(event.name)}`, [list, "vcard"]], true) .set("ai", button => { const card = get.event().card; const bool = button.link == "olhuaquan_heavy"; @@ -91,6 +91,7 @@ const skills = { }, async content(event, trigger, player) { const [target] = event.targets; + await player.draw(); target.addMark(event.name); if (target.countMark(event.name) >= 3 && !target.hasSkill(event.name + "_debuff")) { target.clearMark(event.name); @@ -162,7 +163,7 @@ const skills = { }, onremove(player, skill) { delete player.storage[skill]; - game.log(player, "站立了过来"); + game.log("读秒结束,", player, "站立了过来"); }, marktext: "💫", intro: { diff --git a/character/collab/translate.js b/character/collab/translate.js index f58c42c5ef..06bd74f723 100644 --- a/character/collab/translate.js +++ b/character/collab/translate.js @@ -276,11 +276,13 @@ const translates = { olhuaquan: "花拳", olhuaquan_info: "锁定技,你使用黑色牌指定其他角色后,为此牌秘密选择一个效果:1.重拳,造成的伤害+1;2.轻拳,使用后你摸一张牌。然后其他目标角色依次猜测你选择的效果。", olhuaquan_heavy: "重拳", + olhuaquan_heavy_bg: "重拳", olhuaquan_heavy_info: "造成的伤害+1", olhuaquan_light: "轻拳", + olhuaquan_light_bg: "轻拳", olhuaquan_light_info: "使用后你摸一张牌", olsanou: "三殴", - olsanou_info: "锁定技,其他角色受到你的伤害后或猜错〖花拳〗的效果后,获得一个「击倒」标记。一名角色获得至少3个「击倒」标记后移除此标记并进入“击倒”状态。“击倒”状态的角色始终跳过出牌阶段。角色于“击倒”状态时,有10张牌离开牌堆或进入弃牌堆后,其脱离“击倒”状态。", + olsanou_info: "锁定技,其他角色受到你的伤害后或猜错〖花拳〗的效果后,你摸一张牌并令其获得一个「击倒」标记。一名角色获得至少3个「击倒」标记后移除此标记并进入“击倒”状态。“击倒”状态的角色始终跳过出牌阶段。角色于“击倒”状态时,有10张牌离开牌堆或进入弃牌堆后,其脱离“击倒”状态。", }; export default translates; diff --git a/character/jsrg/skill.js b/character/jsrg/skill.js index 866283b79e..e1b4c15186 100644 --- a/character/jsrg/skill.js +++ b/character/jsrg/skill.js @@ -4947,27 +4947,22 @@ const skills = { } return event.targets.some(i => i.isIn() && i.hasHistory("lose", evt => evt.cards2.length)) && player.getExpansions("jsrgshacheng").length; }, - direct: true, group: "jsrgshacheng_build", - content() { - "step 0"; - if (_status.connectMode) { - game.broadcastAll(function () { - _status.noclearcountdown = true; - }); - } - var targets = trigger.targets.filter(i => i.isIn() && i.hasHistory("lose", evt => evt.cards2.length)); - player - .chooseTarget(get.prompt("jsrgshacheng"), "令一名目标角色摸X张牌,然后移去一张“城”(X为对应角色本回合失去过的牌数且至多为5)", (card, player, target) => { - return get.event("targets").includes(target); - }) - .set("targets", targets) - .set("ai", target => { - return target == get.event("targetx") ? 1 : 0; - }) - .set( - "targetx", - (() => { + async cost(event, trigger, player) { + const cards = player.getExpansions("jsrgshacheng"); + const targets = trigger.targets.filter(i => i.isIn() && i.hasHistory("lose", evt => evt.cards2.length)); + const result = await player + .chooseButtonTarget({ + createDialog: [`###${get.prompt(event.skill)}###移去一张“城”,令一名目标角色摸X张牌(X为该角色本回合失去过的牌数且至多为5)`, cards], + targets: targets, + filterButton: true, + filterTarget(card, player, target) { + return get.event().targets.includes(target); + }, + ai2(target) { + return target == get.event("targetx") ? 1 : 0; + }, + targetx: (() => { let info = []; targets.filter(target => { let att = get.attitude(player, target); @@ -4997,47 +4992,31 @@ const skills = { return null; } return info[0]; - })() - ); - "step 1"; - if (result.bool) { - event.target = result.targets[0]; - var cards = player.getExpansions("jsrgshacheng"); - if (cards.length == 1) { - event._result = { bool: true, links: cards }; - } else { - player.chooseButton([`沙城:移去一张“城”`, cards], true); - } - } else { - if (_status.connectMode) { - game.broadcastAll(function () { - delete _status.noclearcountdown; - game.stopCountChoose(); - }); - } - event.finish(); - } - "step 2"; - if (_status.connectMode) { - game.broadcastAll(function () { - delete _status.noclearcountdown; - game.stopCountChoose(); - }); - } - if (result.bool) { - player.logSkill("jsrgshacheng", target); - player.loseToDiscardpile(result.links); - target.draw( - Math.min( - 5, - target - .getHistory("lose") - .map(evt => evt.cards2.length) - .reduce((p, c) => p + c, 0) - ) - ); + })(), + }) + .forResult(); + if (result?.links?.length && result.targets?.length) { + event.result = { + bool: true, + targets: result.targets, + cost_data: result.links, + }; } }, + async content(event, trigger, player) { + const cards = event.cost_data, + [target] = event.targets; + await player.loseToDiscardpile(cards); + await target.draw( + Math.min( + 5, + target + .getHistory("lose") + .map(evt => evt.cards2.length) + .reduce((p, c) => p + c, 0) + ) + ); + }, marktext: "城", intro: { content: "expansion", @@ -5074,9 +5053,11 @@ const skills = { return event.hasNature("ice") && event.cards?.someInD(); }, forced: true, - content() { - var cards = trigger.cards.filterInD(); - player.addToExpansion(cards, "gain2").gaintag.add("jsrgshacheng"); + async content(event, trigger, player) { + const cards = trigger.cards.filterInD(); + const next = player.addToExpansion(cards, "gain2"); + next.gaintag.add("jsrgshacheng"); + await next; }, global: "jsrgninghan_frozen", subSkill: { diff --git a/character/mobile/skill.js b/character/mobile/skill.js index 43a1e33ad6..738da10fbf 100644 --- a/character/mobile/skill.js +++ b/character/mobile/skill.js @@ -4352,10 +4352,10 @@ const skills = { return { bool: true, cards: suits.slice(0, limit).reduce((list, suit) => list.addArray(player.getCards("h", { suit: suit })), []) }; }; if (event.isMine()) { - next = chooseOneSuitCard(player, player, null, limit, str, ai); + next = chooseOneSuitCard(player, player, null, limit, str, ai()); } else if (player.isOnline()) { let { promise, resolve } = Promise.withResolvers(); - player.send(chooseOneSuitCard, player, player, null, limit, str, ai); + player.send(chooseOneSuitCard, player, player, null, limit, str, ai()); player.wait(result => { if (result == "ai") { result = ai(); @@ -4392,11 +4392,20 @@ const skills = { player.logSkill("mbzhuji", null, null, null, [num >= es ? get.rand(1, 2) : get.rand(3, 4)]); if (num >= es) { const result = await player - .chooseButton(["筑墼:选择一项执行", [[ - ["draw", "摸两张牌"], - ["recover", "回复1点体力"], - ["hujia", "获得1点护甲"], - ], "textbutton"]], true) + .chooseButton( + [ + "筑墼:选择一项执行", + [ + [ + ["draw", "摸两张牌"], + ["recover", "回复1点体力"], + ["hujia", "获得1点护甲"], + ], + "textbutton", + ], + ], + true + ) .set("filterButton", button => { const player = get.player(); if (button.link == "recover") { @@ -4417,7 +4426,7 @@ const skills = { if (!result?.bool || !result.links?.length) { return; } - switch(result.links[0]) { + switch (result.links[0]) { case "draw": { await player.draw(2); break; @@ -13223,15 +13232,14 @@ const skills = { } return _status.changshiMap; }, - content() { - "step 0"; - var list = lib.skill.mbdanggu.changshi.map(i => i[0]); + async content(event, trigger, player) { + const list = lib.skill.mbdanggu.changshi.map(i => i[0]); player.markAuto("mbdanggu", list); game.broadcastAll( function (player, list) { - var cards = []; - for (var i = 0; i < list.length; i++) { - var cardname = "huashen_card_" + list[i]; + const cards = []; + for (let i = 0; i < list.length; i++) { + const cardname = "huashen_card_" + list[i]; lib.card[cardname] = { fullimage: true, image: "character/" + list[i], @@ -13244,37 +13252,36 @@ const skills = { player, list ); - "step 1"; - var next = game.createEvent("mbdanggu_clique"); + const next = game.createEvent("mbdanggu_clique"); next.player = player; next.setContent(lib.skill.mbdanggu.contentx); + await next; }, - contentx() { - "step 0"; - var list = player.getStorage("mbdanggu").slice(); - var first = list.randomRemove(); - event.first = first; - var others = list.randomGets(4); + async contentx(event, trigger, player) { + let list = player.getStorage("mbdanggu").slice(); + const first = list.randomRemove(); + const others = list.randomGets(4); + let result; if (others.length == 1) { - event._result = { bool: true, links: others }; + result = { bool: true, links: others }; } else { - var map = { + const map = { scs_bilan: "scs_hankui", scs_hankui: "scs_bilan", scs_duangui: "scs_guosheng", scs_guosheng: "scs_duangui", }, map2 = lib.skill.mbdanggu.conflictMap(player); - var conflictList = others.filter(changshi => { - if (map[first] && others.some(changshi2 => map[first] == changshi2)) { - return map[first] == changshi; - } else { - return map2[first].includes(changshi); - } - }), - list = others.slice(); + const conflictList = others.filter(changshi => { + if (map[first] && others.some(changshi2 => map[first] == changshi2)) { + return map[first] == changshi; + } else { + return map2[first].includes(changshi); + } + }); + list = others.slice(); if (conflictList.length) { - var conflict = conflictList.randomGet(); + const conflict = conflictList.randomGet(); list.remove(conflict); game.broadcastAll( function (changshi, player) { @@ -13288,25 +13295,24 @@ const skills = { player ); } - player + result = await player .chooseButton(["党锢:请选择结党对象", [[first], "character"], '
可选常侍
', [others, "character"]], true) .set("filterButton", button => { return _status.event.canChoose.includes(button.link); }) .set("canChoose", list) - .set("ai", button => Math.random() * 10); + .set("ai", button => Math.random() * 10) + .forResult(); } - "step 1"; - if (result.bool) { - var first = event.first; - var chosen = result.links[0]; - var skills = []; - var list = lib.skill.mbdanggu.changshi; - var changshis = [first, chosen]; + if (result?.bool) { + const chosen = result.links[0]; + const skills = []; + list = lib.skill.mbdanggu.changshi; + const changshis = [first, chosen]; player.unmarkAuto("mbdanggu", changshis); player.storage.mbdanggu_current = changshis; - for (var changshi of changshis) { - for (var cs of list) { + for (const changshi of changshis) { + for (const cs of list) { if (changshi == cs[0]) { skills.push(cs[1]); } @@ -13337,8 +13343,8 @@ const skills = { game.log(player, "选择了常侍", "#y" + get.translation(changshis)); if (skills.length) { player.addAdditionalSkill("mbdanggu", skills); - var str = ""; - for (var i of skills) { + let str = ""; + for (const i of skills) { str += "【" + get.translation(i) + "】、"; player.popup(i); } @@ -13377,137 +13383,27 @@ const skills = { }, }, mbmowang: { - trigger: { player: "dieBefore" }, - filter(event, player) { + trigger: { + player: ["dieBefore", "rest"], + }, + filter(event, player, name) { + if (name == "rest") { + return true; + } return event.getParent().name != "giveup" && player.maxHp > 0; }, derivation: "mbmowang_faq", forced: true, + forceDie: true, + forceOut: true, direct: true, priority: 15, group: ["mbmowang_die", "mbmowang_return"], - content() { - if (_status.mbmowang_return && _status.mbmowang_return[player.playerid]) { - trigger.cancel(); - } else { - if (player.getStorage("mbdanggu").length) { - player.logSkill("mbmowang"); - game.broadcastAll(function () { - if (lib.config.background_speak) { - game.playAudio("die", "shichangshiRest"); - } - }); - trigger.setContent(lib.skill.mbmowang.dieContent); - trigger.includeOut = true; - } else { - player.changeSkin("mbmowang", "shichangshi_dead"); - } - } - }, - ai: { - combo: "mbdanggu", - neg: true, - }, - dieContent() { - "step 0"; - event.forceDie = true; - if (source) { - game.log(player, "被", source, "杀害"); - if (source.stat[source.stat.length - 1].kill == undefined) { - source.stat[source.stat.length - 1].kill = 1; - } else { - source.stat[source.stat.length - 1].kill++; - } - } else { - game.log(player, "阵亡"); - } - if (player.isIn() && (!_status.mbmowang_return || !_status.mbmowang_return[player.playerid])) { - event.reserveOut = true; - game.log(player, "进入了修整状态"); - game.log(player, "移出了游戏"); - //game.addGlobalSkill('mbmowang_return'); - if (!_status.mbmowang_return) { - _status.mbmowang_return = {}; - } - _status.mbmowang_return[player.playerid] = 1; - } else { - event.finish(); - } - if (!game.countPlayer()) { - game.over(); - } else if (player.hp != 0) { - player.changeHp(0 - player.hp, false).forceDie = true; - } - game.broadcastAll(function (player) { - if (player.isLinked()) { - if (get.is.linked2(player)) { - player.classList.toggle("linked2"); - } else { - player.classList.toggle("linked"); - } - } - if (player.isTurnedOver()) { - player.classList.toggle("turnedover"); - } - }, player); - game.addVideo("link", player, player.isLinked()); - game.addVideo("turnOver", player, player.classList.contains("turnedover")); - "step 1"; - event.trigger("die"); - "step 2"; - if (event.reserveOut) { - if (!game.reserveDead) { - for (var mark in player.marks) { - if (mark == "mbdanggu") { - continue; - } - player.unmarkSkill(mark); - } - var count = 1; - var list = Array.from(player.node.marks.childNodes); - if (list.some(i => i.name == "mbdanggu")) { - count++; - } - while (player.node.marks.childNodes.length > count) { - var node = player.node.marks.lastChild; - if (node.name == "mbdanggu") { - node = node.previousSibling; - } - node.remove(); - } - game.broadcast( - function (player, count) { - while (player.node.marks.childNodes.length > count) { - var node = player.node.marks.lastChild; - if (node.name == "mbdanggu") { - node = node.previousSibling; - } - node.remove(); - } - }, - player, - count - ); - } - for (var i in player.tempSkills) { - player.removeSkill(i); - } - var skills = player.getSkills(); - for (var i = 0; i < skills.length; i++) { - if (lib.skill[skills[i]].temp) { - player.removeSkill(skills[i]); - } - } - event.cards = player.getCards("hejsx"); - if (event.cards.length) { - player.discard(event.cards).forceDie = true; - } - } - "step 3"; - if (event.reserveOut) { + async content(event, trigger, player) { + if (event.triggername == "rest") { game.broadcastAll( function (player, list) { - player.classList.add("out"); + //player.classList.add("out"); if (list.includes(player.name1) || player.name1 == "shichangshi") { player.smoothAvatar(false); player.skin.name = player.name1 + "_dead"; @@ -13522,58 +13418,43 @@ const skills = { player, lib.skill.mbdanggu.changshi.map(i => i[0]) ); + return; } - if (source && lib.config.border_style == "auto" && (lib.config.autoborder_count == "kill" || lib.config.autoborder_count == "mix")) { - switch (source.node.framebg.dataset.auto) { - case "gold": - case "silver": - source.node.framebg.dataset.auto = "gold"; - break; - case "bronze": - source.node.framebg.dataset.auto = "silver"; - break; - default: - source.node.framebg.dataset.auto = lib.config.autoborder_start || "bronze"; - } - if (lib.config.autoborder_count == "kill") { - source.node.framebg.dataset.decoration = source.node.framebg.dataset.auto; - } else { - var dnum = 0; - for (var j = 0; j < source.stat.length; j++) { - if (source.stat[j].damage != undefined) { - dnum += source.stat[j].damage; + if (_status._rest_return?.[player.playerid]) { + trigger.cancel(); + } else { + if (player.getStorage("mbdanggu").length) { + player.logSkill("mbmowang"); + /*game.broadcastAll(function () { + if (lib.config.background_speak) { + game.playAudio("die", "shichangshiRest"); } - } - source.node.framebg.dataset.decoration = ""; - switch (source.node.framebg.dataset.auto) { - case "bronze": - if (dnum >= 4) { - source.node.framebg.dataset.decoration = "bronze"; - } - break; - case "silver": - if (dnum >= 8) { - source.node.framebg.dataset.decoration = "silver"; - } - break; - case "gold": - if (dnum >= 12) { - source.node.framebg.dataset.decoration = "gold"; - } - break; - } + });*/ + //煞笔十常侍 + trigger.restMap = { + type: "round", + count: 1, + audio: "shichangshiRest", + }; + trigger.excludeMark.add("mbdanggu"); + //trigger.noDieAudio = true; + trigger.includeOut = true; + } else { + player.changeSkin("mbmowang", "shichangshi_dead"); } - source.classList.add("topcount"); } }, + ai: { + combo: "mbdanggu", + neg: true, + }, subSkill: { die: { audio: "mbmowang", trigger: { player: "phaseAfter" }, forced: true, forceDie: true, - content() { - "step 0"; + async content(event, trigger, player) { if (lib.skill.mbdanggu.isSingleShichangshi(player)) { if (!player.getStorage("mbdanggu").length) { game.broadcastAll(function (player) { @@ -13594,31 +13475,22 @@ const skills = { } } if (!player.getStorage("mbdanggu").length) { - game.delay(); + await game.delay(); } - "step 1"; - player.die(); + await player.die(); }, }, return: { - trigger: { player: "phaseBefore" }, + trigger: { player: "restEnd" }, forced: true, charlotte: true, silent: true, forceDie: true, forceOut: true, filter(event, player) { - return !event._mbmowang_return && event.player.isOut() && _status.mbmowang_return[event.player.playerid]; + return event.player == player && player.hasSkill("mbdanggu", null, null, false); }, - content() { - "step 0"; - trigger._mbmowang_return = true; - game.broadcastAll(function (player) { - player.classList.remove("out"); - }, trigger.player); - game.log(trigger.player, "移回了游戏"); - delete _status.mbmowang_return[trigger.player.playerid]; - trigger.player.recover(trigger.player.maxHp - trigger.player.hp); + async content(event, trigger, player) { game.broadcastAll(function (player) { if (player.name1 == "shichangshi") { player.smoothAvatar(false); @@ -13634,13 +13506,7 @@ const skills = { player.skin.name2 = player.name2; } } - }, trigger.player); - "step 1"; - event.trigger("restEnd"); - if (!player.hasSkill("mbdanggu", null, null, false)) { - event.finish(); - } - "step 2"; + }, player); delete player.storage.mbdanggu_current; if (lib.skill.mbdanggu.isSingleShichangshi(player)) { game.broadcastAll(function (player) { @@ -13659,12 +13525,11 @@ const skills = { } }, player); } - "step 3"; - var next = game.createEvent("mbdanggu_clique"); + const next = game.createEvent("mbdanggu_clique"); next.player = player; next.setContent(lib.skill.mbdanggu.contentx); - "step 4"; - player.draw(); + await next; + await player.draw(); }, }, }, diff --git a/character/newjiang/card.js b/character/newjiang/card.js index 1fd2fa8b31..53a3d9f73f 100644 --- a/character/newjiang/card.js +++ b/character/newjiang/card.js @@ -1,10 +1,22 @@ import { lib, game, ui, get, ai, _status } from "../../noname.js"; const cards = { - lukai_spade: { fullskin: true }, - lukai_heart: { fullskin: true }, - lukai_diamond: { fullskin: true }, - lukai_club: { fullskin: true }, + lukai_spade: { + fullskin: true, + noname: true, + }, + lukai_heart: { + fullskin: true, + noname: true, + }, + lukai_diamond: { + fullskin: true, + noname: true, + }, + lukai_club: { + fullskin: true, + noname: true, + }, }; export default cards; diff --git a/character/offline/card.js b/character/offline/card.js index 83a2bae08c..57dd62a969 100644 --- a/character/offline/card.js +++ b/character/offline/card.js @@ -4,6 +4,7 @@ const cards = { hschenzhi_poker: { type: "poker", fullskin: true, + noname: true, }, chunqiubi: { derivation: "chenshou", diff --git a/character/offline/translate.js b/character/offline/translate.js index d5f2ca6d7c..d7e7127b00 100644 --- a/character/offline/translate.js +++ b/character/offline/translate.js @@ -1278,7 +1278,7 @@ const translates = { chenshou_prefix: "青史", //eternal_poker: "invisible", hschenzhi_poker: "扑克", - hschenzhi_poker_info: "扑克牌,无效果且类型为poker的牌", + hschenzhi_poker_info: "扑克牌,牌名为扑克,无效果且类型为poker的牌", hschenzhi: "沉滞", hschenzhi_info: "锁定技,你摸牌改为从一副扑克牌中摸牌(包含初始手牌);扑克牌拥有独立的弃牌堆。", hsdianmo: "点墨", diff --git a/character/onlyOL/skill.js b/character/onlyOL/skill.js index 82fe61e25e..1dac88ba25 100644 --- a/character/onlyOL/skill.js +++ b/character/onlyOL/skill.js @@ -53,7 +53,7 @@ const skills = { _status.olduoqi_record.add(player); game.broadcastAll(record => { _status.olduoqi_record = record; - }, _status.olduoqi_record) + }, _status.olduoqi_record); const next = player.insertPhase(); next._noTurnOver = true; next.set("phaseList", ["phaseUse"]); @@ -297,6 +297,12 @@ const skills = { }, olgangquan: { audio: 2, + init(player, skill) { + player.addSkill(skill + "_mark"); + }, + onremove(player, skill) { + player.removeSkill(skill + "_mark"); + }, enable: "chooseToUse", filter(event, player) { const bool = event.olgangquan, @@ -308,7 +314,7 @@ const skills = { hiddenCard(player, name) { return (name == "juedou" && player.hasCard(card => get.type2(card) == "trick", "hes")) || (name == "sha" && player.hasCard(card => get.type2(card) == "equip", "hes")); }, - locked: false, + /*locked: false, mod: { playerEnabled(card, player, target) { if (!card.storage?.olgangquan || get.name(card) != "sha" || player._olgangquanCheck) { @@ -323,7 +329,7 @@ const skills = { return false; } }, - }, + },*/ onChooseToUse(event) { if (game.online || event?.olgangquan) { return; @@ -375,15 +381,18 @@ const skills = { return lib.filter.filterTarget.apply(this, arguments); }, selectTarget() { - if (get.card()?.name == "sha") { + /*if (get.card()?.name == "sha") { if ([player.getNext(), player.getPrevious()].some(target => { return target?.isIn() && !player.canUse(get.card(), target, null, true); })) { return 1; } - } + }*/ return get.info("olgangquan_backup").choice != "sha" ? 1 : -1; }, + filterOk() { + return ui.selected.targets?.length > 0; + }, popname: true, }; }, @@ -400,6 +409,39 @@ const skills = { }, subSkill: { backup: {}, + mark: { + charlotte: true, + silent: true, + markColor: ["rgba(72, 118, 255, 1)", "rgba(255, 69, 0, 1)"], + init(player, skill) { + const evt = get.info("dcjianying").getLastUsed(player); + const bool = evt.cards?.some(card => card.hasGaintag("eternal_olduoqi_tag")); + player.markSkill(skill); + game.broadcastAll( + function (index, player) { + const name = "olgangquan_mark"; + const bgColor = get.info(name).markColor[index], + text = `${index ? "杀" : "斗"}`; + if (player.marks[name]) { + player.marks[name].firstChild.style.backgroundColor = bgColor; + player.marks[name].firstChild.innerHTML = text; + } + player.update(); + }, + Number(!!bool), + player + ); + }, + trigger: { + player: "useCard1", + }, + async content(event, trigger, player) { + get.info(event.name).init(player, event.name); + }, + intro: { + content: "图标的文字就是【罡拳】能印的牌", + }, + }, }, }, //魔貂蝉 @@ -436,7 +478,6 @@ const skills = { filterTarget: lib.filter.notMe, selectTarget: [1, num], complexCard: true, - filterOk() { if (!ui.selected.cards.length) { return false; @@ -468,6 +509,7 @@ const skills = { const card = get.event().olhuanhuo_debuff; return { name: get.name(card, player), + nature: get.nature(card, player), cards: [card], isCard: true, }; @@ -544,13 +586,26 @@ const skills = { filter(event, player) { return !player.hasSkill("olrumo") || !game.hasPlayer(target => target.countCards("h", card => card.hasGaintag("olqingshi_tag"))); }, - skillAnimation: true, - animationColor: "metal", - logTarget(event, player) { - return game.filterPlayer(); + async cost(event, trigger, player) { + let result; + if (!player.hasSkill("olrumo")) { + result = await player.chooseBool(get.prompt2(event.skill)).set("choice", true).forResult(); + } else { + result = { bool: true }; + } + if (result.bool) { + event.result = { + bool: true, + targets: game.filterPlayer(), + }; + } }, async content(event, trigger, player) { - player.addSkill("olrumo"); + if (!player.hasSkill("olrumo")) { + const name = event.name + "_animate"; + player.trySkillAnimate(name, name, player.checkShow(name)); + player.addSkill("olrumo"); + } const { targets } = event; const effect = async target => { const card = get.cardPile(card => { @@ -570,6 +625,10 @@ const skills = { group: ["olqingshi_effect"], subSkill: { tag: {}, + animate: { + skillAnimation: true, + animationColor: "metal", + }, effect: { audio: "olqingshi", trigger: { @@ -585,7 +644,7 @@ const skills = { event.isFirstTarget && game.hasPlayer2(target => { return target.hasHistory("lose", evt => { - if (evt.getParent() != evtx || evt.relatedEvent == evtx) { + if ((evt.relatedEvent || evt.getParent()) != evtx) { return false; } return Object.values(evt.gaintag_map || {}) @@ -654,16 +713,33 @@ const skills = { async cost(event, trigger, player) { const name = event.triggername; if (name == "useCardToPlayer") { - event.result = await player - .chooseToDiscard(`###${get.prompt(event.skill, trigger.player)}###弃置一张牌,为${get.translation(trigger.card)}重新指定目标(无距离限制)`, "chooseonly", "he") - .set("ai", card => { + const targets = game.filterPlayer(target => lib.filter.targetEnabled2(trigger.card, trigger.player, target)); + const next = player.chooseCardTarget({ + prompt: `###${get.prompt(event.skill, trigger.player)}###弃置一张牌,为${get.translation(trigger.card)}重新指定目标(无距离限制)`, + filterCard: lib.filter.cardDiscardable, + position: "he", + filterTarget(card, player, target) { + return get.event().targets.includes(target); + }, + ai1(card) { if (get.event().goon) { return 7 - get.value(card); } return 0; - }) - .set("goon", Math.max(...game.filterPlayer(target => target != trigger.target && lib.filter.targetEnabled2(trigger.card, trigger.player, target)).map(target => get.effect(target, trigger.card, trigger.player, player))) > get.effect(trigger.target, trigger.card, trigger.player, player)) - .forResult(); + }, + ai2(target) { + return get.effect(target, get.event().getTrigger().card, get.event().getTrigger().player, get.player()); + }, + targets: targets, + goon: Math.max(...targets.filter(target => target != trigger.target).map(target => get.effect(target, trigger.card, trigger.player, player))) > get.effect(trigger.target, trigger.card, trigger.player, player), + }); + next.targetprompt2.add(target => { + if (!target.isIn() || target != get.event().getTrigger().target) { + return false; + } + return "原目标"; + }); + event.result = await next.forResult(); } else { event.result = { bool: true, @@ -673,24 +749,8 @@ const skills = { async content(event, trigger, player) { const name = event.triggername; if (name == "useCardToPlayer") { - const { cards } = event; + const { cards, targets } = event; await player.discard(cards); - const result = await player - .chooseTarget(`倾世:为${get.translation(trigger.card)}重新指定目标(无距离限制)`, true, (card, player, target) => { - return get.event().targets.includes(target); - }) - .set( - "targets", - game.filterPlayer(target => lib.filter.targetEnabled2(trigger.card, trigger.player, target)) - ) - .set("ai", target => { - return get.effect(target, get.event().getTrigger().card, get.event().getTrigger().player, get.player()); - }) - .forResult(); - if (!result?.targets?.length) { - return; - } - const { targets } = result; const evt = trigger.getParent(); player.line(targets); evt.targets.length = 0; diff --git a/character/sp/card.js b/character/sp/card.js index 630ef861bd..5a05c156e6 100644 --- a/character/sp/card.js +++ b/character/sp/card.js @@ -2,9 +2,18 @@ import { lib, game, ui, get, ai, _status } from "../../noname.js"; const cards = { //曹婴三种类型 - caoying_basic: { fullskin: true }, - caoying_trick: { fullskin: true }, - caoying_equip: { fullskin: true }, + caoying_basic: { + fullskin: true, + noname: true, + }, + caoying_trick: { + fullskin: true, + noname: true, + }, + caoying_equip: { + fullskin: true, + noname: true, + }, //蒲元衍生 sanlve: { derivation: "ol_puyuan", diff --git a/character/sp/skill.js b/character/sp/skill.js index 10765594af..1e61d630fd 100644 --- a/character/sp/skill.js +++ b/character/sp/skill.js @@ -836,7 +836,9 @@ const skills = { ["基本", "", "sha"], ["基本", "", "shan"], ]; - return ui.create.dialog("卸尾", [list, "vcard"], "hidden"); + const dialog = ui.create.dialog("卸尾", [list, "vcard"], "hidden"); + dialog.direct = true; + return dialog; }, filter(button, player) { return get.event().getParent().filterCard({ name: button.link[2] }, player, get.event().getParent()); @@ -851,14 +853,14 @@ const skills = { isCard: true, }, position: "h", + ignoreMod: true, check(card) { return 6 - get.value(card); }, - log: false, precontent() { const skill = "olxiewei", cards = event.result.cards; - player.logSkill(skill); + //player.logSkill(skill); if (cards.length < 2) { var evt = event.getParent(); evt.set(skill, true); @@ -884,6 +886,9 @@ const skills = { markcount: "expansion", content: "expansion", }, + subSkill: { + backup: {}, + }, }, olyouque: { audio: 2, @@ -892,8 +897,10 @@ const skills = { return player.getExpansions("olxiewei").length && game.hasPlayer(target => player.canCompare(target, true)); }, delay: false, - log: false, - async content(event, trigger, player) { + lose: false, + discard: false, + //log: false, + async precontent(event, trigger, player) { const cards = player.getExpansions("olxiewei"); const result = await player .chooseButtonTarget({ @@ -911,35 +918,38 @@ const skills = { }) .forResult(); if (result?.bool && result.links?.length && result.targets?.length) { - const card = result.links[0], - target = result.targets[0]; - if (!player.canCompare(target, true)) { - return; - } - player.logSkill(event.name, target); - player.addTempSkill(event.name + "_effect"); - let next = player.chooseToCompare(target); - //next.small = true; - if (!next.fixedResult) { - next.fixedResult = {}; - } - next.fixedResult[player.playerid] = card; - const resultx = await next.forResult(); - for (const targetx of [player, target]) { - if (resultx.winner != targetx) { - const card = targetx == player ? resultx.player : resultx.target, - num = get.number(card), - winner = resultx.winner; - await targetx.modedDiscard(targetx.getCards("h", cardx => get.number(cardx, player) > num)); - if (winner && targetx.canUse({ name: "sha", isCard: true }, winner, false, false)) { - const sha = get.autoViewAs({ name: "sha", isCard: true, storage: { olyouque: true } }); - await targetx.useCard(sha, winner, false); - } - } - } + event.result.targets = result.targets; + event.result.cards = result.links; } else { + event.getParent().goto(0); + } + }, + async content(event, trigger, player) { + const card = event.cards[0], + target = event.targets[0]; + if (!player.canCompare(target, true)) { return; } + player.addTempSkill(event.name + "_effect"); + let next = player.chooseToCompare(target); + //next.small = true; + if (!next.fixedResult) { + next.fixedResult = {}; + } + next.fixedResult[player.playerid] = card; + const resultx = await next.forResult(); + for (const targetx of [player, target]) { + if (resultx.winner != targetx) { + const card = targetx == player ? resultx.player : resultx.target, + num = get.number(card), + winner = resultx.winner; + await targetx.modedDiscard(targetx.getCards("h", cardx => get.number(cardx, player) > num)); + if (winner && targetx.canUse({ name: "sha", isCard: true }, winner, false, false)) { + const sha = get.autoViewAs({ name: "sha", isCard: true, storage: { olyouque: true } }); + await targetx.useCard(sha, winner, false); + } + } + } }, ai: { combo: "olxiewei", @@ -956,8 +966,8 @@ const skills = { return event.card?.storage?.olyouque; }, forced: true, - content() { - player.draw(2); + async content(event, trigger, player) { + await player.draw(2); if (!player.getExpansions("olxiewei").some(card => get.suit(card) == "spade")) { player.tempBanSkill("olyouque", "phaseUseAfter"); } @@ -2382,6 +2392,7 @@ const skills = { const count = Math.min(3, game.roundNumber); return [count, count]; }, + position: "he", lose: false, discard: false, visible: false, @@ -30455,17 +30466,18 @@ const skills = { } return true; }, - content() { - "step 0"; - if (player.storage.fanghun) { - player.draw(player.storage.fanghun); + async content(event, trigger, player) { + let num = player.storage.fanghun; + if (num) { + await player.draw(num); } - player.removeMark("fanghun", player.storage.fanghun); - event.num = Math.max(2, player.storage.fanghun2 || 0); - var list; + player.removeMark("fanghun", num); + player.awakenSkill(event.name); + num = Math.max(2, player.storage.fanghun2 || 0); + let list; if (_status.characterlist) { list = []; - for (var i = 0; i < _status.characterlist.length; i++) { + for (let i = 0; i < _status.characterlist.length; i++) { var name = _status.characterlist[i]; if (lib.character[name][1] == "shu") { list.push(name); @@ -30481,7 +30493,7 @@ const skills = { }); } var players = game.players.concat(game.dead); - for (var i = 0; i < players.length; i++) { + for (let i = 0; i < players.length; i++) { list.remove(players[i].name); list.remove(players[i].name1); list.remove(players[i].name2); @@ -30489,26 +30501,20 @@ const skills = { list.remove("zhaoyun"); list.remove("re_zhaoyun"); list.remove("ol_zhaoyun"); - // var dialog=ui.create.dialog(); - // dialog.add([list.randomGets(5),'character']); - player + const result = await player .chooseButton(true) .set("ai", function (button) { return get.rank(button.link, true) - lib.character[button.link][2]; }) - .set("createDialog", ["将武将牌替换为一名角色", [list.randomGets(5), "character"]]); - player.awakenSkill(event.name); - "step 1"; - event.num = Math.min(event.num, 8); - player.reinitCharacter(get.character(player.name2, 3).includes("fuhan") ? player.name2 : player.name1, result.links[0]); - "step 2"; - var num = event.num - player.maxHp; - if (num > 0) { - player.gainMaxHp(num); - } else { - player.loseMaxHp(-num); + .set("createDialog", ["将武将牌替换为一名角色", [list.randomGets(5), "character"]]) + .forResult(); + if (result?.links?.length) { + num = Math.min(num, 8); + await player.reinitCharacter(get.character(player.name2, 3).includes("fuhan") ? player.name2 : player.name1, result.links[0]); + num = num - player.maxHp; + await player[num > 0 ? "gainMaxHp" : "loseMaxHp"](Math.abs(num)); + await player.recover(); } - player.recover(); }, ai: { combo: "fanghun", @@ -30523,19 +30529,18 @@ const skills = { filter(event, player) { return player.countMark("fanghun") > 0; }, - content() { - "step 0"; - if (player.storage.fanghun) { - player.draw(player.storage.fanghun); + async content(event, trigger, player) { + const num = player.countMark("fanghun"); + if (num) { + await player.draw(num); } - player.removeMark("fanghun", player.storage.fanghun); + player.removeMark("fanghun", num); player.awakenSkill(event.name); - "step 1"; - var list; + let list; if (_status.characterlist) { list = []; - for (var i = 0; i < _status.characterlist.length; i++) { - var name = _status.characterlist[i]; + for (let i = 0; i < _status.characterlist.length; i++) { + const name = _status.characterlist[i]; if (lib.character[name][1] == "shu") { list.push(name); } @@ -30549,8 +30554,8 @@ const skills = { return info[1] == "shu"; }); } - var players = game.players.concat(game.dead); - for (var i = 0; i < players.length; i++) { + const players = game.players.concat(game.dead); + for (let i = 0; i < players.length; i++) { list.remove(players[i].name); list.remove(players[i].name1); list.remove(players[i].name2); @@ -30559,54 +30564,82 @@ const skills = { list.remove("re_zhaoyun"); list.remove("ol_zhaoyun"); list = list.randomGets(Math.max(4, game.countPlayer())); - var skills = []; - for (var i of list) { + const skills = []; + for (const i of list) { skills.addArray( (lib.character[i][3] || []).filter(function (skill) { - var info = get.info(skill); + const info = get.info(skill); return info && !info.zhuSkill && !info.limited && !info.juexingji && !info.hiddenSkill && !info.charlotte && !info.dutySkill; }) ); } if (!list.length || !skills.length) { - event.finish(); return; } + await Promise.all(event.next); + event.videoId = lib.status.videoId++; if (player.isUnderControl()) { game.swapPlayerAuto(player); } - var switchToAuto = function () { - _status.imchoosing = false; - event._result = { - bool: true, - skills: skills.randomGets(2), - }; - if (event.dialog) { - event.dialog.close(); - } - if (event.control) { - event.control.close(); - } - }; - var chooseButton = function (list, skills) { - var event = _status.event; - if (!event._result) { - event._result = {}; - } + const chooseCharacterSkills = function (player, list, skills, force = false, num, ai = { bool: false }) { + const { promise, resolve } = Promise.withResolvers(); + const event = _status.event; + //初始化result + event._result ??= {}; event._result.skills = []; - var rSkill = event._result.skills; - var dialog = ui.create.dialog("请选择获得至多两个技能", [list, "character"], "hidden"); + event.selectedSkills ??= event._result.skills; + //创建对话框 + let dialog = ui.create.dialog(`请选择获得至多${get.cnNumber(num)}个技能`, [list, "character"], "hidden"); event.dialog = dialog; - var table = document.createElement("div"); + //创建确定按钮 + event.control_ok = ui.create.control("ok", link => { + _status.imchoosing = false; + event.dialog.close(); + event.control_ok?.close(); + event.control_cancel?.close(); + event._result = { + bool: true, + skills: event.selectedSkills, + }; + resolve(event._result); + game.resume(); + }); + //event.control_ok.classList.add("disabled"); + //如果是非强制的,才创建取消按钮 + if (!force) { + event.control_cancel = ui.create.control("cancel", link => { + _status.imchoosing = false; + event.dialog.close(); + event.control_ok?.close(); + event.control_cancel?.close(); + event._result = { + bool: false, + }; + resolve(event._result); + game.resume(); + }); + } + event.switchToAuto = function () { + _status.imchoosing = false; + event.dialog?.close(); + event.control_ok?.close(); + event.control_cancel?.close(); + event._result = ai; + resolve(event._result); + game.resume(); + }; + //创建用于选择的技能按钮(tdnodes样式) + const table = document.createElement("div"); table.classList.add("add-setting"); table.style.margin = "0"; table.style.width = "100%"; table.style.position = "relative"; - for (var i = 0; i < skills.length; i++) { - var td = ui.create.div(".shadowed.reduce_radius.pointerdiv.tdnode"); + for (let i = 0; i < skills.length; i++) { + const td = ui.create.div(".shadowed.reduce_radius.pointerdiv.tdnode"); td.link = skills[i]; table.appendChild(td); td.innerHTML = "" + get.translation(skills[i]) + ""; + //给按钮添加监听 td.addEventListener(lib.config.touchscreen ? "touchend" : "click", function () { if (_status.dragged) { return; @@ -30618,58 +30651,59 @@ const skills = { setTimeout(function () { _status.tempNoButton = false; }, 500); - var link = this.link; + const link = this.link; if (!this.classList.contains("bluebg")) { - if (rSkill.length >= 2) { + //限制选择数量 + if (event.selectedSkills.length >= num) { return; } - rSkill.add(link); + event.selectedSkills.add(link); this.classList.add("bluebg"); } else { this.classList.remove("bluebg"); - rSkill.remove(link); + event.selectedSkills.remove(link); } + //event.control_ok.classList[event.selectedSkills.length >= 0 ? "remove" : "add"]("disabled"); }); } dialog.content.appendChild(table); dialog.add("  "); dialog.open(); - event.switchToAuto = function () { - event.dialog.close(); - event.control.close(); - game.resume(); - _status.imchoosing = false; - }; - event.control = ui.create.control("ok", function (link) { - event.dialog.close(); - event.control.close(); - game.resume(); - _status.imchoosing = false; - }); - for (var i = 0; i < event.dialog.buttons.length; i++) { + //点亮所有按钮(包括角色的) + for (let i = 0; i < event.dialog.buttons.length; i++) { event.dialog.buttons[i].classList.add("selectable"); } game.pause(); - game.countChoose(); + _status.imchoosing = true; + return promise; + }; + const ai = function () { + return { bool: true, skills: skills.sort((a, b) => get.skillRank(b, "inout") - get.skillRank(a, "inout")).slice(0, 2) }; }; + let next; if (event.isMine()) { - chooseButton(list, skills); - } else if (event.isOnline()) { - event.player.send(chooseButton, list, skills); - event.player.wait(); - game.pause(); + next = chooseCharacterSkills(player, list, skills, true, 2, ai()); + } else if (player.isOnline()) { + let { promise, resolve } = Promise.withResolvers(); + player.send(chooseCharacterSkills, player, list, skills, true, 2, ai()); + player.wait(result => { + if (result == "ai") { + result = ai(); + } + resolve(result); + }); + next = promise; } else { - switchToAuto(); + next = Promise.resolve(ai()); } - "step 2"; - var map = event.result || result; - if (map && map.skills && map.skills.length) { - player.addSkills(map.skills); + const result = await next; + if (result?.skills?.length) { + await player.addSkills(result.skills); } game.broadcastAll(function (list) { game.expandSkills(list); - for (var i of list) { + for (const i of list) { var info = lib.skill[i]; if (!info) { continue; @@ -30679,10 +30713,9 @@ const skills = { } info.audioname2.zhaoxiang = "fuhan"; } - }, map.skills); - "step 3"; + }, result.skills); if (player.isMinHp()) { - player.recover(); + await player.recover(); } }, ai: { @@ -35504,9 +35537,12 @@ const skills = { if (source.getStorage("jilei2").includes(type)) { return 0; } - if (type == "trick" && source.countCards("h", card => { - return get.type(card, null, source) == "trick" && source.hasValueTarget(card); - })) { + if ( + type == "trick" && + source.countCards("h", card => { + return get.type(card, null, source) == "trick" && source.hasValueTarget(card); + }) + ) { return 3; } return ["equip", "trick", "basic"].indexOf(type); diff --git a/character/sp2/skill.js b/character/sp2/skill.js index abca169916..2824e2be49 100644 --- a/character/sp2/skill.js +++ b/character/sp2/skill.js @@ -347,10 +347,10 @@ const skills = { if (!lib.skill.dcshixian.filterx(event) || !player.hasMark("stardangchen_buff")) { return false; } - return typeof get.number(event.card) === "number"; + return true; }, check(event, player) { - return !get.tag(event.card, "norepeat") ^ (event.targets?.reduce((sum, i) => sum + get.effect(event.card, i, player, player), 0) < 0); + return !get.tag(event.card, "norepeat") ^ (event.targets?.reduce((sum, i) => sum + get.effect(i, event.card, player, player), 0) < 0); }, prompt2(event, player) { return "进行一次判定,若判定结果为" + player.countMark("stardangchen_buff") + "的倍数,则" + get.translation(event.card) + "额外结算一次"; @@ -7088,7 +7088,7 @@ const skills = { return ( get.color(event.card) === "black" && event.player.hasHistory("lose", event2 => { - return event2 && event2.hs.length && (event2.relatedEvent || evevt2.getParent()) === event; + return event2 && event2.hs.length && (event2.relatedEvent || event2.getParent()) === event; }) && event.player .getHistory("useCard", event2 => { @@ -10924,196 +10924,83 @@ const skills = { player: "loseAfter", global: ["equipAfter", "addJudgeAfter", "gainAfter", "loseAsyncAfter", "addToExpansionAfter"], }, - direct: true, filter(event, player) { - if (player == _status.currentPhase || event.getParent()?.name == "useCard") { + if (player == _status.currentPhase || (event.relatedEvent || event.getParent())?.name == "useCard") { return false; } if (event.name == "gain" && event.player == player) { return false; } - var evt = event.getl(player); - return evt && evt.cards2 && evt.cards2.length == 1 && ["equip", "trick"].includes(get.type2(evt.cards2[0], evt.type == "discard" && evt.hs.includes(evt.cards2[0]) ? player : false)) && !player.hasSkill("moying2"); + const evt = event.getl(player); + return evt && evt.cards2 && evt.cards2.length == 1 && ["equip", "trick"].includes(get.type2(evt.cards2[0], evt.type == "discard" && evt.hs.includes(evt.cards2[0]) ? player : false)); }, - content() { - "step 0"; - var number = trigger.getl(player).cards2[0].number; - var numbers = [number - 2, number - 1, number, number + 1, number + 2].filter(function (number) { + usable: 1, + async cost(event, trigger, player) { + const number = trigger.getl(player).cards2[0].number; + const numbers = [number - 2, number - 1, number, number + 1, number + 2].filter(function (number) { return number >= 1 && number <= 13; }); - if (player.isUnderControl()) { - game.swapPlayerAuto(player); - } - var switchToAuto = function () { - _status.imchoosing = false; - event._result = { - bool: true, - suit: lib.suit.randomGet(), - number: numbers.randomGet(), - }; - if (event.dialog) { - event.dialog.close(); - } - if (event.control) { - event.control.close(); - } - }; - var chooseButton = function (player, numbers) { - var event = _status.event; - player = player || event.player; - if (!event._result) { - event._result = {}; - } - var dialog = ui.create.dialog("是否发动【墨影】?", "forcebutton", "hidden"); - event.dialog = dialog; - dialog.addText("花色"); - var table = document.createElement("div"); - table.classList.add("add-setting"); - table.style.margin = "0"; - table.style.width = "100%"; - table.style.position = "relative"; - var listi = ["spade", "heart", "club", "diamond"]; - for (var i = 0; i < listi.length; i++) { - var td = ui.create.div(".shadowed.reduce_radius.pointerdiv.tdnode"); - td.link = listi[i]; - table.appendChild(td); - td.innerHTML = "" + get.translation(listi[i]) + ""; - td.addEventListener(lib.config.touchscreen ? "touchend" : "click", function () { - if (_status.dragged) { - return; - } - if (_status.justdragged) { - return; - } - _status.tempNoButton = true; - setTimeout(function () { - _status.tempNoButton = false; - }, 500); - var link = this.link; - var current = this.parentNode.querySelector(".bluebg"); - if (current) { - current.classList.remove("bluebg"); - } - this.classList.add("bluebg"); - event._result.suit = link; - }); - } - dialog.content.appendChild(table); - dialog.addText("点数"); - var table2 = document.createElement("div"); - table2.classList.add("add-setting"); - table2.style.margin = "0"; - table2.style.width = "100%"; - table2.style.position = "relative"; - for (var i = 0; i < numbers.length; i++) { - var td = ui.create.div(".shadowed.reduce_radius.pointerdiv.tdnode"); - td.link = numbers[i]; - table2.appendChild(td); - td.innerHTML = "" + get.strNumber(numbers[i]) + ""; - td.addEventListener(lib.config.touchscreen ? "touchend" : "click", function () { - if (_status.dragged) { - return; - } - if (_status.justdragged) { - return; - } - _status.tempNoButton = true; - setTimeout(function () { - _status.tempNoButton = false; - }, 500); - var link = this.link; - var current = this.parentNode.querySelector(".bluebg"); - if (current) { - current.classList.remove("bluebg"); - } - this.classList.add("bluebg"); - event._result.number = link; - }); - } - dialog.content.appendChild(table2); - dialog.add("  "); - event.dialog.open(); - - event.switchToAuto = function () { - event._result = { - bool: true, - number: numbers.randomGet(), - suit: lib.suit.randomGet(), - }; - event.dialog.close(); - event.control.close(); - game.resume(); - _status.imchoosing = false; - }; - event.control = ui.create.control("ok", "cancel2", function (link) { - var result = event._result; - if (link == "cancel2") { - result.bool = false; - } else { - if (!result.number || !result.suit) { - return; - } - result.bool = true; + const suits = lib.suit.slice(); + const result = await player + .chooseButton([get.prompt2("moying"), `
花色
`, [suits.map(suit => [suit, get.translation(suit)]), "tdnodes"], `
点数
`, [numbers, "tdnodes"]], 2) + .set("filterButton", button => { + const selected = ui.selected.buttons; + if (!selected.length) { + return true; } - event.dialog.close(); - event.control.close(); - game.resume(); - _status.imchoosing = false; - }); - for (var i = 0; i < event.dialog.buttons.length; i++) { - event.dialog.buttons[i].classList.add("selectable"); + return typeof button.link != typeof selected[0].link; + }) + .set("ai", button => { + return Math.random(); + }) + .forResult(); + if (result?.links?.length) { + const links = result.links; + if (!suits.includes(links[0])) { + links.reverse(); } - game.pause(); - game.countChoose(); - }; - if (event.isMine()) { - chooseButton(player, numbers); - } else if (event.isOnline()) { - event.player.send(chooseButton, event.player, numbers); - event.player.wait(); - game.pause(); - } else { - switchToAuto(); + event.result = { + bool: true, + cost_data: [links[0], links[1]], + }; } - "step 1"; - var map = event.result || result; - if (map.bool) { - player.logSkill("moying"); - player.addTempSkill("moying2"); - var cards = []; - for (var i = 0; i < ui.cardPile.childNodes.length; i++) { - var card = ui.cardPile.childNodes[i]; - if (get.suit(card) == map.suit && get.number(card) == map.number) { - cards.push(card); - } - } - if (cards.length) { - player.gain(cards, "gain2", "log"); + }, + async content(event, trigger, player) { + const { + cost_data: [suit, number], + } = event; + const cards = []; + for (let i = 0; i < ui.cardPile.childNodes.length; i++) { + const card = ui.cardPile.childNodes[i]; + if (get.suit(card) == suit && get.number(card) == number) { + cards.push(card); } } + if (cards.length) { + player.gain(cards, "gain2"); + } }, }, - moying2: {}, + //moying2: {}, juanhui: { audio: 2, trigger: { player: "phaseJieshuBegin" }, - direct: true, - content() { - "step 0"; - player.chooseTarget(get.prompt("juanhui"), lib.filter.notMe, "选择记录一名其他角色使用过的牌").set("ai", function (target) { - if (target.isTurnedOver() || target.hasJudge("lebu")) { - return Math.random(); - } - return (1 + target.countCards("h")) * 2 + Math.random(); - }); - "step 1"; - if (result.bool) { - var target = result.targets[0]; - player.logSkill("juanhui", target); - player.storage.juanhui2 = target; - player.storage.juanhui3 = []; - player.addSkill("juanhui2"); - } + async cost(event, trigger, player) { + event.result = await player + .chooseTarget(get.prompt("juanhui"), lib.filter.notMe, "选择记录一名其他角色使用过的牌") + .set("ai", function (target) { + if (target.isTurnedOver() || target.hasJudge("lebu")) { + return Math.random(); + } + return (1 + target.countCards("h")) * 2 + Math.random(); + }) + .forResult(); + }, + async content(event, trigger, player) { + const [target] = event.targets; + player.storage.juanhui2 = target; + player.storage.juanhui3 = []; + player.addSkill("juanhui2"); }, }, juanhui2: { @@ -11272,12 +11159,12 @@ const skills = { }).length == 0 ); }, - content() { + async content(event, trigger, player) { if (trigger.name == "phaseUse") { player.removeSkill("juanhui2"); } else if (event.triggername == "useCardAfter") { - player.recover(); - player.drawTo(3); + await player.recover(); + await player.drawTo(3); } else { var vcard = [get.type(trigger.card), "", trigger.card.name]; if (game.hasNature(trigger.card)) { diff --git a/noname/library/element/card.js b/noname/library/element/card.js index 25ff03bded..65a1edd80b 100644 --- a/noname/library/element/card.js +++ b/noname/library/element/card.js @@ -518,7 +518,7 @@ export class Card extends HTMLDivElement { delete this.node.avatar; delete this.node.framebg; } - if (info.noname && !this.classList.contains("button")) { + if (info.noname) { this.node.name.style.display = "none"; } if (info.color) { diff --git a/noname/library/element/content.js b/noname/library/element/content.js index eb1ff2943f..bba909df7a 100644 --- a/noname/library/element/content.js +++ b/noname/library/element/content.js @@ -1998,7 +1998,7 @@ player.removeVirtualEquip(card); } }; - var updateSelectAllButtons = function() { + var updateSelectAllButtons = function () { const buttons = Array.from(event.dialog.querySelectorAll(".select-all")); for (const button of buttons) { @@ -2009,11 +2009,11 @@ player.removeVirtualEquip(card); /** * 移除所有符合条件的选中按钮 - * - * @param { ((button: HTMLDivElement) => boolean)? } filter + * + * @param { ((button: HTMLDivElement) => boolean)? } filter */ var clearSelected = function (filter) { - for(let i = ui.selected.buttons.length; i--; ) { + for (let i = ui.selected.buttons.length; i--; ) { const button = ui.selected.buttons[i]; if (!filter || filter(button)) { @@ -2028,8 +2028,8 @@ player.removeVirtualEquip(card); /** * 选中所有传入的按钮 * 只能多选相同容器的按钮 - * - * @param { HTMLDivElement[] } button + * + * @param { HTMLDivElement[] } button */ var selectButtons = function (...buttons) { if (!buttons.length) { @@ -2050,11 +2050,11 @@ player.removeVirtualEquip(card); /** * 切换按钮的选中状态 - * - * @param {HTMLElement} button + * + * @param {HTMLElement} button * @returns {boolean} */ - var toggleButton = function(button) { + var toggleButton = function (button) { const nextState = !button.classList.contains("glow2"); if (!nextState) { @@ -2070,8 +2070,8 @@ player.removeVirtualEquip(card); /** * 反转容器中所有按钮的选择状态 - * - * @param { HTMLDivElement } container + * + * @param { HTMLDivElement } container */ var revertSelection = function (container) { const selecteds = new Set(ui.selected.buttons.filter(button => button.parentElement === container)); @@ -2225,7 +2225,7 @@ player.removeVirtualEquip(card); } const isDragging = ui.selected.buttons.length === 1 && document.contains(ui.selected.buttons[0]?.copy); - + buttonss.forEach(btn => { Array.from(btn.children).forEach(element => { if (element.copy && ui.window.contains(element.copy)) { @@ -2298,7 +2298,7 @@ player.removeVirtualEquip(card); const buttons2 = curCard.parentElement; const pos1 = card.nextElementSibling || "last"; const pos2 = curCard.nextElementSibling || "last"; - + // 执行动画喵 aniamtionPromise = game.$elementSwap(curCard, card); } @@ -9381,7 +9381,7 @@ player.removeVirtualEquip(card); } }, async (event, trigger, player) => { - let { cards, card, targets, num } = event; + let { cards, card, targets, num, target } = event; if (event.all_excluded) { return; } @@ -11466,7 +11466,305 @@ player.removeVirtualEquip(card); player.die(event.reason); } }, - die: function () { + die: [ + async (event, trigger, player) => { + const { reason, source, restMap } = event; + event.forceDie = true; + //判断当前事件是否是休整(同时确保各个参数的合法性) + event.reserveOut = ["phase", "round"].includes(restMap.type) && typeof restMap.count == "number"; + //只有真正死亡才会影响每轮起始的角色(注意:不是每个模式都有这个属性,只有个别几个模式有,身份22斗地主都是判断的onround来决定是否进入下一轮) + if (_status.roundStart == player && !event.reserveOut) { + _status.roundStart = player.next || player.getNext() || game.players[0]; + } + if (ui.land && ui.land.player == player) { + game.addVideo("destroyLand"); + ui.land.destroy(); + } + //因为隐匿等原因看不到武将牌的需要展示出来 + let unseen = false; + if (player.classList.contains("unseen")) { + player.classList.remove("unseen"); + unseen = true; + } + //加载侧边的历史记录烂关于这次死亡事件的信息 + const logvid = game.logv(player, "die", source); + event.logvid = logvid; + if (unseen) { + player.classList.add("unseen"); + } + if (source) { + game.log(player, "被", source, "杀害"); + if (source.stat[source.stat.length - 1].kill == undefined) { + source.stat[source.stat.length - 1].kill = 1; + } else { + source.stat[source.stat.length - 1].kill++; + } + } else { + game.log(player, "阵亡"); + } + + /*player.removeEquipTrigger(); + for (const i in lib.skill.globalmap) { + if (lib.skill.globalmap[i].includes(player)) { + lib.skill.globalmap[i].remove(player); + if (lib.skill.globalmap[i].length == 0 && !lib.skill[i].globalFixed) { + game.removeGlobalSkill(i); + } + } + }*/ + //休整的流程 + if (event.reserveOut) { + if (player.isIn() && !_status._rest_return?.[player.playerid]) { + game.log(player, "进入了修整状态"); + game.log(player, "移出了游戏"); + //game.addGlobalSkill('_rest_return'); + _status._rest_return ??= {}; + _status._rest_return[player.playerid] = { + type: restMap.type, + count: restMap.count, + }; + } else { + event.finish(); + } + } + //正常死亡流程 + if (!event.reserveOut) { + game.broadcastAll(function (player) { + player.classList.add("dead"); + player.removeLink(); + player.classList.remove("turnedover"); + player.classList.remove("out"); + player.node.count.innerHTML = "0"; + player.node.hp.hide(); + player.node.equips.hide(); + player.node.count.hide(); + player.previous.next = player.next; + player.next.previous = player.previous; + game.players.remove(player); + game.dead.push(player); + _status.dying.remove(player); + }, player); + } + + //播放阵亡语音或特殊的休整语音(沟槽的十常侍),休整语音也请放到跟死亡语音一起 + if (typeof restMap.audio == "string") { + game.broadcastAll(function (audio) { + if (lib.config.background_speak) { + game.playAudio("die", audio); + } + }, restMap.audio); + } else if (!event.noDieAudio) { + game.tryDieAudio(player); + } + //添加死亡动画(包括录像的) + if (!event.reserveOut) { + game.addVideo("diex", player); + if (event.animate !== false) { + player.$die(source); + } + } + //将体力值修改为0 + if (!game.countPlayer()) { + game.over(); + } else if (player.hp != 0) { + await player.changeHp(0 - player.hp, false).set("forceDie", true); + } + //休整时解除连环和翻面状态 + if (event.reserveOut) { + game.broadcastAll(function (player) { + if (player.isLinked()) { + if (get.is.linked2(player)) { + player.classList.toggle("linked2"); + } else { + player.classList.toggle("linked"); + } + } + if (player.isTurnedOver()) { + player.classList.toggle("turnedover"); + } + }, player); + game.addVideo("link", player, player.isLinked()); + game.addVideo("turnOver", player, player.classList.contains("turnedover")); + } + }, + async (event, trigger, player) => { + const { source, restMap } = event; + //休整不执行展示身份牌和击杀奖惩的操作 + if (player.dieAfter && !event.reserveOut) { + player.dieAfter(source); + } + }, + async (event, trigger, player) => { + if (!event.reserveOut) { + game.callHook("checkDie", [event, player]); + } + await event.trigger("die"); + }, + async (event, trigger, player) => { + const { reason, source, restMap } = event; + if (player.isDead() || event.reserveOut) { + //死亡移除武将牌的标记显示,有些不想移除的可以放进excludeMark排除(比如十常侍的常侍标记) + if (!game.reserveDead) { + const exclude = event.excludeMark; + for (const mark in player.marks) { + if (exclude.includes(mark)) { + continue; + } + player.unmarkSkill(mark); + } + let count = 1; + const list = Array.from(player.node.marks.childNodes); + count += exclude.filter(name => list.some(i => i.name == name)).length; + const func = function (player, count, exclude) { + while (player.node.marks.childNodes.length > count) { + let node = player.node.marks.lastChild; + if (exclude.includes(node.name)) { + node = node.previousSibling; + } + node.remove(); + } + }; + func(player, count, exclude); + game.broadcast( + function (func, player, count, exclude) { + func(player, count, exclude); + }, + func, + player, + count, + exclude + ); + player.removeTip(); + } + //移除临时技能 + for (const i in player.tempSkills) { + player.removeSkill(i); + } + const skills = player.getSkills(); + for (let i = 0; i < skills.length; i++) { + if (lib.skill[skills[i]].temp) { + player.removeSkill(skills[i]); + } + } + //武将牌返回武将牌堆 + if (_status.characterlist && !event.reserveOut) { + if (lib.character[player.name] && !player.name.startsWith("gz_shibing") && !player.name.startsWith("gz_jun_")) { + _status.characterlist.add(player.name); + } + if (lib.character[player.name1] && !player.name1.startsWith("gz_shibing") && !player.name1.startsWith("gz_jun_")) { + _status.characterlist.add(player.name1); + } + if (lib.character[player.name2] && !player.name2.startsWith("gz_shibing") && !player.name2.startsWith("gz_jun_")) { + _status.characterlist.add(player.name2); + } + } + //死亡弃置所有牌包括s和x区域的 + event.cards = player.getCards("hejsx"); + if (event.cards.length) { + await player.discard(event.cards).set("forceDie", true); + //player.$throw(event.cards,1000); + } + } + }, + async (event, trigger, player) => { + const { source, restMap } = event; + //休整不执行展示身份牌和击杀奖惩的操作 + if (player.dieAfter2 && !event.reserveOut) { + player.dieAfter2(source); + } + }, + async (event, trigger, player) => { + const { reason, source, restMap } = event; + if (!event.reserveOut) { + //真正的死亡才会显示再战那些按钮,以及隐藏一些按钮什么的 + game.broadcastAll(function (player) { + if (game.online && player == game.me && !_status.over && !game.controlOver && !ui.exit) { + if (lib.mode[lib.configOL.mode].config.dierestart) { + ui.create.exit(); + } + } + }, player); + if (!_status.connectMode && player == game.me && !_status.over && !game.controlOver) { + ui.control.show(); + if (get.config("revive") && lib.mode[lib.config.mode].config.revive && !ui.revive) { + ui.revive = ui.create.control("revive", ui.click.dierevive); + } + if (get.config("continue_game") && !ui.continue_game && lib.mode[lib.config.mode].config.continue_game && !_status.brawl && !game.no_continue_game) { + ui.continue_game = ui.create.control("再战", game.reloadCurrent); + } + if (get.config("dierestart") && lib.mode[lib.config.mode].config.dierestart && !ui.restart) { + ui.restart = ui.create.control("restart", game.reload); + } + } + + if (!_status.connectMode && player == game.me && !game.modeSwapPlayer) { + // _status.auto=false; + if (ui.auto) { + // ui.auto.classList.remove('glow'); + ui.auto.hide(); + } + if (ui.wuxie) { + ui.wuxie.hide(); + } + } + + if (typeof _status.coin == "number" && source && !_status.auto) { + if (source == game.me || source.isUnderControl()) { + _status.coin += 10; + } + } + } else { + //休整时将角色移出游戏 + game.broadcastAll(function (player) { + player.classList.add("out"); + }, player); + await event.trigger("rest"); + } + if (source && lib.config.border_style == "auto" && (lib.config.autoborder_count == "kill" || lib.config.autoborder_count == "mix")) { + switch (source.node.framebg.dataset.auto) { + case "gold": + case "silver": + source.node.framebg.dataset.auto = "gold"; + break; + case "bronze": + source.node.framebg.dataset.auto = "silver"; + break; + default: + source.node.framebg.dataset.auto = lib.config.autoborder_start || "bronze"; + } + if (lib.config.autoborder_count == "kill") { + source.node.framebg.dataset.decoration = source.node.framebg.dataset.auto; + } else { + let dnum = 0; + for (let j = 0; j < source.stat.length; j++) { + if (source.stat[j].damage != undefined) { + dnum += source.stat[j].damage; + } + } + source.node.framebg.dataset.decoration = ""; + switch (source.node.framebg.dataset.auto) { + case "bronze": + if (dnum >= 4) { + source.node.framebg.dataset.decoration = "bronze"; + } + break; + case "silver": + if (dnum >= 8) { + source.node.framebg.dataset.decoration = "silver"; + } + break; + case "gold": + if (dnum >= 12) { + source.node.framebg.dataset.decoration = "gold"; + } + break; + } + } + source.classList.add("topcount"); + } + }, + ], + die_old: function () { "step 0"; event.forceDie = true; if (_status.roundStart == player) { @@ -11497,16 +11795,16 @@ player.removeVirtualEquip(card); game.log(player, "阵亡"); } - // player.removeEquipTrigger(); + /*player.removeEquipTrigger(); + for (var i in lib.skill.globalmap) { + if (lib.skill.globalmap[i].includes(player)) { + lib.skill.globalmap[i].remove(player); + if (lib.skill.globalmap[i].length == 0 && !lib.skill[i].globalFixed) { + game.removeGlobalSkill(i); + } + } + }*/ - // for(var i in lib.skill.globalmap){ - // if(lib.skill.globalmap[i].includes(player)){ - // lib.skill.globalmap[i].remove(player); - // if(lib.skill.globalmap[i].length==0&&!lib.skill[i].globalFixed){ - // game.removeGlobalSkill(i); - // } - // } - // } game.broadcastAll(function (player) { player.classList.add("dead"); player.removeLink(); diff --git a/noname/library/element/player.js b/noname/library/element/player.js index 06ad81f199..e0db21e17e 100644 --- a/noname/library/element/player.js +++ b/noname/library/element/player.js @@ -8126,17 +8126,20 @@ export class Player extends HTMLDivElement { return next; } /** - * 令玩家死亡 - * @param { GameEvent | GameEventPromise } reason + * 令玩家死亡或进入休整状态 + * @param { GameEvent | GameEventPromise } reason 导致角色死亡的事件 + * @param { Boolean } restMap 进入休整状态状态相关的参数(type是休整的计数方式,"round"代表在你的回合开始前才计数,"phase"是每回合都计数;count是休整多少轮或者多少回合;audio是休整播放的语音) * @returns { GameEventPromise } */ - die(reason) { + die(reason, restMap = { type: null, count: null, audio: null }) { var next = game.createEvent("die"); next.player = this; next.reason = reason; + next.restMap = restMap; if (reason) { next.source = reason.source; } + next.excludeMark = []; next.setContent("die"); return next; } diff --git a/noname/library/index.js b/noname/library/index.js index d3d6bed73c..711d070730 100644 --- a/noname/library/index.js +++ b/noname/library/index.js @@ -10415,6 +10415,7 @@ export class Library { fengyin: "封印", baiban: "白板", _disableJudge: "判定区", + _rest_return: "休整", xiaowu_emotion: "小无表情", wanglang_emotion: "王朗表情", @@ -13484,6 +13485,48 @@ export class Library { } }, }, + //休整 + _rest_return: { + trigger: { global: "phaseBefore" }, + forced: true, + charlotte: true, + silent: true, + forceDie: true, + forceOut: true, + filter(event, player) { + const map = _status._rest_return?.[player.playerid]; + if (map?.count < 0) { + return false; + } + if (map?.type == "round" && event.player != player) { + return false; + } + return !event._rest_return && player.isOut(); + }, + async content(event, trigger, player) { + const map = _status._rest_return?.[player.playerid]; + if (map?.count > 0) { + game.broadcastAll(map => { + map.count--; + }, map); + } + trigger._rest_return = true; + if (!map.count) { + //trigger._rest_return = true; + game.broadcastAll(function (player) { + player.classList.remove("out"); + }, player); + game.log(player, "移回了游戏"); + delete _status._rest_return[player.playerid]; + await player.recoverTo(player.maxHp); + //生成restEnd时机 + const next = game.createEvent("restEnd", false); + next.setContent("emptyEvent"); + next.player = player; + await next; + } + }, + }, /** * @deprecated */