修复parseSkillTextMap的去重问题;修复parseSkillTextMap解析blob会增加后缀的问题;修复部分characterPack没有proxy的问题

This commit is contained in:
kuangshen04 2024-05-07 18:47:27 +08:00
parent 7898a1d6ec
commit 5e8d59912c
6 changed files with 76 additions and 62 deletions

View File

@ -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,

View File

@ -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);
}

View File

@ -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"],

View File

@ -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 (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;
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)
);
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;
}

View File

@ -613,7 +613,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 = [];

View File

@ -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) {