Compare commits

...

4 Commits

14 changed files with 786 additions and 51 deletions

View File

@ -11,3 +11,9 @@ toml = "0.8.19"
tracing = "0.1.40"
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
itertools = "0.13.0"
[features]
default = ["bbs", "ddd", "kh3"]
kh3 = []
bbs = []
ddd = []

View File

@ -0,0 +1,207 @@
spirit = "Ghostabocky"
order = 20
[[routes]]
id = 0
name = "Big Eater"
color = "purple"
[[routes.tips]]
to = "Phantom"
tip = "Hat or Face"
[[routes.tips]]
to = "Shaman"
tip = "Back"
[[routes.tips]]
to = "Split Personality"
tip = "Back"
[[routes]]
id = 1
name = "Phantom"
color = "yellow"
[[routes.tips]]
to = "Big Eater"
tip = "Hat or Back"
[[routes.tips]]
to = "Shaman"
tip = "Face"
[[routes.tips]]
to = "Split Personality"
tip = "Face"
[[routes]]
id = 2
name = "Shaman"
color = "blue"
[[routes.tips]]
to = "Big Eater"
tip = "Face or Back"
[[routes.tips]]
to = "Phantom"
tip = "Face or Back"
[[routes.tips]]
to = "Split Personality"
tip = "Hat"
[[routes]]
id = 3
name = "Split Personality"
color = "green"
[[routes.tips]]
to = "Big Eater"
tip = "Hat"
[[routes.tips]]
to = "Phantom"
tip = "Hat"
[[routes.tips]]
to = "Shaman"
tip = "Face or Back"
[[abilities]]
name = "Start"
pos = "A1"
type = "Start"
price = ""
path = ["E"]
[[abilities]]
name = "Zero Gravira"
pos = "B1"
type = "Magic"
price = "10 LP"
path = ["W", "E"]
[[abilities]]
name = "Attack Boost"
pos = "C1"
type = "Stat"
price = "100 LP"
path = ["W", "E", "S"]
[[abilities]]
name = "Dark Screen"
pos = "C2"
type = "Stat"
price = "20 LP"
path = ["N", "S"]
[[abilities]]
name = "Magic Haste"
pos = "C3"
type = "Stat"
price = "50 LP"
path = ["N", "S"]
[[abilities]]
name = "Magic Boost"
pos = "C4"
type = "Stat"
price = "100 LP"
path = ["N", "S", "E"]
[[abilities]]
name = "Dark Screen"
pos = "C5"
type = "Stat"
price = "100 LP"
route = 1
path = ["N", "E"]
[[abilities]]
name = "Magic Haste"
pos = "D1"
type = "Stat"
price = "30 LP"
path = ["W", "S", "E"]
[[abilities]]
name = "Checkpoint"
pos = "D2"
type = "Checkpoint"
price = "Link x1"
path = ["N", "S"]
[[abilities]]
name = "Treasure Magnet"
pos = "D3"
type = "Support"
price = "50 LP"
path = ["N"]
[[abilities]]
name = "Blindness Block"
pos = "D4"
type = "Stat"
price = "30 LP"
path = ["W", "E"]
[[abilities]]
name = "Magic Haste"
pos = "D5"
type = "Stat"
price = "100 LP"
route = 1
path = ["W"]
[[abilities]]
name = "Dark Screen"
pos = "E1"
type = "Stat"
price = "40 LP"
path = ["W", "S", "E"]
[[abilities]]
name = "Slow Block"
pos = "E2"
type = "Stat"
price = "30 LP"
path = ["N", "S"]
[[abilities]]
name = "Dark Screen"
pos = "E3"
type = "Stat"
price = "60 LP"
path = ["N", "S"]
[[abilities]]
name = "Checkpoint"
pos = "E4"
type = "Checkpoint"
price = "Level 20"
path = ["N", "S", "W"]
[[abilities]]
name = "Dark Aura"
pos = "E5"
type = "Attack"
price = "400 LP"
path = ["N"]
[[abilities]]
name = "Dark Screen"
pos = "F1"
type = "Stat"
price = "80 LP"
route = 3
path = ["W", "S"]
[[abilities]]
name = "Vanish"
pos = "F2"
type = "Magic"
price = "300 LP"
route = 3
path = ["N"]

View File

