Added mission select modal.

Changed file structure so images called like file:// can be loaded properly.
Some commenting.
This commit is contained in:
fire bingo 2018-04-28 17:36:08 -07:00
parent 7a5c02d736
commit 57ddeb08f4
10 changed files with 11242 additions and 10670 deletions

1
.gitignore vendored
View File

@ -8,3 +8,4 @@ web.config
/Fonts
/Dist
/Css/main.min.css
/Js/XduPlayer.min.js

View File

@ -108,6 +108,33 @@
#volume-control #mute-button { cursor: pointer; }
@media screen and (max-width: 550px) {
#click-catcher { background-color: #000000; opacity: 0.7; position: fixed; z-index: 15; top: 0; bottom: 0; left: 0; right: 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; }
#mission-modal { }
#mission-modal #mission-detail { display: block; width: 100%; margin: 10px 0 10px 0; object-fit: contain; }
#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-title { text-align: center; }
#mission-modal #mission-ids { margin-top: auto; width: 100%; display: flex; justify-content: space-around; }
#modal-buttons { bottom: 0; margin-top: 10px; width: 100%; display: flex; justify-content: space-between; }
@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; }
#other-controls-container { width: 100vw; }
}
@media screen and (max-height: 600px) {
#mission-modal #mission-detail { display: none; }
#mission-modal #mission-icon { display: block; max-height: 20%; margin: 10px 0 10px 0; object-fit: contain; }
}

View File

