some work done on character sheets

This commit is contained in:
2025-08-22 13:01:58 -07:00
parent 5c3d34aafa
commit 621d65b9e5
10 changed files with 165 additions and 5 deletions

View File

@@ -33,6 +33,7 @@ if __name__ == "__main__":
elif sys.platform.startswith("darwin"): # macos elif sys.platform.startswith("darwin"): # macos
storage_dir = pathlib.Path(os.environ["HOME"]) / "Library/Application Support/seagull" storage_dir = pathlib.Path(os.environ["HOME"]) / "Library/Application Support/seagull"
else: else:
# TODO: check if XDG env vars are set and prioritize those
storage_dir = pathlib.Path(os.environ["HOME"]) / ".local/share/seagull" storage_dir = pathlib.Path(os.environ["HOME"]) / ".local/share/seagull"
desktop.path_storagedir = storage_dir desktop.path_storagedir = storage_dir

View File

@@ -22,7 +22,8 @@ app = flask.Flask("seagull-game", root_path=path_appdir)
orig_url_for = app.url_for orig_url_for = app.url_for
xml_namespaces = { xml_namespaces = {
"items": "seagull:rules/items" "items": "seagull:rules/items",
"upgrades": "seagull:rules/upgrades"
} }
#REDIS_HOST="stub-implementation.example.net" #REDIS_HOST="stub-implementation.example.net"
@@ -45,6 +46,13 @@ app.url_for = url_for_override
base_context = {} base_context = {}
base_context_live = False base_context_live = False
@app.route("/dialog/<dialog>")
def render_dialog(dialog):
if os.path.exists(path_appdir / f"templates/{dialog}.j2"):
return flask.render_template(f"{dialog}.j2")
else:
return "", 404
def render_base_context(): def render_base_context():
global base_context global base_context
global base_context_live global base_context_live

View File

@@ -6,9 +6,6 @@ import lxml.etree as xmltree
from . import core from . import core
# NOTE: due to how XML libraries handle namespaces, you have to prepend "{seagull:rules/items}" to every tag value
# this is merely the price you pay for editor autocompletions
valid_resources = [ valid_resources = [
"food", "shinies", "psi" # early game "food", "shinies", "psi" # early game
] ]

View File

@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog"> <catalog xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
<uri name="seagull:rules/items" uri="items.xsd" /> <uri name="seagull:rules/items" uri="items.xsd" />
<uri name="seagull:rules/upgrades" uri="upgrades.xsd" />
</catalog> </catalog>

View File

@@ -0,0 +1,32 @@
<?xml version="1.0" standalone="yes"?>
<xs:schema id="UpgradeRules" targetNamespace="seagull:rules/upgrades" xmlns="seagull:rules/upgrades" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" attributeFormDefault="unqualified" elementFormDefault="qualified">
<xs:element name="UpgradeRules" msdata:IsDataSet="true" msdata:UseCurrentLocale="true">
<xs:complexType>
<xs:choice minOccurs="0" maxOccurs="unbounded">
<xs:element name="Upgrade">
<xs:complexType>
<xs:choice maxOccurs="unbounded">
<xs:element name="Id" type="xs:string" minOccurs="1" maxOccurs="1" />
<xs:element name="Name" type="xs:string" minOccurs="1" maxOccurs="1" />
<xs:element name="Desc" type="xs:string" minOccurs="0" maxOccurs="1"/>
<xs:element name="Modifiers" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:sequence>
<xs:element name="Mod" minOccurs="0" maxOccurs="unbounded">
<xs:complexType>
<xs:attribute name="Id" form="unqualified" type="xs:string" />
<xs:attribute name="Name" form="unqualified" type="xs:string" />
<xs:attribute name="Speed" form="unqualified" type="xs:int" />
<xs:attribute name="ChanceSteal" form="unqualified" type="xs:int" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:choice>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<UpgradeRules xmlns="seagull:rules/upgrades">
<Upgrade>
<Id>speed1</Id>
<Name>Speedier Seagull</Name>
<Modifiers>
<Mod Id="up_speed1" Name="Upgrade: Speedier Seagull" Speed="5" />
</Modifiers>
<Desc>You become just a little bit faster, which makes it easier to steal things before your prey's previous owners notice you're coming.</Desc>
</Upgrade>
<Upgrade>
<Id>theft_chance1</Id>
<Name>Swooping Techniques</Name>
<Modifiers>
<Mod Id="up_theft_chance1" Name="Upgrade: Swooping Techniques" ChanceSteal="10" />
</Modifiers>
<Desc>It's all in the neck. The wings are just the steering wheel. You gain a bonus on all dice rolls for stealing.</Desc>
</Upgrade>
</UpgradeRules>

