Compare commits
66 Commits
Author | SHA1 | Date | |
---|---|---|---|
62e702b9fa | |||
428ea1d660 | |||
0def56d476 | |||
85f2815b6a | |||
7b43a86b99 | |||
1dc54f8590 | |||
d6ac86ed8c | |||
afd850fbca | |||
bdc076b664 | |||
47e250ba89 | |||
14efed32e3 | |||
90236c665d | |||
89a93407f1 | |||
2ca5a9e704 | |||
c6c9c99c31 | |||
ae90fd1c37 | |||
5ca0935ac6 | |||
0c039b6ed4 | |||
a93978f39d | |||
b6821d4157 | |||
d8a5d4d177 | |||
022250c4c4 | |||
3101868b30 | |||
bb409c45a1 | |||
4716b5e8e8 | |||
9dc0c8f9cf | |||
0d522b55c5 | |||
f289381955 | |||
c1c6cbfd99 | |||
90625d82b6 | |||
5dba520155 | |||
0e9f6f8d70 | |||
8786c54200 | |||
25f7d90951 | |||
526d0a51cc | |||
737b13da42 | |||
269592c3d6 | |||
d4e96c66a8 | |||
effb55871f | |||
77fc6e4d69 | |||
bf11050984 | |||
1d469d4f3e | |||
e3b7233b20 | |||
b9e91f4977 | |||
eec0bb137b | |||
0b3fb01670 | |||
fb9cab573e | |||
f3ddb3e58f | |||
24cbf4b5ad | |||
e098d27964 | |||
dbf530a333 | |||
d233bf77ce | |||
42e37585d6 | |||
9ca49d25cc | |||
01245c4477 | |||
8933ba986a | |||
b98c2d987d | |||
63a21c69d8 | |||
61e5aaca02 | |||
b74cacb148 | |||
7e8eeffe4d | |||
a4676279f3 | |||
63478f494d | |||
0a56a9b11d | |||
e1f09c35b9 | |||
7a50205cd1 |
1
.eslintignore
Normal file
1
.eslintignore
Normal file
@ -0,0 +1 @@
|
||||
Js/Pixi.min.js
|
29
.eslintrc.json
Normal file
29
.eslintrc.json
Normal file
@ -0,0 +1,29 @@
|
||||
{
|
||||
"env": {
|
||||
"browser": true,
|
||||
"es6": true
|
||||
},
|
||||
"extends": "eslint:recommended",
|
||||
"globals": {
|
||||
"Atomics": "readonly",
|
||||
"SharedArrayBuffer": "readonly",
|
||||
"PIXI": "readonly",
|
||||
"UtageInfo": "readonly",
|
||||
"TextFunctions": "readonly",
|
||||
"Player": "readonly",
|
||||
"Shaders": "readonly",
|
||||
"baseDimensions": "readonly",
|
||||
"commonFunctions": "readonly",
|
||||
"audioController": "readonly"
|
||||
},
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2018,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
"no-console": "off",
|
||||
"no-unused-vars": [2, { "vars": "local", "argsIgnorePattern": "^(success|event|resource|delta|reject)$"}],
|
||||
"no-empty": ["error", { "allowEmptyCatch": true }],
|
||||
"no-mixed-spaces-and-tabs": "off"
|
||||
}
|
||||
}
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -3,6 +3,8 @@
|
||||
web.config
|
||||
/Js/Typed
|
||||
/Js/[Pp]ixi.js
|
||||
/Js/[Pp]ixi.js.map
|
||||
/Js/[Pp]ixi.min.js.map
|
||||
/node_modules
|
||||
/Js/XduPlayer.js
|
||||
/Js/XduPlayer.min.js.map
|
||||
@ -10,3 +12,4 @@ web.config
|
||||
/Dist
|
||||
/Css/main.min.css
|
||||
/Js/XduPlayer.min.js
|
||||
/**/.*.swp
|
6
.gitmodules
vendored
6
.gitmodules
vendored
@ -1,8 +1,8 @@
|
||||
[submodule "Js/Translations"]
|
||||
path = Js/Translations
|
||||
url = https://git.poweris.moe/xdutranslations.git
|
||||
branch = .
|
||||
url = https://git.poweris.moe/yttt-xdu/xdutranslations.git
|
||||
branch = master
|
||||
[submodule "CustomData"]
|
||||
path = CustomData
|
||||
url = https://git.poweris.moe/customdata.git
|
||||
url = https://git.poweris.moe/yttt-xdu/customdata.git
|
||||
branch = .
|
||||
|
33
CHANGELOG.md
33
CHANGELOG.md
@ -15,3 +15,36 @@ DPI is now taken into account when resizing.
|
||||
Added credits to mission modal.
|
||||
Added ability to go fullscreen.
|
||||
Missions JSON moved to translations submodule so missions can be added/enabled without disturbing main project.
|
||||
|
||||
## V1.2.1 (2018-12-29)
|
||||
|
||||
Custom asset support
|
||||
Russian language support
|
||||
Fix translation fallback
|
||||
|
||||
## V1.2.2 (2019-01-20)
|
||||
|
||||
Add language url parameter
|
||||
Fix noise\_disappearance commands
|
||||
|
||||
## V1.3.0 (2019-05-13)
|
||||
|
||||
Macro support
|
||||
DivaMovie
|
||||
Changed metadata to include quests
|
||||
Per-language quest enabling
|
||||
Sort scenes into quests to reduce clutter
|
||||
Preserve ColorTo tinting properly
|
||||
urlparam: questSceneMstId
|
||||
|
||||
## V1.3.1 (2019-06-09)
|
||||
|
||||
Fix MoveCamera macro
|
||||
|
||||
## V1.4.0 (2019-09-29)
|
||||
|
||||
Updated Pixi.js to v5
|
||||
|
||||
## V1.5.0 (2020-07-31)
|
||||
|
||||
XDU Global support
|
||||
|
14
Css/main.css
14
Css/main.css
@ -84,6 +84,8 @@ body { margin: 0; height: 100%; }
|
||||
|
||||
#text-container.rus { font-family: 'PTSans'; }
|
||||
|
||||
#text-container.cze { font-family: 'PTSans'; }
|
||||
|
||||
#text-container #fullscreen-button { position: absolute; top: 0.5rem; left: 0.5rem; font-size: 30px; line-height: 30px; opacity: 0.35; z-index: 11; }
|
||||
|
||||
#text-container #title { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; font-size: 20px; transition: opacity 0.3s; cursor: default; user-select: none; }
|
||||
@ -122,9 +124,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; }
|
||||
|
||||
@ -154,6 +158,12 @@ body { margin: 0; height: 100%; }
|
||||
|
||||
#modal-buttons { bottom: 0; margin-top: auto; width: 100%; display: flex; justify-content: space-between; min-height: 21px; }
|
||||
|
||||
#mission-modal .follow-links { margin-top: auto; display: flex; flex-direction: column; text-align: center; width:100%; }
|
||||
|
||||
#mission-modal .follow-links .follow-links-header { font-weight: bold; }
|
||||
|
||||
#mission-modal .follow-links .follow-links-links { display: flex; flex-direction: row; justify-content: space-around; margin-top: 5px; }
|
||||
|
||||
@media screen and (max-width: 812px) {
|
||||
#modal-container { top: 0; bottom: 0; left: 0; right: 0; transform: none; }
|
||||
.modal { width: 100%; height: 100%; border-radius: 0; }
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit e45642773aa255babfde41b770ce1e4c78ca5251
|
||||
Subproject commit e92af8f0d0c0d4246e44dd0b63508f9e460fe3a8
|
@ -1,5 +1,4 @@
|
||||
//(Math.exp(x)-1)/(Math.E-1)
|
||||
//🔊
|
||||
|
||||
class bufferLoader {
|
||||
constructor(context, soundMap, callback) {
|
||||
|
1263
Js/BgmLoop.json
1263
Js/BgmLoop.json
File diff suppressed because it is too large
Load Diff
@ -4,6 +4,11 @@ let rootUrl = `${window.location.protocol}//${window.location.host}/`;
|
||||
const baseDimensions = {width: 1334, height: 750};
|
||||
const screenRatio = 9/16;
|
||||
|
||||
const CUSTOM = {
|
||||
custom: 'Custom',
|
||||
stock: 'Stock'
|
||||
}
|
||||
|
||||
class commonFunctions {
|
||||
static getFileText(file) {
|
||||
return new Promise((resolve, reject) => {
|
||||
@ -334,7 +339,6 @@ class commonFunctions {
|
||||
if(props[i] == " ") { break; }
|
||||
retval.color += props[i];
|
||||
}
|
||||
retval.color = retval.color;
|
||||
}
|
||||
return retval;
|
||||
}
|
||||
|
393
Js/Main.js
393
Js/Main.js
@ -2,7 +2,7 @@
|
||||
|
||||
const pixiApp = {
|
||||
app: new PIXI.Application(baseDimensions),
|
||||
loader: PIXI.loader
|
||||
loader: PIXI.Loader.shared
|
||||
};
|
||||
|
||||
const utage = new UtageInfo();
|
||||
@ -10,16 +10,17 @@ const shaders = new Shaders();
|
||||
const textFunc = new TextFunctions();
|
||||
let audio = undefined; //Cant create a audio context without user input.
|
||||
const player = new Player(pixiApp, utage, textFunc, audio, shaders);
|
||||
const languages = ["eng", "jpn", "rus"];
|
||||
const version = "YameteTomete XDUPlayer V1.2.1";
|
||||
const languages = ["eng", "jpn", "rus", "cze", "enm", "kor", "zho"];
|
||||
const version = "YameteTomete XDUPlayer V1.5.0";
|
||||
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,15 +28,22 @@ 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),
|
||||
Mute: String.fromCodePoint(0x1f507),
|
||||
HeavyPlusSign: String.fromCodePoint(0x2795)
|
||||
};
|
||||
|
||||
function onBodyLoaded() {
|
||||
bodyLoaded = true;
|
||||
document.getElementById("title-tag").innerText = version;
|
||||
document.addEventListener('webkitfullscreenchange', onFullScreenChange, false);
|
||||
document.addEventListener('mozfullscreenchange', onFullScreenChange, false);
|
||||
document.addEventListener('fullscreenchange', onFullScreenChange, false);
|
||||
document.addEventListener('MSFullscreenChange', onFullScreenChange, false);
|
||||
document.addEventListener('mozfullscreenchange', onFullScreenChange, false);
|
||||
document.addEventListener('fullscreenchange', onFullScreenChange, false);
|
||||
document.addEventListener('MSFullscreenChange', onFullScreenChange, false);
|
||||
}
|
||||
|
||||
(function startLoad() {
|
||||
@ -54,6 +62,7 @@ function onBodyLoaded() {
|
||||
(function checkIsLoaded() {
|
||||
if(bodyLoaded) {
|
||||
document.getElementById('loading-font').style.cssText = "display: none;";
|
||||
checkQueryParameters();
|
||||
loadLocalStorage();
|
||||
}
|
||||
if(utageLoaded && languagesLoaded) {
|
||||
@ -69,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);
|
||||
@ -95,12 +105,12 @@ function loadLocalStorage() {
|
||||
audio.mute(isMuted);
|
||||
}
|
||||
if(isMuted) {
|
||||
document.getElementById('mute-button').innerText = "🔇";
|
||||
document.getElementById('mute-button').innerText = emoji.Mute;
|
||||
} else {
|
||||
document.getElementById('mute-button').innerText = "🔊";
|
||||
document.getElementById('mute-button').innerText = emoji.LoudSound;
|
||||
}
|
||||
//language
|
||||
let lang = localStorage.getItem('language') || "eng";
|
||||
let lang = urlParams['lang'] || localStorage.getItem('language') || "eng";
|
||||
if(languages.includes(lang)) {
|
||||
selectedLang = lang;
|
||||
}
|
||||
@ -117,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.custom : 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");
|
||||
continue;
|
||||
}
|
||||
opt.setAttribute('value', m.MstId);
|
||||
let name = m.Name;
|
||||
if(utage.missionTranslations[m.MstId]) {
|
||||
name = utage.missionTranslations[m.MstId].Name || name;
|
||||
if (!tl_key.Enabled && !utage.quests[cust][q.QuestMstId].Scenes.some((s) => { return utage.sceneTranslations[cust][s].Enabled === true })) {
|
||||
continue;
|
||||
}
|
||||
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");
|
||||
continue;
|
||||
}
|
||||
if (!tl_key.Enabled) {
|
||||
continue;
|
||||
}
|
||||
name = tl_key.Name || name;
|
||||
opt.innerText = name;
|
||||
}
|
||||
sceneBox.appendChild(opt);
|
||||
}
|
||||
}
|
||||
|
||||
@ -155,29 +217,85 @@ function buildLanguageList() {
|
||||
|
||||
function checkQueryParameters() {
|
||||
urlParams = commonFunctions.readQueryParameters();
|
||||
if(urlParams['mstid'] && urlParams['id'] && utage.groupedMissions[urlParams['mstid']] && utage.groupedMissions[urlParams['mstid']].Missions[urlParams['id']]) {
|
||||
document.getElementById('play-from-query').style.cssText = "position: fixed; z-index: 15; text-align: center; top: 50%; left: 50%; display: block;";
|
||||
if (languagesLoaded) {
|
||||
let cust;
|
||||
|
||||
if (urlParams['custom'] && urlParams['custom'] === "1") {
|
||||
cust = CUSTOM.custom;
|
||||
} else {
|
||||
cust = CUSTOM.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.custom;
|
||||
} else {
|
||||
cust = CUSTOM.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) {
|
||||
let tl_key = utage.sceneTranslations[cust][s];
|
||||
if (tl_key) {
|
||||
if (utage.sceneTranslations[cust][s].Enabled) {
|
||||
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 image = questSceneMstId;
|
||||
if ("Image" in scene) {
|
||||
image = scene.Image;
|
||||
}
|
||||
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") {
|
||||
@ -186,15 +304,15 @@ function missionDropDownChanged(event) {
|
||||
credits = "None";
|
||||
}
|
||||
}
|
||||
|
||||
let chapterSelect = '<div><span>Chapter Select:</span><select id="ChapterSelect">';
|
||||
for(let k of Object.keys(mis.Missions)) {
|
||||
var m = mis.Missions[k];
|
||||
if(m.Enabled) {
|
||||
chapterSelect += `<option value="${m.Id}">${m.Id}</option>`
|
||||
}
|
||||
chapterSelect += `<option value="{All}">Play All</option>`
|
||||
for (const p of scene.Parts) {
|
||||
chapterSelect += `<option value="${p}">${p}</option>`
|
||||
}
|
||||
let detailSrc = `${utage.rootDirectory}${(mis.IsCustom ? "CustomData" : "XDUData")}/Asset/Image/Quest/Snap/Detail/${mis.MstId}.png`;
|
||||
let iconSrc = `${utage.rootDirectory}${(mis.IsCustom ? "CustomData" : "XDUData")}/Asset/Image/Quest/Snap/Icon/${mis.MstId}.png`;
|
||||
|
||||
let detailSrc = `${utage.rootDirectory}${(scene.IsCustom ? "CustomData" : "XDUData")}/Asset/Image/Quest/Snap/Detail/${image}.png`;
|
||||
let iconSrc = `${utage.rootDirectory}${(scene.IsCustom ? "CustomData" : "XDUData")}/Asset/Image/Quest/Snap/Icon/${image}.png`;
|
||||
chapterSelect += '</select></div>';
|
||||
cont.innerHTML = `
|
||||
<div id="mission-modal" class="modal">
|
||||
@ -209,8 +327,8 @@ function missionDropDownChanged(event) {
|
||||
</div>
|
||||
<div id="modal-buttons">
|
||||
<button onclick="closeMissionModal(event, false)">Close</button>
|
||||
<span>MstId: ${mis.MstId}</span>
|
||||
<button onclick="missionChanged(${mis.MstId})">Play</button>
|
||||
<span>MstId: ${questSceneMstId}</span>
|
||||
<button onclick="sceneSet('${questSceneMstId}', '${cust}')">Play</button>
|
||||
</div>
|
||||
</div>`;
|
||||
document.getElementById("click-catcher").style.cssText = 'display: flex;';
|
||||
@ -219,10 +337,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);
|
||||
}
|
||||
|
||||
@ -233,67 +359,85 @@ 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');
|
||||
utage.scenes[cust][questSceneMstId]['QuestSceneMstId'] = questSceneMstId;
|
||||
if (!part || part.value === '{All}') {
|
||||
scenePlaylist.push(utage.scenes[cust][questSceneMstId]);
|
||||
} else {
|
||||
currentScene = utage.scenes[cust][questSceneMstId];
|
||||
try {
|
||||
partPlaylist.push.apply(partPlaylist, currentScene.Parts.slice(currentScene.Parts.indexOf(part.value)));
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
return;
|
||||
}
|
||||
}
|
||||
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.custom : 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) => {
|
||||
@ -305,43 +449,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) {
|
||||
@ -355,20 +488,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();
|
||||
}
|
||||
}
|
||||
|
||||
@ -414,11 +537,17 @@ function openHelpModal(event) {
|
||||
iOS: 11+, no audio<br/>
|
||||
</div>
|
||||
</div>
|
||||
<a style="margin-top: auto; text-align: center; "href="https://discord.gg/fpQZQ8g">YameteTomete Discord</a>
|
||||
<div class="follow-links">
|
||||
<div class="follow-links-header">Follow YameteTomete</div>
|
||||
<div class="follow-links-links">
|
||||
<a href="https://discord.gg/fpQZQ8g" target="_blank" >Discord</a>
|
||||
<a href="https://twitter.com/YameteTomete" target="_blank">Twitter</a>
|
||||
</div>
|
||||
</div>
|
||||
<div style="margin-top: auto; text-align: center;">All Symphogear content belongs to its respective owners</div>
|
||||
<div id="modal-buttons">
|
||||
<button onclick="closeModal(event)">Close</button>
|
||||
<a href="https://git.poweris.moe/xduplayer.git/" target="_blank">Source</a>
|
||||
<a href="https://git.poweris.moe/yttt-xdu/XDUPlayer" target="_blank">Source</a>
|
||||
</div>
|
||||
</div>`;
|
||||
document.getElementById("click-catcher").style.cssText = 'display: flex;';
|
||||
@ -432,9 +561,9 @@ function toggleMute(event) {
|
||||
}
|
||||
localStorage.setItem('ismuted', isMuted);
|
||||
if(isMuted) {
|
||||
document.getElementById('mute-button').innerText = "🔇";
|
||||
document.getElementById('mute-button').innerText = emoji.Mute;
|
||||
} else {
|
||||
document.getElementById('mute-button').innerText = "🔊";
|
||||
document.getElementById('mute-button').innerText = emoji.LoudSound;
|
||||
}
|
||||
}
|
||||
|
||||
@ -473,7 +602,7 @@ function onFullScreenChange(event) {
|
||||
} else {
|
||||
document.getElementById('other-controls-container').style.cssText = "";
|
||||
document.getElementById('title-container').style.cssText = "";
|
||||
document.getElementById('fullscreen-button').innerText = "➕";
|
||||
document.getElementById('fullscreen-button').innerText = emoji.HeavyPlusSign;
|
||||
}
|
||||
onWindowResize(event, 0);
|
||||
}
|
||||
|
19
Js/Pixi.min.js
vendored
19
Js/Pixi.min.js
vendored
File diff suppressed because one or more lines are too long
962
Js/Player.js
962
Js/Player.js
File diff suppressed because it is too large
Load Diff
@ -1,25 +1,20 @@
|
||||
//http://glslsandbox.com/e#39992.0
|
||||
|
||||
class Shaders {
|
||||
constructor() {
|
||||
this.leftToRightFadeShader = `
|
||||
precision mediump float;
|
||||
varying vec2 vTextureCoord;
|
||||
uniform vec2 dimensions;
|
||||
uniform vec4 filterArea;
|
||||
uniform vec4 inputPixel;
|
||||
uniform highp vec4 outputFrame;
|
||||
|
||||
uniform float time;
|
||||
uniform vec4 fadeincolor;
|
||||
uniform vec4 fadeoutcolor;
|
||||
|
||||
vec2 mapCoord( vec2 coord ) {
|
||||
coord *= filterArea.xy;
|
||||
coord += filterArea.zw;
|
||||
return coord;
|
||||
}
|
||||
|
||||
void main( void ) {
|
||||
vec2 uv = vTextureCoord;
|
||||
vec2 mappedCoord = mapCoord(uv) / dimensions;
|
||||
vec2 uv = vTextureCoord * inputPixel.xy / outputFrame.zw;
|
||||
vec2 mappedCoord = uv;
|
||||
|
||||
float step2 = time;
|
||||
float step3 = time + 0.2;
|
||||
@ -35,21 +30,16 @@ class Shaders {
|
||||
this.rightToLeftFadeShader = `
|
||||
precision mediump float;
|
||||
varying vec2 vTextureCoord;
|
||||
uniform vec2 dimensions;
|
||||
uniform vec4 filterArea;
|
||||
uniform vec4 inputPixel;
|
||||
uniform highp vec4 outputFrame;
|
||||
|
||||
uniform float time;
|
||||
uniform vec4 fadeincolor;
|
||||
uniform vec4 fadeoutcolor;
|
||||
|
||||
vec2 mapCoord( vec2 coord ) {
|
||||
coord *= filterArea.xy;
|
||||
return coord;
|
||||
}
|
||||
|
||||
void main( void ) {
|
||||
vec2 uv = vTextureCoord;
|
||||
vec2 mappedCoord = mapCoord(uv) / dimensions;
|
||||
vec2 uv = vTextureCoord * inputPixel.xy / outputFrame.zw;
|
||||
vec2 mappedCoord = uv;
|
||||
|
||||
float step2 = (1.0 - time);
|
||||
float step3 = (1.0 - time) - 0.2;
|
||||
@ -65,22 +55,16 @@ class Shaders {
|
||||
this.downToUpFadeShader = `
|
||||
precision mediump float;
|
||||
varying vec2 vTextureCoord;
|
||||
uniform vec2 dimensions;
|
||||
uniform vec4 filterArea;
|
||||
uniform vec4 inputPixel;
|
||||
uniform highp vec4 outputFrame;
|
||||
|
||||
uniform float time;
|
||||
uniform vec4 fadeincolor;
|
||||
uniform vec4 fadeoutcolor;
|
||||
|
||||
vec2 mapCoord( vec2 coord ) {
|
||||
coord *= filterArea.xy;
|
||||
coord += filterArea.zw;
|
||||
return coord;
|
||||
}
|
||||
|
||||
void main( void ) {
|
||||
vec2 uv = vTextureCoord;
|
||||
vec2 mappedCoord = mapCoord(uv) / dimensions;
|
||||
vec2 uv = vTextureCoord * inputPixel.xy / outputFrame.zw;
|
||||
vec2 mappedCoord = uv;
|
||||
|
||||
float step2 = (1.0 - time);
|
||||
float step3 = (1.0 - time) - 0.2;
|
||||
@ -96,22 +80,16 @@ class Shaders {
|
||||
this.uptoDownFadeShader = `
|
||||
precision mediump float;
|
||||
varying vec2 vTextureCoord;
|
||||
uniform vec2 dimensions;
|
||||
uniform vec4 filterArea;
|
||||
uniform vec4 inputPixel;
|
||||
uniform highp vec4 outputFrame;
|
||||
|
||||
uniform float time;
|
||||
uniform vec4 fadeincolor;
|
||||
uniform vec4 fadeoutcolor;
|
||||
|
||||
vec2 mapCoord( vec2 coord ) {
|
||||
coord *= filterArea.xy;
|
||||
coord += filterArea.zw;
|
||||
return coord;
|
||||
}
|
||||
|
||||
void main( void ) {
|
||||
vec2 uv = vTextureCoord;
|
||||
vec2 mappedCoord = mapCoord(uv) / dimensions;
|
||||
vec2 uv = vTextureCoord * inputPixel.xy / outputFrame.zw;
|
||||
vec2 mappedCoord = uv;
|
||||
|
||||
float step2 = time;
|
||||
float step3 = time + 0.2;
|
||||
@ -128,7 +106,6 @@ class Shaders {
|
||||
precision mediump float;
|
||||
varying vec2 vTextureCoord;
|
||||
uniform sampler2D uSampler;
|
||||
uniform vec2 dimensions;
|
||||
uniform float factor;
|
||||
|
||||
vec4 Sepia( in vec4 color )
|
||||
@ -149,10 +126,11 @@ class Shaders {
|
||||
}
|
||||
|
||||
//https://jsfiddle.net/60e5pp8d/1/
|
||||
//v5 changes to shaders, https://github.com/pixijs/pixi.js/wiki/v5-Creating-filters
|
||||
// https://www.html5gamedevs.com/topic/42235-how-to-get-correct-fragment-shader-uv-in-pixi-50-rc0/
|
||||
buildShaders() {
|
||||
let divalefttorightfade = new PIXI.Filter(null, this.leftToRightFadeShader, {
|
||||
time: { type: 'f', value: 0 },
|
||||
dimensions: { type: 'v2', value: [baseDimensions.width, baseDimensions.height] },
|
||||
fadeincolor: { type: 'v4', value: [0.0,0.0,0.0,1.0] },
|
||||
fadeoutcolor: { type: 'v4', value: [0.0,0.0,0.0,0.0] }
|
||||
});
|
||||
@ -161,7 +139,6 @@ class Shaders {
|
||||
|
||||
let divarighttoleftfade = new PIXI.Filter(null, this.rightToLeftFadeShader, {
|
||||
time: { type: 'f', value: 0 },
|
||||
dimensions: { type: 'v2', value: [baseDimensions.width, baseDimensions.height] },
|
||||
fadeincolor: { type: 'v4', value: [0.0,0.0,0.0,1.0] },
|
||||
fadeoutcolor: { type: 'v4', value: [0.0,0.0,0.0,0.0] }
|
||||
});
|
||||
@ -170,7 +147,6 @@ class Shaders {
|
||||
|
||||
let divauptodownfade = new PIXI.Filter(null, this.uptoDownFadeShader, {
|
||||
time: { type: 'f', value: 0 },
|
||||
dimensions: { type: 'v2', value: [baseDimensions.width, baseDimensions.height] },
|
||||
fadeincolor: { type: 'v4', value: [0.0,0.0,0.0,1.0] },
|
||||
fadeoutcolor: { type: 'v4', value: [0.0,0.0,0.0,0.0] }
|
||||
});
|
||||
@ -179,7 +155,6 @@ class Shaders {
|
||||
|
||||
let divadowntoupfade = new PIXI.Filter(null, this.downToUpFadeShader, {
|
||||
time: { type: 'f', value: 0 },
|
||||
dimensions: { type: 'v2', value: [baseDimensions.width, baseDimensions.height] },
|
||||
fadeincolor: { type: 'v4', value: [0.0,0.0,0.0,1.0] },
|
||||
fadeoutcolor: { type: 'v4', value: [0.0,0.0,0.0,0.0] }
|
||||
});
|
||||
@ -187,15 +162,12 @@ class Shaders {
|
||||
this.shaders['divadowntoupfade'] = divadowntoupfade;
|
||||
|
||||
let sepia = new PIXI.Filter(null, this.sepiaShader, {
|
||||
factor: { type: 'f', value: 0.5 },
|
||||
dimensions: { type: 'v2', value: [baseDimensions.width, baseDimensions.height] }
|
||||
factor: { type: 'f', value: 0.5 }
|
||||
});
|
||||
sepia.apply = baseShaderApply;
|
||||
this.shaders['sepia'] = sepia;
|
||||
|
||||
function baseShaderApply(filterManager, input, output) {
|
||||
this.uniforms.dimensions[0] = input.sourceFrame.width;
|
||||
this.uniforms.dimensions[1] = input.sourceFrame.height;
|
||||
filterManager.applyFilter(this, input, output);
|
||||
}
|
||||
}
|
||||
|
@ -84,7 +84,6 @@ class TextFunctions {
|
||||
function putText() {
|
||||
// skip over any HTML chars
|
||||
this.dialogToDisplay.curPos = this.typeHtmlChars(this.dialogToDisplay.text, this.dialogToDisplay.curPos);
|
||||
let substr = this.dialogToDisplay.text.substr(this.dialogToDisplay.curPos);
|
||||
if (this.dialogToDisplay.curPos === this.dialogToDisplay.text.length) {
|
||||
this.showNextIndicator(true);
|
||||
this.scrollingText = false;
|
||||
|
@ -1 +1 @@
|
||||
Subproject commit 533c48371ed01ed7265b6b5f052d1b2c3fce940f
|
||||
Subproject commit ac0bfbd699431e9befdd843379e7c91ad1014cec
|
204
Js/UtageParse.js
204
Js/UtageParse.js
@ -6,7 +6,9 @@ class UtageInfo {
|
||||
this.currentPlayingFile = [];
|
||||
this.rootDirectory = ``;
|
||||
this.groupedMissions = {};
|
||||
this.missionsList = [];
|
||||
this.quests = {};
|
||||
this.questList = [];
|
||||
this.scenes = {};
|
||||
this.characterInfo = {};
|
||||
this.layerInfo = {};
|
||||
this.localizeInfo = {};
|
||||
@ -16,44 +18,64 @@ class UtageInfo {
|
||||
this.currentTranslation = 'eng';
|
||||
this.translationsInner = {};
|
||||
this.charTranslationsInner = {};
|
||||
this.missionTranslationsInner = {};
|
||||
this.questTranslationsInner = {};
|
||||
this.sceneTranslationsInner = {};
|
||||
this.bgmLoopData = {};
|
||||
this.macros = {};
|
||||
}
|
||||
|
||||
loadUtageSettings() {
|
||||
return new Promise((resolve, reject) => {
|
||||
let promises = [
|
||||
commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/XduMissions.json`), //0
|
||||
commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Character.tsv`), //1
|
||||
commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Layer.tsv`), //2
|
||||
commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Localize.tsv`), //3
|
||||
commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/XduQuest.json`), //0
|
||||
commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/XduScene.json`), //1
|
||||
commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Character.tsv`), //2
|
||||
commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Layer.tsv`), //3
|
||||
commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Localize.tsv`), //4
|
||||
//commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Param.tsv`),
|
||||
//commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Scenario.tsv`),
|
||||
commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Sound.tsv`), //4
|
||||
commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Texture.tsv`), //5
|
||||
commonFunctions.getFileJson(`${this.rootDirectory}Js/BgmLoop.json`), //6
|
||||
commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/XduMissionsCustom.json`), //7
|
||||
commonFunctions.getFileText(`${this.rootDirectory}CustomData/Utage/Diva/Settings/CustomCharacter.tsv`), //8
|
||||
commonFunctions.getFileText(`${this.rootDirectory}CustomData/Utage/Diva/Settings/CustomSound.tsv`), //9
|
||||
commonFunctions.getFileText(`${this.rootDirectory}CustomData/Utage/Diva/Settings/CustomTexture.tsv`), //10
|
||||
commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Sound.tsv`), //5
|
||||
commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Texture.tsv`), //6
|
||||
commonFunctions.getFileJson(`${this.rootDirectory}XDUData/Bgm/BgmLoop.json`), //7
|
||||
commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/XduQuestCustom.json`), //8
|
||||
commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/XduSceneCustom.json`), //9
|
||||
commonFunctions.getFileText(`${this.rootDirectory}CustomData/Utage/Diva/Settings/CustomCharacter.tsv`), //10
|
||||
commonFunctions.getFileText(`${this.rootDirectory}CustomData/Utage/Diva/Settings/CustomSound.tsv`), //11
|
||||
commonFunctions.getFileText(`${this.rootDirectory}CustomData/Utage/Diva/Settings/CustomTexture.tsv`), //12
|
||||
commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Scenario/Macro.tsv`), //13
|
||||
commonFunctions.getFileText(`${this.rootDirectory}CustomData/Utage/Diva/Settings/CustomMacro.tsv`), //14
|
||||
];
|
||||
Promise.all(promises)
|
||||
.then((success) => {
|
||||
this.groupMissions(success[0], success[7]);
|
||||
this.missionsList = Object.keys(this.groupedMissions).map((k) => {
|
||||
return {Name: this.groupedMissions[k].Name, MstId: this.groupedMissions[k].MstId};
|
||||
this.quests[CUSTOM.stock] = success[0];
|
||||
this.questList = Object.keys(this.quests[CUSTOM.stock]).map((k) => {
|
||||
return {QuestMstId: k, Name: this.quests[CUSTOM.stock][k].Name, IsCustom: false};
|
||||
});
|
||||
this.missionsList.sort();
|
||||
this.parseCharacterInfo(success[1]);
|
||||
this.parseLayerInfo(success[2]);
|
||||
this.parseLocalizeInfo(success[3]);
|
||||
this.quests[CUSTOM.custom] = success[8];
|
||||
for (const k of Object.keys(this.quests[CUSTOM.custom])) {
|
||||
this.questList.push({QuestMstId: k, Name: this.quests[CUSTOM.custom][k].Name, IsCustom: true});
|
||||
}
|
||||
this.questList.sort((a, b) => { return a.QuestMstId - b.QuestMstId });
|
||||
this.scenes[CUSTOM.stock] = success[1];
|
||||
for (const k of Object.keys(this.scenes[CUSTOM.stock])) {
|
||||
this.scenes[CUSTOM.stock][k]['IsCustom'] = false;
|
||||
}
|
||||
this.parseCharacterInfo(success[2]);
|
||||
this.parseLayerInfo(success[3]);
|
||||
this.parseLocalizeInfo(success[4]);
|
||||
//this.parseParamInfo(success[4]);
|
||||
this.parseSoundInfo(success[4]);
|
||||
this.parseTextureInfo(success[5]);
|
||||
this.bgmLoopData = success[6];
|
||||
this.parseCharacterInfo(success[8], true);
|
||||
this.parseSoundInfo(success[9], true);
|
||||
this.parseTextureInfo(success[10], true);
|
||||
this.parseSoundInfo(success[5]);
|
||||
this.parseTextureInfo(success[6]);
|
||||
this.bgmLoopData = success[7];
|
||||
this.scenes[CUSTOM.custom] = success[9];
|
||||
for (const k of Object.keys(this.scenes[CUSTOM.custom])) {
|
||||
this.scenes[CUSTOM.custom][k]['IsCustom'] = true;
|
||||
}
|
||||
this.parseCharacterInfo(success[10], true);
|
||||
this.parseSoundInfo(success[11], true);
|
||||
this.parseTextureInfo(success[12], true);
|
||||
this.parseMacroFile(success[13]);
|
||||
this.parseMacroFile(success[14]);
|
||||
resolve();
|
||||
}, (failure) => {
|
||||
reject(failure);
|
||||
@ -87,40 +109,6 @@ class UtageInfo {
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
groupMissions(missions, customMissions) {
|
||||
for(let key of Object.keys(missions)) {
|
||||
let mis = missions[key];
|
||||
if(!this.groupedMissions[mis.MstId]) {
|
||||
this.groupedMissions[mis.MstId] = {
|
||||
Name: mis.Name,
|
||||
SummaryText: mis.SummaryText,
|
||||
MstId: mis.MstId,
|
||||
Missions: {}
|
||||
}
|
||||
this.groupedMissions[mis.MstId].Missions[mis.Id] = { Id: mis.Id, Path: mis.Path, Enabled: mis.Enabled };
|
||||
} else {
|
||||
this.groupedMissions[mis.MstId].Missions[mis.Id] = { Id: mis.Id, Path: mis.Path, Enabled: mis.Enabled };
|
||||
}
|
||||
}
|
||||
for(let key of Object.keys(customMissions)) {
|
||||
let mis = customMissions[key];
|
||||
mis.IsCustom = true;
|
||||
if(!this.groupedMissions[mis.MstId]) {
|
||||
this.groupedMissions[mis.MstId] = {
|
||||
IsCustom: true,
|
||||
Name: mis.Name,
|
||||
SummaryText: mis.SummaryText,
|
||||
MstId: mis.MstId,
|
||||
Missions: {}
|
||||
}
|
||||
this.groupedMissions[mis.MstId].Missions[mis.Id] = { Id: mis.Id, Path: mis.Path, Enabled: mis.Enabled, IsCustom: true };
|
||||
} else {
|
||||
this.groupedMissions[mis.MstId].Missions[mis.Id] = { Id: mis.Id, Path: mis.Path, Enabled: mis.Enabled, IsCustom: true };
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
get translations() {
|
||||
return this.translationsInner[this.currentTranslation];
|
||||
}
|
||||
@ -129,20 +117,40 @@ class UtageInfo {
|
||||
return this.charTranslationsInner[this.currentTranslation];
|
||||
}
|
||||
|
||||
get missionTranslations() {
|
||||
return this.missionTranslationsInner[this.currentTranslation];
|
||||
get questTranslations() {
|
||||
return this.questTranslationsInner[this.currentTranslation];
|
||||
}
|
||||
|
||||
get sceneTranslations() {
|
||||
return this.sceneTranslationsInner[this.currentTranslation];
|
||||
}
|
||||
|
||||
setTranslationLanguage(key, missionPath) {
|
||||
return new Promise((resolve, reject) => {
|
||||
this.currentTranslation = key;
|
||||
let promises = [this.loadCharacterTranslations(key),
|
||||
this.loadMissionNamesTranslations(key)];
|
||||
this.loadQuestNamesTranslations(key),
|
||||
this.loadSceneNamesTranslations(key)];
|
||||
if(missionPath) {
|
||||
promises.push(this.loadMissionTranslation(missionPath, key));
|
||||
}
|
||||
Promise.all(promises)
|
||||
.then((success) => {
|
||||
// propagate language-based enables downwards from quests to scenes
|
||||
for (const c of [CUSTOM.custom, CUSTOM.stock]) {
|
||||
for (const k of Object.keys(this.questTranslationsInner[this.currentTranslation][c])) {
|
||||
if (this.questTranslationsInner[this.currentTranslation][c][k].Enabled) {
|
||||
for (const s of this.quests[c][k].Scenes) {
|
||||
// only propagate if exists in translation file (THANKS GLOBAL) and translated name is supplied
|
||||
if (c in this.sceneTranslationsInner[this.currentTranslation]
|
||||
&& s in this.sceneTranslationsInner[this.currentTranslation][c]
|
||||
&& this.sceneTranslationsInner[this.currentTranslation][c][s].Name != "") {
|
||||
this.sceneTranslationsInner[this.currentTranslation][c][s].Enabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
resolve();
|
||||
}, (failure) => {
|
||||
console.log(failure);
|
||||
@ -173,7 +181,7 @@ class UtageInfo {
|
||||
if(this.charTranslationsInner[this.currentTranslation]) {
|
||||
resolve();
|
||||
} else {
|
||||
commonFunctions.getFileJson(`${utage.rootDirectory}Js/Translations/nametranslations_${this.currentTranslation}.json`)
|
||||
commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/nametranslations_${this.currentTranslation}.json`)
|
||||
.then((success) => {
|
||||
this.charTranslationsInner[this.currentTranslation] = success;
|
||||
resolve();
|
||||
@ -185,21 +193,20 @@ class UtageInfo {
|
||||
});
|
||||
}
|
||||
|
||||
loadMissionNamesTranslations() {
|
||||
loadQuestNamesTranslations() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if(this.missionTranslationsInner[this.currentTranslation]) {
|
||||
if(this.questTranslationsInner[this.currentTranslation]) {
|
||||
resolve();
|
||||
} else {
|
||||
var promises = [
|
||||
commonFunctions.getFileJson(`${utage.rootDirectory}Js/Translations/XduMissionsNames_${this.currentTranslation}.json`),
|
||||
commonFunctions.getFileJson(`${utage.rootDirectory}Js/Translations/XduMissionsNamesCustom_${this.currentTranslation}.json`)
|
||||
commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/XduQuestNames_${this.currentTranslation}.json`),
|
||||
commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/XduQuestNamesCustom_${this.currentTranslation}.json`)
|
||||
];
|
||||
Promise.all(promises)
|
||||
.then((success) => {
|
||||
for(let m of Object.keys(success[1])) {
|
||||
success[0][m] = success[1][m];
|
||||
}
|
||||
this.missionTranslationsInner[this.currentTranslation] = success[0];
|
||||
this.questTranslationsInner[this.currentTranslation] = {};
|
||||
this.questTranslationsInner[this.currentTranslation][CUSTOM.stock] = success[0];
|
||||
this.questTranslationsInner[this.currentTranslation][CUSTOM.custom] = success[1];
|
||||
resolve();
|
||||
}, (failure) => {
|
||||
console.log(failure);
|
||||
@ -209,6 +216,59 @@ class UtageInfo {
|
||||
});
|
||||
}
|
||||
|
||||
loadSceneNamesTranslations() {
|
||||
return new Promise((resolve, reject) => {
|
||||
if(this.sceneTranslationsInner[this.currentTranslation]) {
|
||||
resolve();
|
||||
} else {
|
||||
var promises = [
|
||||
commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/XduSceneNames_${this.currentTranslation}.json`),
|
||||
commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/XduSceneNamesCustom_${this.currentTranslation}.json`)
|
||||
];
|
||||
Promise.all(promises)
|
||||
.then((success) => {
|
||||
this.sceneTranslationsInner[this.currentTranslation] = {};
|
||||
this.sceneTranslationsInner[this.currentTranslation][CUSTOM.stock] = success[0];
|
||||
this.sceneTranslationsInner[this.currentTranslation][CUSTOM.custom] = success[1];
|
||||
resolve();
|
||||
}, (failure) => {
|
||||
console.log(failure);
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
parseMacroFile(file) {
|
||||
let lines = file.split('\n');
|
||||
let header = lines[0].split('\t');
|
||||
let macro = false;
|
||||
let name = "";
|
||||
for (let i = 1; i < lines.length; ++i) {
|
||||
let line = commonFunctions.readLine(lines[i], header);
|
||||
if (line && !line.comment) {
|
||||
if (macro === false) {
|
||||
if (line.Command[0] === '*') {
|
||||
name = line.Command.slice(1);
|
||||
if (!(name in this.macros)) {
|
||||
macro = true;
|
||||
this.macros[name] = [];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (line.Command === "EndMacro") {
|
||||
macro = false;
|
||||
continue;
|
||||
}
|
||||
if (!line.Command && !line.Arg1 && !line.Arg2 && !line.Arg3 && !line.Arg4 && !line.Arg5 && !line.Arg6) {
|
||||
continue;
|
||||
}
|
||||
this.macros[name].push(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//http://madnesslabo.net/utage/?page_id=4521&lang=en
|
||||
parseCharacterInfo(text, custom = false) {
|
||||
let lines = text.split("\n");
|
||||
|
12
Player.html
12
Player.html
@ -15,10 +15,9 @@
|
||||
<script src="Js/TextFunctions.js"></script>
|
||||
<script src="Js/UtageParse.js"></script>
|
||||
<script src="Js/Audio.js"></script>
|
||||
<script src="Js/Player.js"></script>
|
||||
<script src="Js/Main.js"></script> -->
|
||||
<script src="Js/Player.js"></script>-->
|
||||
<script src="Js/XduPlayer.min.js"></script>
|
||||
<div id="loading-container" class="centered">
|
||||
<div id="loading-container" class="centered" style="z-index: 20;">
|
||||
<h2 id="loading-utage">Loading Utage Data...</h2>
|
||||
<h2 id="loading-font">Loading Page Data...</h2>
|
||||
</div>
|
||||
@ -26,10 +25,11 @@
|
||||
<div id="title-container"><span>Now Playing: </span><span id="playing-title">None</span></div>
|
||||
<div id="other-controls-container">
|
||||
<div id="volume-control">
|
||||
<span onclick="toggleMute(event)" id="mute-button">🔊</span>
|
||||
<span onclick="toggleMute(event)" id="mute-button">🔊</span> <!-- loud_sound -->
|
||||
<input onchange="onVolumeChange(event)" id="volume-range" value="50" type="range" min="0" max="100" step="1"/>
|
||||
</div>
|
||||
<select id="select-mission" onchange="missionDropDownChanged(event);"></select>
|
||||
<select id="select-quest" onchange="questDropDownChanged(event);"></select>
|
||||
<select id="select-scene" disabled="true" onchange="sceneDropDownChanged(event);"></select>
|
||||
<select id="select-language" onchange="languageChanged(event);"></select>
|
||||
<a style="font-size: 20px; margin-left: 5px;" title="info/help" onclick="openHelpModal(event)">?</a>
|
||||
</div>
|
||||
@ -37,7 +37,7 @@
|
||||
The canvas then resizes as the canvas does and the text-container uses transform scale based off this resolution -->
|
||||
<div id="app-container" onclick="onMainClick(event);">
|
||||
<div id="text-container">
|
||||
<div id="fullscreen-button" onclick="toggleFullscreen(event)">➕</div>
|
||||
<div id="fullscreen-button" onclick="toggleFullscreen(event)">➕</div> <!-- heavy_plus_sign -->
|
||||
<img id="main-ui-img" class="hidden" src="Images/newui_main.png"/>
|
||||
<button id="play-from-query" onclick="playFromQuery(event)" style="display: none;">Play</button>
|
||||
<div id="title" class="hidden">Title Text</div>
|
||||
|
10
gulpfile.js
10
gulpfile.js
@ -26,9 +26,6 @@ const cssToCopy = [
|
||||
"Css/main.min.css",
|
||||
"Css/generic.min.css"
|
||||
];
|
||||
const jsonFiles = [
|
||||
"Js/BgmLoop.json",
|
||||
];
|
||||
const translations = [
|
||||
"Js/Translations/**"
|
||||
];
|
||||
@ -50,7 +47,6 @@ gulp.task('dist', gulp.series(
|
||||
buildCss,
|
||||
copyCss
|
||||
),
|
||||
buildJson,
|
||||
buildJsonTranslations,
|
||||
copyHtml,
|
||||
copyImages,
|
||||
@ -117,12 +113,6 @@ function copyCustomData() {
|
||||
.pipe(gulp.dest('Dist/CustomData'));
|
||||
}
|
||||
|
||||
function buildJson() {
|
||||
return gulp.src(jsonFiles)
|
||||
.pipe(jsonmin())
|
||||
.pipe(gulp.dest('Dist/Js'));
|
||||
}
|
||||
|
||||
function buildJsonTranslations() {
|
||||
return gulp.src(translations)
|
||||
.pipe(jsonmin())
|
||||
|
14467
package-lock.json
generated
14467
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@ -1,16 +1,18 @@
|
||||
{
|
||||
"name": "XduPlayer",
|
||||
"version": "1.0.0",
|
||||
"version": "1.3.0",
|
||||
"private": true,
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"gulp": "github:gulpjs/gulp#4.0",
|
||||
"gulp": "~4.0.2",
|
||||
"gulp-concat": "~2.6.1",
|
||||
"gulp-cssmin": "~0.2.0",
|
||||
"gulp-jsonminify": "^1.1.0",
|
||||
"gulp-rename": "~1.2.2",
|
||||
"gulp-sourcemaps": "~2.6.4",
|
||||
"gulp-uglify": "~3.0.0",
|
||||
"gulp-uglify-es": "~1.0.1"
|
||||
"gulp-uglify-es": "~1.0.1",
|
||||
"npm": "^6.9.0",
|
||||
"eslint": "^5.16.0"
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user