Compare commits

...

66 Commits

Author SHA1 Message Date
62e702b9fa Merge pull request 'feature/czechlang' (#9) from feature/czechlang into master 2021-02-16 10:14:42 -05:00
428ea1d660 changed czech font to PTSans 2021-02-15 20:00:30 +01:00
0def56d476 added czech 2021-02-15 19:48:57 +01:00
85f2815b6a added player support for new scene images 2020-10-21 23:54:33 +02:00
7b43a86b99
master tracks master
we're just going to rebuild beta off the most recently pushed branch
2020-09-12 16:39:42 -04:00
1dc54f8590
master branch tracks beta translations 2020-09-12 03:03:52 -04:00
d6ac86ed8c
load name variants
global stinx
2020-08-11 12:32:41 -04:00
afd850fbca
make sure translation is supplied when propagating enables 2020-08-11 11:55:19 -04:00
bdc076b664
fixed player supporting global 2020-08-11 11:55:17 -04:00
47e250ba89 support for global languages 2020-05-16 15:39:41 +02:00
14efed32e3 Merge branch 'master' of https://git.poweris.moe/yttt-xdu/XDUPlayer 2020-04-17 14:26:49 -07:00
90236c665d Since we dont have battles we use "divaeffectcontinue" as a fade out but they also sometimes call "fadeout" so set a flag so we don't do fade out again if we are already doing it. 2020-04-17 14:26:12 -07:00
89a93407f1 Update repository links for submodules and player info 2020-02-18 18:18:02 -05:00
2ca5a9e704 js: move bgmloop to data folder
Having xdu-specific data in this repo doesn't make much sense when most of the
data is fairly general to the engine, plus now I don't have to make a commit
every time I want to update the data.
2019-11-12 18:58:42 -05:00
c6c9c99c31 json: update bgmloop 2019-10-25 17:56:09 -04:00
ae90fd1c37 Updated pixi again with fork because im clearly still doing something wrong and still need the sprite hack. 2019-09-29 11:53:12 -07:00
5ca0935ac6 Updated to Pixi v5.
This also fixes a chrome video preload spec change.
2019-09-29 11:19:51 -07:00
0c039b6ed4 1.3.1 version bump 2019-06-09 21:36:52 -04:00
a93978f39d Fix movecamera since its a macro now. 2019-06-01 14:38:39 -07:00
b6821d4157 fix broken links 2019-05-24 10:00:38 -04:00
d8a5d4d177 changelog: 1.3.0 2019-05-24 04:49:54 -04:00
022250c4c4 fonts: re-enable russian font
idk why bingo disabled this
2019-05-24 04:22:04 -04:00
3101868b30 Merge branch 'quest-json' of https://git.poweris.moe/xduplayer into quest-json 2019-05-21 20:56:42 -07:00
bb409c45a1 Fixes for colorTo and tint not being kept during dialogue. 2019-05-21 20:56:37 -07:00
4716b5e8e8 divamovie: respect volume controls 2019-05-21 22:42:52 -04:00
9dc0c8f9cf enable-guard play all 2019-05-17 18:53:17 -04:00
0d522b55c5 fix urlparams play
single value, questscenemstid
2019-05-17 13:00:05 -04:00
f289381955 Merge branch 'quest-json' of git.poweris.moe:xduplayer into quest-json 2019-05-17 12:59:21 -04:00
c1c6cbfd99 demagicify custom namespace 2019-05-17 12:44:14 -04:00
90625d82b6 css for follow links instead of table. 2019-05-17 09:38:16 -07:00
5dba520155 continue playing scene after selecting specific part 2019-05-17 12:31:44 -04:00
0e9f6f8d70 custom doesn't matter for part select
it's decided by the current scene
2019-05-17 12:05:42 -04:00
8786c54200 bgmloop: update
why is this in this repo
2019-05-17 06:37:26 -04:00
25f7d90951 metadata changes and quest selector 2019-05-17 05:20:02 -04:00
526d0a51cc copy macros
macros were being edited in-place and affecting later uses
2019-05-13 20:22:17 -04:00
737b13da42 custom macros
dug out an old copy of the Macros file from the wedding gears
event and set up the player to merge removed macros
2019-05-13 17:41:01 -04:00
269592c3d6 Merge branch 'master' of https://git.poweris.moe/xduplayer 2019-05-13 13:16:45 -07:00
d4e96c66a8 Removed webpack for gulp again because its simpler for a project this size. 2019-05-13 13:16:40 -07:00
effb55871f utage: divamovie support
this is used for skillmovies that play during some missions
they must first be converted into webm format
2019-05-13 16:13:01 -04:00
77fc6e4d69 Merge branch 'master' of git.poweris.moe:xduplayer 2019-05-13 03:42:32 -04:00
bf11050984 utage macro support
xdu ships with a Macro.tsv, and loading commands
out of there instead of defining them manually
saves a lot of trouble

bingo didn't know about it

there's probably some regressions, needs further testing
2019-05-13 03:31:42 -04:00
1d469d4f3e webpack, eslint
javascript didn't have proper modules until es6 what the fuck

bingo's code scares me so i hope i didn't break it when fixing
the linting errors
2019-05-12 20:59:45 -04:00
e3b7233b20 remove emoji strings
replaced with html entities/creation from unicode code-point where applicable
my editor doesn't render emoji
2019-05-11 23:36:58 -04:00
b9e91f4977 version bump 2019-01-20 00:55:51 -05:00
eec0bb137b json: update bgmloop 2019-01-20 00:55:32 -05:00
0b3fb01670 I didnt hit save 2019-01-19 14:58:09 -07:00
fb9cab573e fix unbalanced parenthesis 2019-01-19 16:47:00 -05:00
f3ddb3e58f noise_disappearance commands should work. 2019-01-19 14:02:31 -07:00
24cbf4b5ad Merge branch 'master' of https://git.poweris.moe/xduplayer 2018-12-29 11:45:29 -07:00
e098d27964 Fix player not falling back to utage text if translation file didnt exist at all. 2018-12-29 11:44:34 -07:00
dbf530a333 urlparams: rewrite 2018-12-29 13:34:22 -05:00
rdh
d233bf77ce Merge branch 'master' of file:///mnt/bigstuff/source/xduplayer 2018-12-29 12:53:06 -05:00
42e37585d6 urlparams: rewrite 2018-12-29 12:53:03 -05:00
9ca49d25cc urlparams: rewrite 2018-12-29 12:45:27 -05:00
01245c4477 Merge branch 'master' into release 2018-12-29 12:10:52 -05:00
8933ba986a urlparams: add lang parameter 2018-12-29 12:02:23 -05:00
b98c2d987d Merge branch 'master' into release 2018-12-29 11:30:02 -05:00
63a21c69d8 Merge branch 'master' into release 2018-10-21 01:21:22 -04:00
61e5aaca02 Merge branch 'master' into release 2018-09-13 20:34:49 -07:00
rdh
b74cacb148 Merge branch 'master' into release 2018-09-13 09:23:18 -04:00
7e8eeffe4d Merge branch 'master' into release 2018-06-14 16:30:13 +09:00
a4676279f3 Merge branch 'master' into release 2018-06-12 23:16:20 +09:00
63478f494d Merge branch 'master' into release 2018-06-11 21:26:34 -07:00
0a56a9b11d Merge branch 'master' into release 2018-06-08 08:25:51 -07:00
e1f09c35b9 Merge branch 'master' into release 2018-06-08 08:24:22 -07:00
7a50205cd1 translations submodule: track branch
use --remote in the future
2018-06-06 02:16:28 +09:00
21 changed files with 9854 additions and 7688 deletions

1
.eslintignore Normal file
View File

@ -0,0 +1 @@
Js/Pixi.min.js

29
.eslintrc.json Normal file
View 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
View File

@ -3,6 +3,8 @@
web.config web.config
/Js/Typed /Js/Typed
/Js/[Pp]ixi.js /Js/[Pp]ixi.js
/Js/[Pp]ixi.js.map
/Js/[Pp]ixi.min.js.map
/node_modules /node_modules
/Js/XduPlayer.js /Js/XduPlayer.js
/Js/XduPlayer.min.js.map /Js/XduPlayer.min.js.map
@ -10,3 +12,4 @@ web.config
/Dist /Dist
/Css/main.min.css /Css/main.min.css
/Js/XduPlayer.min.js /Js/XduPlayer.min.js
/**/.*.swp

6
.gitmodules vendored
View File

@ -1,8 +1,8 @@
[submodule "Js/Translations"] [submodule "Js/Translations"]
path = Js/Translations path = Js/Translations
url = https://git.poweris.moe/xdutranslations.git url = https://git.poweris.moe/yttt-xdu/xdutranslations.git
branch = . branch = master
[submodule "CustomData"] [submodule "CustomData"]
path = CustomData path = CustomData
url = https://git.poweris.moe/customdata.git url = https://git.poweris.moe/yttt-xdu/customdata.git
branch = . branch = .

View File

@ -14,4 +14,37 @@ Added null check for pixi sprite calculateverticies because it sometimes makes a
DPI is now taken into account when resizing. DPI is now taken into account when resizing.
Added credits to mission modal. Added credits to mission modal.
Added ability to go fullscreen. Added ability to go fullscreen.
Missions JSON moved to translations submodule so missions can be added/enabled without disturbing main project. 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

View File

@ -84,6 +84,8 @@ body { margin: 0; height: 100%; }
#text-container.rus { font-family: 'PTSans'; } #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 #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; } #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; } #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; } #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; } #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) { @media screen and (max-width: 812px) {
#modal-container { top: 0; bottom: 0; left: 0; right: 0; transform: none; } #modal-container { top: 0; bottom: 0; left: 0; right: 0; transform: none; }
.modal { width: 100%; height: 100%; border-radius: 0; } .modal { width: 100%; height: 100%; border-radius: 0; }

@ -1 +1 @@
Subproject commit e45642773aa255babfde41b770ce1e4c78ca5251 Subproject commit e92af8f0d0c0d4246e44dd0b63508f9e460fe3a8

View File

@ -1,5 +1,4 @@
//(Math.exp(x)-1)/(Math.E-1) //(Math.exp(x)-1)/(Math.E-1)
//🔊
class bufferLoader { class bufferLoader {
constructor(context, soundMap, callback) { constructor(context, soundMap, callback) {
@ -182,4 +181,4 @@ class audioController {
} }
this.sources = {}; this.sources = {};
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,11 @@ let rootUrl = `${window.location.protocol}//${window.location.host}/`;
const baseDimensions = {width: 1334, height: 750}; const baseDimensions = {width: 1334, height: 750};
const screenRatio = 9/16; const screenRatio = 9/16;
const CUSTOM = {
custom: 'Custom',
stock: 'Stock'
}
class commonFunctions { class commonFunctions {
static getFileText(file) { static getFileText(file) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
@ -334,8 +339,7 @@ class commonFunctions {
if(props[i] == " ") { break; } if(props[i] == " ") { break; }
retval.color += props[i]; retval.color += props[i];
} }
retval.color = retval.color;
} }
return retval; return retval;
} }
} }

