From 25f7d9095157680e33e4a8d56a02f02c7434e899 Mon Sep 17 00:00:00 2001 From: louis Date: Fri, 17 May 2019 05:20:02 -0400 Subject: [PATCH] metadata changes and quest selector --- .eslintrc.json | 15 ++- CHANGELOG.md | 3 + Css/main.css | 6 +- CustomData | 2 +- Js/Main.js | 345 ++++++++++++++++++++++++++++++----------------- Js/UtageParse.js | 171 ++++++++++++----------- Player.html | 3 +- 7 files changed, 343 insertions(+), 202 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 840546d..c92e89c 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -6,7 +6,15 @@ "extends": "eslint:recommended", "globals": { "Atomics": "readonly", - "SharedArrayBuffer": "readonly" + "SharedArrayBuffer": "readonly", + "PIXI": "readonly", + "UtageInfo": "readonly", + "TextFunctions": "readonly", + "Player": "readonly", + "Shaders": "readonly", + "baseDimensions": "readonly", + "commonFunctions": "readonly", + "audioController": "readonly" }, "parserOptions": { "ecmaVersion": 2018, @@ -14,7 +22,8 @@ }, "rules": { "no-console": "off", - "no-unused-vars": [2, { "argsIgnorePattern": "^(success|event|resource|delta|reject)$"}], - "no-empty": ["error", { "allowEmptyCatch": true }] + "no-unused-vars": [2, { "vars": "local", "argsIgnorePattern": "^(success|event|resource|delta|reject)$"}], + "no-empty": ["error", { "allowEmptyCatch": true }], + "no-mixed-spaces-and-tabs": "off" } } diff --git a/CHANGELOG.md b/CHANGELOG.md index 3036db2..0ea62eb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,3 +31,6 @@ Fix noise\_disappearance commands Macro support DivaMovie +Changed metadata to include quests +Per-language quest enabling +Sort scenes into quests to reduce clutter diff --git a/Css/main.css b/Css/main.css index ce7cb89..1ce64d2 100644 --- a/Css/main.css +++ b/Css/main.css @@ -122,9 +122,11 @@ body { margin: 0; height: 100%; } #title-container { padding: 2px 0; } -#other-controls-container { padding-bottom: 4px; display: flex; width: 550px; justify-content: center; align-items: center; z-index: 10; } +#other-controls-container { padding-bottom: 4px; display: flex; width: 100%; justify-content: center; align-items: center; z-index: 10; } -#select-mission { min-width: 0; } +#select-quest { min-width: 0; width: 25% } + +#select-scene { min-width: 0; width: 25% } #select-language { margin-left: 10px; } diff --git a/CustomData b/CustomData index e456427..e92af8f 160000 --- a/CustomData +++ b/CustomData @@ -1 +1 @@ -Subproject commit e45642773aa255babfde41b770ce1e4c78ca5251 +Subproject commit e92af8f0d0c0d4246e44dd0b63508f9e460fe3a8 diff --git a/Js/Main.js b/Js/Main.js index 15036e8..8ce0edb 100644 --- a/Js/Main.js +++ b/Js/Main.js @@ -16,10 +16,11 @@ let bodyLoaded = false; let utageLoaded = false; let languagesLoaded = false; let selectedLang = "eng"; -let currentMission = undefined; -let currentMissionMst = 0; -let currentMissionIndex = 0; -let currentMissionList = []; +let currentScene = {}; +let currentSceneId = ""; +let scenePlaylist = []; +let currentPart = ""; +let partPlaylist = []; let urlParams = {}; let screenw = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); let screenh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); @@ -27,7 +28,8 @@ let screenSizeTimeout = undefined; let isMuted = false; let volume = 0.5; let fullScreen = false; -let prevMission = '{Select}'; +let prevScene = '{Select}'; +let prevQuest = '{Select}'; const emoji = { LoudSound: String.fromCodePoint(0x1f50a), @@ -76,7 +78,8 @@ function onBodyLoaded() { function onAllLoaded(success) { textFunc.findTextElements(); - buildMissionSelectList(); + buildQuestSelectList(); + buildSceneSelectList(); buildLanguageList(); let appContainer = document.getElementById('app-container'); appContainer.appendChild(pixiApp.app.view); @@ -124,27 +127,79 @@ function loadLocalStorage() { } } -function buildMissionSelectList() { - let selectBox = document.getElementById('select-mission'); - selectBox.innerHTML = ''; - for(let i = -1; i < utage.missionsList.length; ++i) { - let opt = document.createElement('option'); - if(i === -1) { +function buildQuestSelectList() { + let questBox = document.getElementById('select-quest'); + questBox.innerHTML = ''; + for (let i = -1; i < utage.questList.length; ++i) { + let opt = document.createElement('option') + if (i === -1) { opt.setAttribute('value', '{Select}'); - opt.innerText = 'Select Mission'; + opt.innerText = 'Select Event'; } else { - let m = utage.missionsList[i]; - if(!Object.keys(utage.groupedMissions[m.MstId].Missions).some((mis) => { return utage.groupedMissions[m.MstId].Missions[mis].Enabled === true })) { + let q = utage.questList[i]; + let cust = q.IsCustom ? 'Custom' : 'Stock'; + let name = q.Name; + let tl_key = utage.questTranslations[cust][q.QuestMstId]; + if (!tl_key) { + console.log("Failed to build quest list: missing translations"); + return; + } + if (!tl_key.Enabled && !utage.quests[cust][q.QuestMstId].Scenes.some((s) => { return utage.sceneTranslations[cust][s].Enabled === true })) { continue; } - opt.setAttribute('value', m.MstId); - let name = m.Name; - if(utage.missionTranslations[m.MstId]) { - name = utage.missionTranslations[m.MstId].Name || name; - } + name = tl_key.Name || name; + opt.setAttribute('value', `${cust}|${q.QuestMstId}`); opt.innerText = name; } - selectBox.appendChild(opt); + questBox.appendChild(opt); + } +} + +function buildSceneSelectList() { + let sceneBox = document.getElementById('select-scene'); + let questBox = document.getElementById('select-quest'); + sceneBox.innerHTML = ''; + + let opt = document.createElement('option'); + opt.setAttribute('value', '{Select}'); + opt.innerText = "Select Scene"; + + if (questBox.value === '{Select}') { + sceneBox.appendChild(opt); + sceneBox.setAttribute("disabled", "true"); + return; + } else { + sceneBox.removeAttribute("disabled"); + } + + let cust = questBox.value.split("|")[0]; + let questMstId = questBox.value.split("|")[1]; + + for (let i = -2; i < utage.quests[cust][questMstId].Scenes.length; ++i) { + let opt = document.createElement('option'); + if (i === -2) { + opt.setAttribute('value', '{Select}'); + opt.innerText = 'Select Scene'; + } else if (i === -1) { + opt.setAttribute('value', '{All}'); + opt.innerText = 'Play All'; + } else { + let questSceneMstId = utage.quests[cust][questMstId].Scenes[i]; + let s = utage.scenes[cust][questSceneMstId]; + opt.setAttribute('value', `${cust}|${questSceneMstId}`); + let name = s.Name; + let tl_key = utage.sceneTranslations[cust][questSceneMstId]; + if (!tl_key) { + console.log("Failed to build scene list: missing translations"); + return; + } + if (!tl_key.Enabled) { + continue; + } + name = tl_key.Name || name; + opt.innerText = name; + } + sceneBox.appendChild(opt); } } @@ -162,29 +217,71 @@ function buildLanguageList() { function checkQueryParameters() { urlParams = commonFunctions.readQueryParameters(); - if(urlParams['mstid'] && urlParams['id'] && utage.groupedMissions[urlParams['mstid']] && utage.groupedMissions[urlParams['mstid']].Missions[urlParams['id']]) { + let cust; + if (urlParams['custom'] && urlParams['custom'] === "1") { + cust = 'Custom'; + } else { + cust = 'Stock'; + } + let playable = (urlParams['questSceneMstId'] && + utage.scenes[cust][urlParams['questSceneMstId']] && + utage.sceneTranslations[cust][urlParams['questSceneMstId']] && + utage.sceneTranslations[cust][urlParams['questSceneMstId']].Enabled); + if(playable) { document.getElementById('play-from-query').style.cssText = "position: fixed; z-index: 15; text-align: center; top: 50%; left: 50%; display: block;"; } } function playFromQuery(event) { - missionChanged(urlParams['mstid'], urlParams['id']); + let cust; + if (urlParams['custom'] && urlParams['custom'] === "1") { + cust = 'Custom'; + } else { + cust = 'Stock'; + } + sceneSet(urlParams['questSceneMstId'], cust); document.getElementById('play-from-query').style.cssText = "display: none;"; } -function missionDropDownChanged(event) { +function questDropDownChanged(event) { + if(!event || !event.currentTarget || !event.currentTarget.value) { return; } + buildSceneSelectList(); +} + +function sceneDropDownChanged(event) { if(!event || !event.currentTarget || !event.currentTarget.value || event.currentTarget.value === '{Select}') { return; } + + if (event.currentTarget.value === '{All}') { + let quest = document.getElementById("select-quest"); + let cust = quest.value.split("|")[0]; + let questMstId = quest.value.split("|")[1]; + let scene = utage.quests[cust][questMstId].Scenes; + resetPlaylist(); + for (const s of scene) { + utage.scenes[cust][s]['QuestSceneMstId'] = s; + scenePlaylist.push(utage.scenes[cust][s]); + } + playNext(); + return; + } + let cont = document.getElementById("modal-container"); - let misId = event.currentTarget.value; - let mis = utage.groupedMissions[misId]; - if(!mis) { console.log(`Mission ${misId} not found`); return; } - let name = mis.Name; - let summary = mis.SummaryText; + + let cust = event.currentTarget.value.split("|")[0]; + let questSceneMstId = event.currentTarget.value.split("|")[1]; + + let scene = utage.scenes[cust][questSceneMstId]; + if(!scene) { console.log(`Scene ${questSceneMstId} not found`); return; } + + let name = scene.Name; + let summary = scene.SummaryText; let credits = ""; - if(utage.missionTranslations[mis.MstId]) { - name = utage.missionTranslations[mis.MstId].Name || name; - summary = utage.missionTranslations[mis.MstId].SummaryText || summary; - credits = utage.missionTranslations[mis.MstId].Credits || credits; + let tl_key = utage.sceneTranslations[cust][questSceneMstId]; + + if(tl_key) { + name = tl_key.Name || name; + summary = tl_key.SummaryText || summary; + credits = tl_key.Credits || credits; } if(!credits) { if(selectedLang === "eng") { @@ -193,15 +290,15 @@ function missionDropDownChanged(event) { credits = "None"; } } + let chapterSelect = '
Chapter Select:
'; cont.innerHTML = ` `; document.getElementById("click-catcher").style.cssText = 'display: flex;'; @@ -226,10 +323,18 @@ function missionDropDownChanged(event) { function closeMissionModal(event, wasStarted) { if(!wasStarted) { - document.getElementById('select-mission').value = prevMission; + document.getElementById('select-scene').value = prevScene; + document.getElementById('select-quest').value = prevQuest; } else { - prevMission = document.getElementById('select-mission').value; + prevScene = document.getElementById('select-scene').value; + prevQuest = document.getElementById('select-quest').value; } + if (prevScene === '{Select}') { + document.getElementById('select-scene').setAttribute("disabled", "true"); + } else { + document.getElementById('select-scene').removeAttribute("disabled"); + } + closeModal(event); } @@ -240,67 +345,82 @@ function closeModal(event) { cont.innerHTML = ''; } -function missionChanged(mstId, value) { - let mst = utage.groupedMissions[mstId]; - let name = mst.Name; - if(utage.missionTranslations[mstId]) { - name = utage.missionTranslations[mstId].Name || name; +function sceneSet(questSceneMstId, cust) { + resetPlaylist(); + let part = document.getElementById('ChapterSelect').value; + utage.scenes[cust][questSceneMstId]['QuestSceneMstId'] = questSceneMstId; + if (part === '{All}') { + scenePlaylist.push(utage.scenes[cust][questSceneMstId]); + } else { + partPlaylist.push(part); + currentScene = utage.scenes[cust][questSceneMstId]; } - if(!value) { - value = document.getElementById("ChapterSelect").value; + + playNext(); +} + +function playNext() { + + if (!partPlaylist.length) { + if (!scenePlaylist.length) { + resetPlaylist(); + return; // we're probably done + } + currentScene = scenePlaylist.shift(); + partPlaylist = currentScene.Parts.slice(); } + + partChanged(partPlaylist.shift()); +} + +function partChanged(part) { + + let cust = currentScene.IsCustom ? 'Custom' : 'Stock'; + let name = currentScene.Name; + let tl_key = utage.sceneTranslations[cust][currentScene.QuestSceneMstId]; + + if(tl_key) { + name = tl_key.Name || name; + } + if(!audio) { audio = new audioController(utage); audio.changeVolume(volume); audio.mute(isMuted); player.audio = audio; } + player.resetAll() .then((success) => { - let newMission = mst.Missions[value]; - checkMissionList(mst.Missions, value); - currentMission = newMission; - currentMissionMst = mstId; - if(!currentMission.Enabled) { - //Check for the next enabled mission. If there are none just reset. - for(let i = currentMissionIndex + 1; i < currentMissionList.length; ++i) { - const mis = mst.Missions[currentMissionList[i]]; - if(mis && mis.Enabled) { - missionChanged(currentMissionMst, mis.Id); - return; - } - } - //If we got through the loop there are no more enabled so just end - resetMissions(); - return; + if (scenePlaylist.length || partPlaylist.length) { + document.getElementById("skip-button").style.cssText = "display: inline-block;"; + } else { + document.getElementById("skip-button").style.cssText = "display: none;"; } let promises = []; - if(newMission.IsCustom) { - promises.push(utage.parseMissionFile(`${utage.rootDirectory}CustomData/${newMission.Path.replace('Asset/', '').replace('.utage', '').replace('.tsv', '_t.tsv')}`)); + if(currentScene.IsCustom) { + promises.push(utage.parseMissionFile(`${utage.rootDirectory}CustomData/Utage/${currentScene.Folder}/Scenario/${part}_t.tsv`)); + promises.push(utage.loadMissionTranslation(`${utage.rootDirectory}Js/Translations/MissionsCustom/${currentScene.Folder}/${part}_translations_${selectedLang}.json`)); } else { - promises.push(utage.parseMissionFile(`${utage.rootDirectory}XDUData/${newMission.Path.replace('Asset/', '').replace('.utage', '').replace('.tsv', '_t.tsv')}`)); + promises.push(utage.parseMissionFile(`${utage.rootDirectory}XDUData/Utage/${currentScene.Folder}/Scenario/${part}_t.tsv`)); + promises.push(utage.loadMissionTranslation(`${utage.rootDirectory}Js/Translations/Missions/${currentScene.Folder}/${part}_translations_${selectedLang}.json`)); } - promises.push(utage.loadMissionTranslation(`${utage.rootDirectory}Js/Translations/Missions/${currentMission.Path.replace('Asset/Utage/', '').replace('Scenario/', '').replace('.utage', '').replace('.tsv', `_translations_${selectedLang}.json`)}`)) closeMissionModal(undefined, true); Promise.all(promises) .then((success) => { - document.getElementById("playing-title").innerText = `${name} (${value})`; + document.getElementById("playing-title").innerText = `${name} (${part})`; document.getElementById("title-tag").innerText = name; + currentPart = part; player.playFile() .then((success) => { - if(currentMissionIndex !== currentMissionList.length - 1) { - missionChanged(currentMissionMst, mst.Missions[currentMissionList[currentMissionIndex+1]].Id); - } else { - player.resetAll(); - resetMissions(); - } + playNext(); }, (failure) => { player.resetAll(); - resetMissions(); + resetPlaylist(); console.log(failure); }); }, (failure) => { - resetMissions(); + resetPlaylist(); console.log(failure); }); }, (failure) => { @@ -312,43 +432,32 @@ function languageChanged(event) { if(!event || !event.currentTarget || !event.currentTarget.value || event.currentTarget.value === '{Select}' || !languages.includes(event.currentTarget.value)) { return; } selectedLang = event.currentTarget.value; let missionPath = ''; - if(currentMission) { - missionPath = `${utage.rootDirectory}Js/Translations/Missions/${currentMission.Path.replace('Asset/Utage/', '').replace('Scenario/', '').replace('.utage', '').replace('.tsv', `_translations_${selectedLang}.json`)}`; + if(currentPart) { + if (currentScene.IsCustom) { + missionPath = `${utage.rootDirectory}Js/Translations/CustomMissions/${currentScene.Folder}/${currentPart}_translations_${selectedLang}.json`; + } else { + missionPath = `${utage.rootDirectory}Js/Translations/Missions/${currentScene.Folder}/${currentPart}_translations_${selectedLang}.json`; + } } utage.setTranslationLanguage(selectedLang, missionPath) .then((success) => { document.getElementById('text-container').className = selectedLang; - buildMissionSelectList(); + buildQuestSelectList(); + buildSceneSelectList(); localStorage.setItem('language', selectedLang); }); } -function checkMissionList(missions, currentvalue) { - currentMissionList = []; - let i = 0; - for(var m of Object.keys(missions)) { - currentMissionList.push(m); - if(m === currentvalue) { - currentMissionIndex = i; - } - ++i; - } - if(currentMissionIndex + 1 === currentMissionList.length) { - document.getElementById("skip-button").style.cssText = "display: none;"; - } else { - document.getElementById("skip-button").style.cssText = "display: inline-block;"; - } -} - -function resetMissions() { - currentMissionIndex = 0; - currentMissionList = []; - currentMission = undefined; - currentMissionMst = 0; +function resetPlaylist() { + currentScene = {}; + scenePlaylist = []; + currentPart = ""; + partPlaylist = []; document.getElementById("skip-button").style.cssText = "display: inline-block;"; document.getElementById("playing-title").innerText = 'None'; document.getElementById("title-tag").innerText = version; - document.getElementById('select-mission').value = '{Select}'; + document.getElementById("select-quest").value = '{Select}'; + buildSceneSelectList(); } function onMainClick(event) { @@ -362,20 +471,10 @@ function hideUiClicked(event) { function skipClicked(event) { if(player.uiHidden) { player.hideUiClicked(event); - } else if(player.runEvent && currentMissionIndex !== currentMissionList.length - 1) { + } else if(player.runEvent) { event.preventDefault(); event.stopPropagation(); - //Find the next enabled mission - for(let i = currentMissionIndex + 1; i < currentMissionList.length; ++i) { - const mis = utage.groupedMissions[currentMissionMst].Missions[currentMissionList[i]]; - if(mis && mis.Enabled) { - //missionChanged(currentMissionMst, utage.groupedMissions[currentMissionMst].Missions[currentMissionList[currentMissionIndex+1]].Id); - missionChanged(currentMissionMst, mis.Id); - return; - } - } - //If we got through the loop there are no more enabled so just end - resetMissions(); + playNext(); } } @@ -421,7 +520,13 @@ function openHelpModal(event) { iOS: 11+, no audio
- YameteTomete Discord + + + + + + +
Follow YameteTomete
DiscordTwitter
All Symphogear content belongs to its respective owners
- + + ?