324 lines
9.5 KiB
JavaScript
324 lines
9.5 KiB
JavaScript
/* @flow */
|
|
import jQuery from "jquery";
|
|
|
|
/**
|
|
* Path to your game's main ink file relative to this file.
|
|
*/
|
|
import entryPoint from '../game/game.ink';
|
|
|
|
/**
|
|
* You can change this function.
|
|
* It's an easy way to define your own tags and text transformations.
|
|
*/
|
|
function transform (text: string) {
|
|
text = text.replace('<st>', '<span class="subtitle">');
|
|
text = text.replace('</st>', '</span>');
|
|
text = text.replace('<ell>', '<span class="ellipsis">⏸️ </span>');
|
|
return text;
|
|
}
|
|
|
|
/**
|
|
* You don't need to change anything past this point.
|
|
*
|
|
* @var {string|number} index
|
|
*/
|
|
function saveChoice(index: any) {
|
|
window['progress_steps']++;
|
|
window['progress'].push(index);
|
|
if (window['progress_steps'] % 5 === 0) {
|
|
// 5 step autosave
|
|
localStorage.setItem("progress_5", JSON.stringify(window['progress']));
|
|
}
|
|
if (window['progress_steps'] % 30 === 0) {
|
|
// 30 step autosave
|
|
localStorage.setItem("progress_30", JSON.stringify(window['progress']));
|
|
}
|
|
return localStorage.setItem("progress", JSON.stringify(window['progress']));
|
|
};
|
|
|
|
function displayText(interactive = true) {
|
|
let block, delay, html, i;
|
|
const results = [];
|
|
updateBgr();
|
|
jQuery("#content p").addClass("old");
|
|
//document.getElementById('content').innerHTML = ''
|
|
const paragraphs = window['s'].ContinueMaximally().split("\n");
|
|
/* if (interactive) {
|
|
delay = 1000;
|
|
} */
|
|
results.push((function() {
|
|
let j, len;
|
|
const results1 = [];
|
|
for (j = 0, len = paragraphs.length; j < len; j++) {
|
|
i = paragraphs[j];
|
|
if (i !== "") {
|
|
i = transform(i);
|
|
html = jQuery.parseHTML(i);
|
|
block = jQuery('<p>').html(html);
|
|
if (interactive) {
|
|
block.hide();
|
|
}
|
|
jQuery("#content").append(block);
|
|
if (interactive) {
|
|
block.show();
|
|
//block.fadeIn(delay);
|
|
//results1.push(delay += 500);
|
|
results1.push(void 0);
|
|
} else {
|
|
results1.push(void 0);
|
|
}
|
|
} else {
|
|
results1.push(void 0);
|
|
}
|
|
}
|
|
return results1;
|
|
})());
|
|
updateBgr();
|
|
return results;
|
|
};
|
|
|
|
function continueToNextChoice (s: any) {
|
|
let choice, j, len, ref;
|
|
jQuery("#content").empty();
|
|
jQuery("#options").html("");
|
|
jQuery(".options").html("");
|
|
jQuery("#verbs").html("");
|
|
displayText(true);
|
|
const verbs = {};
|
|
let mode = 'menu';
|
|
//let quest = s.EvaluateFunction('current_quest_description', [], true);
|
|
//jQuery("#quest").html(quest.output);
|
|
if (window["picture"] !== undefined && s.currentTags.length > 0) {
|
|
// Scanning "characters" tag for sprites to show
|
|
// EXAMPLE: # characters: boy.happy, mermaid.rest
|
|
s.currentTags.forEach(function(tag) {
|
|
const characters = tag.match(/^characters:\s*(.*)/);
|
|
if (characters !== null && characters.length > 0) {
|
|
const charlist = characters[1].split(",");
|
|
charlist.forEach(function(char) {
|
|
const a = char.split(".");
|
|
let character, pose;
|
|
if (a[0] !== undefined) {
|
|
character = a[0];
|
|
}
|
|
if (a[1] !== undefined) {
|
|
pose = a[1];
|
|
}
|
|
if (pose === "") {
|
|
pose = "rest";
|
|
}
|
|
if (window["characters"] === undefined) {
|
|
window["characters"] = {};
|
|
}
|
|
if (window["characters"][character] !== undefined) {
|
|
window["characters"][character].setPose(pose);
|
|
}
|
|
});
|
|
}
|
|
});
|
|
}
|
|
if (
|
|
s.currentTags.includes('choices: parser')
|
|
|| (
|
|
s.currentChoices[0] !== undefined &&
|
|
(
|
|
s.currentChoices[0].tags.includes('parser')
|
|
|| s.currentChoices[0].text.match("Осмотреть себя")
|
|
)
|
|
)
|
|
) {
|
|
mode = 'parser';
|
|
}
|
|
if (mode === 'parser') {
|
|
jQuery("#options").hide();
|
|
jQuery(".options").hide();
|
|
}
|
|
if (s.currentChoices.length > 0) {
|
|
ref = s.currentChoices;
|
|
for (j = 0, len = ref.length; j < len; j++) {
|
|
choice = ref[j];
|
|
if (choice.text === 'hideme') continue;
|
|
let text = transform(choice.text)
|
|
if (mode === 'parser') {
|
|
text = text.replace("> ", "")
|
|
let verb = text;
|
|
if (text.split(" ").length > 1) {
|
|
verb = text.split(" ")[0];
|
|
}
|
|
let id = Math.round(Math.random() * 100000);
|
|
if (verbs[verb] === undefined) {
|
|
verbs[verb] = id;
|
|
jQuery("#verbs").append(`<li><a href='#' id='verb-${id}' data-verbid='${id}'>${verb}</a></li>`);
|
|
} else {
|
|
id = verbs[verb];
|
|
}
|
|
if (jQuery(`#options-${id}`).length === 0) {
|
|
jQuery("#options").append(`<ul id="options-${id}" class="options"></ul>`);
|
|
}
|
|
jQuery(`#options-${id}`).append(`<li><a href='#' id='choice-${choice.index}' data-index=${choice.index}>${text}</a></li>`);
|
|
} else {
|
|
jQuery(`#options`).append(`<li><a href='#' id='choice-${choice.index}' data-index=${choice.index}>${text}</a></li>`);
|
|
}
|
|
}
|
|
if (mode === 'parser') {
|
|
jQuery("#options").show();
|
|
jQuery(".options:visible").hide();
|
|
}
|
|
}
|
|
const scrollTo = jQuery('#options').offset().top;
|
|
if (scrollTo > 0 && window['progress'].length > 0 && !jQuery('html').is(':animated') && !jQuery('body').is(':animated')) {
|
|
return jQuery('html, body').animate({
|
|
scrollTop: scrollTo
|
|
}, 800);
|
|
}
|
|
};
|
|
|
|
function loadGame (s: any) {
|
|
let index, j, len;
|
|
document.getElementById("content").innerHTML = ""
|
|
document.getElementById("options").innerHTML = ""
|
|
const ref = window['progress'];
|
|
const results = [];
|
|
if (ref.length > 0) {
|
|
window['progress_steps'] = ref.length;
|
|
jQuery("#content").empty();
|
|
for (j = 0, len = ref.length; j < len; j++) {
|
|
index = ref[j];
|
|
displayText(false);
|
|
if (isNaN(parseInt(index))) {
|
|
results.push(window['s'].ChoosePathString(index));
|
|
} else {
|
|
if (s.currentChoices[index] === undefined) {
|
|
console.error('Choice unavailable: '+index);
|
|
console.log(s.currentChoices)
|
|
}
|
|
try {
|
|
results.push(s.ChooseChoiceIndex(index));
|
|
} catch (ex) {
|
|
// Game changed - erase the save and restart.
|
|
localStorage.setItem("progress", '[]');
|
|
window.location.reload();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
continueToNextChoice(s);
|
|
}
|
|
return results;
|
|
};
|
|
|
|
const progress = localStorage.getItem("progress");
|
|
if (progress != null) {
|
|
window['progress'] = JSON.parse(progress);
|
|
} else {
|
|
window['progress_steps'] = 0;
|
|
window['progress'] = [];
|
|
}
|
|
window['s'] = entryPoint
|
|
window['s'].onError = function(error){
|
|
alert(error);
|
|
};
|
|
if (window['s'].globalTags) {
|
|
const title = window['s'].globalTags['title'];
|
|
if (title !== undefined) {
|
|
document.getElementById('title').innerHTML = title;
|
|
document.getElementsByTagName('title')[0].innerHTML = title;
|
|
}
|
|
}
|
|
if (window['progress'].length > 0) {
|
|
loadGame(window['s']);
|
|
}
|
|
continueToNextChoice(window['s']);
|
|
|
|
jQuery(document).on('click', "#restart", function() {
|
|
localStorage.setItem("progress", '[]');
|
|
window.location.reload();
|
|
});
|
|
|
|
jQuery(document).on('click', "#verbs a", function() {
|
|
jQuery(".options:visible").hide();
|
|
const verb = jQuery(this).data('verbid');
|
|
jQuery(`#options-${verb}`).show();
|
|
});
|
|
jQuery(document).on('click', "#verbs li", function() {
|
|
jQuery(this).find('a').click();
|
|
});
|
|
|
|
jQuery(document).on('click', "#undo", function() {
|
|
jQuery("#undo").hide();
|
|
window['progress'].pop()
|
|
localStorage.setItem("progress", JSON.stringify(window['progress']));
|
|
window.location.reload();
|
|
});
|
|
|
|
function choose(index) {
|
|
window['s'].ChooseChoiceIndex(index);
|
|
jQuery("#undo").show()
|
|
saveChoice(index);
|
|
continueToNextChoice(window['s']);
|
|
}
|
|
|
|
jQuery(document).on('click', "#settings", function() {
|
|
jQuery("#page").hide();
|
|
jQuery("#settings_page").show();
|
|
return false;
|
|
});
|
|
jQuery(document).on('click', "#options li a", function() {
|
|
choose(jQuery(this).data("index"));
|
|
return false;
|
|
});
|
|
jQuery(document).on('click', "a.inlinelink", function() {
|
|
window['s'].ChoosePathString(jQuery(this).attr("data-href"));
|
|
saveChoice(jQuery(this).attr("data-href"));
|
|
continueToNextChoice(window['s']);
|
|
return true;
|
|
});
|
|
jQuery(document).on('click', "#options li", function() {
|
|
choose(jQuery(this).find('a').data("index"));
|
|
return false;
|
|
});
|
|
jQuery(document).on('change', "#font_size_control", function() {
|
|
jQuery("body").css("font-size", jQuery("#font_size_control").val()+"rem")
|
|
return false;
|
|
});
|
|
jQuery(document).on('change', "#line_height_control", function() {
|
|
const height = jQuery("#line_height_control").val();
|
|
jQuery("body").css("line-height", height.toString())
|
|
return false;
|
|
});
|
|
jQuery(document).on('click', "#download_save", function() {
|
|
const progress = localStorage.getItem("progress")
|
|
const dataStr = "data:text/json;charset=utf-8," + encodeURIComponent(JSON.stringify(progress));
|
|
const downloadAnchorNode = document.createElement('a');
|
|
downloadAnchorNode.setAttribute("href", dataStr);
|
|
downloadAnchorNode.setAttribute("download", "save.json");
|
|
document.body.appendChild(downloadAnchorNode); // required for firefox
|
|
downloadAnchorNode.click();
|
|
downloadAnchorNode.remove();
|
|
return false;
|
|
});
|
|
|
|
|
|
// TODO keyboard navigation
|
|
jQuery(document).on('keydown', function(key: any) {
|
|
key = key.key
|
|
if (key === '0') {
|
|
key = 10;
|
|
} else {
|
|
key = parseInt(key);
|
|
}
|
|
if (key > 0) {
|
|
if (jQuery("#verbs").is(":visible")) {
|
|
jQuery(`#verbs li:nth-child(${key}) a`).first().trigger("click")
|
|
} else {
|
|
jQuery(`.options:visible li:nth-child(${key}) a`).first().trigger("click")
|
|
}
|
|
}
|
|
return false;
|
|
});
|
|
|
|
function updateBgr() {
|
|
jQuery('#background').attr("href", "images/" + window['s'].variablesState['background'])
|
|
}
|