commit
a012a0aca6
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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"],
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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 = [];
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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) =>
|
||||
|
|
Loading…
Reference in New Issue