From d94dd77fb880dba813c8a4a201baa39bfb6c27ec Mon Sep 17 00:00:00 2001 From: firebingo Date: Sun, 13 May 2018 17:51:31 -0700 Subject: [PATCH] Slight rework of translations system to add character name translations. --- Css/main.css | 2 +- Js/Main.js | 53 ++++++++------ Js/Player.js | 14 ++-- Js/Translations/nametranslations_eng.json | 89 +++++++++++++++++++++++ Js/Translations/nametranslations_jpn.json | 89 +++++++++++++++++++++++ Js/UtageParse.js | 58 ++++++++++++--- gulpfile.js | 10 +++ 7 files changed, 275 insertions(+), 40 deletions(-) create mode 100644 Js/Translations/nametranslations_eng.json create mode 100644 Js/Translations/nametranslations_jpn.json diff --git a/Css/main.css b/Css/main.css index f1f3c79..e61d316 100644 --- a/Css/main.css +++ b/Css/main.css @@ -74,7 +74,7 @@ #dialog-box { color: white; font-weight: bold; text-shadow: 1px 1px 6px black; transition: opacity 0.1s; } -#dialog-box #character { position: absolute; top: -5px; left: 70px; font-size: 30px; cursor: default; user-select: none; } +#dialog-box #character { position: absolute; left: 70px; font-size: 30px; cursor: default; user-select: none; } #dialog-box #dialog { overflow: hidden; position: absolute; padding: 0 30px 0 70px; margin-top: 60px; box-sizing: border-box; height: 120px; width: 100%; font-size: 28px; font-weight: normal; line-height: 68px; } diff --git a/Js/Main.js b/Js/Main.js index 22bf300..649123d 100644 --- a/Js/Main.js +++ b/Js/Main.js @@ -69,26 +69,31 @@ function onAllLoaded(success) { } function loadLocalStorage() { - //audio - volume = localStorage.getItem('volume') || 0.5; - volume = Number(volume); - document.getElementById('volume-range').value = volume * 100; - isMuted = localStorage.getItem('ismuted') || false; - if(isMuted === "false") { isMuted = false; } - else if(isMuted === "true") { isMuted = true; } - if(audio) { - audio.changeVolume(volume); - audio.mute(isMuted); - } - if(isMuted) { - document.getElementById('mute-button').innerText = "🔇"; - } else { - document.getElementById('mute-button').innerText = "🔊"; - } - //language - let lang = localStorage.getItem('language') || "eng"; - if(languages.includes(lang)) { - selectedLang = lang; + try { + //audio + volume = localStorage.getItem('volume') || 0.5; + volume = Number(volume); + document.getElementById('volume-range').value = volume * 100; + isMuted = localStorage.getItem('ismuted') || false; + if(isMuted === "false") { isMuted = false; } + else if(isMuted === "true") { isMuted = true; } + if(audio) { + audio.changeVolume(volume); + audio.mute(isMuted); + } + if(isMuted) { + document.getElementById('mute-button').innerText = "🔇"; + } else { + document.getElementById('mute-button').innerText = "🔊"; + } + //language + let lang = localStorage.getItem('language') || "eng"; + if(languages.includes(lang)) { + selectedLang = lang; + } + utage.setTranslationLanguage(selectedLang, ''); + } catch(error) { + console.log(error); } } @@ -174,7 +179,7 @@ function missionChanged(value) { currentMission = newMission; let promises = [ utage.parseMissionFile(`${utage.rootDirectory}XDUData/${newMission.Path.replace('Asset/', '').replace('.utage', '').replace('.tsv', '_t.tsv')}`), - utage.loadMissionTranslation(`${utage.rootDirectory}XDUData/${newMission.Path.replace('Asset/', '').replace('.utage', '').replace('.tsv', `_translations_${selectedLang}.json`)}`, selectedLang) + utage.loadMissionTranslation(`${utage.rootDirectory}XDUData/${newMission.Path.replace('Asset/', '').replace('.utage', '').replace('.tsv', `_translations_${selectedLang}.json`)}`) ]; closeMissionModal(undefined, true); @@ -201,7 +206,11 @@ function missionChanged(value) { function languageChanged(event) { if(!event || !event.currentTarget || !event.currentTarget.value || event.currentTarget.value === '{Select}' || !languages.includes(event.currentTarget.value)) { return; } selectedLang = event.currentTarget.value; - utage.loadMissionTranslation(`${utage.rootDirectory}XDUData/${currentMission.Path.replace('Asset/', '').replace('.utage', '').replace('.tsv', `_translations_${selectedLang}.json`)}`, selectedLang); + let missionPath = ''; + if(currentMission) { + missionPath = `${utage.rootDirectory}XDUData/${currentMission.Path.replace('Asset/', '').replace('.utage', '').replace('.tsv', `_translations_${selectedLang}.json`)}`; + } + utage.setTranslationLanguage(selectedLang, missionPath); } function onMainClick(event) { diff --git a/Js/Player.js b/Js/Player.js index 3169c0a..edf704c 100644 --- a/Js/Player.js +++ b/Js/Player.js @@ -443,13 +443,13 @@ class Player { this.lerpTargets.push({type: 'alpha', object: sprite, curTime: 0, time: 300, finalV: 1, initV: 0}); this.lerpTargets.push({type: 'alpha', object: sprite, curTime: -(this.waitTime+500), time: 300, finalV: 0, initV: 1, post: "destroy"}); } catch (error) { } - let text = cur.English ? (utage.currentTranslation[cur.English] || cur.Text) : cur.Text; + let text = cur.English ? (utage.translations[cur.English] || cur.Text) : cur.Text; this.text.titleText(true, text); break; } case "divaeffect": { this.waitTime = Number(cur.Arg5) * 1000; - let text = cur.English ? (utage.currentTranslation[cur.English] || cur.Text) : cur.Text; + let text = cur.English ? (utage.translations[cur.English] || cur.Text) : cur.Text; this.text.divaText(true, text); break; } @@ -933,10 +933,10 @@ class Player { } if(!cur.Command && cur.Arg1 && cur.Text) { //If its chracter off screen text - let text = cur.English ? (utage.currentTranslation[cur.English] || cur.Text) : cur.Text; + let text = cur.English ? (utage.translations[cur.English] || cur.Text) : cur.Text; text = commonFunctions.convertUtageTextTags(text); if(cur.Arg2 && cur.Arg2.toLowerCase() === "") { - this.text.characterName(true, cur.Arg1); + this.text.characterName(true, utage.charTranslations[cur.Arg1] || cur.Arg1); this.text.dialogText(true, commonFunctions.convertUtageTextTags(text)); } else { let charName = ""; @@ -946,7 +946,7 @@ class Player { for(let c of Object.keys(this.currentCharacters)) { if(!this.currentCharacters[c]) { continue; } if(this.currentCharacters[c].charName === cur.Arg1) { - this.text.characterName(true, this.currentCharacters[c].character.NameText); + this.text.characterName(true, utage.charTranslations[this.currentCharacters[c].character.NameText] || this.currentCharacters[c].character.NameText); this.text.dialogText(true, text); this.currentCharacters[c].sprite.tint = 0xFFFFFF; found = true; @@ -959,14 +959,14 @@ class Player { } //If we didnt find the character just dump the text anyways with Arg1 as the name if(!found) { - this.text.characterName(true, cur.Arg1); + this.text.characterName(true, utage.charTranslations[cur.Arg1] || cur.Arg1); this.text.dialogText(true, text); } } this.manualNext = true; //Sometimes they don't give a Arg1 for the text. } else if(!cur.Command && cur.Arg2.toLowerCase() === "" && cur.Text) { - let text = cur.English ? (utage.currentTranslation[cur.English] || cur.Text) : cur.Text; + let text = cur.English ? (utage.translations[cur.English] || cur.Text) : cur.Text; this.text.characterName(true, ""); this.text.dialogText(true, commonFunctions.convertUtageTextTags(text)); this.manualNext = true; diff --git a/Js/Translations/nametranslations_eng.json b/Js/Translations/nametranslations_eng.json new file mode 100644 index 0000000..64afa32 --- /dev/null +++ b/Js/Translations/nametranslations_eng.json @@ -0,0 +1,89 @@ +{ + "黙示録の赤き竜": "", + "黒服": "", + "魔物": "", + "騎士": "", + "駅構内アナウンス": "", + "風鳴翼(ダミー)": "Tsubasa (Dummy)", + "風鳴翼": "Tsubasa", + "風鳴弦十郎": "", + "雪音クリス(ダミー)": "Chris (Dummy)", + "雪音クリス&暁切歌": "Chris & Kirika", + "雪音クリス": "Chris", + "錬金術師": "", + "野次馬": "", + "観客": "", + "藤尭朔也&友里あおい": "", + "藤尭朔也": "", + "緒川慎次": "", + "立花響(ダミー)": "Hibiki (Dummy)", + "立花響&雪音クリス": "Hibiki & Chris", + "立花響": "Hibiki", + "立花洸": "", + "男性": "", + "特殊部隊隊員": "", + "海賊(ダミー)": "", + "櫻井了子": "", + "板場弓美": "", + "月読調(ダミー)": "Shirabe (Dummy)", + "月読調&暁切歌": "Shirabe & Kirika", + "月読調": "Shirabe", + "暁切歌(ダミー)": "Kirika (Dummy)", + "暁切歌&月読調": "Kirika & Shirabe", + "暁切歌": "Kirika", + "振袖の妖怪": "", + "巨大バルーン": "", + "小日向未来": "Miku", + "寺島詩織": "", + "宮司(ダミー)": "", + "安藤創世&寺島詩織&板場弓美": "", + "安藤創世&寺島詩織": "", + "安藤創世": "", + "天羽奏": "", + "友里あおい": "", + "偽マリア": "", + "偽ナスターシャ": "", + "人魂妖怪": "", + "乗組員": "", + "一角の碧の獅子": "", + "ローブの男": "", + "レイア": "", + "ミカ": "", + "マリア(ダミー)": "Maria (Dummy)", + "マリア": "Maria", + "プレラーティ(ダミー)": "", + "プレラーティ": "", + "ブラックバート(ダミー)": "", + "ブラックバート": "", + "フィーネ(ダミー)": "", + "フィーネ": "", + "ファラ": "", + "バルーン": "", + "パヴァリア光明結社のマーク": "", + "ノイズ": "", + "ネフィリム": "", + "ナスターシャ": "", + "ドラゴン": "", + "ティキ(ダミー)": "", + "ツタンカーメンのマスク": "", + "ソーニャ(ダミー)": "", + "セレナ": "", + "ステファン(ダミー)": "", + "サンジェルマン(ダミー)": "", + "サンジェルマン": "", + "ゴライアス": "", + "キャロル": "", + "カリオストロ(ダミー)": "", + "カリオストロ": "", + "ガリィ": "", + "カースドファラオ": "", + "おばあさん(ダミー)": "", + "エルフナイン": "", + "ウェル博士": "", + "ウェイター": "", + "アンティキティラの歯車": "", + "アドルフ博士": "", + "アダム(ダミー)": "", + "F.I.S.司令官": "", + "???": "" +} \ No newline at end of file diff --git a/Js/Translations/nametranslations_jpn.json b/Js/Translations/nametranslations_jpn.json new file mode 100644 index 0000000..0d18889 --- /dev/null +++ b/Js/Translations/nametranslations_jpn.json @@ -0,0 +1,89 @@ +{ + "黙示録の赤き竜": "黙示録の赤き竜", + "黒服": "黒服", + "魔物": "魔物", + "騎士": "騎士", + "駅構内アナウンス": "駅構内アナウンス", + "風鳴翼(ダミー)": "風鳴翼(ダミー)", + "風鳴翼": "風鳴翼", + "風鳴弦十郎": "風鳴弦十郎", + "雪音クリス(ダミー)": "雪音クリス(ダミー)", + "雪音クリス&暁切歌": "雪音クリス&暁切歌", + "雪音クリス": "雪音クリス", + "錬金術師": "錬金術師", + "野次馬": "野次馬", + "観客": "観客", + "藤尭朔也&友里あおい": "藤尭朔也&友里あおい", + "藤尭朔也": "藤尭朔也", + "緒川慎次": "緒川慎次", + "立花響(ダミー)": "立花響(ダミー)", + "立花響&雪音クリス": "立花響&雪音クリス", + "立花響": "立花響", + "立花洸": "立花洸", + "男性": "男性", + "特殊部隊隊員": "特殊部隊隊員", + "海賊(ダミー)": "海賊(ダミー)", + "櫻井了子": "櫻井了子", + "板場弓美": "板場弓美", + "月読調(ダミー)": "月読調(ダミー)", + "月読調&暁切歌": "月読調&暁切歌", + "月読調": "月読調", + "暁切歌(ダミー)": "暁切歌(ダミー)", + "暁切歌&月読調": "暁切歌&月読調", + "暁切歌": "暁切歌", + "振袖の妖怪": "振袖の妖怪", + "巨大バルーン": "巨大バルーン", + "小日向未来": "小日向未来", + "寺島詩織": "寺島詩織", + "宮司(ダミー)": "宮司(ダミー)", + "安藤創世&寺島詩織&板場弓美": "安藤創世&寺島詩織&板場弓美", + "安藤創世&寺島詩織": "安藤創世&寺島詩織", + "安藤創世": "安藤創世", + "天羽奏": "天羽奏", + "友里あおい": "友里あおい", + "偽マリア": "偽マリア", + "偽ナスターシャ": "偽ナスターシャ", + "人魂妖怪": "人魂妖怪", + "乗組員": "乗組員", + "一角の碧の獅子": "一角の碧の獅子", + "ローブの男": "ローブの男", + "レイア": "レイア", + "ミカ": "ミカ", + "マリア(ダミー)": "マリア(ダミー)", + "マリア": "マリア", + "プレラーティ(ダミー)": "プレラーティ(ダミー)", + "プレラーティ": "プレラーティ", + "ブラックバート(ダミー)": "ブラックバート(ダミー)", + "ブラックバート": "ブラックバート", + "フィーネ(ダミー)": "フィーネ(ダミー)", + "フィーネ": "フィーネ", + "ファラ": "ファラ", + "バルーン": "バルーン", + "パヴァリア光明結社のマーク": "パヴァリア光明結社のマーク", + "ノイズ": "ノイズ", + "ネフィリム": "ネフィリム", + "ナスターシャ": "ナスターシャ", + "ドラゴン": "ドラゴン", + "ティキ(ダミー)": "ティキ(ダミー)", + "ツタンカーメンのマスク": "ツタンカーメンのマスク", + "ソーニャ(ダミー)": "ソーニャ(ダミー)", + "セレナ": "セレナ", + "ステファン(ダミー)": "ステファン(ダミー)", + "サンジェルマン(ダミー)": "サンジェルマン(ダミー)", + "サンジェルマン": "サンジェルマン", + "ゴライアス": "ゴライアス", + "キャロル": "キャロル", + "カリオストロ(ダミー)": "カリオストロ(ダミー)", + "カリオストロ": "カリオストロ", + "ガリィ": "ガリィ", + "カースドファラオ": "カースドファラオ", + "おばあさん(ダミー)": "おばあさん(ダミー)", + "エルフナイン": "エルフナイン", + "ウェル博士": "ウェル博士", + "ウェイター": "ウェイター", + "アンティキティラの歯車": "アンティキティラの歯車", + "アドルフ博士": "アドルフ博士", + "アダム(ダミー)": "アダム(ダミー)", + "F.I.S.司令官": "F.I.S.司令官", + "???": "???" +} \ No newline at end of file diff --git a/Js/UtageParse.js b/Js/UtageParse.js index 4ae4340..23f4256 100644 --- a/Js/UtageParse.js +++ b/Js/UtageParse.js @@ -13,8 +13,9 @@ class UtageInfo { this.paramInfo = {}; this.soundInfo = {}; this.textureInfo = {}; - this.translations = {}; - this.currentTranslation = {}; + this.translationsInner = {}; + this.currentTranslation = 'eng'; + this.charTranslationsInner = {}; this.bgmLoopData = {}; } @@ -78,19 +79,57 @@ class UtageInfo { }); } - loadMissionTranslation(file, key) { + get translations() { + return this.translationsInner[this.currentTranslation]; + } + + get charTranslations() { + return this.charTranslationsInner[this.currentTranslation]; + } + + setTranslationLanguage(key, missionPath) { return new Promise((resolve, reject) => { - if(this.translations[key]) { - this.currentTranslation = this.translations[key]; + this.currentTranslation = key; + var promises = [this.loadCharacterTranslations(key)]; + if(missionPath) { + promises.push(this.loadMissionTranslation(missionPath, key)); + } + Promise.all(promises) + .then((success) => { + resolve(); + }, (failure) => { + console.log(failure); + resolve(); + }); + }); + } + + loadMissionTranslation(file) { + return new Promise((resolve, reject) => { + if(this.translationsInner[this.currentTranslation]) { resolve(); } else { commonFunctions.getFileJson(file) .then((success) => { - this.translations[key] = success; - this.currentTranslation = success; + this.translationsInner[this.currentTranslation] = success; + resolve(); + }, (failure) => { + resolve(); + }); + } + }); + } + + loadCharacterTranslations() { + return new Promise((resolve, reject) => { + if(this.charTranslationsInner[this.currentTranslation]) { + resolve(); + } else { + commonFunctions.getFileJson(`${utage.rootDirectory}Js/Translations/nametranslations_${this.currentTranslation}.json`) + .then((success) => { + this.charTranslationsInner[this.currentTranslation] = success; resolve(); }, (failure) => { - this.currentTranslation = {}; resolve(); }); } @@ -248,7 +287,6 @@ class UtageInfo { } resetTranslations() { - this.translations = {}; - this.currentTranslation = {}; + this.translationsInner = {}; } } \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.js index edfd7f8..84c47a1 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -30,6 +30,9 @@ const jsonFiles = [ "Js/BgmLoop.json", "Js/XduMissions.json" ]; +const translations = [ +"Js/Translations/*.json" +]; const jsDest = "Js"; gulp.task('dev', gulp.series( @@ -49,6 +52,7 @@ gulp.task('dist', gulp.series( copyCss ), buildJson, + buildJsonTranslations, copyHtml, copyImages ), @@ -113,3 +117,9 @@ function buildJson() { .pipe(jsonmin()) .pipe(gulp.dest('Dist/Js')); } + +function buildJsonTranslations() { + return gulp.src(translations) + .pipe(jsonmin()) + .pipe(gulp.dest('Dist/Js/Translations')); +}