@ -0,0 +1,228 @@
spirit = "KO Kabuto"
order = 18
[[routes]]
id = 0
name = "Tank"
color = "purple"
[[routes.tips]]
to = "Grenadier"
tip = "Belly or Back"
[[routes.tips]]
to = "Bodyguard"
tip = "Head"
[[routes.tips]]
to = "Launcher"
tip = "Head"
[[routes]]
id = 1
name = "Grenadier"
color = "yellow"
[[routes.tips]]
to = "Tank"
tip = "Head or Back"
[[routes.tips]]
to = "Bodyguard"
tip = "Belly"
[[routes.tips]]
to = "Launcher"
tip = "Belly"
[[routes]]
id = 2
name = "Bodyguard"
color = "blue"
[[routes.tips]]
to = "Tank"
tip = "Head or Belly"
[[routes.tips]]
to = "Grenadier"
tip = "Head or Belly"
[[routes.tips]]
to = "Launcher"
tip = "Back"
[[routes]]
id = 3
name = "Launcher"
color = "green"
[[routes.tips]]
to = "Tank"
tip = "Belly"
[[routes.tips]]
to = "Grenadier"
tip = "Belly"
[[routes.tips]]
to = "Bodyguard"
tip = "Head or Back"
[[routes]]
id = 100
name = "Secret Route 1"
color = "secret1"
tips = []
[[abilities]]
name = "Reload Boost"
pos = "A2"
type = "Stat"
price = "150 LP"
path = ["S", "E"]
[[abilities]]
name = "Secret"
pos = "A3"
type = "Secret"
price = "10 LP"
path = ["N", "E"]
[[abilities]]
name = "Defense Boost"
pos = "A4"
type = "Stat"
price = "200 LP"
route = 1
path = ["E"]
[[abilities]]
name = "Checkpoint"
pos = "B2"
type = "Checkpoint"
price = "Link x3"
path = ["W", "E"]
[[abilities]]
name = "Thunder Screen"
pos = "B3"
type = "Stat"
price = "20 LP"
route = 100
path = ["W", "S"]
tip = "Unlocks with Secret panel at A3"
[[abilities]]
name = "Thunder Screen"
pos = "B4"
type = "Stat"
price = "40 LP"
route = 100
path = ["W", "N", "S"]
tip = "Unlocks with Secret panel at A3"
[[abilities]]
name = "Thunder Screen"
pos = "B5"
type = "Stat"
price = "60 LP"
route = 100
path = ["N", "S"]
tip = "Unlocks with Secret panel at A3"
[[abilities]]
name = "Checkpoint"
pos = "B6"
type = "Checkpoint"
price = "Level 20"
route = 100
path = ["N", "S"]
tip = "Unlocks with Secret panel at A3"
[[abilities]]
name = "Icebreaker"
pos = "B7"
type = "Attack"
price = "100 LP"
route = 100
path = ["N"]
tip = "Unlocks with Secret panel at A3"
[[abilities]]
name = "Start"
pos = "C1"
type = "Start"
price = ""
path = ["S"]
[[abilities]]
name = "Link Block"
pos = "C2"
type = "Defense"
price = "10 LP"
path = ["W", "N", "S"]
[[abilities]]
name = "Fire Screen"
pos = "C3"
type = "Stat"
price = "20 LP"
path = ["N", "S", "E"]
[[abilities]]
name = "Fire Screen"
pos = "C4"
type = "Stat"
price = "40 LP"
path = ["N", "S"]
[[abilities]]
name = "Defense Boost"
pos = "C5"
type = "Stat"
price = "100 LP"
path = ["N"]
[[abilities]]
name = "Circle Raid"
pos = "C6"
type = "Attack"
price = "100 LP"
path = ["N"]
[[abilities]]
name = "Fira"
pos = "D3"
type = "Magic"
price = "100 LP"
path = ["S", "W"]
[[abilities]]
name = "Blizzard Screen"
pos = "D4"
type = "Stat"
price = "20 LP"
path = ["N", "S", "E"]
[[abilities]]
name = "Blizzard Screen"
pos = "D5"
type = "Stat"
price = "40 LP"
path = ["N", "S"]
[[abilities]]
name = "Blizzard Screen"
pos = "D6"
type = "Stat"
price = "60 LP"
path = ["N"]
[[abilities]]
name = "Defense Boost"
pos = "E4"
type = "Stat"
price = "200 LP"
route = 2
path = ["W"]

View File

