Compare commits

..

2 Commits

72 changed files with 571 additions and 26 deletions

View File

@ -1,18 +1,18 @@
[package] [package]
name = "khguide" name = "khguide"
version = "1.3.2" version = "1.4.0"
edition = "2024" edition = "2024"
[dependencies] [dependencies]
askama = "0.14" askama = "0.14.0"
serde = { version = "1.0", features = ["derive"] } serde = { version = "1.0.228", features = ["derive"] }
serde_json = "1.0" serde_json = "1.0.145"
toml = "0.8" toml = "0.9.8"
tracing = "0.1" tracing = "0.1.41"
tracing-subscriber = { version = "0.3", features = ["env-filter"] } tracing-subscriber = { version = "0.3.20", features = ["env-filter"] }
itertools = "0.14" itertools = "0.14.0"
blake3 = "1.8" blake3 = "1.8.2"
ordered-float = { version = "5.0", features = ["serde"] } ordered-float = { version = "5.1.0", features = ["serde"] }
[features] [features]
default = ["bbs", "ddd", "kh3", "kh2", "kh1"] default = ["bbs", "ddd", "kh3", "kh2", "kh1"]

View File

@ -0,0 +1,6 @@
name = "Apple"
group = "fruit"
[[locations]]
world = "Any"
room = "Moogle Shop"

View File

@ -0,0 +1,6 @@
name = "Apricot"
group = "fruit"
[[locations]]
world = "Any"
room = "Moogle Shop"

View File

@ -0,0 +1,7 @@
name = "Banana"
group = "special"
[[locations]]
world = "Monstropolis"
room = "Upper Level"
note = "Banana Flan"

View File

@ -0,0 +1,12 @@
name = "Basil"
group = "herb"
[[locations]]
world = "Kingdom of Corona"
room = "The Forest"
note = "Spawn in Thoroughfare and go back to The Forest around the trees"
[[locations]]
world = "Toy Box"
room = "Andy's House"
note = "Outside the house in the garden"

View File

@ -0,0 +1,16 @@
name = "Bay Leaf"
group = "herb"
[[locations]]
world = "Any"
room = "Moogle Shop"
[[locations]]
world = "Kingdom of Corona"
room = "The Forest"
note = "Spawn in Thoroughfare and go back to The Forest around the trees"
[[locations]]
world = "Toy Box"
room = "Andy's House"
note = "Outside the house in the garden"

View File

@ -0,0 +1,11 @@
name = "Beef"
group = "meat"
[[locations]]
world = "Any"
room = "Moogle Shop"
[[locations]]
world = "Toy Box"
room = "Galaxy Toys"
notes = "Rest Area"

View File

@ -0,0 +1,6 @@
name = "Black Truffle"
group = "mushroom"
[[locations]]
world = "Any"
room = "Moogle Shop"

View File

@ -0,0 +1,6 @@
name = "Black Trumpet"
group = "mushroom"
[[locations]]
world = "Any"
room = "Moogle Shop"

View File

@ -0,0 +1,2 @@
name = "Blackberry"
group = "fruit"

View File

@ -0,0 +1,7 @@
name = "Blood Orange"
group = "special"
[[locations]]
world = "Kingdom of Corona"
room = "Hills"
note = "Orange Flan"

View File

@ -0,0 +1,6 @@
name = "Butter"
group = "other"
[[locations]]
world = "Any"
room = "Moogle Shop"

View File

@ -0,0 +1,2 @@
name = "Carrot"
group = "vegetable"

View File

@ -0,0 +1,6 @@
name = "Caviar"
group = "other"
[[locations]]
world = "Any"
room = "Moogle Shop"

View File

@ -0,0 +1,6 @@
name = "Celery"
group = "vegetable"
[[locations]]
world = "Any"
room = "Moogle Shop"

View File

@ -0,0 +1,11 @@
name = "Chanterelle"
group = "mushroom"
[[locations]]
world = "Any"
room = "Moogle Shop"
[[locations]]
world = "Kingdom of Corona"
room = "The Forest"
note = "Spawn in Thoroughfare and go back to The Forest around the trees"

View File

@ -0,0 +1,11 @@
name = "Cheese"
group = "other"
[[locations]]
world = "Any"
room = "Moogle Shop"
[[locations]]
world = "Toy Box"
room = "Galaxy Toys"
notes = "1F on the right side stands"

View File

