stories = []; function initGame(story) { state.info = {}; state.info.time = { id: "time", name: "Time", type: "counter", value: 60*60*9, get render() { return renderTime(this.value); } } state.player.stats = {}; state.timers = []; } function createStatDisplays(stats, statType) { const holder = document.querySelector("#" + statType + "-info"); holder.innerHTML = ""; Object.entries(stats).forEach(([key, val]) => { if (val.type == "meter") { const field = document.createElement("div"); field.id = statType + "-info-" + key; field.setAttribute("max", val.max); field.setAttribute("value", val.value); field.classList.add("stat-bar-holder"); const label = document.createElement("div"); label.classList.add("stat-bar-label"); label.textContent = val.name; const bar = document.createElement("div"); bar.classList.add("stat-bar"); bar.style["background-color"] = val.color; field.appendChild(label); field.appendChild(bar); holder.appendChild(field); } else if (val.type == "counter") { const field = document.createElement("div"); field.id = statType + "-info-" + key; holder.appendChild(field); } }); } function initGamePostSetup() { createStatDisplays(state.info, "world"); createStatDisplays(state.player.stats, "player"); } function getStat(stat) { return state.player.stats[stat].value; } function changeStat(stat, amount) { let value = state.player.stats[stat].value; value += amount; value = Math.max(value, state.player.stats[stat].min); value = Math.min(value, state.player.stats[stat].max); state.player.stats[stat].value = value; } // TODO: format string this lol function renderTime(time) { let hours = Math.floor(time / 3600) % 12; const ampm = Math.floor(time / 3600) % 24 < 12 ? "AM" : "PM"; let minutes = Math.floor(time / 60) % 60; let seconds = time % 60; if (minutes <= 9) minutes = "0" + minutes; if (seconds <= 9) seconds = "0" + seconds; return hours + ":" + minutes + ":" + seconds + " " + ampm; } function updateStatDisplay(stats, statType) { Object.entries(stats).forEach(([key, val]) => { if (val.hidden === true) { const field = document.querySelector("#" + statType + "-info-" + key); field.style.display = "none"; } else { const field = document.querySelector("#" + statType + "-info-" + key); field.style.display = "block"; if (val.type == "meter") { const bar = document.querySelector("#" + statType + "-info-" + key + " > .stat-bar"); bar.style["background-color"] = val.color; } } if (val.type == "meter") { const field = document.querySelector("#" + statType + "-info-" + key + " > .stat-bar"); field.style.width = (val.value / val.max * 100) + "%"; } else if (val.type == "counter") { const field = document.querySelector("#" + statType + "-info-" + key); field.innerText = val.name + ": " + (val.render !== undefined ? val.render : val.value); } }); } /* { id: an optional name; needed to manually kill a timer func: the function to invoke delay: how long to wait between invocations loop: false = no looping, true = loop forever } Returns the timeout id - but you still need to cancel it through stopTimer! */ function startTimer(config) { const timeout = setTimeout(() => { const result = config.func(config); refresh(); // the timer may have terminated itself! // we have to make sure it still exists if (state.timers.some(x => x.timeout == timeout)){ state.timers = state.timers.filter(x => x.timeout != timeout); if (typeof(result) === "number") { config.delay = result; } // you shouldn't use a delay of 0 anyway if (result && config.loop) { startTimer(config); } } }, config.delay); state.timers.push({id: config.id, timeout: timeout, classes: config.classes || []}); return timeout; } function stopTimer(id) { const matches = state.timers.filter(timer => timer.id == id); matches.forEach(timer => clearTimeout(timer.timeout)); state.timers = state.timers.filter(timer => timer.id != id); } function stopClassTimers(timerClass, inverse) { const matches = state.timers.filter(timer => timer.classes.includes(timerClass)); const others = state.timers.filter(timer => !timer.classes.includes(timerClass)); if (inverse) { others.forEach(timer => clearTimeout(timer.timeout)); state.timers = matches; } else { matches.forEach(timer => clearTimeout(timer.timeout)); state.timers = others; } } function stopAllTimers() { state.timers.forEach(x => clearTimeout(x.timeout)); state.timers = []; } function setBackgroundColor(r, g, b) { document.querySelector(".scene").style["background-color"] = "rgb(" + r + "," + g + "," + b + ")"; }