@ -173,7 +173,7 @@ class commonFunctions {
}
static getPropertiesFromTweenCommand(props, reverseY = true) {
var retval = {};
let retval = {};
let indexX = props.indexOf("x=");
if(indexX !== -1) {
retval.x = "";

View File

@ -20,6 +20,7 @@ let screenh = Math.max(document.documentElement.clientHeight, window.innerHeight
let screenSizeTimeout = undefined;
let isMuted = false;
let volume = 0.5;
let prevMission = '{Select}';
function onBodyLoaded() {
bodyLoaded = true;
@ -99,9 +100,9 @@ function buildMissionSelectList() {
opt.innerText = 'Select Mission';
} else {
let m = utage.missionsList[i];
//if(m.includes('MA1-') || m.includes('MA2-')|| m.includes('MA3-')) {
// continue;
//}
if(!m.includes('MA3.5-')) {
continue;
}
opt.setAttribute('value', m);
opt.innerText = m.replace('|', ' - ');
}
@ -121,16 +122,52 @@ function buildLanguageList() {
selectBox.value = selectedLang;
}
function missionChanged(event) {
function missionDropDownChanged(event) {
if(!event || !event.currentTarget || !event.currentTarget.value || event.currentTarget.value === '{Select}') { return; }
let newMission = utage.availableMissions[event.currentTarget.value.split('|')[0]];
let cont = document.getElementById("modal-container");
let misId = event.currentTarget.value.split('|')[0];
let mis = utage.availableMissions[misId];
if(!mis) { console.log(`Mission ${misId} not found`); return; }
cont.innerHTML = '' +
'<div id="mission-modal" class="modal">' +
`<span class="mission-title">Name: ${mis.Name || 'none'}</span>` +
`<img id="mission-detail" src="${rootUrl}XDUPlayer/XDUData/Asset/Image/Quest/Snap/Detail/${mis.MstId}.png">` +
`<img id="mission-icon" src="${rootUrl}XDUPlayer/XDUData/Asset/Image/Quest/Snap/Icon/${mis.MstId}.png">` +
`<span>Summary: ${mis.SummaryText || 'none'}</span>` +
'<div id="mission-ids">' +
`<span>MstId: ${mis.MstId}</span>` +
`<span>Id: ${mis.Id}</span>` +
'</div>' +
'<div id="modal-buttons">' +
'<button onclick="closeMissionModal(event, false)">Close</button>' +
`<button onclick="missionChanged(${misId})">Play</button>` +
'</div>' +
'</div>';
document.getElementById("click-catcher").style.cssText = 'display: flex;';
cont.style.cssText = 'display: flex;';
}
function closeMissionModal(event, wasStarted) {
if(!wasStarted) {
document.getElementById('select-mission').value = prevMission;
} else {
prevMission = document.getElementById('select-mission').value;
}
let cont = document.getElementById("modal-container");
document.getElementById("click-catcher").style.cssText = 'display: none;';
cont.style.cssText = 'display: none;';
cont.innerHTML = '';
}
function missionChanged(value) {
let newMission = utage.availableMissions[value];
currentMission = newMission;
let promises = [
utage.parseMissionFile(`${utage.rootDirectory}XDUData/${newMission.Path.replace('Asset/', '').replace('.utage', '').replace('.tsv', '_t.tsv')}`),
utage.loadMissionTranslation(`${utage.rootDirectory}XDUData/${newMission.Path.replace('Asset/', '').replace('.utage', '').replace('.tsv', `_translations_${selectedLang}.json`)}`, selectedLang),
player.resetAll()
];
closeMissionModal(undefined, true);
Promise.all(promises)
.then((success) => {

View File

@ -9,14 +9,13 @@ class Player {
this.text = text;
this.audio = audio;
//consts
this.resolutionScale = 1;
this.resolutionScale = 1; //I created this thinking that I would need to handle changing offset when resolution changes. But lucikly I can just scale the parent container and it works without needing this.
this.baseFps = 60; //I am assuming that PIXI is going to stay as keeping 60fps = delta1.
this.bgLayerName = "背景";
this.defaultCharPattern = 'すまし';
this.bgLayerName = "背景"; //The label for the BG layer.
this.defaultCharPattern = 'すまし'; //The mission file doesn't always give a pattern for putting a character on the screen.
this.backCharTint = 0x808080;
this.titleWaitTime = 1;
this.titleWaitTime = 5;
this.blackBackSp = undefined;
this.currentCharacters = {};
this.lastCharOffLayer = undefined;
this.layers = {};
@ -49,6 +48,7 @@ class Player {
return runningPromise;
}
//Runs through the tsv file and loads any files it will need to play.
preCheckFilesToGet() {
return new Promise((resolve, reject) => {
let toLoadBgm = {};
@ -143,7 +143,9 @@ class Player {
});
}
//note containers render in the order they are added, eg. the last added is always on top.
//Creates all the pixi containers for ther layers defined in layers.tsv
//also creates containers for fading
//note containers render in the order they are added, eg. the last added is always on top
buildLayerContainers() {
let layersToAdd = [];
for(let l of Object.keys(this.utage.layerInfo)) {
@ -180,6 +182,8 @@ class Player {
}
}
//Laoding progress functions
onPixiProgress(loader, resource) {
this.assetLoadPercent = loader.progress;
this.text.titleText(true, `Loading Assets... ${loader.progress.toFixed(0)}%`);
@ -211,9 +215,9 @@ class Player {
}
}
//Runs every frame. Delta is a float scaled from 1=60fps.
onPixiTick(delta) {
try
{
try {
if(!this.runEvent) { return; }
let deltaTime = (1000/this.baseFps)*delta;
this.secondTicker -= deltaTime;
@ -243,6 +247,8 @@ class Player {
}
}
//This loop is run every frame and handles all the animation liek tweens in the mission.
//interpolation is not just linear even if its called HandleLerps
loopHandleLerps(deltaTime) {
try {
//Loop through the lerp targets, modify the needed objects. If a object is at its 1 time state remove it from the list.
@ -310,27 +316,23 @@ class Player {
}
}
//Processes a line from the mission tsv
processCommand(delta) {
try {
let cur = this.currentCommand;
//if(this.checkIfAllOff()) {
// this.text.dialogText(false, "");
// this.text.characterName(false, "");
//} else {
// this.text.dialogText(true, "");
// this.text.characterName(true, "");
//}
switch((cur.Command || "").toLowerCase()) {
case "scenetitle01":
case "scenetitle01": {
this.waitTime = this.titleWaitTime * 1000;
var text = cur.English ? (utage.currentTranslation[cur.English] || cur.Text) : cur.Text;
let text = cur.English ? (utage.currentTranslation[cur.English] || cur.Text) : cur.Text;
this.text.titleText(true, text);
break;
case "divaeffect":
this.waitTime = 1000//Number(cur.Arg5) * 1000;
var text = cur.English ? (utage.currentTranslation[cur.English] || cur.Text) : cur.Text;
}
case "divaeffect": {
this.waitTime = Number(cur.Arg5) * 1000;
let text = cur.English ? (utage.currentTranslation[cur.English] || cur.Text) : cur.Text;
this.text.divaText(true, text);
break;
}
//FadeTo
case "fadeout":
this.text.dialogText(false, "");
@ -457,13 +459,14 @@ class Player {
this.processShake(delta, cur);
break;
}
default:
this.processCommandOther(delta);
break;
//custom effects
case "henshin01_bgmoff":
this.audio.stopSound('bgm');
this.checkPutCharacterScreen(cur, true);
break;
default:
this.processCommandOther(delta);
break;
}
} catch(error) {
console.log(error);
@ -479,6 +482,7 @@ class Player {
this.checkPutText(cur);
}
//Checks if the current command is trying to put a new character on the screen or not
checkPutCharacterScreen(cur, special = false) {
if((!cur.Command || special) && cur.Arg1 && this.utage.characterInfo[cur.Arg1]) {
let lay = undefined;
@ -534,13 +538,14 @@ class Player {
}
}
//Checks if the current command is trying to put text on the screen.
checkPutText(cur) {
if(this.playingVoice) {
this.audio.stopSound(this.playingVoice);
}
if(!cur.Command && cur.Arg1 && cur.Text) {
//If its chracter off screen text
var text = cur.English ? (utage.currentTranslation[cur.English] || cur.Text) : cur.Text;
let text = cur.English ? (utage.currentTranslation[cur.English] || cur.Text) : cur.Text;
text = commonFunctions.convertUtageTextTags(text);
if(cur.Arg2 && cur.Arg2.toLowerCase() === "<off>") {
this.text.characterName(true, cur.Arg1);
@ -571,8 +576,9 @@ class Player {
}
}
this.manualNext = true;
//Sometimes they don't give a Arg1 for the text.
} else if(!cur.Command && cur.Arg2.toLowerCase() === "<off>" && cur.Text) {
var text = cur.English ? (utage.currentTranslation[cur.English] || cur.Text) : cur.Text;
let text = cur.English ? (utage.currentTranslation[cur.English] || cur.Text) : cur.Text;
this.text.characterName(true, "");
this.text.dialogText(true, commonFunctions.convertUtageTextTags(text));
this.manualNext = true;
@ -583,10 +589,12 @@ class Player {
}
}
//Handle a tween command
processTween(delta, cur) {
this.text.dialogText(false, "");
this.text.characterName(false, "");
let curChar = undefined;
//Find the character for the tween.
for(let c of Object.keys(this.currentCharacters)) {
if(!this.currentCharacters[c]) { continue; }
if(this.currentCharacters[c].charName === cur.Arg1) {
@ -716,13 +724,6 @@ class Player {
this.currentCommand = undefined;
}
checkIfAllOff() {
for(let c of Object.keys(this.currentCharacters)) {
if(this.currentCharacters[c]) { return false; }
}
return true;
}
onMainClick(event) {
if(!this.runEvent) {
return
@ -791,7 +792,6 @@ class Player {
this.lastCharOffLayer = undefined;
this.layers = {};
this.sprites = {};
this.blackBackSp = undefined;
this.currentCommand = undefined;
this.runEvent = false;
this.secondTicker = 1000;

View File

@ -123,8 +123,13 @@ class UtageInfo {
} else {
read.NameText = lastNameText;
}
if(read.FileName && !read.FileName.startsWith('file://')) {
read.FileName = `${this.rootDirectory}XDUData/Character/${read.FileName}`;
if(read.FileName) {
if(!read.FileName.startsWith('file://')) {
read.FileName = `${this.rootDirectory}XDUData/Sample/Texture/Character/${read.FileName}`;
} else {
read.FileName = read.FileName.replace('file://', '');
read.FileName = `${this.rootDirectory}XDUData/${read.FileName}`;
}
}
if(!this.characterInfo[lastCharName]) {
this.characterInfo[lastCharName] = {};
@ -203,7 +208,7 @@ class UtageInfo {
read.FileName = `${read.FileName}.opus`;
}
switch(read.Type.toLowerCase()) {
case 'se':
case 'se':
if(read.FileName.includes(',')) {
let s = read.FileName.split(',');
read.FileName = `${s[0].split('_').join('/')}/${s[1]}`;
@ -232,7 +237,12 @@ class UtageInfo {
} else {
let read = commonFunctions.readLine(line, headers);
if(read && read.Label) {
read.FileName = `${this.rootDirectory}XDUData/BG/${read.FileName}`;
if(!read.FileName.startsWith("file://")) {
read.FileName = `${this.rootDirectory}XDUData/Sample/Texture/BG/${read.FileName}`;
} else {
read.FileName = read.FileName.replace("file://", '');
read.FileName = `${this.rootDirectory}XDUData/${read.FileName}`;
}
this.textureInfo[read.Label] = read;
}
}

File diff suppressed because it is too large Load Diff

2
Js/XduPlayer.min.js vendored

File diff suppressed because one or more lines are too long

View File

@ -8,6 +8,12 @@
<script src="Js/Pixi.min.js"></script>
</head>
<body onload="onBodyLoaded()">
<!-- <script src="Js/Common.js"></script>
<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/XduPlayer.min.js"></script>
<div id="loading-container" class="centered">
<h2 id="loading-utage">Loading Utage Data...</h2>
@ -19,7 +25,7 @@
<span onclick="toggleMute(event)" id="mute-button">🔊</span>
<input onchange="onVolumeChange(event)" id="volume-range" value="50" type="range" min="0" max="100" step="1"/>
</div>
<select id="select-mission" onchange="missionChanged(event);"></select>
<select id="select-mission" onchange="missionDropDownChanged(event);"></select>
<select id="select-language" onchange="languageChanged(event);"></select>
</div>
<!-- Im doing weird shit so that text container is always the base resolution of XDU (1334, 750).
@ -61,5 +67,7 @@
<span style="font-family: 'SourceCodePro-Regular'">test</span> -->
</div>
</div>
<div id="click-catcher" style="display: none;" onclick="closeMissionModal(event, false)"></div>
<div id="modal-container" style="display: none;"></div>
</body>
</html>

View File

@ -15,19 +15,19 @@ const jsFiles = [
"Js/Main.js"
];
const jsToCopy = [
'Js/XduPlayer.min.js',
'Js/Pixi.min.js'
"Js/XduPlayer.min.js",
"Js/Pixi.min.js"
];
const cssFiles = [
'Css/main.css'
"Css/main.css"
];
const cssToCopy = [
'Css/main.min.css',
'Css/generic.min.css'
"Css/main.min.css",
"Css/generic.min.css"
];
const jsonFiles = [
'Js/BgmLoop.json',
'Js/XduMissions.json'
"Js/BgmLoop.json",
"Js/XduMissions.json"
];
const jsDest = "Js";
@ -54,6 +54,11 @@ gulp.task('dist', gulp.series(
)
);
gulp.task('watch', () => {
gulp.watch(cssFiles, {ignoreInitial: false}, gulp.series(buildCss)),
gulp.watch(jsFiles, {ignoreInitial: false}, gulp.series(buildJs));
});
function buildJs() {
return gulp.src(jsFiles)
.pipe(sourcemaps.init())
@ -67,7 +72,7 @@ function buildJs() {
function copyJs() {
return gulp.src(jsToCopy)
.pipe(gulp.dest('Dist/Js'));;
.pipe(gulp.dest('Dist/Js'));
}
function buildCss() {