@ -0,0 +1,11 @@
name = "Chocolate"
group = "other"
[[locations]]
world = "Any"
room = "Moogle Shop"
[[locations]]
world = "Toy Box"
room = "Galaxy Toys"
notes = "2F on the right side at the very end of the platform"

View File

@ -0,0 +1,6 @@
name = "Cloves"
group = "herb"
[[locations]]
world = "Any"
room = "Moogle Shop"

View File

@ -0,0 +1,7 @@
name = "Cod"
group = "seafood"
[[locations]]
world = "Kingdom of Corona"
room = "Thoroughfare"
note = "At the wharf to the left from save point"

View File

@ -0,0 +1,21 @@
name = "Cornichon"
group = "other"
[[locations]]
world = "Any"
room = "Moogle Shop"
[[locations]]
world = "Toy Box"
room = "Galaxy Toys"
note = "1F outside the store to the right"
[[locations]]
world = "Toy Box"
room = "Galaxy Toys"
note = "Rest Area"
[[locations]]
world = "Toy Box"
room = "Galaxy Toys"
note = "Action Figures, in the very back of the store"

View File

@ -0,0 +1,2 @@
name = "Crab"
group = "seafood"

View File

@ -0,0 +1,7 @@
name = "Dill"
group = "herb"
[[locations]]
world = "Monstropolis"
room = "Lobby & Offices"
note = "Vending Machine at the Laugh Floor's entrance"

View File

@ -0,0 +1,11 @@
name = "Eel"
group = "seafood"
[[locations]]
world = "Any"
room = "Moogle Shop"
[[locations]]
world = "Kingdom of Corona"
room = "The Forest"
note = "Spawn in Thoroughfare and go back to The Forest near the water"

View File

@ -0,0 +1,2 @@
name = "Eggplant"
group = "vegetable"

View File

@ -0,0 +1,12 @@
name = "Filet Mignon"
group = "meat"
[[locations]]
world = "Monstropolis"
room = "Lobby & Offices"
note = "Laugh Floor on the desk in the very back"
[[locations]]
world = "The Carribean"
room = "Fort"
note = "In a box on the front terrace from the spawn"

View File

@ -0,0 +1,2 @@
name = "Garlic"
group = "vegetable"

View File

@ -0,0 +1,2 @@
name = "Gooseberry"
group = "fruit"

View File

@ -0,0 +1,7 @@
name = "Grapes"
group = "special"
[[locations]]
world = "Arendelle"
room = "Mountain Ridge"
note = "Grape Flan"

View File

@ -0,0 +1,6 @@
name = "Honey"
group = "other"
[[locations]]
world = "100 Acre Wood"
room = "Pooh's Hunny Harvest"

View File

@ -0,0 +1,6 @@
name = "King Oyster Mushroom"
group = "mushroom"
[[locations]]
world = "Any"
room = "Moogle Shop"

View File

@ -0,0 +1,6 @@
name = "Lemon"
group = "fruit"
[[locations]]
world = "Any"
room = "Moogle Shop"

View File

@ -0,0 +1,7 @@
name = "Lobster"
group = "seafood"
[[locations]]
world = "Kingdom of Corona"
room = "The Forest"
note = "Spawn in Thoroughfare and go back to The Forest near the water"

View File

@ -0,0 +1,7 @@
name = "Melon"
group = "special"
[[locations]]
world = "San Fransokyo"
room = "South District"
note = "Honeydew Flan"

View File

@ -0,0 +1,6 @@
name = "Miller Mushroom"
group = "mushroom"
[[locations]]
world = "The Carribean"
room = "Hudded Isles"

View File

@ -0,0 +1,6 @@
name = "Morel"
group = "mushroom"
[[locations]]
world = "Any"
room = "Moogle Shop"

View File

@ -0,0 +1,7 @@
name = "Mussle"
group = "seafood"
[[locations]]
world = "Kingdom of Corona"
room = "Thoroughfare"
note = "At the wharf to the left from save point"

View File

@ -0,0 +1,6 @@
name = "Olive Oil"
group = "other"
[[locations]]
world = "Any"
room = "Moogle Shop"

View File

@ -0,0 +1,6 @@
name = "Onion"
group = "vegetable"
[[locations]]
world = "Any"
room = "Moogle Shop"

View File

@ -0,0 +1,2 @@
name = "Orange"
group = "fruit"

View File

@ -0,0 +1,11 @@
name = "Parsley"
group = "herb"
[[locations]]
world = "Any"
room = "Moogle Shop"
[[locations]]
world = "Toy Box"
room = "Andy's House"
note = "Outside the house in the garden"