View File

@ -2,7 +2,7 @@
const pixiApp = { const pixiApp = {
app: new PIXI.Application(baseDimensions), app: new PIXI.Application(baseDimensions),
loader: PIXI.loader loader: PIXI.Loader.shared
}; };
const utage = new UtageInfo(); const utage = new UtageInfo();
@ -10,16 +10,17 @@ const shaders = new Shaders();
const textFunc = new TextFunctions(); const textFunc = new TextFunctions();
let audio = undefined; //Cant create a audio context without user input. let audio = undefined; //Cant create a audio context without user input.
const player = new Player(pixiApp, utage, textFunc, audio, shaders); const player = new Player(pixiApp, utage, textFunc, audio, shaders);
const languages = ["eng", "jpn", "rus"]; const languages = ["eng", "jpn", "rus", "cze", "enm", "kor", "zho"];
const version = "YameteTomete XDUPlayer V1.2.1"; const version = "YameteTomete XDUPlayer V1.5.0";
let bodyLoaded = false; let bodyLoaded = false;
let utageLoaded = false; let utageLoaded = false;
let languagesLoaded = false; let languagesLoaded = false;
let selectedLang = "eng"; let selectedLang = "eng";
let currentMission = undefined; let currentScene = {};
let currentMissionMst = 0; let currentSceneId = "";
let currentMissionIndex = 0; let scenePlaylist = [];
let currentMissionList = []; let currentPart = "";
let partPlaylist = [];
let urlParams = {}; let urlParams = {};
let screenw = Math.max(document.documentElement.clientWidth, window.innerWidth || 0); let screenw = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
let screenh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0); let screenh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
@ -27,15 +28,22 @@ let screenSizeTimeout = undefined;
let isMuted = false; let isMuted = false;
let volume = 0.5; let volume = 0.5;
let fullScreen = false; 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() { function onBodyLoaded() {
bodyLoaded = true; bodyLoaded = true;
document.getElementById("title-tag").innerText = version; document.getElementById("title-tag").innerText = version;
document.addEventListener('webkitfullscreenchange', onFullScreenChange, false); document.addEventListener('webkitfullscreenchange', onFullScreenChange, false);
document.addEventListener('mozfullscreenchange', onFullScreenChange, false); document.addEventListener('mozfullscreenchange', onFullScreenChange, false);
document.addEventListener('fullscreenchange', onFullScreenChange, false); document.addEventListener('fullscreenchange', onFullScreenChange, false);
document.addEventListener('MSFullscreenChange', onFullScreenChange, false); document.addEventListener('MSFullscreenChange', onFullScreenChange, false);
} }
(function startLoad() { (function startLoad() {
@ -54,6 +62,7 @@ function onBodyLoaded() {
(function checkIsLoaded() { (function checkIsLoaded() {
if(bodyLoaded) { if(bodyLoaded) {
document.getElementById('loading-font').style.cssText = "display: none;"; document.getElementById('loading-font').style.cssText = "display: none;";
checkQueryParameters();
loadLocalStorage(); loadLocalStorage();
} }
if(utageLoaded && languagesLoaded) { if(utageLoaded && languagesLoaded) {
@ -69,7 +78,8 @@ function onBodyLoaded() {
function onAllLoaded(success) { function onAllLoaded(success) {
textFunc.findTextElements(); textFunc.findTextElements();
buildMissionSelectList(); buildQuestSelectList();
buildSceneSelectList();
buildLanguageList(); buildLanguageList();
let appContainer = document.getElementById('app-container'); let appContainer = document.getElementById('app-container');
appContainer.appendChild(pixiApp.app.view); appContainer.appendChild(pixiApp.app.view);
@ -95,12 +105,12 @@ function loadLocalStorage() {
audio.mute(isMuted); audio.mute(isMuted);
} }
if(isMuted) { if(isMuted) {
document.getElementById('mute-button').innerText = "🔇"; document.getElementById('mute-button').innerText = emoji.Mute;
} else { } else {
document.getElementById('mute-button').innerText = "🔊"; document.getElementById('mute-button').innerText = emoji.LoudSound;
} }
//language //language
let lang = localStorage.getItem('language') || "eng"; let lang = urlParams['lang'] || localStorage.getItem('language') || "eng";
if(languages.includes(lang)) { if(languages.includes(lang)) {
selectedLang = lang; selectedLang = lang;
} }
@ -117,27 +127,79 @@ function loadLocalStorage() {
} }
} }
function buildMissionSelectList() { function buildQuestSelectList() {
let selectBox = document.getElementById('select-mission'); let questBox = document.getElementById('select-quest');
selectBox.innerHTML = ''; questBox.innerHTML = '';
for(let i = -1; i < utage.missionsList.length; ++i) { for (let i = -1; i < utage.questList.length; ++i) {
let opt = document.createElement('option'); let opt = document.createElement('option')
if(i === -1) { if (i === -1) {
opt.setAttribute('value', '{Select}'); opt.setAttribute('value', '{Select}');
opt.innerText = 'Select Mission'; opt.innerText = 'Select Event';
} else { } else {
let m = utage.missionsList[i]; let q = utage.questList[i];
if(!Object.keys(utage.groupedMissions[m.MstId].Missions).some((mis) => { return utage.groupedMissions[m.MstId].Missions[mis].Enabled === true })) { 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; continue;
} }
opt.setAttribute('value', m.MstId); if (!tl_key.Enabled && !utage.quests[cust][q.QuestMstId].Scenes.some((s) => { return utage.sceneTranslations[cust][s].Enabled === true })) {
let name = m.Name; continue;
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; 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() { function checkQueryParameters() {
urlParams = commonFunctions.readQueryParameters(); urlParams = commonFunctions.readQueryParameters();
if(urlParams['mstid'] && urlParams['id'] && utage.groupedMissions[urlParams['mstid']] && utage.groupedMissions[urlParams['mstid']].Missions[urlParams['id']]) { if (languagesLoaded) {
document.getElementById('play-from-query').style.cssText = "position: fixed; z-index: 15; text-align: center; top: 50%; left: 50%; display: block;"; 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) { 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;"; 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 || !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 cont = document.getElementById("modal-container");
let misId = event.currentTarget.value;
let mis = utage.groupedMissions[misId]; let cust = event.currentTarget.value.split("|")[0];
if(!mis) { console.log(`Mission ${misId} not found`); return; } let questSceneMstId = event.currentTarget.value.split("|")[1];
let name = mis.Name;
let summary = mis.SummaryText; 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 = ""; let credits = "";
if(utage.missionTranslations[mis.MstId]) { let tl_key = utage.sceneTranslations[cust][questSceneMstId];
name = utage.missionTranslations[mis.MstId].Name || name;
summary = utage.missionTranslations[mis.MstId].SummaryText || summary; if(tl_key) {
credits = utage.missionTranslations[mis.MstId].Credits || credits; name = tl_key.Name || name;
summary = tl_key.SummaryText || summary;
credits = tl_key.Credits || credits;
} }
if(!credits) { if(!credits) {
if(selectedLang === "eng") { if(selectedLang === "eng") {
@ -186,15 +304,15 @@ function missionDropDownChanged(event) {
credits = "None"; credits = "None";
} }
} }
let chapterSelect = '<div><span>Chapter Select:</span><select id="ChapterSelect">'; let chapterSelect = '<div><span>Chapter Select:</span><select id="ChapterSelect">';
for(let k of Object.keys(mis.Missions)) { chapterSelect += `<option value="{All}">Play All</option>`
var m = mis.Missions[k]; for (const p of scene.Parts) {
if(m.Enabled) { chapterSelect += `<option value="${p}">${p}</option>`
chapterSelect += `<option value="${m.Id}">${m.Id}</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>'; chapterSelect += '</select></div>';
cont.innerHTML = ` cont.innerHTML = `
<div id="mission-modal" class="modal"> <div id="mission-modal" class="modal">
@ -209,8 +327,8 @@ function missionDropDownChanged(event) {
</div> </div>
<div id="modal-buttons"> <div id="modal-buttons">
<button onclick="closeMissionModal(event, false)">Close</button> <button onclick="closeMissionModal(event, false)">Close</button>
<span>MstId: ${mis.MstId}</span> <span>MstId: ${questSceneMstId}</span>
<button onclick="missionChanged(${mis.MstId})">Play</button> <button onclick="sceneSet('${questSceneMstId}', '${cust}')">Play</button>
</div> </div>
</div>`; </div>`;
document.getElementById("click-catcher").style.cssText = 'display: flex;'; document.getElementById("click-catcher").style.cssText = 'display: flex;';
@ -219,10 +337,18 @@ function missionDropDownChanged(event) {
function closeMissionModal(event, wasStarted) { function closeMissionModal(event, wasStarted) {
if(!wasStarted) { if(!wasStarted) {
document.getElementById('select-mission').value = prevMission; document.getElementById('select-scene').value = prevScene;
document.getElementById('select-quest').value = prevQuest;
} else { } 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); closeModal(event);
} }
@ -233,67 +359,85 @@ function closeModal(event) {
cont.innerHTML = ''; cont.innerHTML = '';
} }
function missionChanged(mstId, value) { function sceneSet(questSceneMstId, cust) {
let mst = utage.groupedMissions[mstId]; resetPlaylist();
let name = mst.Name; let part = document.getElementById('ChapterSelect');
if(utage.missionTranslations[mstId]) { utage.scenes[cust][questSceneMstId]['QuestSceneMstId'] = questSceneMstId;
name = utage.missionTranslations[mstId].Name || name; 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) { if(!audio) {
audio = new audioController(utage); audio = new audioController(utage);
audio.changeVolume(volume); audio.changeVolume(volume);
audio.mute(isMuted); audio.mute(isMuted);
player.audio = audio; player.audio = audio;
} }
player.resetAll() player.resetAll()
.then((success) => { .then((success) => {
let newMission = mst.Missions[value]; if (scenePlaylist.length || partPlaylist.length) {
checkMissionList(mst.Missions, value); document.getElementById("skip-button").style.cssText = "display: inline-block;";
currentMission = newMission; } else {
currentMissionMst = mstId; document.getElementById("skip-button").style.cssText = "display: none;";
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;
} }
let promises = []; let promises = [];
if(newMission.IsCustom) { if(currentScene.IsCustom) {
promises.push(utage.parseMissionFile(`${utage.rootDirectory}CustomData/${newMission.Path.replace('Asset/', '').replace('.utage', '').replace('.tsv', '_t.tsv')}`)); 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 { } 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); closeMissionModal(undefined, true);
Promise.all(promises) Promise.all(promises)
.then((success) => { .then((success) => {
document.getElementById("playing-title").innerText = `${name} (${value})`; document.getElementById("playing-title").innerText = `${name} (${part})`;
document.getElementById("title-tag").innerText = name; document.getElementById("title-tag").innerText = name;
currentPart = part;
player.playFile() player.playFile()
.then((success) => { .then((success) => {
if(currentMissionIndex !== currentMissionList.length - 1) { playNext();
missionChanged(currentMissionMst, mst.Missions[currentMissionList[currentMissionIndex+1]].Id);
} else {
player.resetAll();
resetMissions();
}
}, (failure) => { }, (failure) => {
player.resetAll(); player.resetAll();
resetMissions(); resetPlaylist();
console.log(failure); console.log(failure);
}); });
}, (failure) => { }, (failure) => {
resetMissions(); resetPlaylist();
console.log(failure); console.log(failure);
}); });
}, (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; } if(!event || !event.currentTarget || !event.currentTarget.value || event.currentTarget.value === '{Select}' || !languages.includes(event.currentTarget.value)) { return; }
selectedLang = event.currentTarget.value; selectedLang = event.currentTarget.value;
let missionPath = ''; let missionPath = '';
if(currentMission) { if(currentPart) {
missionPath = `${utage.rootDirectory}Js/Translations/Missions/${currentMission.Path.replace('Asset/Utage/', '').replace('Scenario/', '').replace('.utage', '').replace('.tsv', `_translations_${selectedLang}.json`)}`; 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) utage.setTranslationLanguage(selectedLang, missionPath)
.then((success) => { .then((success) => {
document.getElementById('text-container').className = selectedLang; document.getElementById('text-container').className = selectedLang;
buildMissionSelectList(); buildQuestSelectList();
buildSceneSelectList();
localStorage.setItem('language', selectedLang); localStorage.setItem('language', selectedLang);
}); });
} }
function checkMissionList(missions, currentvalue) { function resetPlaylist() {
currentMissionList = []; currentScene = {};
let i = 0; scenePlaylist = [];
for(var m of Object.keys(missions)) { currentPart = "";
currentMissionList.push(m); partPlaylist = [];
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;
document.getElementById("skip-button").style.cssText = "display: inline-block;"; document.getElementById("skip-button").style.cssText = "display: inline-block;";
document.getElementById("playing-title").innerText = 'None'; document.getElementById("playing-title").innerText = 'None';
document.getElementById("title-tag").innerText = version; document.getElementById("title-tag").innerText = version;
document.getElementById('select-mission').value = '{Select}'; document.getElementById("select-quest").value = '{Select}';
buildSceneSelectList();
} }
function onMainClick(event) { function onMainClick(event) {
@ -355,20 +488,10 @@ function hideUiClicked(event) {
function skipClicked(event) { function skipClicked(event) {
if(player.uiHidden) { if(player.uiHidden) {
player.hideUiClicked(event); player.hideUiClicked(event);
} else if(player.runEvent && currentMissionIndex !== currentMissionList.length - 1) { } else if(player.runEvent) {
event.preventDefault(); event.preventDefault();
event.stopPropagation(); event.stopPropagation();
//Find the next enabled mission playNext();
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();
} }
} }
@ -414,11 +537,17 @@ function openHelpModal(event) {
iOS: 11+, no audio<br/> iOS: 11+, no audio<br/>
</div> </div>
</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 style="margin-top: auto; text-align: center;">All Symphogear content belongs to its respective owners</div>
<div id="modal-buttons"> <div id="modal-buttons">
<button onclick="closeModal(event)">Close</button> <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>
</div>`; </div>`;
document.getElementById("click-catcher").style.cssText = 'display: flex;'; document.getElementById("click-catcher").style.cssText = 'display: flex;';
@ -432,9 +561,9 @@ function toggleMute(event) {
} }
localStorage.setItem('ismuted', isMuted); localStorage.setItem('ismuted', isMuted);
if(isMuted) { if(isMuted) {
document.getElementById('mute-button').innerText = "🔇"; document.getElementById('mute-button').innerText = emoji.Mute;
} else { } else {
document.getElementById('mute-button').innerText = "🔊"; document.getElementById('mute-button').innerText = emoji.LoudSound;
} }
} }
@ -473,7 +602,7 @@ function onFullScreenChange(event) {
} else { } else {
document.getElementById('other-controls-container').style.cssText = ""; document.getElementById('other-controls-container').style.cssText = "";
document.getElementById('title-container').style.cssText = ""; document.getElementById('title-container').style.cssText = "";
document.getElementById('fullscreen-button').innerText = ""; document.getElementById('fullscreen-button').innerText = emoji.HeavyPlusSign;
} }
onWindowResize(event, 0); onWindowResize(event, 0);
} }

19
Js/Pixi.min.js vendored

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@ -1,25 +1,20 @@
//http://glslsandbox.com/e#39992.0 //http://glslsandbox.com/e#39992.0
class Shaders { class Shaders {
constructor() { constructor() {
this.leftToRightFadeShader = ` this.leftToRightFadeShader = `
precision mediump float; precision mediump float;
varying vec2 vTextureCoord; varying vec2 vTextureCoord;
uniform vec2 dimensions; uniform vec4 inputPixel;
uniform vec4 filterArea; uniform highp vec4 outputFrame;
uniform float time; uniform float time;
uniform vec4 fadeincolor; uniform vec4 fadeincolor;
uniform vec4 fadeoutcolor; uniform vec4 fadeoutcolor;
vec2 mapCoord( vec2 coord ) {
coord *= filterArea.xy;
coord += filterArea.zw;
return coord;
}
void main( void ) { void main( void ) {
vec2 uv = vTextureCoord; vec2 uv = vTextureCoord * inputPixel.xy / outputFrame.zw;
vec2 mappedCoord = mapCoord(uv) / dimensions; vec2 mappedCoord = uv;
float step2 = time; float step2 = time;
float step3 = time + 0.2; float step3 = time + 0.2;
@ -35,21 +30,16 @@ class Shaders {
this.rightToLeftFadeShader = ` this.rightToLeftFadeShader = `
precision mediump float; precision mediump float;
varying vec2 vTextureCoord; varying vec2 vTextureCoord;
uniform vec2 dimensions; uniform vec4 inputPixel;
uniform vec4 filterArea; uniform highp vec4 outputFrame;
uniform float time; uniform float time;
uniform vec4 fadeincolor; uniform vec4 fadeincolor;
uniform vec4 fadeoutcolor; uniform vec4 fadeoutcolor;
vec2 mapCoord( vec2 coord ) {
coord *= filterArea.xy;
return coord;
}
void main( void ) { void main( void ) {
vec2 uv = vTextureCoord; vec2 uv = vTextureCoord * inputPixel.xy / outputFrame.zw;
vec2 mappedCoord = mapCoord(uv) / dimensions; vec2 mappedCoord = uv;
float step2 = (1.0 - time); float step2 = (1.0 - time);
float step3 = (1.0 - time) - 0.2; float step3 = (1.0 - time) - 0.2;
@ -65,22 +55,16 @@ class Shaders {
this.downToUpFadeShader = ` this.downToUpFadeShader = `
precision mediump float; precision mediump float;
varying vec2 vTextureCoord; varying vec2 vTextureCoord;
uniform vec2 dimensions; uniform vec4 inputPixel;
uniform vec4 filterArea; uniform highp vec4 outputFrame;
uniform float time; uniform float time;
uniform vec4 fadeincolor; uniform vec4 fadeincolor;
uniform vec4 fadeoutcolor; uniform vec4 fadeoutcolor;
vec2 mapCoord( vec2 coord ) {
coord *= filterArea.xy;
coord += filterArea.zw;
return coord;
}
void main( void ) { void main( void ) {
vec2 uv = vTextureCoord; vec2 uv = vTextureCoord * inputPixel.xy / outputFrame.zw;
vec2 mappedCoord = mapCoord(uv) / dimensions; vec2 mappedCoord = uv;
float step2 = (1.0 - time); float step2 = (1.0 - time);
float step3 = (1.0 - time) - 0.2; float step3 = (1.0 - time) - 0.2;
@ -96,22 +80,16 @@ class Shaders {
this.uptoDownFadeShader = ` this.uptoDownFadeShader = `
precision mediump float; precision mediump float;
varying vec2 vTextureCoord; varying vec2 vTextureCoord;
uniform vec2 dimensions; uniform vec4 inputPixel;
uniform vec4 filterArea; uniform highp vec4 outputFrame;
uniform float time; uniform float time;
uniform vec4 fadeincolor; uniform vec4 fadeincolor;
uniform vec4 fadeoutcolor; uniform vec4 fadeoutcolor;
vec2 mapCoord( vec2 coord ) {
coord *= filterArea.xy;
coord += filterArea.zw;
return coord;
}
void main( void ) { void main( void ) {
vec2 uv = vTextureCoord; vec2 uv = vTextureCoord * inputPixel.xy / outputFrame.zw;
vec2 mappedCoord = mapCoord(uv) / dimensions; vec2 mappedCoord = uv;
float step2 = time; float step2 = time;
float step3 = time + 0.2; float step3 = time + 0.2;
@ -128,7 +106,6 @@ class Shaders {
precision mediump float; precision mediump float;
varying vec2 vTextureCoord; varying vec2 vTextureCoord;
uniform sampler2D uSampler; uniform sampler2D uSampler;
uniform vec2 dimensions;
uniform float factor; uniform float factor;
vec4 Sepia( in vec4 color ) vec4 Sepia( in vec4 color )
@ -149,10 +126,11 @@ class Shaders {
} }
//https://jsfiddle.net/60e5pp8d/1/ //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() { buildShaders() {
let divalefttorightfade = new PIXI.Filter(null, this.leftToRightFadeShader, { let divalefttorightfade = new PIXI.Filter(null, this.leftToRightFadeShader, {
time: { type: 'f', value: 0 }, 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] }, fadeincolor: { type: 'v4', value: [0.0,0.0,0.0,1.0] },
fadeoutcolor: { type: 'v4', value: [0.0,0.0,0.0,0.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, { let divarighttoleftfade = new PIXI.Filter(null, this.rightToLeftFadeShader, {
time: { type: 'f', value: 0 }, 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] }, fadeincolor: { type: 'v4', value: [0.0,0.0,0.0,1.0] },
fadeoutcolor: { type: 'v4', value: [0.0,0.0,0.0,0.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, { let divauptodownfade = new PIXI.Filter(null, this.uptoDownFadeShader, {
time: { type: 'f', value: 0 }, 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] }, fadeincolor: { type: 'v4', value: [0.0,0.0,0.0,1.0] },
fadeoutcolor: { type: 'v4', value: [0.0,0.0,0.0,0.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, { let divadowntoupfade = new PIXI.Filter(null, this.downToUpFadeShader, {
time: { type: 'f', value: 0 }, 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] }, fadeincolor: { type: 'v4', value: [0.0,0.0,0.0,1.0] },
fadeoutcolor: { type: 'v4', value: [0.0,0.0,0.0,0.0] } fadeoutcolor: { type: 'v4', value: [0.0,0.0,0.0,0.0] }
}); });
@ -187,16 +162,13 @@ class Shaders {
this.shaders['divadowntoupfade'] = divadowntoupfade; this.shaders['divadowntoupfade'] = divadowntoupfade;
let sepia = new PIXI.Filter(null, this.sepiaShader, { let sepia = new PIXI.Filter(null, this.sepiaShader, {
factor: { type: 'f', value: 0.5 }, factor: { type: 'f', value: 0.5 }
dimensions: { type: 'v2', value: [baseDimensions.width, baseDimensions.height] }
}); });
sepia.apply = baseShaderApply; sepia.apply = baseShaderApply;
this.shaders['sepia'] = sepia; this.shaders['sepia'] = sepia;
function baseShaderApply(filterManager, input, output) { function baseShaderApply(filterManager, input, output) {
this.uniforms.dimensions[0] = input.sourceFrame.width;
this.uniforms.dimensions[1] = input.sourceFrame.height;
filterManager.applyFilter(this, input, output); filterManager.applyFilter(this, input, output);
} }
} }
} }

View File

@ -84,7 +84,6 @@ class TextFunctions {
function putText() { function putText() {
// skip over any HTML chars // skip over any HTML chars
this.dialogToDisplay.curPos = this.typeHtmlChars(this.dialogToDisplay.text, this.dialogToDisplay.curPos); 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) { if (this.dialogToDisplay.curPos === this.dialogToDisplay.text.length) {
this.showNextIndicator(true); this.showNextIndicator(true);
this.scrollingText = false; this.scrollingText = false;
@ -191,4 +190,4 @@ class TextFunctions {
this.scrollingText = false; this.scrollingText = false;
this.lineHeight = -1; this.lineHeight = -1;
} }
} }

@ -1 +1 @@
Subproject commit 533c48371ed01ed7265b6b5f052d1b2c3fce940f Subproject commit ac0bfbd699431e9befdd843379e7c91ad1014cec

View File

@ -6,7 +6,9 @@ class UtageInfo {
this.currentPlayingFile = []; this.currentPlayingFile = [];
this.rootDirectory = ``; this.rootDirectory = ``;
this.groupedMissions = {}; this.groupedMissions = {};
this.missionsList = []; this.quests = {};
this.questList = [];
this.scenes = {};
this.characterInfo = {}; this.characterInfo = {};
this.layerInfo = {}; this.layerInfo = {};
this.localizeInfo = {}; this.localizeInfo = {};
@ -16,51 +18,71 @@ class UtageInfo {
this.currentTranslation = 'eng'; this.currentTranslation = 'eng';
this.translationsInner = {}; this.translationsInner = {};
this.charTranslationsInner = {}; this.charTranslationsInner = {};
this.missionTranslationsInner = {}; this.questTranslationsInner = {};
this.sceneTranslationsInner = {};
this.bgmLoopData = {}; this.bgmLoopData = {};
this.macros = {};
} }
loadUtageSettings() { loadUtageSettings() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
let promises = [ let promises = [
commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/XduMissions.json`), //0 commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/XduQuest.json`), //0
commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Character.tsv`), //1 commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/XduScene.json`), //1
commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Layer.tsv`), //2 commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Character.tsv`), //2
commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Localize.tsv`), //3 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/Param.tsv`),
//commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Scenario.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/Sound.tsv`), //5
commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Texture.tsv`), //5 commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Texture.tsv`), //6
commonFunctions.getFileJson(`${this.rootDirectory}Js/BgmLoop.json`), //6 commonFunctions.getFileJson(`${this.rootDirectory}XDUData/Bgm/BgmLoop.json`), //7
commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/XduMissionsCustom.json`), //7 commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/XduQuestCustom.json`), //8
commonFunctions.getFileText(`${this.rootDirectory}CustomData/Utage/Diva/Settings/CustomCharacter.tsv`), //8 commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/XduSceneCustom.json`), //9
commonFunctions.getFileText(`${this.rootDirectory}CustomData/Utage/Diva/Settings/CustomSound.tsv`), //9 commonFunctions.getFileText(`${this.rootDirectory}CustomData/Utage/Diva/Settings/CustomCharacter.tsv`), //10
commonFunctions.getFileText(`${this.rootDirectory}CustomData/Utage/Diva/Settings/CustomTexture.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) Promise.all(promises)
.then((success) => { .then((success) => {
this.groupMissions(success[0], success[7]); this.quests[CUSTOM.stock] = success[0];
this.missionsList = Object.keys(this.groupedMissions).map((k) => { this.questList = Object.keys(this.quests[CUSTOM.stock]).map((k) => {
return {Name: this.groupedMissions[k].Name, MstId: this.groupedMissions[k].MstId}; return {QuestMstId: k, Name: this.quests[CUSTOM.stock][k].Name, IsCustom: false};
}); });
this.missionsList.sort(); this.quests[CUSTOM.custom] = success[8];
this.parseCharacterInfo(success[1]); for (const k of Object.keys(this.quests[CUSTOM.custom])) {
this.parseLayerInfo(success[2]); this.questList.push({QuestMstId: k, Name: this.quests[CUSTOM.custom][k].Name, IsCustom: true});
this.parseLocalizeInfo(success[3]); }
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.parseParamInfo(success[4]);
this.parseSoundInfo(success[4]); this.parseSoundInfo(success[5]);
this.parseTextureInfo(success[5]); this.parseTextureInfo(success[6]);
this.bgmLoopData = success[6]; this.bgmLoopData = success[7];
this.parseCharacterInfo(success[8], true); this.scenes[CUSTOM.custom] = success[9];
this.parseSoundInfo(success[9], true); for (const k of Object.keys(this.scenes[CUSTOM.custom])) {
this.parseTextureInfo(success[10], true); 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(); resolve();
}, (failure) => { }, (failure) => {
reject(failure); reject(failure);
}); });
}); });
} }
parseMissionFile(file) { parseMissionFile(file) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
commonFunctions.getFileText(file) commonFunctions.getFileText(file)
@ -86,41 +108,7 @@ 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() { get translations() {
return this.translationsInner[this.currentTranslation]; return this.translationsInner[this.currentTranslation];
} }
@ -129,20 +117,40 @@ class UtageInfo {
return this.charTranslationsInner[this.currentTranslation]; return this.charTranslationsInner[this.currentTranslation];
} }
get missionTranslations() { get questTranslations() {
return this.missionTranslationsInner[this.currentTranslation]; return this.questTranslationsInner[this.currentTranslation];
}
get sceneTranslations() {
return this.sceneTranslationsInner[this.currentTranslation];
} }
setTranslationLanguage(key, missionPath) { setTranslationLanguage(key, missionPath) {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
this.currentTranslation = key; this.currentTranslation = key;
let promises = [this.loadCharacterTranslations(key), let promises = [this.loadCharacterTranslations(key),
this.loadMissionNamesTranslations(key)]; this.loadQuestNamesTranslations(key),
this.loadSceneNamesTranslations(key)];
if(missionPath) { if(missionPath) {
promises.push(this.loadMissionTranslation(missionPath, key)); promises.push(this.loadMissionTranslation(missionPath, key));
} }
Promise.all(promises) Promise.all(promises)
.then((success) => { .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(); resolve();
}, (failure) => { }, (failure) => {
console.log(failure); console.log(failure);
@ -173,7 +181,7 @@ class UtageInfo {
if(this.charTranslationsInner[this.currentTranslation]) { if(this.charTranslationsInner[this.currentTranslation]) {
resolve(); resolve();
} else { } else {
commonFunctions.getFileJson(`${utage.rootDirectory}Js/Translations/nametranslations_${this.currentTranslation}.json`) commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/nametranslations_${this.currentTranslation}.json`)
.then((success) => { .then((success) => {
this.charTranslationsInner[this.currentTranslation] = success; this.charTranslationsInner[this.currentTranslation] = success;
resolve(); resolve();
@ -185,21 +193,20 @@ class UtageInfo {
}); });
} }
loadMissionNamesTranslations() { loadQuestNamesTranslations() {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
if(this.missionTranslationsInner[this.currentTranslation]) { if(this.questTranslationsInner[this.currentTranslation]) {
resolve(); resolve();
} else { } else {
var promises = [ var promises = [
commonFunctions.getFileJson(`${utage.rootDirectory}Js/Translations/XduMissionsNames_${this.currentTranslation}.json`), commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/XduQuestNames_${this.currentTranslation}.json`),
commonFunctions.getFileJson(`${utage.rootDirectory}Js/Translations/XduMissionsNamesCustom_${this.currentTranslation}.json`) commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/XduQuestNamesCustom_${this.currentTranslation}.json`)
]; ];
Promise.all(promises) Promise.all(promises)
.then((success) => { .then((success) => {
for(let m of Object.keys(success[1])) { this.questTranslationsInner[this.currentTranslation] = {};
success[0][m] = success[1][m]; this.questTranslationsInner[this.currentTranslation][CUSTOM.stock] = success[0];
} this.questTranslationsInner[this.currentTranslation][CUSTOM.custom] = success[1];
this.missionTranslationsInner[this.currentTranslation] = success[0];
resolve(); resolve();
}, (failure) => { }, (failure) => {
console.log(failure); console.log(failure);
@ -208,6 +215,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 //http://madnesslabo.net/utage/?page_id=4521&lang=en
parseCharacterInfo(text, custom = false) { parseCharacterInfo(text, custom = false) {
@ -362,4 +422,4 @@ class UtageInfo {
resetTranslations() { resetTranslations() {
this.translationsInner = {}; this.translationsInner = {};
} }
} }

View File

@ -15,10 +15,9 @@
<script src="Js/TextFunctions.js"></script> <script src="Js/TextFunctions.js"></script>
<script src="Js/UtageParse.js"></script> <script src="Js/UtageParse.js"></script>
<script src="Js/Audio.js"></script> <script src="Js/Audio.js"></script>
<script src="Js/Player.js"></script> <script src="Js/Player.js"></script>-->
<script src="Js/Main.js"></script> -->
<script src="Js/XduPlayer.min.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-utage">Loading Utage Data...</h2>
<h2 id="loading-font">Loading Page Data...</h2> <h2 id="loading-font">Loading Page Data...</h2>
</div> </div>
@ -26,10 +25,11 @@
<div id="title-container"><span>Now Playing: </span><span id="playing-title">None</span></div> <div id="title-container"><span>Now Playing: </span><span id="playing-title">None</span></div>
<div id="other-controls-container"> <div id="other-controls-container">
<div id="volume-control"> <div id="volume-control">
<span onclick="toggleMute(event)" id="mute-button">🔊</span> <span onclick="toggleMute(event)" id="mute-button">&#128266;</span> <!-- loud_sound -->
<input onchange="onVolumeChange(event)" id="volume-range" value="50" type="range" min="0" max="100" step="1"/> <input onchange="onVolumeChange(event)" id="volume-range" value="50" type="range" min="0" max="100" step="1"/>
</div> </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> <select id="select-language" onchange="languageChanged(event);"></select>
<a style="font-size: 20px; margin-left: 5px;" title="info/help" onclick="openHelpModal(event)">?</a> <a style="font-size: 20px; margin-left: 5px;" title="info/help" onclick="openHelpModal(event)">?</a>
</div> </div>
@ -37,7 +37,7 @@
The canvas then resizes as the canvas does and the text-container uses transform scale based off this resolution --> 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="app-container" onclick="onMainClick(event);">
<div id="text-container"> <div id="text-container">
<div id="fullscreen-button" onclick="toggleFullscreen(event)"></div> <div id="fullscreen-button" onclick="toggleFullscreen(event)">&#10133;</div> <!-- heavy_plus_sign -->
<img id="main-ui-img" class="hidden" src="Images/newui_main.png"/> <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> <button id="play-from-query" onclick="playFromQuery(event)" style="display: none;">Play</button>
<div id="title" class="hidden">Title Text</div> <div id="title" class="hidden">Title Text</div>
@ -78,4 +78,4 @@
<span style="font-family: 'SourceCodePro-Regular'">test</span> --> <span style="font-family: 'SourceCodePro-Regular'">test</span> -->
</div> </div>
</body> </body>
</html> </html>

View File

@ -26,9 +26,6 @@ const cssToCopy = [
"Css/main.min.css", "Css/main.min.css",
"Css/generic.min.css" "Css/generic.min.css"
]; ];
const jsonFiles = [
"Js/BgmLoop.json",
];
const translations = [ const translations = [
"Js/Translations/**" "Js/Translations/**"
]; ];
@ -50,7 +47,6 @@ gulp.task('dist', gulp.series(
buildCss, buildCss,
copyCss copyCss
), ),
buildJson,
buildJsonTranslations, buildJsonTranslations,
copyHtml, copyHtml,
copyImages, copyImages,
@ -117,12 +113,6 @@ function copyCustomData() {
.pipe(gulp.dest('Dist/CustomData')); .pipe(gulp.dest('Dist/CustomData'));
} }
function buildJson() {
return gulp.src(jsonFiles)
.pipe(jsonmin())
.pipe(gulp.dest('Dist/Js'));
}
function buildJsonTranslations() { function buildJsonTranslations() {
return gulp.src(translations) return gulp.src(translations)
.pipe(jsonmin()) .pipe(jsonmin())

14467
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -1,16 +1,18 @@
{ {
"name": "XduPlayer", "name": "XduPlayer",
"version": "1.0.0", "version": "1.3.0",
"private": true, "private": true,
"license": "MIT", "license": "MIT",
"devDependencies": { "devDependencies": {
"gulp": "github:gulpjs/gulp#4.0", "gulp": "~4.0.2",
"gulp-concat": "~2.6.1", "gulp-concat": "~2.6.1",
"gulp-cssmin": "~0.2.0", "gulp-cssmin": "~0.2.0",
"gulp-jsonminify": "^1.1.0", "gulp-jsonminify": "^1.1.0",
"gulp-rename": "~1.2.2", "gulp-rename": "~1.2.2",
"gulp-sourcemaps": "~2.6.4", "gulp-sourcemaps": "~2.6.4",
"gulp-uglify": "~3.0.0", "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"
} }
} }