diff --git a/mode/boss.js b/mode/boss.js index df936e6ea..d971b6481 100644 --- a/mode/boss.js +++ b/mode/boss.js @@ -1437,7 +1437,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) { }, init: function () { for (var i in lib.characterPack.mode_boss) { - if (get.convertedCharacter(lib.characterPack.mode_boss[i]).isHiddenBoss) continue; + if (lib.characterPack.mode_boss[i].isHiddenBoss) continue; lib.mode.boss.config[i + "_boss_config"] = { name: get.translation(i), init: true, diff --git a/mode/single.js b/mode/single.js index 10215e15b..caab69e66 100644 --- a/mode/single.js +++ b/mode/single.js @@ -242,7 +242,14 @@ game.import("mode", function (lib, game, ui, get, ai, _status) { ["spade", 12, "zhangba"], ["spade", 13, "nanman"], ], - characterSingle: { + characterSingle: Object.assign(new Proxy( + {}, + { + set(target, prop, newValue) { + return Reflect.set(target, prop, get.convertedCharacter(newValue)); + }, + } + ), { caocao: ["male", "wei", 4, ["jianxiong"], ["zhu"]], simayi: ["male", "wei", 3, ["fankui", "guicai"]], xiahoudun: ["male", "wei", 4, ["ganglie"]], @@ -300,7 +307,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) { jin_simashi: ["male", "jin", "3/4", ["yimie", "tairan"]], zhanghuyuechen: ["male", "jin", 4, ["xijue"]], duyu: ["male", "jin", 4, ["sanchen", "zhaotao"]], - }, + }), startBefore: function () {}, onreinit: function () { _status.mode = _status.connectMode ? lib.configOL.single_mode : get.config("single_mode"); @@ -349,7 +356,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) { for (var j in singleTranslate) lib.translate[j] = singleTranslate[j]; _status.characterlist = []; for (var i in characterSingle) { - if (!jin && get.convertedCharacter(characterSingle[i]) == "jin") continue; + if (!jin && characterSingle[i].group === "jin") continue; lib.character[i] = characterSingle[i]; _status.characterlist.push(i); } diff --git a/mode/versus.js b/mode/versus.js index 653cedf28..65cdbbe81 100644 --- a/mode/versus.js +++ b/mode/versus.js @@ -752,8 +752,8 @@ game.import("mode", function (lib, game, ui, get, ai, _status) { for (var i in lib.characterPack.boss) { if (!lib.character[i]) { if ( - get.convertedCharacter(lib.characterPack.boss[i]).isJiangeBoss || - get.convertedCharacter(lib.characterPack.boss[i]).isJiangeMech + lib.characterPack.boss[i].isJiangeBoss || + lib.characterPack.boss[i].isJiangeMech ) { lib.character[i] = lib.characterPack.boss[i]; } @@ -4711,7 +4711,14 @@ game.import("mode", function (lib, game, ui, get, ai, _status) { ctx.stroke(); }, }, - jiangeboss: { + jiangeboss: Object.assign(new Proxy( + {}, + { + set(target, prop, newValue) { + return Reflect.set(target, prop, get.convertedCharacter(newValue)); + }, + } + ), { boss_liedixuande: [ "male", "shu", @@ -4874,7 +4881,7 @@ game.import("mode", function (lib, game, ui, get, ai, _status) { ["jiangeboss", "hiddenboss", "bossallowed"], "shu", ], - }, + }), cardsFour: [ ["spade", 7, "sha"], ["spade", 8, "sha"], diff --git a/noname/game/index.js b/noname/game/index.js index 1ad182e66..56ccc0fce 100644 --- a/noname/game/index.js +++ b/noname/game/index.js @@ -1461,12 +1461,7 @@ export class Game { * @returns { string[] } 语音地址列表 */ parseSkillText(skill, player, skillInfo) { - const audios = game.parseSkillTextMap(skill, player, skillInfo); - const voiceMap = []; - audios.forEach(audioname => { - if(audioname.text) voiceMap.push(audioname.text); - }); - return voiceMap; + return game.parseSkillTextMap(skill, player, skillInfo).map(data => data.text).filter(Boolean); } /** * 根据skill中的audio,audioname,audioname2和player来获取技能台词列表及其对应的源文件名 @@ -1486,28 +1481,26 @@ export class Game { if (!history.includes(skill)) return true; if (history[0] === skill) return false; //deadlock - throw new RangeError(`parseSkillAudio: ${skill} in ${history}forms a deadlock`); + throw new RangeError(`parseSkillTextMap: ${skill} in ${history} forms a deadlock`); }; const getName = filter => { const name = (player.tempname || []).find(i => filter(i)); - return ( - name || - [player.name, player.name1, player.name2].reduce((result, name) => { - if (result) return result; - if (!name) return result; - if (filter(name)) return name; - let tempname = (get.character(name).trashBin || []).find(tag => tag.startsWith("tempname:")); - if (!tempname) return result; - tempname = tempname - .split(":") - .slice(1) - .find(i => filter(i)); - return tempname || result; - }, void 0) - ); + if (name) return name; + return [player.name, player.name1, player.name2].reduce((result, name) => { + if (result) return result; + if (!name) return result; + if (filter(name)) return name; + return get.character(name).tempname.find(i => filter(i)) || result; + }, void 0); }; + const getTextMap = (path, name, ext) => ({ + name, + file: `${path}${name}${ext}`, + text: lib.translate[`#${name}`], + }); + function getAudioList(skill, options, skillInfo) { const info = skillInfo || lib.skill[skill]; if (!info) { @@ -1520,7 +1513,6 @@ export class Game { let audioInfo = info.audio; if (Array.isArray(info.audioname)) audioname.addArray(info.audioname); if (info.audioname2) audioInfo = info.audioname2[getName(i => info.audioname2[i])] || audioInfo; - if (typeof audioInfo === "function") audioInfo = audioInfo(player); return parseAudio(skill, options, audioInfo); } @@ -1530,50 +1522,47 @@ export class Game { const history = options.history.slice(); options = { audioname, history }; if (Array.isArray(audioInfo)) { - if (typeof audioInfo[0] === "string" && typeof audioInfo[1] === "number") { - // [audioname, number] - if (checkSkill(audioInfo[0], history)) return getAudioList(audioInfo[0], options).slice(0, audioInfo[1]); - return parseAudio(audioInfo[0], options, audioInfo[1]); + if (audioInfo.length === 2 && typeof audioInfo[0] === "string" && typeof audioInfo[1] === "number") { + const [name, number] = audioInfo; + if (checkSkill(name, history)) return getAudioList(name, options).slice(0, number); + return parseAudio(name, options, number); } - return audioInfo.reduce((total, i) => total.addArray(parseAudio(skill, options, i)), []); + + const map = {}; + audioInfo.forEach((i) => { + parseAudio(skill, options, i).forEach(data => map[data.name] = data); + }); + return Object.values(map); } if (!["string", "number", "boolean"].includes(typeof audioInfo)) return parseAudio(skill, options, [true, 2]); if (audioInfo === false) return []; - if (typeof audioInfo === "string" && checkSkill(audioInfo, history)) return getAudioList(audioInfo, options); - + if (typeof audioInfo === "string") { + if (["data:", "blob:"].some(prefix => audioInfo.startsWith(prefix))) return [getTextMap("", audioInfo, "")]; + if(checkSkill(audioInfo, history)) return getAudioList(audioInfo, options); + } audioInfo = String(audioInfo); - let list = audioInfo.match(/(?:(.*):|^)(true|\d+)(?::(.*)|$)/); // [path, number|true, format] + const list = audioInfo.match(/(?:(.*):|^)(true|\d+)(?::(.*)|$)/); // [path, number|true, ext] if (!list) { - let path = "", - format = ""; + let path = "", ext = ""; if (!/^db:|^ext:|\//.test(audioInfo)) path = "skill/"; - if (!/\.\w+$/.test(audioInfo) && !["data:", "blob:"].some(name => audioInfo.startsWith(name))) format = ".mp3"; - if (path && format) return parseAudio(audioInfo, options, [true, 2]); - - const key = audioInfo, file = `${path}${audioInfo}${format}`; - const data = {key, file}; - if(lib.translate[`#${key}`]) data.text = lib.translate[`#${key}`]; - return [data]; + if (!/\.\w+$/.test(audioInfo)) ext = ".mp3"; + if (path && ext) return parseAudio(audioInfo, options, [true, 2]); + //@TODO + console.warn(`${skill}中“${audioInfo}”的地址写法暂时没有完全支持台词系统。`); + return [getTextMap(path, audioInfo, ext)]; } + let [, path = "skill", audioNum, ext = "mp3"] = list; let _audioname = getName(i => audioname.includes(i)); _audioname = _audioname ? `_${_audioname}` : ""; - if (list[2] === "true") { - const key = `${skill}${_audioname}`, file = `${list[1] || "skill"}/${skill}${_audioname}.${list[3] || "mp3"}`; - const data = {key, file}; - if(lib.translate[`#${key}`]) data.text = lib.translate[`#${key}`]; - return [data]; - } + if (audioNum === "true") return [getTextMap(`${path}/`, `${skill}${_audioname}`, `.${ext}`)]; - const audioList = [] - list[2] = parseInt(list[2]); - for (let i = 1; i <= list[2]; i++) { - const key = `${skill}${_audioname}${i}`, file = `${list[1] || "skill"}/${skill}${_audioname}${i}.${list[3] || "mp3"}`; - const data = {key, file}; - if(lib.translate[`#${key}`]) data.text = lib.translate[`#${key}`]; - audioList.push(data); + const audioList = []; + audioNum = parseInt(audioNum); + for (let i = 1; i <= audioNum; i++) { + audioList.push(getTextMap(`${path}/`, `${skill}${_audioname}${i}`, `.${ext}`)); } return audioList; } diff --git a/noname/get/index.js b/noname/get/index.js index 2c8292102..1cd4539c4 100644 --- a/noname/get/index.js +++ b/noname/get/index.js @@ -596,7 +596,7 @@ export class Get { let info = lib.character[name]; if (!info) { const pack = Object.keys(lib.characterPack).find(pack => name in lib.characterPack[pack]); - if (pack) info = get.convertedCharacter(lib.characterPack[pack][name]); + if (pack) info = lib.characterPack[pack][name]; } if (typeof num === "number") { if (!info) info = []; diff --git a/noname/library/element/character.js b/noname/library/element/character.js index 085de4def..5576d14f0 100644 --- a/noname/library/element/character.js +++ b/noname/library/element/character.js @@ -155,6 +155,11 @@ export class Character { * @type { string[] } **/ initFilters = []; + /** + * 武将牌的“临时名称” + * @type { string[] } + */ + tempname = []; /** * @param { Object|[string, string, string|number, string[], any[]|undefined, any[]|undefined] } [data] */ @@ -197,6 +202,7 @@ export class Character { this.initFilters = []; this.trashBin = []; this.dieAudios = []; + this.tempname = []; } /** * @param { any[] } trash @@ -258,6 +264,8 @@ export class Character { this.dieAudios.push(item.slice(4)); } else if (item.startsWith("die_audio:")){ this.dieAudios = item.slice(10).split(":"); + } else if (item.startsWith("tempname:")) { + this.tempname = item.slice(9).split(":"); } else { keptTrashes.push(item); } @@ -383,6 +391,9 @@ export class Character { if (character.dieAudios.length === 1) trashes.push(`die:${character.dieAudios[0]}`) else trashes.push(`die_audio:${character.dieAudios.join(":")}`); } + if (character.tempname.length > 0) { + trashes.push(`tempname:${character.tempname.join(":")}`); + } return new Proxy(trashes.concat(character.trashBin), { set(target, prop, newValue) { diff --git a/noname/ui/click/index.js b/noname/ui/click/index.js index fec5835d3..c469f35dc 100644 --- a/noname/ui/click/index.js +++ b/noname/ui/click/index.js @@ -3554,17 +3554,15 @@ export class Click { if (characterGroups) Promise.all( characterGroups.map((characterGroup) => - new Promise((resolve, reject) => { + Promise.resolve().then(async () => { const imageName = `group_${characterGroup}`, information = lib.card[imageName]; - if (!information) resolve(`${lib.assetURL}image/card/${imageName}.png`); + if (!information) return `${lib.assetURL}image/card/${imageName}.png`; const image = information.image; - if (!image) resolve(`${lib.assetURL}image/card/${imageName}.png`); - else if (image.startsWith("db:")) - game.getDB("image", image.slice(3)).then(resolve, reject); - else if (image.startsWith("ext:")) - resolve(`${lib.assetURL}${image.replace(/^ext:/, "extension/")}`); - else resolve(`${lib.assetURL}${image}`); + if (!image) return `${lib.assetURL}image/card/${imageName}.png`; + if (image.startsWith("db:")) return await game.getDB("image", image.slice(3)); + if (image.startsWith("ext:")) return `${lib.assetURL}${image.replace(/^ext:/, "extension/")}`; + return `${lib.assetURL}${image}`; }).then( (source) => new Promise((resolve, reject) => { @@ -3589,17 +3587,15 @@ export class Click { ); else { const characterGroup = nameInfo[1]; - new Promise((resolve, reject) => { + Promise.resolve().then(async () => { const imageName = `group_${characterGroup}`, information = lib.card[imageName]; - if (!information) resolve(`${lib.assetURL}image/card/${imageName}.png`); + if (!information) return `${lib.assetURL}image/card/${imageName}.png`; const image = information.image; - if (!image) resolve(`${lib.assetURL}image/card/${imageName}.png`); - else if (image.startsWith("db:")) - game.getDB("image", image.slice(3)).then(resolve, reject); - else if (image.startsWith("ext:")) - resolve(`${lib.assetURL}${image.replace(/^ext:/, "extension/")}`); - else resolve(`${lib.assetURL}${image}`); + if (!image) return `${lib.assetURL}image/card/${imageName}.png`; + if (image.startsWith("db:")) return await game.getDB("image", image.slice(3)); + if (image.startsWith("ext:")) return `${lib.assetURL}${image.replace(/^ext:/, "extension/")}`; + return `${lib.assetURL}${image}`; }) .then( (source) =>