View File

@ -0,0 +1,2 @@
name = "Pear"
group = "fruit"

View File

@ -0,0 +1,6 @@
name = "Porcini"
group = "mushroom"
[[locations]]
world = "Any"
room = "Moogle Shop"

View File

@ -0,0 +1,2 @@
name = "Portobello"
group = "mushroom"

View File

@ -0,0 +1,7 @@
name = "Pumpkin"
group = "vegetable"
[[locations]]
world = "Kingdom of Corona"
room = "Thoroughfare"
note = "Stands on the main street"

View File

@ -0,0 +1,2 @@
name = "Quail"
group = "meat"

View File

@ -0,0 +1,2 @@
name = "Raspberry"
group = "fruit"

View File

@ -0,0 +1,6 @@
name = "Rice"
group = "other"
[[locations]]
world = "Any"
room = "Moogle Shop"

View File

@ -0,0 +1,11 @@
name = "Rosemary"
group = "herb"
[[locations]]
world = "Any"
room = "Moogle Shop"
[[locations]]
world = "Toy Box"
room = "Andy's House"
note = "Outside the house in the garden"

View File

@ -0,0 +1,6 @@
name = "Saffron"
group = "herb"
[[locations]]
world = "Any"
room = "Moogle Shop"

View File

@ -0,0 +1,12 @@
name = "Scallop"
group = "seafood"
[[locations]]
world = "Kingdom of Corona"
room = "Thoroughfare"
note = "At the wharf to the left from save point"
[[locations]]
world = "Kingdom of Corona"
room = "The Forest"
note = "Spawn in Thoroughfare and go back to The Forest near the water"

View File

@ -0,0 +1,12 @@
name = "Sea Bass"
group = "seafood"
[[locations]]
world = "Kingdom of Corona"
room = "Thoroughfare"
note = "At the wharf to the left from save point"
[[locations]]
world = "Kingdom of Corona"
room = "The Forest"
note = "Spawn in Thoroughfare and go back to The Forest near the water"

View File

@ -0,0 +1,11 @@
name = "Sole"
group = "seafood"
[[locations]]
world = "Any"
room = "Moogle Shop"
[[locations]]
world = "Kingdom of Corona"
room = "Thoroughfare"
note = "At the wharf to the left from save point"

View File

@ -0,0 +1,7 @@
name = "Sour Cherry"
group = "special"
[[locations]]
world = "Olympus"
room = "Overlook"
note = "Cherry Flan"

View File

@ -0,0 +1,7 @@
name = "Strawberry"
group = "special"
[[locations]]
world = "Toy Box"
room = "Rest Area"
note = "Strawberry Flan"

View File

@ -0,0 +1,11 @@
name = "Thyme"
group = "herb"
[[locations]]
world = "Any"
room = "Moogle Shop"
[[locations]]
world = "Toy Box"
room = "Andy's House"
note = "Outside the house in the garden"

View File

@ -0,0 +1,7 @@
name = "Tomato"
group = "vegetable"
[[locations]]
world = "Kingdom of Corona"
room = "Thoroughfare"
note = "Stands on the main street"

View File

@ -0,0 +1,6 @@
name = "Veal"
group = "meat"
[[locations]]
world = "Any"
room = "Moogle Shop"

View File

@ -0,0 +1,7 @@
name = "Watermelon"
group = "special"
[[locations]]
world = "The Caribbean"
room = "Fort"
note = "Watermelon Flan"

View File

@ -0,0 +1,2 @@
name = "Zucchini"
group = "vegetable"

View File

