inkchargen/src/index.js
2024-01-17 08:20:35 +06:00

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">⏸️&nbsp;</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'])
}