@ -0,0 +1,207 @@
spirit = "Wheeflower"
order = 19
[[routes]]
id = 0
name = "Keeper"
color = "purple"
[[routes.tips]]
to = "Multi-Tasker"
tip = "Leaves or Bulb"
[[routes.tips]]
to = "Spell Slinger"
tip = "Head"
[[routes.tips]]
to = "Green Thumb"
tip = "Head"
[[routes]]
id = 1
name = "Multi-Tasker"
color = "yellow"
[[routes.tips]]
to = "Keeper"
tip = "Head or Bulb"
[[routes.tips]]
to = "Spell Slinger"
tip = "Leaves"
[[routes.tips]]
to = "Green Thumb"
tip = "Leaves"
[[routes]]
id = 2
name = "Spell Slinger"
color = "blue"
[[routes.tips]]
to = "Keeper"
tip = "Head or Leaves"
[[routes.tips]]
to = "Multi-Tasker"
tip = "Head or Leaves"
[[routes.tips]]
to = "Green Thumb"
tip = "Bulb"
[[routes]]
id = 3
name = "Green Thumb"
color = "green"
[[routes.tips]]
to = "Keeper"
tip = "Bulb"
[[routes.tips]]
to = "Multi-Tasker"
tip = "Bulb"
[[routes.tips]]
to = "Spell Slinger"
tip = "Head or Leaves"
[[abilities]]
name = "Magic Haste"
pos = "A3"
type = "Stat"
price = "50 LP"
route = 1
path = ["E"]
[[abilities]]
name = "Water Screen"
pos = "B3"
type = "Stat"
price = "60 LP"
route = 1
path = ["W", "E"]
[[abilities]]
name = "Blizzara"
pos = "B5"
type = "Magic"
price = "100 LP"
path = ["E"]
[[abilities]]
name = "Magic Boost"
pos = "C3"
type = "Stat"
price = "100 LP"
path = ["W", "E"]
[[abilities]]
name = "Checkpoint"
pos = "C5"
type = "Checkpoint"
price = "Level 10"
path = ["W", "E"]
[[abilities]]
name = "Cure Boost"
pos = "C7"
type = "Stat"
price = "50 LP"
path = ["E"]
[[abilities]]
name = "Start"
pos = "D1"
type = "Start"
price = ""
path = ["S"]
[[abilities]]
name = "Blizzard"
pos = "D2"
type = "Magic"
price = "10 LP"
path = ["N", "S"]
[[abilities]]
name = "Magic Haste"
pos = "D3"
type = "Stat"
price = "30 LP"
path = ["N", "S", "W"]
[[abilities]]
name = "Water Screen"
pos = "D4"
type = "Stat"
price = "20 LP"
path = ["N", "S", "E"]
[[abilities]]
name = "Esuna"
pos = "D5"
type = "Stat"
price = "50 LP"
path = ["N", "S", "W"]
[[abilities]]
name = "Sleep Block"
pos = "D6"
type = "Stat"
price = "30 LP"
path = ["N", "S", "E"]
[[abilities]]
name = "Water Screen"
pos = "D7"
type = "Stat"
price = "40 LP"
path = ["N", "W", "E"]
[[abilities]]
name = "Bind Block"
pos = "E4"
type = "Stat"
price = "30 LP"
path = ["W", "E"]
[[abilities]]
name = "Checkpoint"
pos = "E6"
type = "Checkpoint"
price = "Level 20"
path = ["W", "E"]
[[abilities]]
name = "HP Boost"
pos = "E7"
type = "Stat"
price = "30 LP"
path = ["W"]
[[abilities]]
name = "Cure Boost"
pos = "F4"
type = "Stat"
price = "100 LP"
route = 2
path = ["W", "E"]
[[abilities]]
name = "Blizzaga"
pos = "F6"
type = "Magic"
price = "150 LP"
path = ["W"]
[[abilities]]
name = "Magic Boost"
pos = "G4"
type = "Stat"
price = "200 LP"
route = 2
path = ["W"]

View File