@ -1,5 +1,8 @@
import "../common/prototypes.js"; import "../common/prototypes.js";
const RECIPE_STORAGE_NAME = "kh1/synth/recipe.";
const LIST_STORAGE_NAME = "kh1/synth/needed-maths";
let markedNeededMaterials = []; let markedNeededMaterials = [];
document.addEventListener("DOMContentLoaded", (event) => { document.addEventListener("DOMContentLoaded", (event) => {
@ -7,12 +10,13 @@ document.addEventListener("DOMContentLoaded", (event) => {
for (const recipe of recipes) { for (const recipe of recipes) {
recipe.checked = recipe.checked =
localStorage.getItem("kh1-synth-" + recipe.id) === "true" ?? false; localStorage.getItem(RECIPE_STORAGE_NAME + recipe.id) === "true" ??
false;
updateSynthRecipeState(recipe); updateSynthRecipeState(recipe);
recipe.addEventListener("input", function () { recipe.addEventListener("input", function () {
// Change the recipe's state and update and needed materials list based on the remaining recipes // Change the recipe's state and update and needed materials list based on the remaining recipes
localStorage.setItem("kh1-synth-" + this.id, this.checked); localStorage.setItem(RECIPE_STORAGE_NAME + this.id, this.checked);
updateSynthRecipeState(this); updateSynthRecipeState(this);
calcNeededMats(); calcNeededMats();
}); });
@ -26,8 +30,8 @@ document.addEventListener("DOMContentLoaded", (event) => {
} }
// Turn the single saved string into an array with each material // Turn the single saved string into an array with each material
if (localStorage.getItem("kh1-synth-needed-mats") != null) { if (localStorage.getItem(LIST_STORAGE_NAME) != null) {
let saved = localStorage.getItem("kh1-synth-needed-mats"); let saved = localStorage.getItem(LIST_STORAGE_NAME);
saved = saved.split(","); saved = saved.split(",");
markedNeededMaterials = saved; markedNeededMaterials = saved;
markedNeededMaterials = markedNeededMaterials.filter( markedNeededMaterials = markedNeededMaterials.filter(
@ -128,7 +132,7 @@ function updateMarkedNeededMats(ingredient) {
markedNeededMaterials.push(ingredient); markedNeededMaterials.push(ingredient);
} }
markedNeededMaterials = markedNeededMaterials.filter((n) => n && n !== ""); markedNeededMaterials = markedNeededMaterials.filter((n) => n && n !== "");
localStorage.setItem("kh1-synth-needed-mats", markedNeededMaterials); localStorage.setItem(LIST_STORAGE_NAME, markedNeededMaterials);
} }
function markNeededMat(mat) { function markNeededMat(mat) {

View File

@ -1,17 +1,27 @@
let globalStats = { str: 0, mag: 0, def: 0, hp: 0, mp: 0 }; const STORAGE_NAME = "kh3/food-sim/recipe.";
const types = ["starters", "soups", "fish", "meat", "deserts"]; const types = ["starters", "soups", "fish", "meat", "deserts"];
let globalStats = { str: 0, mag: 0, def: 0, hp: 0, mp: 0 };
let typeItem = []; let typeItem = [];
let hasSelection = [false, false, false, false, false]; let hasSelection = [false, false, false, false, false];
let ingredientsList = [];
document.addEventListener("DOMContentLoaded", (event) => { document.addEventListener("DOMContentLoaded", (event) => {
updateStats(); updateStats();
types.forEach(function (type, typeIdx) { types.forEach(function (type, typeIdx) {
let savedRecipe = localStorage.getItem(STORAGE_NAME + typeIdx);
const recipes = document.querySelectorAll( const recipes = document.querySelectorAll(
"div.recipes." + type + " .recipe", "div.recipes." + type + " .recipe",
); );
recipes.forEach(function (item, index) { recipes.forEach(function (item, index) {
let recipeName = item.querySelector(".title").innerText;
if (savedRecipe != undefined && recipeName == savedRecipe) {
selectRecipe(item, typeIdx);
}
item.addEventListener("click", function () { item.addEventListener("click", function () {
if (!hasSelection[typeIdx]) { if (!hasSelection[typeIdx]) {
hasSelection[typeIdx] = true; hasSelection[typeIdx] = true;
@ -71,6 +81,16 @@ document.addEventListener("DOMContentLoaded", (event) => {
}); });
function unselectRecipe(index) { function unselectRecipe(index) {
// Remove all ingredients of this recipe
let ingredients = typeItem[index].querySelectorAll(".ingredients ul li");
for (let ingredient of ingredients) {
ingredientsList = ingredientsList.filter(
(ing) => ing != ingredient["innerText"],
);
}
localStorage.removeItem(STORAGE_NAME + index);
typeItem[index].style["box-shadow"] = "0px 0px 10px rgba(0, 0, 0, 0.4)"; typeItem[index].style["box-shadow"] = "0px 0px 10px rgba(0, 0, 0, 0.4)";
let stats = JSON.parse(typeItem[index].dataset["stats"]); let stats = JSON.parse(typeItem[index].dataset["stats"]);
removeStats(stats); removeStats(stats);
@ -80,6 +100,17 @@ function selectRecipe(item, index) {
typeItem[index] = item; typeItem[index] = item;
item.style["box-shadow"] = "0px 0px 10px rgba(0, 255, 0, 0.8)"; item.style["box-shadow"] = "0px 0px 10px rgba(0, 255, 0, 0.8)";
// Add all ingredients of this recipe to a global list
let ingredients = item.querySelectorAll(".ingredients ul li");
for (let ingredient of ingredients) {
ingredientsList.push(ingredient["innerText"]);
}
let recipeName = item.querySelector(".title").innerText;
console.log(item);
console.log(item.querySelectorAll(".title"));
localStorage.setItem(STORAGE_NAME + index, recipeName);
let stats = JSON.parse(item.dataset["stats"]); let stats = JSON.parse(item.dataset["stats"]);
addStats(stats); addStats(stats);
} }
@ -149,6 +180,14 @@ function updateStats() {
); );
updatePoint(poly, 2, HP_MAX_POINT, hpProgress, globalStats.hp, "stat-hp"); updatePoint(poly, 2, HP_MAX_POINT, hpProgress, globalStats.hp, "stat-hp");
updatePoint(poly, 3, MP_MAX_POINT, mpProgress, globalStats.mp, "stat-mp"); updatePoint(poly, 3, MP_MAX_POINT, mpProgress, globalStats.mp, "stat-mp");
// let list = document.getElementById("ingredients-list");
// list.innerHTML = "";
// for (let ingredient of ingredientsList) {
// let ingredientElem = document.createElement("li");
// ingredientElem.innerText = ingredient;
// list.appendChild(ingredientElem);
// }
} }
function updatePoint(poly, statId, max, progress, value, statElem) { function updatePoint(poly, statId, max, progress, value, statElem) {

View File

@ -1,5 +1,6 @@
use askama::Template; use askama::Template;
use food::Recipes; use food::Recipes;
use ingredient::Ingredient;
use crate::{ use crate::{
RuntimeModule, RuntimeModule,
@ -8,9 +9,11 @@ use crate::{
}; };
mod food; mod food;
mod ingredient;
const ENEMIES_PATH: &str = "./input/kh3/enemies"; const ENEMIES_PATH: &str = "./input/kh3/enemies";
const RECIPES_PATH: &str = "./input/kh3/recipes.toml"; const RECIPES_PATH: &str = "./input/kh3/recipes.toml";
const INGREDIENTS_PATH: &str = "./input/kh3/ingredients";
#[derive(Template)] #[derive(Template)]
#[template(path = "pages/kh3/drops.html")] #[template(path = "pages/kh3/drops.html")]
@ -24,15 +27,23 @@ struct RecipesTemplate {
pub recipes: Recipes, pub recipes: Recipes,
} }
#[derive(Template)]
#[template(path = "pages/kh3/ingredients.html")]
struct IngredientsTemplate {
pub ingredients: Vec<Ingredient>,
}
pub struct Module; pub struct Module;
impl RuntimeModule for Module { impl RuntimeModule for Module {
fn start_module() { fn start_module() {
tracing::info!("Loading enemy data from {}", ENEMIES_PATH); tracing::info!("Loading enemy data from {}", ENEMIES_PATH);
let enemies = Enemy::import(ENEMIES_PATH); let enemies = Enemy::import(ENEMIES_PATH);
let drops = Drops::new(Game::Kh3, enemies); let drops = Drops::new(Game::Kh3, enemies);
tracing::info!("Loading ingredients data from {}", ENEMIES_PATH);
let ingredients = Ingredient::import(INGREDIENTS_PATH);
tracing::info!("Loading recipes data from {}", RECIPES_PATH); tracing::info!("Loading recipes data from {}", RECIPES_PATH);
let recipes_str = std::fs::read_to_string(RECIPES_PATH).unwrap(); let recipes_str = std::fs::read_to_string(RECIPES_PATH).unwrap();
let recipes = toml::from_str::<Recipes>(&recipes_str).unwrap(); let recipes = toml::from_str::<Recipes>(&recipes_str).unwrap();
@ -42,6 +53,11 @@ impl RuntimeModule for Module {
create_file("./out/kh3", "drops", drops_template).unwrap(); create_file("./out/kh3", "drops", drops_template).unwrap();
tracing::info!("Generating the KH3 ingredients template");
let ingredients_template = IngredientsTemplate { ingredients };
create_file("./out/kh3", "ingredients", ingredients_template).unwrap();
tracing::info!("Generating the KH3 recipes template"); tracing::info!("Generating the KH3 recipes template");
let food_template = RecipesTemplate { recipes }; let food_template = RecipesTemplate { recipes };

View File

@ -0,0 +1,58 @@
use std::path::PathBuf;
use serde::Deserialize;
#[derive(Debug, Deserialize, PartialEq, Eq)]
#[serde(rename_all = "lowercase")]
pub enum IngredientGroup {
Meat,
Seafood,
Vegetable,
Mushroom,
Herb,
Fruit,
Other,
Special,
}
#[derive(Debug, Deserialize, PartialEq, Eq)]
pub struct Ingredient {
pub name: String,
pub group: IngredientGroup,
pub locations: Vec<Location>,
}
#[derive(Debug, Deserialize, PartialEq, Eq)]
pub struct Location {
pub world: String,
pub room: String,
pub note: Option<String>,
}
impl Ingredient {
pub fn import(path: &str) -> Vec<Ingredient> {
let mut ingredients: Vec<Ingredient> = vec![];
// Loading multiple files into one vector due to the size of each board
let paths = std::fs::read_dir(path)
.unwrap()
.filter_map(|f| f.ok())
.map(|f| f.path())
.filter_map(|p| match p.extension().is_some_and(|e| e == "toml") {
true => Some(p),
false => None,
})
.collect::<Vec<PathBuf>>();
for path in paths {
let str = std::fs::read_to_string(path).unwrap();
let ingredient = toml::from_str::<Ingredient>(&str);
if let Ok(ingredient) = ingredient {
ingredients.push(ingredient);
}
}
ingredients
}
}

View File

@ -26,8 +26,8 @@
<br /> <br />
{% for drop in data.drops %} {% for drop in data.drops %}
{% call macros::drop("shard") %} {% call drops_macros::drop("shard") %}
{% call macros::drop("stone") %} {% call drops_macros::drop("stone") %}
{% call macros::drop("gem") %} {% call drops_macros::drop("gem") %}
{% call macros::drop("crystal") %} {% call drops_macros::drop("crystal") %}
{% endfor %} {% endfor %}

View File

@ -1,5 +1,5 @@
{% extends "layouts/base.html" %} {% extends "layouts/base.html" %}
{% import "macros/common/macros.html" as macros %} {% import "macros/common/drops.html" as drops_macros %}
{% block title %}KH1 - Drops{% endblock %} {% block title %}KH1 - Drops{% endblock %}

View File

@ -1,5 +1,4 @@
{% extends "layouts/base.html" %} {% extends "layouts/base.html" %}
{% import "macros/common/macros.html" as macros %}
{% block title %}KH1 - Sythensis{% endblock %} {% block title %}KH1 - Sythensis{% endblock %}

View File

@ -1,5 +1,5 @@
{% extends "layouts/base.html" %} {% extends "layouts/base.html" %}
{% import "macros/common/macros.html" as macros %} {% import "macros/common/drops.html" as drops_macros %}
{% block title %}KH2 - Drops{% endblock %} {% block title %}KH2 - Drops{% endblock %}

View File

@ -1,7 +1,7 @@
{% extends "layouts/base.html" %} {% extends "layouts/base.html" %}
{% import "macros/common/macros.html" as macros %} {% import "macros/common/drops.html" as drops_macros %}
{% block title %}KH2 - Drops{% endblock %} {% block title %}KH3 - Drops{% endblock %}
{% block head %} {% block head %}
<link rel="stylesheet" href="{{ crate::find_hash("/public/styles/common/drops.css") }}"></link> <link rel="stylesheet" href="{{ crate::find_hash("/public/styles/common/drops.css") }}"></link>

View File

@ -57,6 +57,8 @@
<input type="checkbox" id="hearty-meal" name="hearty-meal" /> <input type="checkbox" id="hearty-meal" name="hearty-meal" />
<label for="hearty-meal">Hearty Meal</label> <label for="hearty-meal">Hearty Meal</label>
</div> </div>
<ul id="ingredients-list"></ul>
</div> </div>
<h1>Starters</h1> <h1>Starters</h1>

View File

@ -0,0 +1,14 @@
{% extends "layouts/base.html" %}
{% block title %}KH3 - Ingredients{% endblock %}
{% block head %}
<link rel="stylesheet" href="{{ crate::find_hash("/public/styles/common/ingredients.css") }}"></link>
<script
type="module"
src="{{ crate::find_hash("/public/scripts/common/ingredients.js") }}"
></script>
{% endblock %}
{% block content %}
{% endblock %}