giant freakin documentation and reorganization pass, it also uses cmake because all the building was getting too complicated for shell scripts
This commit is contained in:
232
pak/static/css/seagull.css
Normal file
232
pak/static/css/seagull.css
Normal file
@@ -0,0 +1,232 @@
|
||||
html, body { height: 100% }
|
||||
|
||||
/** MAIN GAME **/
|
||||
|
||||
div#root {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
z-index: 0;
|
||||
|
||||
font-family: sans-serif;
|
||||
}
|
||||
|
||||
div#main-sidebar {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
max-width: 265px;
|
||||
/*padding-left: 5px;*/
|
||||
padding-right: 5px;
|
||||
border-right: 0.125em solid rgb(192, 192, 192);
|
||||
}
|
||||
|
||||
div#side-seagull-name {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
div#side-seagull-name-editor {
|
||||
display: none;
|
||||
}
|
||||
|
||||
div#main-content {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
div#main-header {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
min-height: 100px;
|
||||
vertical-align: middle;
|
||||
|
||||
border-bottom: 0.125em solid rgb(192,192,192);
|
||||
}
|
||||
|
||||
div#main-day-stats {
|
||||
width: 100%;
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
vertical-align: middle;
|
||||
font-size: large;
|
||||
}
|
||||
|
||||
div#main-button-bar {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
min-height: 125px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
div#main-log {
|
||||
display: flex;
|
||||
flex-direction: column-reverse;
|
||||
}
|
||||
|
||||
div.log-line {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
vertical-align: top;
|
||||
width: 100%;
|
||||
min-height: 1.5em;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
div.log-line-alt {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
vertical-align: top;
|
||||
width: 100%;
|
||||
min-height: 1.5em;
|
||||
padding-top: 5px;
|
||||
|
||||
background-color: rgb(192, 192, 192);
|
||||
}
|
||||
|
||||
div.log-tick {
|
||||
font-size: 0.75em;
|
||||
margin-right: 0.2em;
|
||||
}
|
||||
|
||||
div.log-msg {
|
||||
margin-left: 0.2em;
|
||||
}
|
||||
|
||||
div#charsheet {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
|
||||
background-color: rgb(240, 240, 240);
|
||||
}
|
||||
|
||||
/** MODAL **/
|
||||
|
||||
div#modal-background {
|
||||
font-family: sans-serif;
|
||||
background-color: rgba(0, 0, 0, 0.6);
|
||||
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
div#modal {
|
||||
width: 75%;
|
||||
height: 75%;
|
||||
margin: auto;
|
||||
margin-top: 50px;
|
||||
border: 0.25em dotted rgba(192, 192, 192, 255);
|
||||
background-color: rgba(255, 255, 255, 255);
|
||||
padding: 0.3em
|
||||
}
|
||||
|
||||
button.main-bar {
|
||||
width: 2.5em;
|
||||
height: 2.5em;
|
||||
margin: 2.5px;
|
||||
background-color: rgba(0,0,0,0);
|
||||
border: 1px solid black;
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
button#button-modal-close {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
|
||||
width: 2.5em;
|
||||
height: 2.5em;
|
||||
margin: 2.5px;
|
||||
background-color: rgba(0,0,0,0);
|
||||
border: 0px;
|
||||
font-size: 2em;
|
||||
}
|
||||
|
||||
/** CHARSHEET **/
|
||||
|
||||
div#charsheet-root {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
div#charsheet-leftside {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 33%;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
div.attr {
|
||||
/* common to all attribute blocks */
|
||||
font-size: x-large;
|
||||
color: #ffffff;
|
||||
width: 100%;
|
||||
height: 30%;
|
||||
|
||||
vertical-align: middle;
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
|
||||
text-align: center;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
div#attr-points {
|
||||
font-size: x-large;
|
||||
width: 100%;
|
||||
height: 10%;
|
||||
|
||||
vertical-align: middle;
|
||||
margin-top: auto;
|
||||
margin-bottom: auto;
|
||||
|
||||
text-align: center;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
}
|
||||
|
||||
div#attr-agility {
|
||||
background: linear-gradient(to right, rgb(0,170,0), rgb(0,99,0));
|
||||
}
|
||||
|
||||
div#attr-instinct {
|
||||
background: linear-gradient(to right, rgb(170,0,255), rgb(90,0,135));
|
||||
}
|
||||
|
||||
div#attr-leadership {
|
||||
background: linear-gradient(to right, rgb(255,170,0), rgb(139,93,0));
|
||||
}
|
||||
|
||||
div#charsheet-rightside {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 67%;
|
||||
height: 100%;
|
||||
overflow-x: scroll;
|
||||
}
|
||||
|
||||
nav#nav-upgrades {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
}
|
||||
|
||||
nav#nav-upgrades li {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
div#charsheet-upgrade-tree {
|
||||
display: flex;
|
||||
flex-wrap: nowrap;
|
||||
flex-direction: row;
|
||||
width: max-content;
|
||||
}
|
BIN
pak/static/image/seagull.jpg
Normal file
BIN
pak/static/image/seagull.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 27 KiB |
BIN
pak/static/image/splash.png
Normal file
BIN
pak/static/image/splash.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 187 KiB |
32
pak/static/js/dlg-charsheet.js
Normal file
32
pak/static/js/dlg-charsheet.js
Normal file
@@ -0,0 +1,32 @@
|
||||
var charsheet_elements = {}
|
||||
charsheet_elements["lbl_agility"] = document.getElementById("lbl-attr-agility");
|
||||
charsheet_elements["lbl_instinct"] = document.getElementById("lbl-attr-instinct");
|
||||
charsheet_elements["lbl_leadership"] = document.getElementById("lbl-attr-leadership");
|
||||
charsheet_elements["lbl_instinct_txt"] = document.getElementById("lbl-attr-instinct-txt");
|
||||
charsheet_elements["btn_upgrade_agility"] = document.getElementById("btn-upgrade-agility");
|
||||
charsheet_elements["btn_upgrade_instinct"] = document.getElementById("btn-upgrade-instinct");
|
||||
charsheet_elements["btn_upgrade_leadership"] = document.getElementById("btn-upgrade-leadership");
|
||||
charsheet_elements["blk_tree"] = document.getElementById("charsheet-upgrade-tree");
|
||||
|
||||
function update_charsheet() {
|
||||
charsheet_elements["lbl_agility"].innerHTML = gamestate["agility"];
|
||||
charsheet_elements["lbl_instinct"].innerHTML = gamestate["instinct"];
|
||||
charsheet_elements["lbl_leadership"].innerHTML = gamestate["leadership"];
|
||||
|
||||
if (gamestate["story_beat"] >= 3) {
|
||||
charsheet_elements["lbl_instinct_txt"].innerHTML = "Intelligence";
|
||||
charsheet_elements["btn_upgrade_instinct"].innerHTML = "Intelligence Upgrades";
|
||||
}
|
||||
}
|
||||
|
||||
async function display_tree(tree) {
|
||||
var upgrade_tree = await fetch(`/upgrades/${tree}`)
|
||||
.then(res => res.text())
|
||||
console.log(upgrade_tree)
|
||||
|
||||
charsheet_elements["blk_tree"].innerHTML = upgrade_tree
|
||||
}
|
||||
|
||||
charsheet_elements["btn_upgrade_agility"].addEventListener("click", (ev) => {display_tree("agility")});
|
||||
charsheet_elements["btn_upgrade_instinct"].addEventListener("click", (ev) => {display_tree("instinct")});
|
||||
charsheet_elements["btn_upgrade_leadership"].addEventListener("click", (ev) => {display_tree("leadership")});
|
38
pak/static/js/seagull-desktop.js
Normal file
38
pak/static/js/seagull-desktop.js
Normal file
@@ -0,0 +1,38 @@
|
||||
globalThis.desktop_mode = true;
|
||||
|
||||
async function prepare_gamestate() {
|
||||
var gamestate_loaded = null;
|
||||
try {
|
||||
gamestate_loaded = await window.pywebview.api.load_data("gamestate");
|
||||
} catch (exc) {
|
||||
console.error("no gamestate");
|
||||
gamestate_loaded = null;
|
||||
}
|
||||
|
||||
if (gamestate_loaded == null) {
|
||||
record_log("Welcome to Seagull Game! We haven't found a save in your app data, so we're starting a new game!");
|
||||
gamestate = structuredClone(gamestate_default);
|
||||
}
|
||||
else {
|
||||
console.log(gamestate_loaded);
|
||||
gamestate = JSON.parse(gamestate_loaded);
|
||||
record_log("Welcome back! Game loaded.")
|
||||
}
|
||||
|
||||
tick_meter_running = true;
|
||||
|
||||
if (window.pywebview.api.debug_mode) {
|
||||
dev_toolbox(true);
|
||||
}
|
||||
}
|
||||
|
||||
function save_game() {
|
||||
window.pywebview.api.save_data("gamestate", JSON.stringify(gamestate));
|
||||
record_log("Game saved.");
|
||||
}
|
||||
|
||||
function reset_game() {
|
||||
tick_meter_running = false;
|
||||
window.pywebview.api.delete_data("gamestate");
|
||||
window.location.reload();
|
||||
}
|
27
pak/static/js/seagull-web.js
Normal file
27
pak/static/js/seagull-web.js
Normal file
@@ -0,0 +1,27 @@
|
||||
globalThis.desktop_mode = false;
|
||||
|
||||
function load_gamestate() {
|
||||
var gamestate_loaded = window.localStorage.getItem("gamestate");
|
||||
|
||||
if (gamestate_loaded == null) {
|
||||
record_log("Welcome to Seagull Game! We haven't found a save in your browser storage, so we're starting a new game!");
|
||||
gamestate = structuredClone(gamestate_default);
|
||||
}
|
||||
else {
|
||||
gamestate = JSON.parse(gamestate_loaded);
|
||||
record_log("Welcome back! Game loaded.")
|
||||
}
|
||||
}
|
||||
|
||||
function save_game() {
|
||||
window.localStorage.setItem("gamestate", JSON.stringify(gamestate));
|
||||
record_log("Game saved.");
|
||||
}
|
||||
|
||||
var tick_meter_running = true;
|
||||
|
||||
function reset_game() {
|
||||
tick_meter_running = false;
|
||||
window.localStorage.removeItem("gamestate");
|
||||
window.location.reload();
|
||||
}
|
564
pak/static/js/seagull.js
Normal file
564
pak/static/js/seagull.js
Normal file
@@ -0,0 +1,564 @@
|
||||
const ver_numeric = 0;
|
||||
const ver_string = "pre alpha";
|
||||
|
||||
const sleep = ms => new Promise(r => setTimeout(r, ms)); // sleep(int ms)
|
||||
const avg = input => input.reduce((a,b) => a+b) / input.length; // avg([1,2,3...])
|
||||
const urlExists = async url => (await fetch(url)).ok
|
||||
|
||||
var page_elements = {};
|
||||
|
||||
globalThis.gamestate = {};
|
||||
globalThis.tick_meter_running = false;
|
||||
var ticks_since_last_save = 0;
|
||||
|
||||
globalThis.gamestate_default = {
|
||||
"statever": "1",
|
||||
"tick": 1,
|
||||
"name": "Nameless",
|
||||
"class": "Seaglet",
|
||||
"level": 1,
|
||||
"shinies": 0,
|
||||
"colony": 1,
|
||||
"food": 0,
|
||||
"autosave": 35,
|
||||
"story_beat": 0,
|
||||
"xp": 0,
|
||||
"xp_next": 50,
|
||||
"enc_human": "pause",
|
||||
"enc_seagull": "pause",
|
||||
"agility": 0,
|
||||
"instinct": 0,
|
||||
"leadership": 0,
|
||||
"income": {
|
||||
"last_food": Array(10).fill(0),
|
||||
"last_shinies": Array(10).fill(0),
|
||||
"calc_food": 0,
|
||||
"calc_shinies": 0
|
||||
},
|
||||
"modifiers": {
|
||||
"speed": [],
|
||||
"chancesteal": []
|
||||
},
|
||||
"upgrades": []
|
||||
};
|
||||
|
||||
const tickdiffs_reset = {
|
||||
"food": 0,
|
||||
"shinies": 0
|
||||
}
|
||||
var tickdiffs = {}
|
||||
|
||||
var bool_log_alt = false
|
||||
globalThis.record_log = function (text) {
|
||||
const div_logrow = document.createElement("div");
|
||||
if (bool_log_alt) { div_logrow.className = "log-line"; }
|
||||
else { div_logrow.className = "log-line-alt"; }
|
||||
bool_log_alt = !bool_log_alt;
|
||||
|
||||
const div_logtick = document.createElement("div");
|
||||
div_logtick.className = "log-tick"
|
||||
div_logtick.innerHTML = "Day " + gamestate["tick"];
|
||||
div_logrow.append(div_logtick);
|
||||
|
||||
const div_logmsg = document.createElement("div");
|
||||
div_logmsg.innerHTML = text;
|
||||
div_logmsg.className = "log-msg";
|
||||
div_logrow.append(div_logmsg);
|
||||
|
||||
page_elements["div_log"].append(div_logrow);
|
||||
}
|
||||
|
||||
function record_log_with_choices() {
|
||||
const div_logrow = document.createElement("div");
|
||||
if (bool_log_alt) { div_logrow.className = "log-line"; }
|
||||
else { div_logrow.className = "log-line-alt"; }
|
||||
bool_log_alt = !bool_log_alt;
|
||||
|
||||
const div_logtick = document.createElement("div");
|
||||
div_logtick.className = "log-tick"
|
||||
div_logtick.innerHTML = "Day " + gamestate["tick"];
|
||||
div_logrow.append(div_logtick);
|
||||
|
||||
const div_logdata = document.createElement("div");
|
||||
|
||||
const div_logmsg = document.createElement("div");
|
||||
div_logmsg.innerHTML = arguments[0];
|
||||
div_logmsg.className = "log-msg";
|
||||
div_logdata.append(div_logmsg);
|
||||
|
||||
const div_logactions = document.createElement("div");
|
||||
div_logactions.className = "log-button-row";
|
||||
|
||||
for (var i = 1; i < arguments.length; i += 2) {
|
||||
console.log(i)
|
||||
var label = arguments[i];
|
||||
var callback = arguments[i+1];
|
||||
|
||||
var btn_action = document.createElement("button");
|
||||
btn_action.innerHTML = label;
|
||||
btn_action.className = "log-action-button";
|
||||
btn_action.setAttribute("onclick", callback + "; tick_meter_running = true;");
|
||||
div_logactions.append(btn_action);
|
||||
}
|
||||
div_logdata.append(div_logactions);
|
||||
|
||||
div_logrow.append(div_logdata);
|
||||
page_elements["div_log"].append(div_logrow);
|
||||
tick_meter_running = false;
|
||||
}
|
||||
|
||||
globalThis.modal_dialog_open = false;
|
||||
globalThis.modal_dialog_scripted = false;
|
||||
globalThis.modal_dialog_name = "";
|
||||
var dialog_queue = [];
|
||||
|
||||
function modal_no_prop(event) { event.stopPropagation(); }
|
||||
|
||||
async function open_modal_dialog(dialog) {
|
||||
if (!modal_dialog_open) {
|
||||
tick_meter_running = false;
|
||||
modal_dialog_open = true;
|
||||
modal_dialog_name = dialog;
|
||||
|
||||
var modal_background = document.createElement("div");
|
||||
modal_background.setAttribute("id", "modal-background");
|
||||
modal_background.style.zIndex = "10";
|
||||
modal_background.style.visibility = "visible";
|
||||
modal_background = document.body.appendChild(modal_background);
|
||||
|
||||
var modal_close = document.createElement("button");
|
||||
modal_close.setAttribute("id", "button-modal-close");
|
||||
modal_close.innerHTML = "❌";
|
||||
modal_close.addEventListener("click", (ev) => {close_modal_dialog()});
|
||||
modal_close = modal_background.appendChild(modal_close);
|
||||
|
||||
var modal_root = document.createElement("div");
|
||||
modal_root.setAttribute("id", "modal");
|
||||
modal_root.onclick = modal_no_prop;
|
||||
modal_root = modal_background.appendChild(modal_root);
|
||||
|
||||
var dialog_data = await fetch(`/dialog/${dialog}`)
|
||||
.then(res => { return res.text(); });
|
||||
|
||||
modal_root.innerHTML = dialog_data;
|
||||
if (urlExists(`/static/js/dlg-${dialog}.js`)) {
|
||||
//*
|
||||
var script = document.createElement("script");
|
||||
script.setAttribute("id", "dialog-script");
|
||||
script.src = `/static/js/dlg-${dialog}.js`;
|
||||
document.head.appendChild(script);
|
||||
modal_dialog_scripted = true;
|
||||
}
|
||||
} else {
|
||||
var dialog_data = await fetch(`/dialog/${dialog}`)
|
||||
.then(res => { return res.text(); });
|
||||
var dialog_script = null;
|
||||
if (urlExists(`/static/js/dlg-${dialog}.js`)) {
|
||||
dialog_script = `/static/js/dlg-${dialog}.js`;
|
||||
}
|
||||
|
||||
dialog_queue.push([dialog_data, dialog_script, dialog]);
|
||||
}
|
||||
}
|
||||
|
||||
async function close_modal_dialog() {
|
||||
if (!modal_dialog_open) { return; }
|
||||
|
||||
var modal_background = document.getElementById("modal-background");
|
||||
var modal_root = document.getElementById("modal-root");
|
||||
var dialog_script = document.getElementById("dialog-script");
|
||||
if (dialog_script) {
|
||||
document.head.removeChild(dialog_script);
|
||||
}
|
||||
|
||||
if (dialog_queue.length == 0) {
|
||||
modal_background.style.zIndex = "-10";
|
||||
modal_background.style.visibility = "hidden";
|
||||
document.body.removeChild(modal_background);
|
||||
|
||||
tick_meter_running = true;
|
||||
modal_dialog_open = false;
|
||||
modal_dialog_name = "";
|
||||
modal_dialog_scripted = false;
|
||||
} else {
|
||||
next_dialog = dialog_queue.pop();
|
||||
modal_root.innerHTML = next_dialog[0];
|
||||
modal_dialog_name = next_dialog[2];
|
||||
if (next_dialog[1]) {
|
||||
script = document.createElement("script");
|
||||
script.setAttribute("id", "dialog-script");
|
||||
script.src = next_dialog[1];
|
||||
document.head.appendChild(script);
|
||||
modal_dialog_scripted = true;
|
||||
} else { modal_dialog_scripted = false; }
|
||||
}
|
||||
}
|
||||
|
||||
function update_ui() {
|
||||
page_elements["lbl_name"].innerHTML = gamestate["name"];
|
||||
page_elements["lbl_tick"].innerHTML = gamestate["tick"];
|
||||
page_elements["lbl_colony"].innerHTML = gamestate["colony"];
|
||||
page_elements["lbl_shinies"].innerHTML = gamestate["shinies"].toFixed(2);
|
||||
page_elements["lbl_food"].innerHTML = gamestate["food"].toFixed(2);
|
||||
page_elements["lbl_inc_food"].innerHTML = gamestate["income"]["calc_food"].toFixed(2);
|
||||
page_elements["lbl_inc_shinies"].innerHTML = gamestate["income"]["calc_shinies"].toFixed(2);
|
||||
page_elements["lbl_class"].innerHTML = gamestate["class"];
|
||||
page_elements["lbl_xp"].innerHTML = gamestate["xp"];
|
||||
page_elements["lbl_xp_next"].innerHTML = gamestate["xp_next"];
|
||||
page_elements["lbl_level"].innerHTML = gamestate["level"];
|
||||
page_elements["menu_enc_human"].value = gamestate["enc_human"];
|
||||
page_elements["menu_enc_seagull"].value = gamestate["enc_seagull"];
|
||||
}
|
||||
|
||||
var dev_toolbox_open = false;
|
||||
function dev_toolbox(open) {
|
||||
if (open != dev_toolbox_open) {
|
||||
if (open) {
|
||||
var div_toolbox = document.createElement("div");
|
||||
page_elements["div_toolbox"] = div_toolbox;
|
||||
div_toolbox.setAttribute("id", "dev_toolbox");
|
||||
fetch("/dev/get-toolbox")
|
||||
.then((response) => response.text())
|
||||
.then((resp) => {div_toolbox.innerHTML = resp})
|
||||
page_elements["div_sidebar"].appendChild(div_toolbox);
|
||||
}
|
||||
else {
|
||||
var div_toolbox = page_elements["div_toolbox"];
|
||||
page_elements["div_sidebar"].removeChild(div_toolbox);
|
||||
div_toolbox.remove();
|
||||
delete page_elements["div_toolbox"];
|
||||
}
|
||||
}
|
||||
|
||||
dev_toolbox_open = open;
|
||||
}
|
||||
|
||||
function reward_xp(amount) {
|
||||
gamestate["xp"] += amount;
|
||||
if (gamestate["xp"] >= gamestate["xp_next"]) {
|
||||
var old_xp_next = gamestate["xp_next"];
|
||||
gamestate["xp"] -= old_xp_next;
|
||||
gamestate["level"] += 1;
|
||||
gamestate["xp_next"] = (old_xp_next * 1.5) + (gamestate["level"] * 5);
|
||||
record_log(`You have advanced to level ${gamestate["level"]}.`);
|
||||
|
||||
if (gamestate["level"] == 2) {
|
||||
gamestate["story_beat"] = 1;
|
||||
record_log("The humans have fired off some sort of large rocket from a nearby platform. You watch it as it pierces the sky above you and fades into the heavens.");
|
||||
} else if (gamestate["level"] == 3) {
|
||||
gamestate["story_beat"] = 2;
|
||||
gamestate["class"] = "Seagull";
|
||||
record_log("You have grown up from a young, eager seaglet to a full blown Seagull. As your colony participates in the ritual honoring your coming of age, you begin to detect a shift in the winds, though you're not certain exactly how.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
globalThis.steal_resource = async function (resource, target, amount, itemstr) {
|
||||
var items = itemstr.split(",")
|
||||
var stealdata = await fetch(`/act/steal/${resource}/${target}`, {method: "POST", headers: {"Content-Type": "application/json"},body: JSON.stringify({gamestate: gamestate})})
|
||||
.then(res => { return res.json(); })
|
||||
.catch(e => { throw e; });
|
||||
|
||||
if (stealdata["success"] && amount > 0) {
|
||||
gamestate[resource] += amount;
|
||||
tickdiffs[resource] += amount;
|
||||
reward_xp(2);
|
||||
record_log(`Stole ${resource} from a ${target}: ${items.join(", ")}`);
|
||||
}
|
||||
else { record_log(`Didn't steal ${resource} from a ${target}`); }
|
||||
}
|
||||
|
||||
globalThis.recruit = async function (amount) {
|
||||
if (gamestate["shinies"] < amount) {
|
||||
record_log("You do not have enough shinies to recruit this seagull.");
|
||||
return;
|
||||
}
|
||||
var stealdata = await fetch("/act/recruit", {method: "POST", body: JSON.stringify({gamestate: gamestate})})
|
||||
.then(res => { return res.json(); })
|
||||
.catch(e => { throw e; });
|
||||
|
||||
if (stealdata["success"] && amount > 0) {
|
||||
gamestate["shinies"] -= amount;
|
||||
reward_xp(5);
|
||||
gamestate["colony"] += 1;
|
||||
record_log("Successfully recruited a seagull into the colony");
|
||||
}
|
||||
else { record_log("The other gull wasn't impressed. Recruiting failed."); }
|
||||
}
|
||||
|
||||
const hnd_devtoolkit = new Konami(() => {
|
||||
if (modal_dialog_name == "about") {
|
||||
close_modal_dialog();
|
||||
dev_toolbox(true);
|
||||
var snd = new Audio("/static/sound/open_dev_toolkit.wav");
|
||||
snd.play();
|
||||
}
|
||||
})
|
||||
|
||||
async function game_tick() {
|
||||
gamestate["tick"] += 1;
|
||||
ticks_since_last_save += 1;
|
||||
page_elements["lbl_tick"].innerHTML = gamestate["tick"];
|
||||
|
||||
if (gamestate["tick"] % 5 == 0) {
|
||||
var colony_tickdata = await fetch("/tick/colony", {
|
||||
method: "POST",
|
||||
body: JSON.stringify({
|
||||
colony: gamestate["colony"] - 1,
|
||||
modifiers: [],
|
||||
avg_food: gamestate["income"]["calc_food"],
|
||||
avg_shinies: gamestate["income"]["calc_shinies"]
|
||||
}),
|
||||
headers: {
|
||||
"Content-Type": "application/json"
|
||||
}
|
||||
})
|
||||
.then(res => {
|
||||
var json = res.json()
|
||||
console.log(json)
|
||||
return json
|
||||
})
|
||||
.catch(e => {throw e;});
|
||||
|
||||
if (colony_tickdata["success"]) {
|
||||
gamestate["food"] += colony_tickdata["food"];
|
||||
tickdiffs["food"] += colony_tickdata["food"];
|
||||
gamestate["shinies"] += colony_tickdata["shinies"];
|
||||
tickdiffs["shinies"] += colony_tickdata["shinies"];
|
||||
|
||||
record_log(`Your colony provides you with ${colony_tickdata["food"].toFixed(2)} food and ${colony_tickdata["shinies"].toFixed(2)} shinies.`);
|
||||
}
|
||||
}
|
||||
|
||||
var tickdata = await fetch("/tick")
|
||||
.then(res => {
|
||||
var json = res.json()
|
||||
console.log(json)
|
||||
return json
|
||||
})
|
||||
.catch(e => { throw e; });
|
||||
console.log(JSON.stringify(tickdata));
|
||||
|
||||
if (tickdata["code"] != 200) {
|
||||
console.error("Non-200 tick code: " + tickdata["code"]);
|
||||
return;
|
||||
}
|
||||
|
||||
if (tickdata["event_type"] == 0) {
|
||||
// pass
|
||||
} else if (tickdata["event_type"] == 1) {
|
||||
// Flavor event - no gameplay effect, but occasionally says something fun.
|
||||
record_log(tickdata["log"]);
|
||||
} else if (tickdata["event_type"] == 10) { // ENCHUMAN
|
||||
var total_food = 0;
|
||||
var food_descs = [];
|
||||
var total_shinies = 0;
|
||||
var shinies_descs = [];
|
||||
|
||||
switch (page_elements["menu_enc_human"].value) {
|
||||
case "pause":
|
||||
tickdata.items.food.forEach((item) => {
|
||||
total_food += item["amount"];
|
||||
food_descs.push(item["desc"]);
|
||||
});
|
||||
tickdata.items.shinies.forEach((item) => {
|
||||
total_shinies += item["amount"];
|
||||
shinies_descs.push(item["desc"]);
|
||||
});
|
||||
|
||||
var logstring = "You have encountered a human. It is carrying these resources:\n\n"
|
||||
logstring += "<ol>\n"
|
||||
if (total_food > 0) {
|
||||
logstring += `<li><b>${total_food.toFixed(2)} food:</b> ${food_descs.join(", ")}</li>\n`;
|
||||
}
|
||||
if (total_shinies > 0) {
|
||||
logstring += `<li><b>${total_shinies.toFixed(2)} shinies:</b> ${shinies_descs.join(", ")}</li>\n`;
|
||||
}
|
||||
logstring += "</ol>\nWhat would you like to do?";
|
||||
|
||||
record_log_with_choices(logstring,
|
||||
"Steal food", `steal_resource('food', 'humans', ${total_food}, "${food_descs.toString()}")`,
|
||||
"Steal shinies", `steal_resource('shinies', 'humans', ${total_shinies}, "${shinies_descs.toString()}")`
|
||||
)
|
||||
|
||||
break;
|
||||
case "steal-food":
|
||||
record_log("You have encountered a human. Attempting to steal food.");
|
||||
tickdata.items.food.forEach((item) => {
|
||||
total_food += item["amount"];
|
||||
food_descs.push(item["desc"]);
|
||||
})
|
||||
steal_resource("food", "humans", total_food, food_descs.toString());
|
||||
break;
|
||||
case "steal-shinies":
|
||||
record_log("You have encountered a human. Attempting to steal shinies.");
|
||||
tickdata.items.shinies.forEach((item) => {
|
||||
total_shinies += item["amount"];
|
||||
shinies_descs.push(item["desc"]);
|
||||
})
|
||||
steal_resource("shinies", "humans", total_shinies, shinies_descs.toString());
|
||||
break;
|
||||
default:
|
||||
console.error("undefined action " + page_elements["menu_enc_human"]);
|
||||
break;
|
||||
}
|
||||
} else if (tickdata["event_type"] == 11) { // ENCGULL
|
||||
var total_food = 0;
|
||||
var food_descs = [];
|
||||
var total_shinies = 0;
|
||||
var shinies_descs = [];
|
||||
|
||||
switch (page_elements["menu_enc_seagull"].value) {
|
||||
case "pause":
|
||||
tickdata.items.food.forEach((item) => {
|
||||
total_food += item["amount"];
|
||||
food_descs.push(item["desc"]);
|
||||
});
|
||||
tickdata.items.shinies.forEach((item) => {
|
||||
total_shinies += item["amount"];
|
||||
shinies_descs.push(item["desc"]);
|
||||
});
|
||||
|
||||
var logstring = "You have encountered a seagull. It is carrying these resources:\n\n"
|
||||
logstring += "<ol>\n"
|
||||
if (total_food > 0) {
|
||||
logstring += `<li><b>${total_food.toFixed(2)} food:</b> ${food_descs.join(", ")}</li>\n`;
|
||||
}
|
||||
if (total_shinies > 0) {
|
||||
logstring += `<li><b>${total_shinies.toFixed(2)} shinies:</b> ${shinies_descs.join(", ")}</li>\n`;
|
||||
}
|
||||
logstring += "</ol>\nWhat would you like to do?";
|
||||
|
||||
record_log_with_choices(logstring,
|
||||
"Recruit", `recruit(${tickdata.recruit_cost})`,
|
||||
"Steal food", `steal_resource('food', 'seagulls', ${total_food}, "${food_descs.toString()}")`,
|
||||
"Steal shinies", `steal_resource('shinies', 'seagulls', ${total_shinies}, "${shinies_descs.toString()}")`
|
||||
)
|
||||
|
||||
break;
|
||||
case "recruit":
|
||||
recruit(tickdata.recruit_cost);
|
||||
break
|
||||
case "steal-food":
|
||||
record_log("You have encountered a seagull. Attempting to steal food.");
|
||||
tickdata.items.food.forEach((item) => {
|
||||
total_food += item["amount"];
|
||||
food_descs.push(item["desc"]);
|
||||
})
|
||||
steal_resource("food", "seagulls", total_food, food_descs.toString());
|
||||
break;
|
||||
case "steal-shinies":
|
||||
record_log("You have encountered a seagull. Attempting to steal shinies.");
|
||||
tickdata.items.shinies.forEach((item) => {
|
||||
total_shinies += item["amount"];
|
||||
shinies_descs.push(item["desc"]);
|
||||
})
|
||||
steal_resource("shinies", "seagulls", total_shinies, shinies_descs.toString());
|
||||
break;
|
||||
default:
|
||||
console.error("undefined action " + page_elements["menu_enc_human"]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// sanity check
|
||||
if (!("autosave" in gamestate)) {
|
||||
gamestate["autosave"] = 35;
|
||||
}
|
||||
if (ticks_since_last_save % gamestate["autosave"] == 0 && ticks_since_last_save != 0) {
|
||||
save_game();
|
||||
ticks_since_last_save = 0;
|
||||
}
|
||||
|
||||
gamestate["income"]["last_food"].shift()
|
||||
gamestate["income"]["last_food"].push(tickdiffs["food"])
|
||||
gamestate["income"]["last_shinies"].shift()
|
||||
gamestate["income"]["last_shinies"].push(tickdiffs["shinies"])
|
||||
tickdiffs = structuredClone(tickdiffs_reset);
|
||||
|
||||
gamestate["income"]["calc_food"] = avg(gamestate["income"]["last_food"])
|
||||
gamestate["income"]["calc_shinies"] = avg(gamestate["income"]["last_shinies"])
|
||||
|
||||
update_ui();
|
||||
}
|
||||
|
||||
var start_event = "";
|
||||
var target = null;
|
||||
if (desktop_mode) {
|
||||
// pywebview's native JS is nerfed in a few places and needs the additional python API
|
||||
// which gets loaded after initial DOM via injections
|
||||
start_event = "pywebviewready";
|
||||
target = window;
|
||||
}
|
||||
else {
|
||||
// in web mode, browsers are expected to have working local storage by this point
|
||||
start_event = "DOMContentLoaded";
|
||||
target = document;
|
||||
}
|
||||
|
||||
function update_action(enc, value) {
|
||||
gamestate[`enc_${enc}`] = value;
|
||||
}
|
||||
|
||||
target.addEventListener(start_event, function (ev) {
|
||||
tickdiffs = structuredClone(tickdiffs_reset);
|
||||
|
||||
page_elements["div_log"] = document.querySelector("#main-log");
|
||||
page_elements["div_sidebar"] = document.querySelector("#main-sidebar");
|
||||
page_elements["div_name"] = document.querySelector("#side-seagull-name");
|
||||
page_elements["div_name_editor"] = document.querySelector("#side-seagull-name-editor");
|
||||
page_elements["lbl_name"] = document.querySelector("#lbl-seagull-name");
|
||||
page_elements["lbl_class"] = document.querySelector("#lbl-seagull-class");
|
||||
page_elements["lbl_colony"] = document.querySelector("#lbl-seagull-colony");
|
||||
page_elements["lbl_shinies"] = document.querySelector("#lbl-seagull-shinies");
|
||||
page_elements["lbl_food"] = document.querySelector("#lbl-seagull-food");
|
||||
page_elements["lbl_inc_food"] = document.querySelector("#lbl-seagull-food-income");
|
||||
page_elements["lbl_inc_shinies"] = document.querySelector("#lbl-seagull-shinies-income");
|
||||
page_elements["edt_name"] = document.querySelector("#edt-seagull-name");
|
||||
page_elements["lbl_tick"] = document.querySelector("#main-day-counter");
|
||||
page_elements["lbl_xp"] = document.querySelector("#lbl-seagull-xp-current");
|
||||
page_elements["lbl_xp_next"] = document.querySelector("#lbl-seagull-xp-next");
|
||||
page_elements["lbl_level"] = document.querySelector("#lbl-seagull-lvl");
|
||||
page_elements["menu_enc_human"] = document.querySelector("#menu-enc-human");
|
||||
page_elements["menu_enc_seagull"] = document.querySelector("#menu-enc-seagull");
|
||||
page_elements["btn_charsheet"] = document.querySelector("#button-charsheet");
|
||||
page_elements["btn_settings"] = document.querySelector("#button-settings");
|
||||
page_elements["btn_about"] = document.querySelector("#button-about");
|
||||
|
||||
page_elements["menu_enc_human"].addEventListener("change", (ev) => {update_action("human", ev.target.value)});
|
||||
page_elements["menu_enc_seagull"].addEventListener("change", (ev) => {update_action("seagull", ev.target.value)});
|
||||
page_elements["btn_charsheet"].addEventListener("click", (ev) => {open_modal_dialog("charsheet")});
|
||||
page_elements["btn_about"].addEventListener("click", (ev) => {open_modal_dialog("about")});
|
||||
|
||||
prepare_gamestate();
|
||||
|
||||
record_log("seagull game ver. " + ver_string);
|
||||
|
||||
const interval = setInterval(() => {
|
||||
if (tick_meter_running) { game_tick(); }
|
||||
}, 1200);
|
||||
|
||||
update_ui();
|
||||
});
|
||||
|
||||
function change_seagull_name() {
|
||||
page_elements["div_name"].style.display = "none";
|
||||
page_elements["div_name_editor"].style.display = "block";
|
||||
}
|
||||
|
||||
function confirm_seagull_name() {
|
||||
const new_name = page_elements["edt_name"].value;
|
||||
page_elements["lbl_name"].innerHTML = new_name;
|
||||
gamestate["name"] = new_name;
|
||||
save_game();
|
||||
|
||||
page_elements["div_name"].style.display = "block";
|
||||
page_elements["div_name_editor"].style.display = "none";
|
||||
}
|
||||
|
||||
function cancel_seagull_name() {
|
||||
page_elements["edt_name"].value = "";
|
||||
|
||||
page_elements["div_name"].style.display = "block";
|
||||
page_elements["div_name_editor"].style.display = "none";
|
||||
}
|
BIN
pak/static/sound/open_dev_toolkit.wav
Normal file
BIN
pak/static/sound/open_dev_toolkit.wav
Normal file
Binary file not shown.
Reference in New Issue
Block a user