6
0

Merge branch 'master' into release

Dieser Commit ist enthalten in:
louis f 2018-06-14 16:30:13 +09:00
Commit 7e8eeffe4d
10 geänderte Dateien mit 99 neuen und 12091 gelöschten Zeilen

Datei anzeigen

@ -6,3 +6,12 @@ Updated Pixi JS to 4.8.1.
Support for custom missions.
Made translations a submodule.
Various fixes to xdu functions.
## V1.2.0 (2018-06-13)
Added title tag that updates with current mission.
Added null check for pixi sprite calculateverticies because it sometimes makes a texture invalid when it shouldn't be. This is kinda a hack and should be investigated deeper in the future.
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.

Datei anzeigen

@ -54,6 +54,8 @@
body { margin: 0; }
.flex-grow { flex-grow: 1; }
.centered { position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; }
.hidden { opacity: 0; }
@ -66,6 +68,8 @@ body { margin: 0; }
#text-container { color: white; position: absolute; margin: auto; height: 750px; width: 1334px; font-family: 'FOT-RodinNTLGPro'; }
#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 #diva { position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); text-align: center; font-size: 34px; transition: opacity 0.3s; cursor: default; user-select: none; }
@ -116,7 +120,7 @@ body { margin: 0; }
#modal-container { position: fixed; z-index: 16; top: 50%; left: 50%; transform: translate(-50%, -50%); }
.modal { background-color: #393939; color: #F0F0F0; height: 400px; width: 350px; position: relative; margin: auto; display: flex; flex-direction: column; align-items: center; box-shadow: 0px 0px 20px 3px #070707; border-radius: 7px; box-sizing: border-box; padding: 10px; }
.modal { background-color: #393939; color: #F0F0F0; height: 425px; width: 350px; position: relative; margin: auto; display: flex; flex-direction: column; align-items: center; box-shadow: 0px 0px 20px 3px #070707; border-radius: 7px; box-sizing: border-box; padding: 10px; }
#mission-modal { }
@ -124,15 +128,15 @@ body { margin: 0; }
#mission-modal #mission-icon { display: none; margin: 10px 0 10px 0; object-fit: contain; }
#mission-modal span { max-width: 100%; word-break: break-word; max-height: 120px; overflow: auto;}
#mission-modal #mission-summary { max-width: 100%; word-break: break-word; margin-bottom: 5px; min-height: 0; overflow-y: auto; }
#mission-modal .mission-title { font-weight: bold; text-align: center; }
#mission-modal #mission-ids { margin-top: auto; width: 100%; display: flex; flex-direction: column; align-items: center; }
#mission-modal #mission-ids { margin: 5px 0 5px 0; width: 100%; display: flex; flex-direction: column; align-items: center; min-height: 21px; }
#mission-modal #mission-ids div { display: flex; align-items: center; }
#modal-buttons { bottom: 0; margin-top: auto; width: 100%; display: flex; justify-content: space-between; }
#modal-buttons { bottom: 0; margin-top: auto; width: 100%; display: flex; justify-content: space-between; min-height: 21px; }
@media screen and (max-width: 812px) {
#modal-container { top: 0; bottom: 0; left: 0; right: 0; transform: none; }

Datei anzeigen

@ -11,7 +11,7 @@ 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"];
const version = "YameteTomete XDUPlayer V1.1.0";
const version = "YameteTomete XDUPlayer V1.2.0";
let bodyLoaded = false;
let utageLoaded = false;
let languagesLoaded = false;
@ -26,12 +26,17 @@ let screenh = Math.max(document.documentElement.clientHeight, window.innerHeight
let screenSizeTimeout = undefined;
let isMuted = false;
let volume = 0.5;
let fullScreen = false;
let prevMission = '{Select}';
const availableMstIds = [202070, 202071, 202013, 338001, 338002, 338003, 338004]//[202070, 202013, 338001, 338002, 338003, 338004, 338005, 338006, 338007, 338009, 338010, 338011];
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);
}
(function startLoad() {
@ -122,7 +127,7 @@ function buildMissionSelectList() {
opt.innerText = 'Select Mission';
} else {
let m = utage.missionsList[i];
if(!availableMstIds.includes(m.MstId)) {
if(!Object.keys(utage.groupedMissions[m.MstId].Missions).some((mis) => { return utage.groupedMissions[m.MstId].Missions[mis].Enabled === true })) {
continue;
}
opt.setAttribute('value', m.MstId);
@ -168,14 +173,25 @@ function missionDropDownChanged(event) {
if(!mis) { console.log(`Mission ${misId} not found`); return; }
let name = mis.Name;
let summary = mis.SummaryText;
let credits = "";
if(utage.missionTranslations[mis.MstId]) {
name = utage.missionTranslations[mis.MstId].Name || name;
summary = utage.missionTranslations[mis.MstId].SummaryText || summary;
credits = utage.missionTranslations[mis.MstId].Credits || credits;
}
if(!credits) {
if(selectedLang === "eng") {
credits = "YameteTomete";
} else {
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];
chapterSelect += `<option value="${m.Id}">${m.Id}</option>`
if(m.Enabled) {
chapterSelect += `<option value="${m.Id}">${m.Id}</option>`
}
}
chapterSelect += '</select></div>';
cont.innerHTML = `
@ -183,7 +199,9 @@ function missionDropDownChanged(event) {
<span class="mission-title">${name || 'none'}</span>
<img id="mission-detail" src="${utage.rootDirectory}XDUData/Asset/Image/Quest/Snap/Detail/${mis.MstId}.png"/>
<img id="mission-icon" src="${utage.rootDirectory}XDUData/Asset/Image/Quest/Snap/Icon/${mis.MstId}.png"/>
<span>Summary: ${summary || 'none'}</span>
<div id="mission-summary">Summary: ${summary || 'none'}</div>
<div class="flex-grow"></div>
<div>Credits (${selectedLang}): ${credits}</div>
<div id="mission-ids">
${chapterSelect}
</div>
@ -234,6 +252,10 @@ function missionChanged(mstId, value) {
checkMissionList(mst.Missions, value);
currentMission = newMission;
currentMissionMst = mstId;
if(!currentMission.Enabled) {
missionChanged(currentMissionMst, mst.Missions[currentMissionList[currentMissionIndex+1]].Id);
return;
}
let promises = [
utage.parseMissionFile(`${utage.rootDirectory}XDUData/${newMission.Path.replace('Asset/', '').replace('.utage', '').replace('.tsv', '_t.tsv')}`),
utage.loadMissionTranslation(`${utage.rootDirectory}Js/Translations/Missions/${currentMission.Path.replace('Asset/Utage/', '').replace('Scenario/', '').replace('.utage', '').replace('.tsv', `_translations_${selectedLang}.json`)}`)
@ -246,7 +268,7 @@ function missionChanged(mstId, value) {
player.playFile()
.then((success) => {
if(currentMissionIndex !== currentMissionList.length - 1) {
missionChanged(currentMissionMst, mst.Missions[currentMissionList[currentMissionIndex+1]].Id)
missionChanged(currentMissionMst, mst.Missions[currentMissionList[currentMissionIndex+1]].Id);
} else {
player.resetAll();
resetMissions();
@ -364,7 +386,6 @@ function openHelpModal(event) {
<div style="margin: 5px;">Mobile:<br/>
Android: 5+, Updated Chrome/Firefox/Edge<br/>
iOS: 11+, no audio<br/>
Recommended to request desktop site
</div>
</div>
<a style="margin-top: auto; text-align: center; "href="https://discord.gg/fpQZQ8g">YameteTomete Discord</a>
@ -399,18 +420,50 @@ function onVolumeChange(event) {
localStorage.setItem('volume', volume);
}
function onWindowResize(event) {
function toggleFullscreen(event) {
event.preventDefault();
event.stopPropagation();
fullScreen = !fullScreen;
let docEl = document.documentElement;
if(fullScreen) {
let requestFullScreen = docEl.requestFullscreen || docEl.mozRequestFullScreen || docEl.webkitRequestFullScreen || docEl.msRequestFullscreen;
if(requestFullScreen && !document.fullscreenElement && !document.mozFullScreenElement && !document.webkitFullscreenElement && !document.msFullscreenElement) {
requestFullScreen.call(docEl);
}
} else {
let cancelFullScreen = document.exitFullscreen || document.mozCancelFullScreen || document.webkitExitFullscreen || document.msExitFullscreen;
if(cancelFullScreen) {
cancelFullScreen.call(document);
}
}
}
function onFullScreenChange(event) {
if(document.fullscreenElement || document.mozFullScreenElement || document.webkitFullscreenElement || document.msFullscreenElement) {
fullScreen = true;
document.getElementById('other-controls-container').style.cssText = "display: none;";
document.getElementById('title-container').style.cssText = "display: none;";
document.getElementById('fullscreen-button').innerText = "✖️";
} else {
document.getElementById('other-controls-container').style.cssText = "";
document.getElementById('title-container').style.cssText = "";
document.getElementById('fullscreen-button').innerText = "";
}
onWindowResize(event, 0);
}
function onWindowResize(event, delay = 400) {
if(screenSizeTimeout) {
clearTimeout(screenSizeTimeout);
screenSizeTimeout = undefined;
}
screenw = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
screenh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
let topContainerHeight = document.getElementById('other-controls-container').offsetHeight;
topContainerHeight += document.getElementById('title-container').offsetHeight;
let res = commonFunctions.getNewResolution(baseDimensions, screenw, screenh, (topContainerHeight ? topContainerHeight + 6 : topContainerHeight));
screenSizeTimeout = setTimeout(() => {
screenw = Math.max(document.documentElement.clientWidth, window.innerWidth || 0);
screenh = Math.max(document.documentElement.clientHeight, window.innerHeight || 0);
let topContainerHeight = document.getElementById('other-controls-container').offsetHeight + 6;
topContainerHeight += document.getElementById('title-container').offsetHeight;
let res = commonFunctions.getNewResolution(baseDimensions, screenw, screenh, topContainerHeight);
player.updateResolution(res);
document.getElementById('app-container').style.cssText = `width: ${res.width}px; height: ${res.height}px;`;
}, 400);
}, delay);
}

Datei anzeigen

@ -1443,8 +1443,14 @@ class Player {
updateResolution(res) {
let newScale = res.height / baseDimensions.height;
this.pixi.app.stage.scale.set(newScale, newScale);
this.pixi.app.renderer.resize(res.width, res.height);
//Set the scale by the pixel ratio so pixi makes the stage the proper size
this.pixi.app.stage.scale.set(newScale * window.devicePixelRatio, newScale * window.devicePixelRatio);
//Sizes the canvas/pixi's renderer to the actual render resolution
this.pixi.app.renderer.resize(res.width * window.devicePixelRatio, res.height * window.devicePixelRatio);
//Css size overwrites the display size of the canvas
this.pixi.app.view.style.width = res.width;
this.pixi.app.view.style.height = res.height;
//Transform the text container to be the right scale, browser handles all dpi stuff for html elements itself
document.getElementById('text-container').style.cssText = `transform: scale(${newScale})`;
}

@ -1 +1 @@
Subproject commit 8ad734b4873e63ebc4d351eb3b443419b8977315
Subproject commit 5b7839ae9b5e47b5bd29d64c06c22a3b000d8959

Datei anzeigen

@ -23,7 +23,7 @@ class UtageInfo {
loadUtageSettings(resolve, reject) {
return new Promise((resolve, reject) => {
let promises = [
commonFunctions.getFileJson(`${this.rootDirectory}Js/XduMissions.json`),
commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/XduMissions.json`),
commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Character.tsv`),
commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Layer.tsv`),
commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Localize.tsv`),
@ -32,7 +32,7 @@ class UtageInfo {
commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Sound.tsv`),
commonFunctions.getFileText(`${this.rootDirectory}XDUData/Utage/Diva/Settings/Texture.tsv`),
commonFunctions.getFileJson(`${this.rootDirectory}Js/BgmLoop.json`),
commonFunctions.getFileJson(`${this.rootDirectory}Js/XduMissionsCustom.json`),
commonFunctions.getFileJson(`${this.rootDirectory}Js/Translations/XduMissionsCustom.json`),
];
Promise.all(promises)
.then((success) => {
@ -92,9 +92,9 @@ class UtageInfo {
MstId: mis.MstId,
Missions: {}
}
this.groupedMissions[mis.MstId].Missions[mis.Id] = { Id: mis.Id, Path: mis.Path };
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 };
this.groupedMissions[mis.MstId].Missions[mis.Id] = { Id: mis.Id, Path: mis.Path, Enabled: mis.Enabled };
}
}
for(let key of Object.keys(customMissions)) {
@ -106,9 +106,9 @@ class UtageInfo {
MstId: mis.MstId,
Missions: {}
}
this.groupedMissions[mis.MstId].Missions[mis.Id] = { Id: mis.Id, Path: mis.Path };
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 };
this.groupedMissions[mis.MstId].Missions[mis.Id] = { Id: mis.Id, Path: mis.Path, Enabled: mis.Enabled };
}
}
}

