state sync

This commit is contained in:
2025-11-23 14:59:17 -08:00
parent 537bdf1ad7
commit 39f4a8d3fc
812 changed files with 373062 additions and 84 deletions

View File

@@ -29,6 +29,7 @@ from . import gamedata
# \brief The Flask instance. See <a href="https://flask.palletsprojects.com/en/stable/api/">Flask documentation</a>.
app = flask.Flask("seagull-game", root_path=path_appdir, template_folder="templates", static_folder="static")
CORS(app)
app.config["SEND_FILE_MAX_AGE_DEFAULT"] = 0
orig_url_for = app.url_for
xml_namespaces = {
@@ -69,7 +70,8 @@ common_rule_schema = xmltree.XMLSchema(doc_common_rule_schema)
## \brief Validates all XML files in gamedata.
# \internal
#
# This is typically run on program startup.
# This is typically run on program startup. Other modules will register validators
# and this function will check against them all.
def validate_xml_files():
for schema in schemas:
for file in gamedata.vfs.vfs.glob(schema[1]):
@@ -94,6 +96,8 @@ def render_dialog(dialog):
gamedata.vfs.copy_out(f"templates/{dialog}.j2", dest=path_appdir.as_posix())
if gamedata.vfs.exists(f"static/js/dlg-{dialog}.js"):
gamedata.vfs.copy_out(f"static/js/dlg-{dialog}.js", dest=path_appdir.as_posix())
if gamedata.vfs.exists(f"static/js/dlg-{dialog}.mjs"):
gamedata.vfs.copy_out(f"static/js/dlg-{dialog}.mjs")
return flask.render_template(f"{dialog}.j2")
else:
return "", 404

View File

@@ -20,6 +20,8 @@ doc_item_schema = xmltree.parse(pth_item_schema.as_posix())
item_schema = xmltree.XMLSchema(doc_item_schema)
item_schema_parser = xmltree.XMLParser(schema=item_schema)
core.schemas.append((item_schema, "rules/items/**.xml"))
## \brief Generates an absolutely reasonable description of a given item that a target might have.
# \param resource The resource to generate a description for.
# \param target The poor soul carrying the item.

View File

@@ -10,6 +10,11 @@ from . import core, gamedata, items, jsonizer
rant_env = os.environ.copy()
rant_env["RANT_MODULES_PATH"] = (core.path_appdir / "basepak/rant").as_posix()
## \brief Generates some flavor text.
# \internal
#
# This calls the built-in copy of [Rant](https://rant-lang.org) to procedurally generate
# some flavor text with provided template files.
def generate_flavor_text():
if core.desktop_mode:
rant_path = core.path_appdir / "opt/rant/bin/rant"
@@ -54,18 +59,33 @@ def tick():
case 1: # FLAVOR
result["log"] = generate_flavor_text()
case 10: # ENCHUMAN
result["items"] = {
# TODO: read ranges from XML rule files
items_generated = {
"food": items.generate_item_list("food", "humans", 0, 2),
"shinies": items.generate_item_list("shinies", "humans", 0, 2)
}
if len(items_generated["food"]) < 1 and len(items_generated["shinies"]) < 1:
# empty item list, force something
coin_flip = bool(random.getrandbits(1)) #zippy!
if coin_flip:
items_generated["food"] = items.generate_item_list("food", "humans", 1, 3)
else:
items_generated["shinies"] = items.generate_item_list("shinies", "humans", 1, 3)
result["items"] = items_generated
case 11: # ENCGULL
result["items"] = {
# TODO: read ranges from XML rule files
"food": items.generate_item_list("food", "seagulls", 0, 2),
"shinies": items.generate_item_list("shinies", "seagulls", 0, 2)
items_generated = {
"food": items.generate_item_list("food", "humans", 0, 2),
"shinies": items.generate_item_list("shinies", "humans", 0, 2)
}
result["recruit_cost"] = round(random.uniform(0, 10), 2)
if len(items_generated["food"]) < 1 and len(items_generated["shinies"]) < 1:
# empty item list, force something
coin_flip = bool(random.getrandbits(1)) #zippy!
if coin_flip:
items_generated["food"] = items.generate_item_list("food", "humans", 1, 3)
else:
items_generated["shinies"] = items.generate_item_list("shinies", "humans", 1, 3)
result["items"] = items_generated
case _:
core.log.warning("undefined tick: {0}".format(result["event_type"]))

View File

@@ -7,7 +7,6 @@ from collections import namedtuple
import flask
import lxml.etree as xmltree
import mermaid
from . import core, gamedata, jsonizer, util
@@ -130,16 +129,19 @@ def get_upgrade_tree(tree):
buf_mmd.write(f" class {upgrade.id} unlocked\n")
else:
buf_mmd.write(f" class {upgrade.id} open\n")
buf_mmd.write(f" click {upgrade.id} call purchase_upgrade('{tree}','{upgrade.id}')\n")
buf_mmd.write(f" click {upgrade.id} call purchase_upgrade({tree},{upgrade.id})\n")
for line in dependency_lines:
buf_mmd.write(line)
buf_mmd.seek(0)
mmd_str = buf_mmd.read()
mmd_upgradetree = mermaid.Mermaid(mmd_str, height=400)
retval = flask.make_response(mmd_str, 200)
retval.headers["Content-Type"] = "text/plain"
return retval
#mmd_upgradetree = mermaid.Mermaid(mmd_str, height=400)
#print(mmd_str)
return mmd_upgradetree.svg_response.content
#return mmd_upgradetree.svg_response.content
@core.app.route("/upgrades/<tree>/<upgrade>")
def get_upgrade_data(tree, upgrade):
@@ -163,11 +165,26 @@ def get_upgrade_data(tree, upgrade):
hnd_food = hnd_requires.xpath("./upgrades:Food", namespaces=core.xml_namespaces)[0]
except IndexError:
hnd_food = None
try:
hnd_agility = hnd_requires.xpath("./upgrades:Agility", namespaces=core.xml_namespaces)[0]
except IndexError:
hnd_agility = None
try:
hnd_instinct = hnd_requires.xpath("./upgrades:Instinct", namespaces=core.xml_namespaces)[0]
except IndexError:
hnd_instinct = None
try:
hnd_leadership = hnd_requires.xpath("./upgrades:Leadership", namespaces=core.xml_namespaces)[0]
except IndexError:
hnd_leadership = None
try:
hnd_shinies = hnd_requires.xpath("./upgrades:Shinies", namespaces=core.xml_namespaces)[0]
except IndexError:
hnd_shinies = None
except IndexError:
hnd_agility = None
hnd_instinct = None
hnd_leadership = None
hnd_requires = None
hnd_shinies = None
hnd_food = None
@@ -177,15 +194,10 @@ def get_upgrade_data(tree, upgrade):
"id": hnd_id.text,
"name": hnd_name.text,
"desc": hnd_desc.text,
"food": int(hnd_food.text) if hnd_food else 0,
"shinies": int(hnd_shinies.text) if hnd_shinies else 0,
"food": int(hnd_food.text) if hnd_food is not None else 0,
"shinies": int(hnd_shinies.text) if hnd_shinies is not None else 0,
"agility": int(hnd_agility.text) if hnd_agility is not None else 0,
"instinct": int(hnd_instinct.text) if hnd_instinct is not None else 0,
"leadership": int(hnd_leadership.text) if hnd_leadership is not None else 0,
"requires": require_list
}, cls=jsonizer.JSONizer), 200)
def get_upgrade_tree_mmd(tree):
if not gamedata.vfs.exists(f"upgrades/{tree}.mmd"):
return flask.make_response("No Upgrade Tree", 404)
with gamedata.vfs.open(f"upgrades/{tree}.mmd") as fd_upgradetree:
mmd_upgradetree = mermaid.Mermaid(fd_upgradetree.read(), height=400)
return mmd_upgradetree.svg_response.content