@ -4,6 +4,8 @@ use itertools::Itertools;
use rinja::Template;
use serde::Deserialize;
use crate::create_file;
#[derive(Debug, Deserialize, PartialEq, Eq)]
enum Character {
#[serde(alias = "A")]
@ -119,7 +121,7 @@ struct Finisher {
}
#[derive(Template)]
#[template(path = "pages/bbs-commands.html")]
#[template(path = "pages/bbs/melding.html")]
struct CommandsTemplate {
pub commands: Vec<Command>,
pub crystals: Vec<String>,
@ -130,15 +132,15 @@ const FINISHERS_PATH: &str = "./input/bbs/finish-commands.json";
const COMMANDS_PATH: &str = "./input/bbs/commands.json";
pub fn init() {
tracing::info!("Loading abilities json data from {}", ABILITIES_PATH);
tracing::info!("Loading abilities data from {}", ABILITIES_PATH);
let abilities_str = std::fs::read_to_string(ABILITIES_PATH).unwrap();
let abilities = serde_json::from_str::<Vec<Ability>>(&abilities_str).unwrap();
tracing::info!("Loading finishers json data from {}", ABILITIES_PATH);
tracing::info!("Loading finishers data from {}", ABILITIES_PATH);
let finishers_str = std::fs::read_to_string(FINISHERS_PATH).unwrap();
let finishers = serde_json::from_str::<HashMap<String, Finisher>>(&finishers_str).unwrap();
tracing::info!("Loading commands json data from {}", ABILITIES_PATH);
tracing::info!("Loading commands data from {}", ABILITIES_PATH);
let commands_str = std::fs::read_to_string(COMMANDS_PATH).unwrap();
let mut commands = serde_json::from_str::<Vec<Command>>(&commands_str).unwrap();
@ -157,8 +159,8 @@ pub fn init() {
}
}
tracing::info!("Generating the BBS commands table template");
let template = CommandsTemplate { commands, crystals };
tracing::info!("Generating the BBS melding table template");
let melding_template = CommandsTemplate { commands, crystals };
std::fs::write("./out/bbs-commands.html", template.render().unwrap()).unwrap();
create_file("./out/bbs", "melding", melding_template.render().unwrap()).unwrap();
}

View File

@ -4,6 +4,8 @@ use itertools::Itertools;
use rinja::Template;
use serde::{Deserialize, Deserializer};
use crate::create_file;
#[derive(Debug, Deserialize, PartialEq, Eq)]
struct Board {
order: u32,
@ -348,7 +350,7 @@ impl Display for Interaction {
}
#[derive(Template)]
#[template(path = "pages/ddd-abilities.html")]
#[template(path = "pages/ddd/boards.html")]
struct AbilitiesTemplate {
pub boards: Vec<Board>,
}
@ -356,7 +358,7 @@ struct AbilitiesTemplate {
const ABILITIES_PATH: &str = "./input/ddd/abilities";
pub fn init() {
tracing::info!("Loading ability links json data from {}", ABILITIES_PATH);
tracing::info!("Loading ability boards data from {}", ABILITIES_PATH);
let mut boards: Vec<Board> = vec![];
// Loading multiple files into one vector due to the size of each board
let paths = std::fs::read_dir(ABILITIES_PATH)
@ -385,7 +387,7 @@ pub fn init() {
boards.sort_by(|a, b| a.order.cmp(&b.order));
tracing::info!("Generating the DDD ability boards template");
let template = AbilitiesTemplate { boards };
let boards_template = AbilitiesTemplate { boards };
std::fs::write("./out/ddd-abilities.html", template.render().unwrap()).unwrap();
create_file("./out/ddd", "boards", boards_template.render().unwrap()).unwrap();
}

View File

@ -3,6 +3,8 @@ use std::fmt::Display;
use rinja::Template;
use serde::Deserialize;
use crate::create_file;
#[derive(Debug, Deserialize, PartialEq, Eq)]
struct Recipes {
starters: Vec<Recipe>,
@ -55,7 +57,7 @@ impl Display for FoodStats {
}
#[derive(Template)]
#[template(path = "pages/kh3-recipes.html")]
#[template(path = "pages/kh3/food-sim.html")]
struct RecipesTemplate {
pub recipes: Recipes,
}
@ -68,7 +70,7 @@ pub fn init() {
let recipes = toml::from_str::<Recipes>(&recipes_str).unwrap();
tracing::info!("Generating the KH3 recipes template");
let template = RecipesTemplate { recipes };
let food_template = RecipesTemplate { recipes };
std::fs::write("./out/kh3-recipes.html", template.render().unwrap()).unwrap();
create_file("./out/kh3", "food-sim", food_template.render().unwrap()).unwrap();
}

View File

@ -1,13 +1,23 @@
#![allow(dead_code)]
use rinja::Template;
use tracing_subscriber::EnvFilter;
#[cfg(feature = "bbs")]
mod bbs;
#[cfg(feature = "ddd")]
mod ddd;
#[cfg(feature = "kh3")]
mod kh3;
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
#[derive(Template)]
#[template(path = "pages/index.html")]
struct IndexTemplate {}
fn main() {
// Initialize tracing
tracing_subscriber::fmt()
@ -15,7 +25,23 @@ fn main() {
.event_format(tracing_subscriber::fmt::format().with_source_location(true))
.init();
tracing::info!("Generating the main menu template");
let template = IndexTemplate {};
std::fs::write("./out/index.html", template.render().unwrap()).unwrap();
#[cfg(feature = "bbs")]
bbs::init();
#[cfg(feature = "ddd")]
ddd::init();
#[cfg(feature = "kh3")]
kh3::init();
}
fn create_file(dir: &str, file: &str, buf: String) -> std::io::Result<()> {
std::fs::create_dir_all(dir)?;
std::fs::write(format!("{}/{}.html", dir, file), buf)?;
Ok(())
}

View File

@ -1,18 +1,20 @@
<h2>Dispositions</h2>
{% for route in board.get_dispositions() %}
<div class="route">
<div>
<div class="disposition {{+ route.color +}}"></div>
<span>{{ route.name }}</span>
<div class="dispositions">
{% for route in board.get_dispositions() %}
<div class="route">
<div>
<div class="disposition {{+ route.color +}}"></div>
<span>{{ route.name }}</span>
</div>
<ul>
{% for tip in route.tips %}
<li>
<div class="disposition {{+ tip.to_color +}}"></div>
{{+ tip.to +}} ➔ {{+ tip.tip +}}
</li>
{% endfor %}
</ul>
</div>
<ul>
{% for tip in route.tips %}
<li>
<div class="disposition {{+ tip.to_color +}}"></div>
{{+ tip.to +}} ➔ {{+ tip.tip +}}
</li>
{% endfor %}
</ul>
</div>
{% endfor %}
{% endfor %}
</div>

View File

@ -2,6 +2,7 @@
<html lang="en">
<head>
<title>{% block title %}{% endblock %}</title>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<style>
body {
position: relative;
@ -40,6 +41,23 @@
ul {
line-height: 1.5;
}
a {
color: #00ff00;
text-decoration: none;
&:hover {
color: #9dff9d;
}
&:visited {
color: #00a200;
&:hover {
color: #65a565;
}
}
}
</style>
{% block head %}{% endblock %}

View File

@ -1,6 +1,6 @@
{% extends "layouts/base.html" %}
{% block title %}Commands{% endblock %}
{% block title %}BBS - Command Melding{% endblock %}
{% block head %}
<style>

View File

@ -1,6 +1,6 @@
{% extends "layouts/base.html" %}
{% block title %}Abilities{% endblock %}
{% block title %}DDD - Spirit Boards{% endblock %}
{% block head %}
<style>
@ -36,33 +36,39 @@
}
}
div.route {
.dispositions {
display: flex;
align-items: center;
flex-wrap: wrap;
& div {
div.route {
display: flex;
align-items: center;
}
width: 40%;
& .disposition {
width: 32px;
height: 32px;
margin-right: 5px;
display: inline-block;
vertical-align: middle;
}
& div {
display: flex;
align-items: center;
}
& span {
font-size: 18px;
}
& .disposition {
width: 32px;
height: 32px;
margin-right: 5px;
display: inline-block;
vertical-align: middle;
}
& ul {
list-style: disclosure-closed;
line-height: 2.5;
& span {
font-size: 18px;
}
& li {
display: list-item;
& ul {
list-style: disclosure-closed;
line-height: 2.5;
& li {
display: list-item;
}
}
}
}

View File

@ -0,0 +1,29 @@
{% extends "layouts/base.html" %}
{% block title %}Menu{% endblock %}
{% block head %}
{% endblock %}
{% block content %}
{% if cfg!(feature = "bbs") %}
<h1>Kingdom Hearts Birth by Sleep</h1>
<ul>
<li><a href="./bbs/melding.html">Command Melding</a></li>
</ul>
{% endif %}
{% if cfg!(feature = "ddd") %}
<h1>Kingdom Hearts Dream Drop Distance</h1>
<ul>
<li><a href="./ddd/boards.html">Spirit Boards</a></li>
</ul>
{% endif %}
{% if cfg!(feature = "kh3") %}
<h1>Kingdom Hearts III</h1>
<ul>
<li><a href="./kh3/food-sim.html">Food Simulator</a></li>
</ul>
{% endif %}
{% endblock %}

View File

@ -1,6 +1,6 @@
{% extends "layouts/base.html" %}
{% block title %}Recipes{% endblock %}
{% block title %}KH3 - Food Simulator{% endblock %}
{% block head %}
<style>