Datei-Diff unterdrückt, da er zu groß ist Diff laden

Datei anzeigen

@ -1,226 +0,0 @@
{
"312000111": {
"Path": "Asset/Utage/event011/Scenario/312000111.tsv.utage",
"MstId": 338001,
"Id": "312000111",
"Name": "EV31-1:黒衣の花嫁",
"SummaryText": ""
},
"312000112": {
"Path": "Asset/Utage/event011/Scenario/312000112.tsv.utage",
"MstId": 338001,
"Id": "312000112",
"Name": "EV31-1:黒衣の花嫁",
"SummaryText": ""
},
"312000121": {
"Path": "Asset/Utage/event011/Scenario/312000121.tsv.utage",
"MstId": 338001,
"Id": "312000121",
"Name": "EV31-1:黒衣の花嫁",
"SummaryText": ""
},
"312000122": {
"Path": "Asset/Utage/event011/Scenario/312000122.tsv.utage",
"MstId": 338001,
"Id": "312000122",
"Name": "EV31-1:黒衣の花嫁",
"SummaryText": ""
},
"312000131": {
"Path": "Asset/Utage/event011/Scenario/312000131.tsv.utage",
"MstId": 338001,
"Id": "312000131",
"Name": "EV31-1:黒衣の花嫁",
"SummaryText": ""
},
"312000132": {
"Path": "Asset/Utage/event011/Scenario/312000132.tsv.utage",
"MstId": 338001,
"Id": "312000132",
"Name": "EV31-1:黒衣の花嫁",
"SummaryText": ""
},
"312000141": {
"Path": "Asset/Utage/event011/Scenario/312000141.tsv.utage",
"MstId": 338001,
"Id": "312000141",
"Name": "EV31-1:黒衣の花嫁",
"SummaryText": ""
},
"312000142": {
"Path": "Asset/Utage/event011/Scenario/312000142.tsv.utage",
"MstId": 338001,
"Id": "312000142",
"Name": "EV31-1:黒衣の花嫁",
"SummaryText": ""
},
"312000211": {
"Path": "Asset/Utage/event011/Scenario/312000211.tsv.utage",
"MstId": 338002,
"Id": "312000211",
"Name": "EV31-2:純白の光明",
"SummaryText": ""
},
"312000212": {
"Path": "Asset/Utage/event011/Scenario/312000212.tsv.utage",
"MstId": 338002,
"Id": "312000212",
"Name": "EV31-2:純白の光明",
"SummaryText": ""
},
"312000221": {
"Path": "Asset/Utage/event011/Scenario/312000221.tsv.utage",
"MstId": 338002,
"Id": "312000221",
"Name": "EV31-2:純白の光明",
"SummaryText": ""
},
"312000222": {
"Path": "Asset/Utage/event011/Scenario/312000222.tsv.utage",
"MstId": 338002,
"Id": "312000222",
"Name": "EV31-2:純白の光明",
"SummaryText": ""
},
"312000311": {
"Path": "Asset/Utage/event011/Scenario/312000311.tsv.utage",
"MstId": 338003,
"Id": "312000311",
"Name": "EV31-3:立ちはだかる黒",
"SummaryText": ""
},
"312000312": {
"Path": "Asset/Utage/event011/Scenario/312000312.tsv.utage",
"MstId": 338003,
"Id": "312000312",
"Name": "EV31-3:立ちはだかる黒",
"SummaryText": ""
},
"312000411": {
"Path": "Asset/Utage/event011/Scenario/312000411.tsv.utage",
"MstId": 338004,
"Id": "312000411",
"Name": "EV31-4:その身に纏う純白",
"SummaryText": ""
},
"312000412": {
"Path": "Asset/Utage/event011/Scenario/312000412.tsv.utage",
"MstId": 338004,
"Id": "312000412",
"Name": "EV31-4:その身に纏う純白",
"SummaryText": ""
},
"312000421": {
"Path": "Asset/Utage/event011/Scenario/312000421.tsv.utage",
"MstId": 338004,
"Id": "312000421",
"Name": "EV31-4:その身に纏う純白",
"SummaryText": ""
},
"312000422": {
"Path": "Asset/Utage/event011/Scenario/312000422.tsv.utage",
"MstId": 338004,
"Id": "312000422",
"Name": "EV31-4:その身に纏う純白",
"SummaryText": ""
},
"312000511": {
"Path": "Asset/Utage/event011/Scenario/312000511.tsv.utage",
"MstId": 338005,
"Id": "312000511",
"Name": "EV31-5:ブルー……。",
"SummaryText": ""
},
"312000512": {
"Path": "Asset/Utage/event011/Scenario/312000512.tsv.utage",
"MstId": 338005,
"Id": "312000512",
"Name": "EV31-5:ブルー……。",
"SummaryText": ""
},
"312000611": {
"Path": "Asset/Utage/event011/Scenario/312000611.tsv.utage",
"MstId": 338006,
"Id": "312000611",
"Name": "EV31-6:マリッジブルー",
"SummaryText": ""
},
"312000612": {
"Path": "Asset/Utage/event011/Scenario/312000612.tsv.utage",
"MstId": 338006,
"Id": "312000612",
"Name": "EV31-6:マリッジブルー",
"SummaryText": ""
},
"312000711": {
"Path": "Asset/Utage/event011/Scenario/312000711.tsv.utage",
"MstId": 338007,
"Id": "312000711",
"Name": "EV31-7:ウェディングドレス?",
"SummaryText": ""
},
"312000712": {
"Path": "Asset/Utage/event011/Scenario/312000712.tsv.utage",
"MstId": 338007,
"Id": "312000712",
"Name": "EV31-7:ウェディングドレス?",
"SummaryText": ""
},
"312000811": {
"Path": "Asset/Utage/event011/Scenario/312000811.tsv.utage",
"MstId": 338008,
"Id": "312000811",
"Name": "EV31-8:幸せを呼び起こせッ!",
"SummaryText": ""
},
"312000812": {
"Path": "Asset/Utage/event011/Scenario/312000812.tsv.utage",
"MstId": 338008,
"Id": "312000812",
"Name": "EV31-8:幸せを呼び起こせッ!",
"SummaryText": ""
},
"312000821": {
"Path": "Asset/Utage/event011/Scenario/312000821.tsv.utage",
"MstId": 338008,
"Id": "312000821",
"Name": "EV31-8:幸せを呼び起こせッ!",
"SummaryText": ""
},
"312000822": {
"Path": "Asset/Utage/event011/Scenario/312000822.tsv.utage",
"MstId": 338008,
"Id": "312000822",
"Name": "EV31-8:幸せを呼び起こせッ!",
"SummaryText": ""
},
"312000911": {
"Path": "Asset/Utage/event011/Scenario/312000911.tsv.utage",
"MstId": 338009,
"Id": "312000911",
"Name": "EV31-9:ブライダル戦姫ッ!",
"SummaryText": ""
},
"312000912": {
"Path": "Asset/Utage/event011/Scenario/312000912.tsv.utage",
"MstId": 338009,
"Id": "312000912",
"Name": "EV31-9:ブライダル戦姫ッ!",
"SummaryText": ""
},
"312001011": {
"Path": "Asset/Utage/event011/Scenario/312001011.tsv.utage",
"MstId": 338010,
"Id": "312001011",
"Name": "EV31-10:ウェディングドレスッ!",
"SummaryText": ""
},
"312001111": {
"Path": "Asset/Utage/event011/Scenario/312001111.tsv.utage",
"MstId": 338011,
"Id": "312001111",
"Name": "EV31-11:ふたりのしあわせ",
"SummaryText": ""
}
}

Datei anzeigen

@ -35,6 +35,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>
<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>

Datei anzeigen

@ -28,8 +28,6 @@ const cssToCopy = [
];
const jsonFiles = [
"Js/BgmLoop.json",
"Js/XduMissions.json",
"Js/XduMissionsCustom.json"
];
const translations = [
"Js/Translations/**"