View File

@@ -0,0 +1,20 @@
<div id="charsheet-leftside">
<div class="attr" id="attr-agility">
Agility: <span id="lbl-attr-agility">0</span>
</div>
<div class="attr" id="attr-instinct">
<span id="lbl-attr-instinct-txt">Instinct</span>: <span id="lbl-attr-instinct">0</span>
</div>
</div>
<div id="charsheet-rightside">
<div id="charsheet-upgrade-tabbar">
<nav id="nav-upgrades"><ul>
<li><button id="btn-upgrade-agility">Agility Upgrades</button></li>
<li><button id="btn-upgrade-instinct">Instinct Upgrades</button></li>
</ul></nav>
</div>
<div id="charsheet-upgrade-tree">
<pre class="mermaid" id="upgrade-tree">
</pre>
</div>
</div>

12
app/upgrades/agility.mmd Normal file
View File

@@ -0,0 +1,12 @@
---
title: Agility Upgrades
---
flowchart LR
speed1["Speedier Seagull"]
speed2["Greased Wings"]
theft_chance1["Swooping Techniques"]
theft_chance2["The Element of Surprise"]
speed1-->speed2
theft_chance1-->speed1
theft_chance1-->theft_chance2

View File

@@ -4,6 +4,7 @@ div#root {
display: flex; display: flex;
width: 100%; width: 100%;
height: 100%; height: 100%;
z-index: 0;
font-family: sans-serif; font-family: sans-serif;
} }
@@ -74,3 +75,38 @@ div.log-tick {
div.log-msg { div.log-msg {
margin-left: 0.2em; margin-left: 0.2em;
} }
div#charsheet {
display: flex;
flex-direction: row;
width: 100%;
background-color: rgb(240, 240, 240);
}
div#charsheet-leftside {
display: flex;
flex-direction: column;
}
div#charsheet-rightside {
display: flex;
flex-direction: column;
}
div.attr {
font-size: larger;
}
div#modal-background {
z-index: -10;
background-color: rgba(0, 0, 0, 168);
visibility: hidden;
}
div#modal {
width: 90%;
height: 90%;
border: 1.25em double rgba(192, 192, 192, 255);
background-color: rgba(255, 255, 255, 255);
}

View File

@@ -22,7 +22,9 @@ const gamestate_default = {
"xp": 0, "xp": 0,
"xp_next": 50, "xp_next": 50,
"enc_human": "pause", "enc_human": "pause",
"enc_seagull": "pause" "enc_seagull": "pause",
"agility": 0,
"instinct": 0
}; };
var bool_log_alt = false var bool_log_alt = false
@@ -84,6 +86,38 @@ function record_log_with_choices() {
tick_meter_running = false; tick_meter_running = false;
} }
var modal_dialog_open = false;
var dialog_queue = [];
function modal_no_prop(event) { event.stopPropagation(); }
async function open_modal_dialog(dialog) {
var modal_background = document.getElementById("modal-background");
if (!modal_background) {
modal_background = document.createElement("div");
modal_background.setAttribute("id", "modal-background");
}
var modal_root = document.getElementById("modal");
if (!modal_root) {
modal_root = document.createElement("div");
modal_root.setAttribute("id", "modal");
modal_root.onclick = modal_no_prop;
modal_background.appendChild(modal_root);
}
if (!modal_dialog_open) {
tick_meter_running = false;
modal_dialog_open = true;
modal_background.style = "z-index: 10 !important; visibility: visible !important;";
}
dialog_data = await fetch(`/dialog/${dialog}`)
.then(res => { return res.text(); });
modal_root.innerHTML = dialog_data;
}
function update_ui() { function update_ui() {
page_elements["lbl_name"].innerHTML = gamestate["name"]; page_elements["lbl_name"].innerHTML = gamestate["name"];
page_elements["lbl_tick"].innerHTML = gamestate["tick"]; page_elements["lbl_tick"].innerHTML = gamestate["tick"];