Compare commits
No commits in common. "378de24dd14e192dadfbff719ee6c1c160aec12f" and "e6cf0e30679395cd9b29b8f2b0c7faade9f71292" have entirely different histories.
378de24dd1
...
e6cf0e3067
|
|
@ -1,51 +0,0 @@
|
|||
[[codes]]
|
||||
name = "Default Status"
|
||||
stars = 5
|
||||
|
||||
[[codes]]
|
||||
name = "Zero Defense"
|
||||
stars = 4
|
||||
|
||||
[[codes]]
|
||||
name = "HP Slip"
|
||||
stars = 3
|
||||
|
||||
[[codes]]
|
||||
name = "MP Slip"
|
||||
stars = 4
|
||||
|
||||
[[codes]]
|
||||
name = "No Shotlocks"
|
||||
stars = 2
|
||||
|
||||
[[codes]]
|
||||
name = "No Cure"
|
||||
stars = 5
|
||||
|
||||
[[codes]]
|
||||
name = "No Battle Items"
|
||||
stars = 3
|
||||
|
||||
[[codes]]
|
||||
name = "No Links"
|
||||
stars = 2
|
||||
|
||||
[[codes]]
|
||||
name = "No Formchanges/Grand Magic"
|
||||
stars = 4
|
||||
|
||||
[[codes]]
|
||||
name = "No Attractions"
|
||||
stars = 1
|
||||
|
||||
[[codes]]
|
||||
name = "No Team Attacks"
|
||||
stars = 1
|
||||
|
||||
[[codes]]
|
||||
name = "No Kupo Coin"
|
||||
stars = 2
|
||||
|
||||
[[codes]]
|
||||
name = "Ability Limit"
|
||||
stars = 4
|
||||
|
|
@ -1,169 +0,0 @@
|
|||
[[fights]]
|
||||
world = "Olympus"
|
||||
enemy = "Rock Titan"
|
||||
merit = 100
|
||||
|
||||
[[fights]]
|
||||
world = "Olympus"
|
||||
enemy = "Ice Titan, Lava Titan and Tornado Titan"
|
||||
merit = 200
|
||||
|
||||
[[fights]]
|
||||
world = "Twilight Town"
|
||||
enemy = "Demon Tide"
|
||||
merit = 100
|
||||
|
||||
[[fights]]
|
||||
world = "Toy Box"
|
||||
enemy = "Angelic Amber"
|
||||
merit = 100
|
||||
|
||||
[[fights]]
|
||||
world = "Toy Box"
|
||||
enemy = "King of Toys"
|
||||
merit = 200
|
||||
|
||||
[[fights]]
|
||||
world = "Kingdom of Corona"
|
||||
enemy = "Chaos Carriage"
|
||||
merit = 100
|
||||
|
||||
[[fights]]
|
||||
world = "Kingdom of Corona"
|
||||
enemy = "Grim Guarianess"
|
||||
merit = 200
|
||||
|
||||
[[fights]]
|
||||
world = "Monstropolis"
|
||||
enemy = "Lump of Horror"
|
||||
merit = 200
|
||||
|
||||
[[fights]]
|
||||
world = "Arendelle"
|
||||
enemy = "Marshmallow"
|
||||
merit = 100
|
||||
|
||||
[[fights]]
|
||||
world = "Arendelle"
|
||||
enemy = "Skoll"
|
||||
merit = 200
|
||||
|
||||
[[fights]]
|
||||
world = "The Caribbean"
|
||||
enemy = "Lightning Angler"
|
||||
merit = 100
|
||||
|
||||
[[fights]]
|
||||
world = "The Caribbean"
|
||||
enemy = "Davy Jones"
|
||||
merit = 200
|
||||
|
||||
[[fights]]
|
||||
world = "San Fransokyo"
|
||||
enemy = "Darkubes"
|
||||
merit = 100
|
||||
|
||||
[[fights]]
|
||||
world = "San Fransokyo"
|
||||
enemy = "Dark Baymax"
|
||||
merit = 200
|
||||
|
||||
[[fights]]
|
||||
world = "Keyblade Graveyard"
|
||||
enemy = "Demon Tide"
|
||||
merit = 200
|
||||
|
||||
[[fights]]
|
||||
world = "Keyblade Graveyard"
|
||||
enemy = "Young Xehanort, Ansem, Xemnas"
|
||||
merit = 200
|
||||
|
||||
[[fights]]
|
||||
world = "Keyblade Graveyard"
|
||||
enemy = "Dark Inferno"
|
||||
merit = 400
|
||||
|
||||
[[fights]]
|
||||
world = "Scala ad Caelum"
|
||||
enemy = "Armored Xehanort"
|
||||
merit = 200
|
||||
|
||||
[[fights]]
|
||||
world = "Scala ad Caelum"
|
||||
enemy = "Master Xehanort"
|
||||
merit = 200
|
||||
|
||||
[[fights]]
|
||||
world = "Re Mind"
|
||||
enemy = "Armored Xehanort"
|
||||
merit = 200
|
||||
|
||||
[[fights]]
|
||||
world = "Limitcut"
|
||||
enemy = "Ansem"
|
||||
merit = 500
|
||||
|
||||
[[fights]]
|
||||
world = "Limitcut"
|
||||
enemy = "Xemnas"
|
||||
merit = 500
|
||||
|
||||
[[fights]]
|
||||
world = "Limitcut"
|
||||
enemy = "Xigbar"
|
||||
merit = 500
|
||||
|
||||
[[fights]]
|
||||
world = "Limitcut"
|
||||
enemy = "Luxord"
|
||||
merit = 500
|
||||
|
||||
[[fights]]
|
||||
world = "Limitcut"
|
||||
enemy = "Larxene"
|
||||
merit = 500
|
||||
|
||||
[[fights]]
|
||||
world = "Limitcut"
|
||||
enemy = "Marluxia"
|
||||
merit = 500
|
||||
|
||||
[[fights]]
|
||||
world = "Limitcut"
|
||||
enemy = "Saix"
|
||||
merit = 500
|
||||
|
||||
[[fights]]
|
||||
world = "Limitcut"
|
||||
enemy = "Terra-Xehanort"
|
||||
merit = 500
|
||||
|
||||
[[fights]]
|
||||
world = "Limitcut"
|
||||
enemy = "Dark Riku"
|
||||
merit = 500
|
||||
|
||||
[[fights]]
|
||||
world = "Limitcut"
|
||||
enemy = "Vanitas"
|
||||
merit = 500
|
||||
|
||||
[[fights]]
|
||||
world = "Limitcut"
|
||||
enemy = "Young Xehanort"
|
||||
merit = 500
|
||||
|
||||
[[fights]]
|
||||
world = "Limitcut"
|
||||
enemy = "Xion"
|
||||
merit = 500
|
||||
|
||||
[[fights]]
|
||||
world = "Limitcut"
|
||||
enemy = "Master Xehanort"
|
||||
merit = 500
|
||||
|
||||
[[fights]]
|
||||
world = "Secret"
|
||||
enemy = "Yozora"
|
||||
merit = 600
|
||||
|
|
@ -1,139 +0,0 @@
|
|||
const CODES_STORAGE_NAME = "kh3/pro-codes-sim/codes/";
|
||||
const MERIT_STORAGE_NAME = "kh3/pro-codes-sim/merit/";
|
||||
const STAR_MULTIPLIER = 1.25;
|
||||
|
||||
let selectionAllState = false;
|
||||
let stars = 0;
|
||||
let totalMerit = 0;
|
||||
let fightMerit = [];
|
||||
|
||||
document.addEventListener("DOMContentLoaded", (event) => {
|
||||
const codes = document.querySelectorAll("#codes .slot input");
|
||||
const fights = document.querySelectorAll("#fights .slot button");
|
||||
|
||||
// Loading enabled codes
|
||||
for (let code of codes) {
|
||||
const hasCodeToggled =
|
||||
localStorage.getItem(CODES_STORAGE_NAME + code.id) === "true"
|
||||
? true
|
||||
: false;
|
||||
if (hasCodeToggled) {
|
||||
// Normally the toggleCode gets called after the checkbox is checked,
|
||||
// since we don't interact with it at this point we mark it as checked manually here
|
||||
code.checked = true;
|
||||
toggleCode(code);
|
||||
}
|
||||
}
|
||||
|
||||
// Loading marked fights and their merit
|
||||
for (let fight of fights) {
|
||||
const source = fight.dataset["meritSource"];
|
||||
const merit =
|
||||
Number(localStorage.getItem(MERIT_STORAGE_NAME + source)) ?? 0;
|
||||
if (merit > 0) {
|
||||
markFight(fight, merit);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function markFight(data, loadedMerit = 0) {
|
||||
const source = data.dataset["meritSource"];
|
||||
const enemyName = data.dataset["enemy"];
|
||||
const baseMerit = data.dataset["baseMerit"];
|
||||
const isMarked = data.dataset["marked"] === "true" ? true : false;
|
||||
const fightLabel = data.parentNode.querySelector("span");
|
||||
const isLoading = loadedMerit > 0;
|
||||
|
||||
if (isMarked) {
|
||||
data.dataset["marked"] = false;
|
||||
totalMerit -= fightMerit[source];
|
||||
updateMeritCounter();
|
||||
fightMerit[source] = 0;
|
||||
|
||||
localStorage.removeItem(MERIT_STORAGE_NAME + source);
|
||||
|
||||
data.innerText = "Mark";
|
||||
data.classList.remove("danger");
|
||||
fightLabel.innerText = enemyName;
|
||||
} else {
|
||||
let merit = isLoading
|
||||
? loadedMerit
|
||||
: baseMerit * (stars * STAR_MULTIPLIER);
|
||||
data.dataset["marked"] = true;
|
||||
totalMerit += merit;
|
||||
updateMeritCounter();
|
||||
fightMerit[source] = merit;
|
||||
|
||||
localStorage.setItem(MERIT_STORAGE_NAME + source, merit);
|
||||
|
||||
data.innerText = "Unmark";
|
||||
data.classList.add("danger");
|
||||
fightLabel.innerText = enemyName + " | " + merit + " Merit";
|
||||
}
|
||||
}
|
||||
|
||||
function toggleCode(code) {
|
||||
let codeStars = Number(code.dataset["stars"]);
|
||||
|
||||
if (code.checked) {
|
||||
stars += codeStars;
|
||||
localStorage.setItem(CODES_STORAGE_NAME + code.id, true);
|
||||
} else {
|
||||
stars -= codeStars;
|
||||
selectionAllState = false;
|
||||
updateAllButton();
|
||||
localStorage.removeItem(CODES_STORAGE_NAME + code.id);
|
||||
}
|
||||
updateStarsCounter();
|
||||
}
|
||||
|
||||
function toggleAllCodes() {
|
||||
const codes = document.querySelectorAll("#codes .slot input");
|
||||
|
||||
if (!selectionAllState) {
|
||||
selectionAllState = true;
|
||||
updateAllButton();
|
||||
for (let code of codes) {
|
||||
if (code.checked) {
|
||||
continue;
|
||||
}
|
||||
code.checked = true;
|
||||
stars += Number(code.dataset["stars"]);
|
||||
localStorage.setItem(CODES_STORAGE_NAME + code.id, true);
|
||||
}
|
||||
} else {
|
||||
selectionAllState = false;
|
||||
updateAllButton();
|
||||
for (let code of codes) {
|
||||
if (!code.checked) {
|
||||
continue;
|
||||
}
|
||||
code.checked = false;
|
||||
stars -= Number(code.dataset["stars"]);
|
||||
localStorage.removeItem(CODES_STORAGE_NAME + code.id);
|
||||
}
|
||||
}
|
||||
|
||||
updateStarsCounter();
|
||||
}
|
||||
|
||||
function updateStarsCounter() {
|
||||
let counter = document.getElementById("totalStars");
|
||||
counter.innerText = "Stars: " + stars;
|
||||
}
|
||||
|
||||
function updateMeritCounter() {
|
||||
let counter = document.getElementById("totalMerit");
|
||||
counter.innerText = "Merit: " + totalMerit;
|
||||
}
|
||||
|
||||
function updateAllButton() {
|
||||
const btn = document.querySelector("#codes .slot button");
|
||||
if (selectionAllState) {
|
||||
btn.classList.add("danger");
|
||||
} else {
|
||||
btn.classList.remove("danger");
|
||||
}
|
||||
}
|
||||
|
||||
Object.assign(window, { markFight, toggleCode, toggleAllCodes });
|
||||
|
|
@ -17,19 +17,3 @@ table {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
.filters {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
.row {
|
||||
display: flex;
|
||||
|
||||
div {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
flex: 0 1 100px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,8 +67,8 @@ button {
|
|||
background: var(--button-bg-color);
|
||||
color: var(--text-color);
|
||||
padding: 8px;
|
||||
border-style: groove;
|
||||
border-color: var(--button-border-color);
|
||||
border-style: groove;
|
||||
border-bottom-color: var(--primary-color);
|
||||
transition-duration: 0.1s;
|
||||
|
||||
|
|
@ -85,10 +85,6 @@ button {
|
|||
opacity: 0.6;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
&.danger {
|
||||
border-bottom-color: var(--error-color);
|
||||
}
|
||||
}
|
||||
|
||||
input[type="text"] {
|
||||
|
|
@ -112,6 +108,7 @@ input[type="radio"] {
|
|||
cursor: pointer;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
padding-top: 8px;
|
||||
|
||||
& + label {
|
||||
cursor: pointer;
|
||||
|
|
@ -136,7 +133,7 @@ input[type="radio"] {
|
|||
content: "\2713";
|
||||
color: var(--primary-color);
|
||||
font-size: 48px;
|
||||
top: -16px;
|
||||
top: -10px;
|
||||
left: -4px;
|
||||
align-content: center;
|
||||
text-align: center;
|
||||
|
|
@ -155,7 +152,7 @@ input[type="radio"] {
|
|||
|
||||
&:checked:after {
|
||||
font-size: 16px;
|
||||
top: 2px;
|
||||
top: 10px;
|
||||
left: 6px;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,4 @@
|
|||
|
||||
--primary-color: #00aa00;
|
||||
--primary-light-color: #60de60;
|
||||
|
||||
--error-color: hsl(2, 68%, 53%);
|
||||
--error-color-lighter: hsl(2, 68%, 63%);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -90,19 +90,10 @@
|
|||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
width: 40%;
|
||||
row-gap: 1rem;
|
||||
row-gap: 20px;
|
||||
position: relative;
|
||||
|
||||
div {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
}
|
||||
|
||||
.tracked-filter {
|
||||
margin-bottom: 16px;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,39 +0,0 @@
|
|||
#content {
|
||||
display: flex;
|
||||
margin: 0 4rem;
|
||||
}
|
||||
|
||||
#score,
|
||||
#codes,
|
||||
#fights {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
max-height: 80vh;
|
||||
margin-top: 2rem;
|
||||
width: 33%;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
.slot {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 0.5rem;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.inset-box-shadow {
|
||||
box-shadow: inset 0px 0px 40px 40px var(--bg-color);
|
||||
width: 200%;
|
||||
height: 100%;
|
||||
position: absolute;
|
||||
margin-left: -200px;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.scrollable {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
overflow: scroll;
|
||||
padding: 60px 0px;
|
||||
}
|
||||
}
|
||||
27
src/kh3.rs
27
src/kh3.rs
|
|
@ -1,7 +1,6 @@
|
|||
use askama::Template;
|
||||
use food::Recipes;
|
||||
use ingredient::Ingredient;
|
||||
use pro_codes::{ProCode, ProCodeFight, ProCodeFights, ProCodes};
|
||||
|
||||
use crate::{
|
||||
RuntimeModule,
|
||||
|
|
@ -11,13 +10,10 @@ use crate::{
|
|||
|
||||
mod food;
|
||||
mod ingredient;
|
||||
mod pro_codes;
|
||||
|
||||
const ENEMIES_PATH: &str = "./input/kh3/enemies";
|
||||
const RECIPES_PATH: &str = "./input/kh3/recipes.toml";
|
||||
const INGREDIENTS_PATH: &str = "./input/kh3/ingredients";
|
||||
const PRO_CODES_PATH: &str = "./input/kh3/pro-codes/codes.toml";
|
||||
const PRO_CODE_FIGHTS_PATH: &str = "./input/kh3/pro-codes/fights.toml";
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "pages/kh3/drops.html")]
|
||||
|
|
@ -37,13 +33,6 @@ struct IngredientsTemplate {
|
|||
pub ingredients: Vec<Ingredient>,
|
||||
}
|
||||
|
||||
#[derive(Template)]
|
||||
#[template(path = "pages/kh3/pro-codes-sim.html")]
|
||||
struct ProCodesTemplate {
|
||||
pub pro_codes: Vec<ProCode>,
|
||||
pub fights: Vec<ProCodeFight>,
|
||||
}
|
||||
|
||||
pub struct Module;
|
||||
|
||||
impl RuntimeModule for Module {
|
||||
|
|
@ -59,29 +48,19 @@ impl RuntimeModule for Module {
|
|||
let recipes_str = std::fs::read_to_string(RECIPES_PATH).unwrap();
|
||||
let recipes = toml::from_str::<Recipes>(&recipes_str).unwrap();
|
||||
|
||||
tracing::info!("Loading pro codes data from {}", PRO_CODES_PATH);
|
||||
let pro_codes_str = std::fs::read_to_string(PRO_CODES_PATH).unwrap();
|
||||
let pro_codes = toml::from_str::<ProCodes>(&pro_codes_str).unwrap();
|
||||
let pro_code_fights_str = std::fs::read_to_string(PRO_CODE_FIGHTS_PATH).unwrap();
|
||||
let pro_code_fights = toml::from_str::<ProCodeFights>(&pro_code_fights_str).unwrap();
|
||||
|
||||
tracing::info!("Generating the KH3 drops template");
|
||||
let drops_template = DropsTemplate { data: drops };
|
||||
|
||||
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");
|
||||
let food_template = RecipesTemplate { recipes };
|
||||
create_file("./out/kh3", "food-sim", food_template).unwrap();
|
||||
|
||||
tracing::info!("Generating the KH3 pro codes template");
|
||||
let pro_codes_template = ProCodesTemplate {
|
||||
pro_codes: pro_codes.codes,
|
||||
fights: pro_code_fights.fights,
|
||||
};
|
||||
create_file("./out/kh3", "pro-codes-sim", pro_codes_template).unwrap();
|
||||
create_file("./out/kh3", "food-sim", food_template).unwrap();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,38 +0,0 @@
|
|||
use serde::Deserialize;
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq)]
|
||||
pub struct ProCodes {
|
||||
pub codes: Vec<ProCode>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq)]
|
||||
pub struct ProCode {
|
||||
pub name: String,
|
||||
pub stars: u8,
|
||||
}
|
||||
|
||||
impl ProCode {
|
||||
pub fn id(&self) -> String {
|
||||
self.name.replace(" ", "_").to_lowercase()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq)]
|
||||
pub struct ProCodeFights {
|
||||
pub fights: Vec<ProCodeFight>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize, PartialEq, Eq)]
|
||||
pub struct ProCodeFight {
|
||||
pub world: String,
|
||||
pub enemy: String,
|
||||
pub merit: u16,
|
||||
}
|
||||
|
||||
impl ProCodeFight {
|
||||
pub fn source(&self) -> String {
|
||||
let world = self.world.replace(" ", "_").to_lowercase();
|
||||
let enemy = self.enemy.replace(" ", "_").to_lowercase();
|
||||
format!("{world}/{enemy}")
|
||||
}
|
||||
}
|
||||
|
|
@ -1,44 +1,36 @@
|
|||
<div>
|
||||
<input
|
||||
type="radio"
|
||||
id="hasAny"
|
||||
name="charFilter"
|
||||
autocomplete="off"
|
||||
value=""
|
||||
checked
|
||||
/>
|
||||
<label for="hasAny">Any</label>
|
||||
</div>
|
||||
<input
|
||||
type="radio"
|
||||
id="hasAny"
|
||||
name="charFilter"
|
||||
autocomplete="off"
|
||||
value=""
|
||||
checked
|
||||
/>
|
||||
<label for="hasAny">Any</label>
|
||||
|
||||
<div>
|
||||
<input
|
||||
type="radio"
|
||||
id="hasTerra"
|
||||
autocomplete="off"
|
||||
value="T"
|
||||
name="charFilter"
|
||||
/>
|
||||
<label for="hasTerra">Terra</label>
|
||||
</div>
|
||||
<input
|
||||
type="radio"
|
||||
id="hasTerra"
|
||||
autocomplete="off"
|
||||
value="T"
|
||||
name="charFilter"
|
||||
/>
|
||||
<label for="hasTerra">Terra</label>
|
||||
|
||||
<div>
|
||||
<input
|
||||
type="radio"
|
||||
id="hasVentus"
|
||||
autocomplete="off"
|
||||
value="V"
|
||||
name="charFilter"
|
||||
/>
|
||||
<label for="hasVentus">Ventus</label>
|
||||
</div>
|
||||
<input
|
||||
type="radio"
|
||||
id="hasVentus"
|
||||
autocomplete="off"
|
||||
value="V"
|
||||
name="charFilter"
|
||||
/>
|
||||
<label for="hasVentus">Ventus</label>
|
||||
|
||||
<div>
|
||||
<input
|
||||
type="radio"
|
||||
id="hasAqua"
|
||||
autocomplete="off"
|
||||
value="A"
|
||||
name="charFilter"
|
||||
/>
|
||||
<label for="hasAqua">Aqua</label>
|
||||
</div>
|
||||
<input
|
||||
type="radio"
|
||||
id="hasAqua"
|
||||
autocomplete="off"
|
||||
value="A"
|
||||
name="charFilter"
|
||||
/>
|
||||
<label for="hasAqua">Aqua</label>
|
||||
|
|
|
|||
|
|
@ -1,39 +1,29 @@
|
|||
<div class="row">
|
||||
<input type="text" id="filter" autocomplete="off" />
|
||||
</div>
|
||||
<input type="text" id="filter" autocomplete="off" />
|
||||
<br />
|
||||
<input
|
||||
type="radio"
|
||||
id="searchResult"
|
||||
name="search"
|
||||
autocomplete="off"
|
||||
value="commands"
|
||||
checked
|
||||
/>
|
||||
<label for="searchResult">Result</label>
|
||||
|
||||
<div class="row">
|
||||
<div>
|
||||
<input
|
||||
type="radio"
|
||||
id="searchResult"
|
||||
name="search"
|
||||
autocomplete="off"
|
||||
value="commands"
|
||||
checked
|
||||
/>
|
||||
<label for="searchResult">Result</label>
|
||||
</div>
|
||||
<input
|
||||
type="radio"
|
||||
id="searchIngredients"
|
||||
autocomplete="off"
|
||||
value="ingredients"
|
||||
name="search"
|
||||
/>
|
||||
<label for="searchIngredients">Ingredients</label>
|
||||
|
||||
<div>
|
||||
<input
|
||||
type="radio"
|
||||
id="searchIngredients"
|
||||
autocomplete="off"
|
||||
value="ingredients"
|
||||
name="search"
|
||||
/>
|
||||
<label for="searchIngredients">Ingredients</label>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<input
|
||||
type="radio"
|
||||
id="searchAbilities"
|
||||
autocomplete="off"
|
||||
value="abilities"
|
||||
name="search"
|
||||
/>
|
||||
<label for="searchAbilities">Abilities</label>
|
||||
</div>
|
||||
</div>
|
||||
<input
|
||||
type="radio"
|
||||
id="searchAbilities"
|
||||
autocomplete="off"
|
||||
value="abilities"
|
||||
name="search"
|
||||
/>
|
||||
<label for="searchAbilities">Abilities</label>
|
||||
|
|
|
|||
|
|
@ -1,55 +1,45 @@
|
|||
<div>
|
||||
<input
|
||||
type="radio"
|
||||
id="isAny"
|
||||
name="typeFilter"
|
||||
autocomplete="off"
|
||||
value=""
|
||||
checked
|
||||
/>
|
||||
<label for="isAny">Any</label>
|
||||
</div>
|
||||
<input
|
||||
type="radio"
|
||||
id="isAny"
|
||||
name="typeFilter"
|
||||
autocomplete="off"
|
||||
value=""
|
||||
checked
|
||||
/>
|
||||
<label for="isAny">Any</label>
|
||||
|
||||
<div>
|
||||
<input
|
||||
type="radio"
|
||||
id="isAttack"
|
||||
name="typeFilter"
|
||||
autocomplete="off"
|
||||
value="attack"
|
||||
/>
|
||||
<label for="isAttack">Attack</label>
|
||||
</div>
|
||||
<input
|
||||
type="radio"
|
||||
id="isAttack"
|
||||
name="typeFilter"
|
||||
autocomplete="off"
|
||||
value="attack"
|
||||
/>
|
||||
<label for="isAttack">Attack</label>
|
||||
|
||||
<div>
|
||||
<input
|
||||
type="radio"
|
||||
id="isMagic"
|
||||
name="typeFilter"
|
||||
autocomplete="off"
|
||||
value="magic"
|
||||
/>
|
||||
<label for="isMagic">Magic</label>
|
||||
</div>
|
||||
<input
|
||||
type="radio"
|
||||
id="isMagic"
|
||||
name="typeFilter"
|
||||
autocomplete="off"
|
||||
value="magic"
|
||||
/>
|
||||
<label for="isMagic">Magic</label>
|
||||
|
||||
<div>
|
||||
<input
|
||||
type="radio"
|
||||
id="isAction"
|
||||
name="typeFilter"
|
||||
autocomplete="off"
|
||||
value="action"
|
||||
/>
|
||||
<label for="isAction">Action</label>
|
||||
</div>
|
||||
<input
|
||||
type="radio"
|
||||
id="isAction"
|
||||
name="typeFilter"
|
||||
autocomplete="off"
|
||||
value="action"
|
||||
/>
|
||||
<label for="isAction">Action</label>
|
||||
|
||||
<div>
|
||||
<input
|
||||
type="radio"
|
||||
id="isShotlock"
|
||||
name="typeFilter"
|
||||
autocomplete="off"
|
||||
value="shotlock"
|
||||
/>
|
||||
<label for="isShotlock">Shotlock</label>
|
||||
</div>
|
||||
<input
|
||||
type="radio"
|
||||
id="isShotlock"
|
||||
name="typeFilter"
|
||||
autocomplete="off"
|
||||
value="shotlock"
|
||||
/>
|
||||
<label for="isShotlock">Shotlock</label>
|
||||
|
|
|
|||
|
|
@ -11,11 +11,11 @@
|
|||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div class="filters">
|
||||
{% include "components/bbs/search.html" %}
|
||||
<div class="row">{% include "components/bbs/type-filters.html" %}</div>
|
||||
<div class="row">{% include "components/bbs/char-filters.html" %}</div>
|
||||
</div>
|
||||
{% include "components/bbs/search.html" %}
|
||||
<br />
|
||||
{% include "components/bbs/type-filters.html" %}
|
||||
<br />
|
||||
{% include "components/bbs/char-filters.html" %}
|
||||
|
||||
<table>
|
||||
<thead>
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@
|
|||
<li><a href="./kh3/drops.html">Material Drops</a></li>
|
||||
<li><a href="./kh3/ingredients.html">Ingredients</a></li>
|
||||
<li><a href="./kh3/food-sim.html">Food Simulator</a></li>
|
||||
<li><a href="./kh3/pro-codes-sim.html">Pro Codes Simulator</a></li>
|
||||
</ul>
|
||||
{% endif %}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,45 +0,0 @@
|
|||
{% extends "layouts/base.html" %}
|
||||
|
||||
{% block title %}KH3 - Pro Codes Simulator{% endblock %}
|
||||
|
||||
{% block head %}
|
||||
<link rel="stylesheet" href="{{ crate::find_hash("/public/styles/kh3/pro-codes-sim.css") }}"></link>
|
||||
<script
|
||||
type="module"
|
||||
src="{{ crate::find_hash("/public/scripts/kh3/pro-codes-sim.js") }}"
|
||||
></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block content %}
|
||||
<div id="score">
|
||||
<h1 id="totalMerit">Merit: 0</h1>
|
||||
<h2 id="totalStars">Stars: 0</h2>
|
||||
</div>
|
||||
<div id="codes">
|
||||
<div class="slot">
|
||||
<button onclick="toggleAllCodes()">Toggle All</button>
|
||||
</div>
|
||||
{% for code in pro_codes %}
|
||||
<div class="slot">
|
||||
<input type="checkbox" id="{{code.id()}}" autocomplete="off" data-stars="{{code.stars}}" onclick="toggleCode(this)">
|
||||
<label for="{{code.id()}}">{{code.name}}</label>
|
||||
<span>
|
||||
{% for star in 0..5 %}
|
||||
{% if star < code.stars %}★{% else %}☆{% endif %}
|
||||
{% endfor %}
|
||||
</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
<div id="fights">
|
||||
<div class="inset-box-shadow"></div>
|
||||
<div class="scrollable">
|
||||
{% for fight in fights %}
|
||||
<div class="slot">
|
||||
<button onclick="markFight(this)" data-enemy="{{fight.enemy}}" data-merit-source="{{fight.source()}}" data-base-merit="{{fight.merit}}">Mark</button>
|
||||
<span>{{fight.enemy}}</span>
|
||||
</div>
|
||||
{% endfor %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
Loading…
Reference in New Issue