Compare commits

...

2 Commits

16 changed files with 1875 additions and 539 deletions

View File

@ -1,6 +1,6 @@
[package]
name = "khguide"
version = "1.0.2"
version = "1.1.0"
edition = "2021"
[dependencies]

View File

@ -1,457 +0,0 @@
[
{
"spirit": "Meow Wow",
"routes": [
{
"id": 0,
"name": "Stray",
"color": "cyan"
},
{
"id": 1,
"name": "Smart Cookie",
"color": "purple"
}
],
"abilities": [
{
"name": "Start",
"pos": "A2",
"type": "Start",
"price": "",
"path": ["E"]
},
{
"name": "Link Critical",
"pos": "B2",
"type": "Spirit",
"price": "10 LP",
"path": ["W", "E"]
},
{
"name": "Magic Haste",
"pos": "C1",
"type": "Stat",
"price": "30 LP",
"path": ["S", "E"]
},
{
"name": "Cure",
"pos": "C2",
"type": "Magic",
"price": "50 LP",
"path": ["N", "W", "E", "S"]
},
{
"name": "Item Boost",
"pos": "C3",
"type": "Stat",
"price": "30 LP",
"path": ["E", "N"]
},
{
"name": "Light Screen",
"pos": "D1",
"type": "Stat",
"price": "20 LP",
"path": ["E", "W"]
},
{
"name": "Checkpoint",
"pos": "D2",
"type": "Checkpoint",
"price": "Level 10",
"path": ["E", "W"]
},
{
"name": "Slow",
"pos": "D3",
"type": "Magic",
"price": "50 LP",
"path": ["E", "W"]
},
{
"name": "Defense Boost",
"pos": "E1",
"type": "Stat",
"price": "100 LP",
"path": ["E", "W"]
},
{
"name": "Cura",
"pos": "E2",
"type": "Magic",
"price": "100 LP",
"path": ["E", "W"]
},
{
"name": "Poison Block",
"pos": "E3",
"type": "Stat",
"price": "30 LP",
"path": ["E", "S", "W"]
},
{
"name": "Spark",
"pos": "E4",
"type": "Magic",
"price": "50 LP",
"path": ["N"]
},
{
"name": "Confusion Block",
"pos": "F1",
"type": "Stat",
"price": "30 LP",
"route": 0,
"path": ["E", "W"]
},
{
"name": "Leaf Bracer",
"pos": "F2",
"type": "Support",
"price": "300 LP",
"path": ["E", "W"]
},
{
"name": "Attack Haste",
"pos": "F3",
"type": "Stat",
"price": "30 LP",
"route": 1,
"path": ["E", "W"]
},
{
"name": "HP Boost",
"pos": "G1",
"type": "Stat",
"price": "30 LP",
"route": 0,
"path": ["W"]
},
{
"name": "Checkpoint",
"pos": "G2",
"type": "Checkpoint",
"price": "Level 25",
"path": ["E", "W"]
},
{
"name": "Magic Boost",
"pos": "G3",
"type": "Stat",
"price": "100 LP",
"route": 1,
"path": ["W"]
},
{
"name": "Curaga",
"pos": "H2",
"type": "Magic",
"price": "150 LP",
"path": ["W"]
}
]
},
{
"spirit": "Komory Bat",
"routes": [
{
"id": 0,
"name": "Rescuer",
"color": "cyan"
},
{
"id": 1,
"name": "Aggro",
"color": "purple"
}
],
"abilities": [
{
"name": "Start",
"pos": "A3",
"type": "Start",
"price": "",
"path": ["E"]
},
{
"name": "Waking Dream",
"pos": "B3",
"type": "Spirit",
"price": "10 LP",
"path": ["W", "E"]
},
{
"name": "Checkpoint",
"pos": "C1",
"type": "Checkpoint",
"price": "Link x2",
"path": ["E", "S"]
},
{
"name": "Zero Gravity",
"pos": "C2",
"type": "Magic",
"price": "50 LP",
"path": ["N", "E", "S"]
},
{
"name": "Confuse",
"pos": "C3",
"type": "Magic",
"price": "50 LP",
"path": ["S", "N", "W", "E"]
},
{
"name": "Dark Screen",
"pos": "C4",
"type": "Stat",
"price": "20 LP",
"path": ["N", "E", "S"]
},
{
"name": "Magic Haste",
"pos": "C5",
"type": "Stat",
"price": "50 LP",
"route": 0,
"path": ["N", "E"]
},
{
"name": "Zero Gravira",
"pos": "D1",
"type": "Magic",
"price": "100 LP",
"path": ["W"]
},
{
"name": "Confusion Block",
"pos": "D2",
"type": "Stat",
"price": "30 LP",
"path": ["W", "S"]
},
{
"name": "Drain Dive",
"pos": "D3",
"type": "Attack",
"price": "50 LP",
"path": ["N", "S", "W", "E"]
},
{
"name": "Magic Boost",
"pos": "D4",
"type": "Stat",
"price": "100 LP",
"path": ["W", "N", "E"]
},
{
"name": "Magic Haste",
"pos": "D5",
"type": "Stat",
"price": "100 LP",
"route": 0,
"path": ["W"]
},
{
"name": "Attack Boost",
"pos": "E2",
"type": "Stat",
"price": "100 LP",
"path": ["S"]
},
{
"name": "Magic Haste",
"pos": "E3",
"type": "Stat",
"price": "30 LP",
"path": ["W", "E", "N"]
},
{
"name": "Attack Haste",
"pos": "E4",
"type": "Stat",
"price": "30 LP",
"route": 1,
"path": ["W", "E"]
},
{
"name": "Dark Screen",
"pos": "F3",
"type": "Stat",
"price": "40 LP",
"path": ["W", "E"]
},
{
"name": "Attack Haste",
"pos": "F4",
"type": "Stat",
"price": "50 LP",
"route": 1,
"path": ["W"]
},
{
"name": "Checkpoint",
"pos": "G3",
"type": "Checkpoint",
"price": "Link x2",
"path": ["W", "E"]
},
{
"name": "Confusing Strike",
"pos": "H3",
"type": "Attack",
"price": "100 LP",
"path": ["W"]
}
]
},
{
"spirit": "Necho Cat",
"routes": [
{
"id": 0,
"name": "Diva",
"color": "cyan"
},
{
"id": 1,
"name": "Artist",
"color": "green"
}
],
"abilities": [
{
"name": "Magic Boost",
"pos": "A4",
"type": "Stat",
"price": "200 LP",
"route": 0,
"path": ["E"]
},
{
"name": "Support Boost",
"pos": "B1",
"type": "Spirit",
"price": "200 LP",
"path": ["E"]
},
{
"name": "HP Boost",
"pos": "B3",
"type": "Stat",
"price": "30 LP",
"path": ["E"]
},
{
"name": "Confusion Block",
"pos": "B4",
"type": "Stat",
"price": "30 LP",
"route": 0,
"path": ["W", "E"]
},
{
"name": "Thunder Boost",
"pos": "B5",
"type": "Stat",
"price": "50 LP",
"path": ["E", "S"]
},
{
"name": "Magic Haste",
"pos": "B6",
"type": "Stat",
"price": "50 LP",
"path": ["E", "N"]
},
{
"name": "Checkpoint",
"pos": "C1",
"type": "Checkpoint",
"price": "Link x3",
"path": ["W", "S"]
},
{
"name": "Magic Boost",
"pos": "C2",
"type": "Stat",
"price": "100 LP",
"path": ["E", "N", "S"]
},
{
"name": "Sleepra",
"pos": "C3",
"type": "Magic",
"price": "100 LP",
"path": ["W", "E", "N", "S"]
},
{
"name": "Magic Haste",
"pos": "C4",
"type": "Stat",
"price": "50 LP",
"path": ["W", "E", "N", "S"]
},
{
"name": "Thunder Boost",
"pos": "C5",
"type": "Stat",
"price": "30 LP",
"path": ["W", "E", "N", "S"]
},
{
"name": "Thunder",
"pos": "C6",
"type": "Magic",
"price": "10 LP",
"path": ["W", "N", "S"]
},
{
"name": "Start",
"pos": "C7",
"type": "Start",
"price": "",
"path": ["N"]
},
{
"name": "Thunder Boost",
"pos": "D2",
"type": "Stat",
"price": "100 LP",
"route": 1,
"path": ["W", "E"]
},
{
"name": "Magic Haste",
"pos": "D3",
"type": "Stat",
"price": "100 LP",
"path": ["W", "S"]
},
{
"name": "Time Bomb",
"pos": "D4",
"type": "Magic",
"price": "50 LP",
"path": ["W", "N"]
},
{
"name": "Sleep Block",
"pos": "D5",
"type": "Stat",
"price": "30 LP",
"path": ["W"]
},
{
"name": "Magic Haste",
"pos": "E2",
"type": "Stat",
"price": "150 LP",
"route": 1,
"path": ["W"]
}
]
}
]

View File

@ -0,0 +1,214 @@
{
"spirit": "Hebby Repp",
"order": 6,
"routes": [
{
"id": 0,
"name": "Wheeler",
"color": "purple",
"tips": [
{
"to": "Salamander",
"tip": "Head"
},
{
"to": "Serpent",
"tip": "Head"
},
{
"to": "Hydra",
"tip": "Chest"
}
]
},
{
"id": 1,
"name": "Salamander",
"color": "yellow",
"tips": [
{
"to": "Hydra",
"tip": "Head"
},
{
"to": "Serpent",
"tip": "Head"
},
{
"to": "Wheeler",
"tip": "Chest"
}
]
},
{
"id": 2,
"name": "Serpent",
"color": "blue",
"tips": [
{
"to": "Wheeler",
"tip": "Head"
},
{
"to": "Hydra",
"tip": "Head"
},
{
"to": "Salamander",
"tip": "Tail"
}
]
},
{
"id": 3,
"name": "Hydra",
"color": "green",
"tips": [
{
"to": "Salamander",
"tip": "Head"
},
{
"to": "Wheeler",
"tip": "Head"
},
{
"to": "Serpent",
"tip": "Chest"
}
]
}
],
"abilities": [
{
"name": "Start",
"pos": "A1",
"type": "Start",
"price": "",
"path": ["E"]
},
{
"name": "Fire Screen",
"pos": "A4",
"type": "Stat",
"price": "60 LP",
"route": 0,
"path": ["E", "S"]
},
{
"name": "Defense Boost",
"pos": "A5",
"type": "Stat",
"price": "100 LP",
"route": 0,
"path": ["N"]
},
{
"name": "Fire",
"pos": "B1",
"type": "Magic",
"price": "10 LP",
"path": ["W", "E"]
},
{
"name": "Fire Screen",
"pos": "B3",
"type": "Stat",
"price": "20 LP",
"path": ["E", "S"]
},
{
"name": "Fire Boost",
"pos": "B4",
"type": "Stat",
"price": "50 LP",
"path": ["N", "W", "S"]
},
{
"name": "Fire Screen",
"pos": "B5",
"type": "Stat",
"price": "40 LP",
"path": ["N", "E"]
},
{
"name": "HP Boost",
"pos": "C1",
"type": "Stat",
"price": "30 LP",
"path": ["W", "E"]
},
{
"name": "Magic Boost",
"pos": "C3",
"type": "Stat",
"price": "100 LP",
"path": ["W", "E"]
},
{
"name": "Fire Boost",
"pos": "C5",
"type": "Stat",
"price": "100 LP",
"path": ["W", "E"]
},
{
"name": "Fire Boost",
"pos": "D1",
"type": "Stat",
"price": "30 LP",
"path": ["W", "S"]
},
{
"name": "Slow Block",
"pos": "D2",
"type": "Stat",
"price": "30 LP",
"path": ["N", "S"]
},
{
"name": "Magic Haste",
"pos": "D3",
"type": "Stat",
"price": "30 LP",
"path": ["N", "W", "E"]
},
{
"name": "Fira",
"pos": "D4",
"type": "Magic",
"price": "100 LP",
"path": ["S"]
},
{
"name": "Checkpoint",
"pos": "D5",
"type": "Checkpoint",
"price": "Link x3",
"path": ["W", "N", "S"]
},
{
"name": "Fire Windmill",
"pos": "D6",
"type": "Attack",
"price": "150 LP",
"path": ["N"]
},
{
"name": "HP Boost",
"pos": "E3",
"type": "Stat",
"price": "50 LP",
"route": 1,
"path": ["W", "E"]
},
{
"name": "Magic Haste",
"pos": "F3",
"type": "Stat",
"price": "50 LP",
"route": 1,
"path": ["W"]
}
]
}

View File

@ -0,0 +1,221 @@
{
"spirit": "Komory Bat",
"order": 4,
"routes": [
{
"id": 0,
"name": "Rescuer",
"color": "blue",
"tips": [
{
"to": "Aggro",
"tip": "Face"
},
{
"to": "Wingman",
"tip": "Face"
},
{
"to": "Saboteur",
"tip": "Ears"
}
]
},
{
"id": 1,
"name": "Aggro",
"color": "purple",
"tips": [
{
"to": "Rescuer",
"tip": "Face"
},
{
"to": "Wingman",
"tip": "Wings"
},
{
"to": "Saboteur",
"tip": "Face"
}
]
},
{
"id": 2,
"name": "Wingman",
"color": "yellow",
"tips": [
{
"to": "Rescuer",
"tip": "Face"
},
{
"to": "Aggro",
"tip": "Ears"
},
{
"to": "Saboteur",
"tip": "Wings"
}
]
},
{
"id": 3,
"name": "Saboteur",
"color": "green",
"tips": [
{
"to": "Rescuer",
"tip": "Face"
},
{
"to": "Aggro",
"tip": "Ears"
},
{
"to": "Wingman",
"tip": "Ears"
}
]
}
],
"abilities": [
{
"name": "Start",
"pos": "A3",
"type": "Start",
"price": "",
"path": ["E"]
},
{
"name": "Waking Dream",
"pos": "B3",
"type": "Spirit",
"price": "10 LP",
"path": ["W", "E"]
},
{
"name": "Checkpoint",
"pos": "C1",
"type": "Checkpoint",
"price": "Link x2",
"path": ["E", "S"]
},
{
"name": "Zero Gravity",
"pos": "C2",
"type": "Magic",
"price": "50 LP",
"path": ["N", "E", "S"]
},
{
"name": "Confuse",
"pos": "C3",
"type": "Magic",
"price": "50 LP",
"path": ["S", "N", "W", "E"]
},
{
"name": "Dark Screen",
"pos": "C4",
"type": "Stat",
"price": "20 LP",
"path": ["N", "E", "S"]
},
{
"name": "Magic Haste",
"pos": "C5",
"type": "Stat",
"price": "50 LP",
"route": 0,
"path": ["N", "E"]
},
{
"name": "Zero Gravira",
"pos": "D1",
"type": "Magic",
"price": "100 LP",
"path": ["W"]
},
{
"name": "Confusion Block",
"pos": "D2",
"type": "Stat",
"price": "30 LP",
"path": ["W", "S"]
},
{
"name": "Drain Dive",
"pos": "D3",
"type": "Attack",
"price": "50 LP",
"path": ["N", "S", "W", "E"]
},
{
"name": "Magic Boost",
"pos": "D4",
"type": "Stat",
"price": "100 LP",
"path": ["W", "N", "E"]
},
{
"name": "Magic Haste",
"pos": "D5",
"type": "Stat",
"price": "100 LP",
"route": 0,
"path": ["W"]
},
{
"name": "Attack Boost",
"pos": "E2",
"type": "Stat",
"price": "100 LP",
"path": ["S"]
},
{
"name": "Magic Haste",
"pos": "E3",
"type": "Stat",
"price": "30 LP",
"path": ["W", "E", "N"]
},
{
"name": "Attack Haste",
"pos": "E4",
"type": "Stat",
"price": "30 LP",
"route": 1,
"path": ["W", "E"]
},
{
"name": "Dark Screen",
"pos": "F3",
"type": "Stat",
"price": "40 LP",
"path": ["W", "E"]
},
{
"name": "Attack Haste",
"pos": "F4",
"type": "Stat",
"price": "50 LP",
"route": 1,
"path": ["W"]
},
{
"name": "Checkpoint",
"pos": "G3",
"type": "Checkpoint",
"price": "Link x2",
"path": ["W", "E"]
},
{
"name": "Confusing Strike",
"pos": "H3",
"type": "Attack",
"price": "100 LP",
"path": ["W"]
}
]
}

View File

@ -0,0 +1,221 @@
{
"spirit": "Meow Wow",
"order": 1,
"routes": [
{
"id": 0,
"name": "Stray",
"color": "purple",
"tips": [
{
"to": "Smart Cookie",
"tip": "Tail"
},
{
"to": "Rascal",
"tip": "Face"
},
{
"to": "Sidekick",
"tip": "Legs"
}
]
},
{
"id": 1,
"name": "Smart Cookie",
"color": "blue",
"tips": [
{
"to": "Stray",
"tip": "Tail"
},
{
"to": "Rascal",
"tip": "Tail"
},
{
"to": "Sidekick",
"tip": "Face"
}
]
},
{
"id": 3,
"name": "Rascal",
"color": "yellow",
"tips": [
{
"to": "Stray",
"tip": "Legs"
},
{
"to": "Smart Cookie",
"tip": "Face"
},
{
"to": "Sidekick",
"tip": "Tail"
}
]
},
{
"id": 4,
"name": "Sidekick",
"color": "green",
"tips": [
{
"to": "Stray",
"tip": "Legs"
},
{
"to": "Smart Cookie",
"tip": "Face"
},
{
"to": "Rascal",
"tip": "Tail"
}
]
}
],
"abilities": [
{
"name": "Start",
"pos": "A2",
"type": "Start",
"price": "",
"path": ["E"]
},
{
"name": "Link Critical",
"pos": "B2",
"type": "Spirit",
"price": "10 LP",
"path": ["W", "E"]
},
{
"name": "Magic Haste",
"pos": "C1",
"type": "Stat",
"price": "30 LP",
"path": ["S", "E"]
},
{
"name": "Cure",
"pos": "C2",
"type": "Magic",
"price": "50 LP",
"path": ["N", "W", "E", "S"]
},
{
"name": "Item Boost",
"pos": "C3",
"type": "Stat",
"price": "30 LP",
"path": ["E", "N"]
},
{
"name": "Light Screen",
"pos": "D1",
"type": "Stat",
"price": "20 LP",
"path": ["E", "W"]
},
{
"name": "Checkpoint",
"pos": "D2",
"type": "Checkpoint",
"price": "Level 10",
"path": ["E", "W"]
},
{
"name": "Slow",
"pos": "D3",
"type": "Magic",
"price": "50 LP",
"path": ["E", "W"]
},
{
"name": "Defense Boost",
"pos": "E1",
"type": "Stat",
"price": "100 LP",
"path": ["E", "W"]
},
{
"name": "Cura",
"pos": "E2",
"type": "Magic",
"price": "100 LP",
"path": ["E", "W"]
},
{
"name": "Poison Block",
"pos": "E3",
"type": "Stat",
"price": "30 LP",
"path": ["E", "S", "W"]
},
{
"name": "Spark",
"pos": "E4",
"type": "Magic",
"price": "50 LP",
"path": ["N"]
},
{
"name": "Confusion Block",
"pos": "F1",
"type": "Stat",
"price": "30 LP",
"route": 0,
"path": ["E", "W"]
},
{
"name": "Leaf Bracer",
"pos": "F2",
"type": "Support",
"price": "300 LP",
"path": ["E", "W"]
},
{
"name": "Attack Haste",
"pos": "F3",
"type": "Stat",
"price": "30 LP",
"route": 1,
"path": ["E", "W"]
},
{
"name": "HP Boost",
"pos": "G1",
"type": "Stat",
"price": "30 LP",
"route": 0,
"path": ["W"]
},
{
"name": "Checkpoint",
"pos": "G2",
"type": "Checkpoint",
"price": "Level 25",
"path": ["E", "W"]
},
{
"name": "Magic Boost",
"pos": "G3",
"type": "Stat",
"price": "100 LP",
"route": 1,
"path": ["W"]
},
{
"name": "Curaga",
"pos": "H2",
"type": "Magic",
"price": "150 LP",
"path": ["W"]
}
]
}

View File

@ -0,0 +1,214 @@
{
"spirit": "Necho Cat",
"order": 11,
"routes": [
{
"id": 0,
"name": "Diva",
"color": "blue",
"tips": [
{
"to": "Multi-Talent",
"tip": "Face"
},
{
"to": "Dancer",
"tip": "Face"
},
{
"to": "Artist",
"tip": "Body"
}
]
},
{
"id": 1,
"name": "Artist",
"color": "green",
"tips": [
{
"to": "Dancer",
"tip": "Face"
},
{
"to": "Multi-Talent",
"tip": "Face"
},
{
"to": "Diva",
"tip": "Legs"
}
]
},
{
"id": 2,
"name": "Multi-Talent",
"color": "purple",
"tips": [
{
"to": "Diva",
"tip": "Face"
},
{
"to": "Artist",
"tip": "Face"
},
{
"to": "Dancer",
"tip": "Legs"
}
]
},
{
"id": 3,
"name": "Dancer",
"color": "yellow",
"tips": [
{
"to": "Artist",
"tip": "Legs"
},
{
"to": "Multi-Talent",
"tip": "Face"
},
{
"to": "Diva",
"tip": "Legs"
}
]
}
],
"abilities": [
{
"name": "Magic Boost",
"pos": "A4",
"type": "Stat",
"price": "200 LP",
"route": 0,
"path": ["E"]
},
{
"name": "Support Boost",
"pos": "B1",
"type": "Spirit",
"price": "200 LP",
"path": ["E"]
},
{
"name": "HP Boost",
"pos": "B3",
"type": "Stat",
"price": "30 LP",
"path": ["E"]
},
{
"name": "Confusion Block",
"pos": "B4",
"type": "Stat",
"price": "30 LP",
"route": 0,
"path": ["W", "E"]
},
{
"name": "Thunder Boost",
"pos": "B5",
"type": "Stat",
"price": "50 LP",
"path": ["E", "S"]
},
{
"name": "Magic Haste",
"pos": "B6",
"type": "Stat",
"price": "50 LP",
"path": ["E", "N"]
},
{
"name": "Checkpoint",
"pos": "C1",
"type": "Checkpoint",
"price": "Link x3",
"path": ["W", "S"]
},
{
"name": "Magic Boost",
"pos": "C2",
"type": "Stat",
"price": "100 LP",
"path": ["E", "N", "S"]
},
{
"name": "Sleepra",
"pos": "C3",
"type": "Magic",
"price": "100 LP",
"path": ["W", "E", "N", "S"]
},
{
"name": "Magic Haste",
"pos": "C4",
"type": "Stat",
"price": "50 LP",
"path": ["W", "E", "N", "S"]
},
{
"name": "Thunder Boost",
"pos": "C5",
"type": "Stat",
"price": "30 LP",
"path": ["W", "E", "N", "S"]
},
{
"name": "Thunder",
"pos": "C6",
"type": "Magic",
"price": "10 LP",
"path": ["W", "N", "S"]
},
{
"name": "Start",
"pos": "C7",
"type": "Start",
"price": "",
"path": ["N"]
},
{
"name": "Thunder Boost",
"pos": "D2",
"type": "Stat",
"price": "100 LP",
"route": 1,
"path": ["W", "E"]
},
{
"name": "Magic Haste",
"pos": "D3",
"type": "Stat",
"price": "100 LP",
"path": ["W", "S"]
},
{
"name": "Time Bomb",
"pos": "D4",
"type": "Magic",
"price": "50 LP",
"path": ["W", "N"]
},
{
"name": "Sleep Block",
"pos": "D5",
"type": "Stat",
"price": "30 LP",
"path": ["W"]
},
{
"name": "Magic Haste",
"pos": "E2",
"type": "Stat",
"price": "150 LP",
"route": 1,
"path": ["W"]
}
]
}

View File

@ -0,0 +1,236 @@
{
"spirit": "Pricklemane",
"order": 5,
"routes": [
{
"id": 0,
"name": "Intellectual",
"color": "blue",
"tips": [
{
"to": "Volcano",
"tip": "Feet"
},
{
"to": "Bouncer",
"tip": "Face"
},
{
"to": "Scrapper",
"tip": "Feet"
}
]
},
{
"id": 1,
"name": "Volcano",
"color": "purple",
"tips": [
{
"to": "Intellectual",
"tip": "Face"
},
{
"to": "Bouncer",
"tip": "Face"
},
{
"to": "Scrapper",
"tip": "Tail"
}
]
},
{
"id": 2,
"name": "Scrapper",
"color": "yellow",
"tips": [
{
"to": "Bouncer",
"tip": "Tail"
},
{
"to": "Volcano",
"tip": "Face"
},
{
"to": "Intellectual",
"tip": "Feet"
}
]
},
{
"id": 3,
"name": "Bouncer",
"color": "green",
"tips": [
{
"to": "Scrapper",
"tip": "Face"
},
{
"to": "Volcano",
"tip": "Face"
},
{
"to": "Intellectual",
"tip": "Tail"
}
]
},
{
"id": 100,
"name": "Secret Route 1",
"color": "secret1",
"tips": []
}
],
"abilities": [
{
"name": "HP Boost",
"pos": "A3",
"type": "Stat",
"price": "30 LP",
"path": ["E"]
},
{
"name": "Attack Boost",
"pos": "A5",
"type": "Stat",
"price": "100 LP",
"path": ["E"]
},
{
"name": "HP Boost",
"pos": "A6",
"type": "Stat",
"price": "50 LP",
"route": 100,
"path": ["E"]
},
{
"name": "Start",
"pos": "B1",
"type": "Start",
"price": "",
"path": ["S"]
},
{
"name": "Strike Raid",
"pos": "B2",
"type": "Attack",
"price": "10 LP",
"path": ["N", "S"]
},
{
"name": "Item Boost",
"pos": "B3",
"type": "Stat",
"price": "30 LP",
"path": ["N", "S", "W", "E"]
},
{
"name": "Time Bomb",
"pos": "B4",
"type": "Magic",
"price": "100 LP",
"path": ["N", "S", "E"]
},
{
"name": "Attack Haste",
"pos": "B5",
"type": "Stat",
"price": "30 LP",
"path": ["N", "S", "W", "E"]
},
{
"name": "Secret",
"pos": "B6",
"type": "Secret",
"price": "10 LP",
"path": ["N", "S", "W", "E"]
},
{
"name": "Poison Block",
"pos": "B7",
"type": "Stat",
"price": "30 LP",
"route": 100,
"path": ["N", "S"]
},
{
"name": "Circle Raid",
"pos": "B8",
"type": "Attack",
"price": "100 LP",
"route": 100,
"path": ["N"]
},
{
"name": "Stop Block",
"pos": "C2",
"type": "Stat",
"price": "30 LP",
"route": 0,
"path": ["S", "E"]
},
{
"name": "Sleep Block",
"pos": "C3",
"type": "Stat",
"price": "30 LP",
"path": ["W", "E", "N"]
},
{
"name": "Checkpoint",
"pos": "C4",
"type": "Checkpoint",
"price": "Level 10",
"path": ["W", "E"]
},
{
"name": "Fire Screen",
"pos": "C5",
"type": "Stat",
"price": "20 LP",
"path": ["W"]
},
{
"name": "Attack Haste",
"pos": "C6",
"type": "Stat",
"price": "50 LP",
"route": 100,
"path": ["W"]
},
{
"name": "Attack Haste",
"pos": "D2",
"type": "Stat",
"price": "100 LP",
"route": 0,
"path": ["W"]
},
{
"name": "Checkpoint",
"pos": "D3",
"type": "Checkpoint",
"price": "Link x5",
"path": ["W", "E"]
},
{
"name": "Defense Boost",
"pos": "D4",
"type": "Stat",
"price": "100 LP",
"path": ["W"]
},
{
"name": "Combo Plus",
"pos": "E3",
"type": "Support",
"price": "200 LP",
"path": ["W"]
}
]
}

View File

@ -0,0 +1,237 @@
{
"spirit": "Tama Sheep",
"order": 2,
"routes": [
{
"id": 0,
"name": "Mumbler",
"color": "blue",
"tips": [
{
"to": "Picker-Upper",
"tip": "Face"
},
{
"to": "Snooze Maker",
"tip": "Face"
},
{
"to": "Pillow Fluffer",
"tip": "Horn"
}
]
},
{
"id": 1,
"name": "Picker-Upper",
"color": "purple",
"tips": [
{
"to": "Mumbler",
"tip": "Face"
},
{
"to": "Pillow Fluffer",
"tip": "Face"
},
{
"to": "Snooze Maker",
"tip": "Horn"
}
]
},
{
"id": 2,
"name": "Snooze Maker",
"color": "yellow",
"tips": [
{
"to": "Pillow Fluffer",
"tip": "Feet"
},
{
"to": "Picker-Upper",
"tip": "Face"
},
{
"to": "Mumbler",
"tip": "Feet"
}
]
},
{
"id": 3,
"name": "Pillow Fluffer",
"color": "green",
"tips": [
{
"to": "Snooze Maker",
"tip": "Face"
},
{
"to": "Picker-Upper",
"tip": "Face"
},
{
"to": "Mumbler",
"tip": "Feet"
}
]
},
{
"id": 100,
"name": "Secret Route 1",
"color": "secret1",
"tips": []
}
],
"abilities": [
{
"name": "Start",
"pos": "A1",
"type": "Start",
"price": "",
"path": ["S"]
},
{
"name": "Sleep",
"pos": "A2",
"type": "Magic",
"price": "10 LP",
"path": ["N", "S", "E"]
},
{
"name": "Magic Boost",
"pos": "A3",
"type": "Stat",
"price": "100 LP",
"path": ["N", "S"]
},
{
"name": "Sleep Block",
"pos": "A4",
"type": "Stat",
"price": "30 LP",
"path": ["N", "E"]
},
{
"name": "Magic Haste",
"pos": "B2",
"type": "Stat",
"price": "30 LP",
"path": ["E", "W"]
},
{
"name": "Defense Boost",
"pos": "B4",
"type": "Stat",
"price": "100 LP",
"path": ["E", "W"]
},
{
"name": "Water Screen",
"pos": "C2",
"type": "Stat",
"price": "20 LP",
"path": ["E", "W"]
},
{
"name": "Slow Block",
"pos": "C4",
"type": "Stat",
"price": "30 LP",
"path": ["E", "W"]
},
{
"name": "Secret",
"pos": "D2",
"type": "Secret",
"price": "10 LP",
"path": ["W", "S"]
},
{
"name": "Balloon",
"pos": "D3",
"type": "Magic",
"price": "50 LP",
"route": 100,
"path": ["N", "E"]
},
{
"name": "Checkpoint",
"pos": "D4",
"type": "Checkpoint",
"price": "Link x1",
"path": ["E", "W"]
},
{
"name": "Stop Block",
"pos": "E2",
"type": "Stat",
"price": "30 LP",
"route": 100,
"path": ["S", "E"]
},
{
"name": "HP Boost",
"pos": "E3",
"type": "Stat",
"price": "30 LP",
"route": 100,
"path": ["W", "N"]
},
{
"name": "Sleepra",
"pos": "E4",
"type": "Magic",
"price": "100 LP",
"path": ["E", "W"]
},
{
"name": "Magic Haste",
"pos": "F2",
"type": "Stat",
"price": "50 LP",
"route": 100,
"path": ["E", "W", "S"]
},
{
"name": "Water Screen",
"pos": "F3",
"type": "Stat",
"price": "40 LP",
"route": 0,
"path": ["N", "E"]
},
{
"name": "Checkpoint",
"pos": "F4",
"type": "Checkpoint",
"price": "Link x2",
"path": ["E", "W"]
},
{
"name": "Magic Haste",
"pos": "G2",
"type": "Stat",
"price": "100 LP",
"route": 100,
"path": ["W"]
},
{
"name": "Support Boost",
"pos": "G3",
"type": "Support",
"price": "200 LP",
"route": 0,
"path": ["W"]
},
{
"name": "Sleepga",
"pos": "G4",
"type": "Magic",
"price": "150 LP",
"path": ["W"]
}
]
}

View File

@ -0,0 +1,228 @@
{
"spirit": "Yoggy Ram",
"order": 3,
"routes": [
{
"id": 0,
"name": "Trailblazer",
"color": "yellow",
"tips": [
{
"to": "Jumper",
"tip": "Face"
},
{
"to": "Leader",
"tip": "Face"
},
{
"to": "Powerhouse",
"tip": "Chest"
}
]
},
{
"id": 1,
"name": "Powerhouse",
"color": "purple",
"tips": [
{
"to": "Leader",
"tip": "Chest"
},
{
"to": "Trailblazer",
"tip": "Face"
},
{
"to": "Jumper",
"tip": "Chest"
}
]
},
{
"id": 2,
"name": "Leader",
"color": "blue",
"tips": [
{
"to": "Powerhouse",
"tip": "Hind Legs"
},
{
"to": "Jumper",
"tip": "Face"
},
{
"to": "Trailblazer",
"tip": "Hind Legs"
}
]
},
{
"id": 3,
"name": "Jumper",
"color": "green",
"tips": [
{
"to": "Trailblazer",
"tip": "Face"
},
{
"to": "Powerhouse",
"tip": "Face"
},
{
"to": "Leader",
"tip": "Tail"
}
]
}
],
"abilities": [
{
"name": "Fire Screen",
"pos": "A3",
"type": "Stat",
"price": "80 LP",
"route": 0,
"path": ["E", "S"]
},
{
"name": "Defense Boost",
"pos": "A4",
"type": "Stat",
"price": "200 LP",
"route": 0,
"path": ["N"]
},
{
"name": "Start",
"pos": "B2",
"type": "Start",
"price": "",
"path": ["S", "E"]
},
{
"name": "Esuna",
"pos": "B3",
"type": "Magic",
"price": "10 LP",
"path": ["N", "S", "E", "W"]
},
{
"name": "Fire Screen",
"pos": "B4",
"type": "Stat",
"price": "20 LP",
"path": ["N", "S"]
},
{
"name": "Bind Block",
"pos": "B5",
"type": "Stat",
"price": "30 LP",
"path": ["N", "S"]
},
{
"name": "Fire Screen",
"pos": "B6",
"type": "Stat",
"price": "40 LP",
"path": ["N", "S"]
},
{
"name": "Fire Screen",
"pos": "B7",
"type": "Stat",
"price": "60 LP",
"path": ["N", "S"]
},
{
"name": "Defense Boost",
"pos": "B8",
"type": "Stat",
"price": "100 LP",
"path": ["N"]
},
{
"name": "HP Boost",
"pos": "C1",
"type": "Stat",
"price": "30 LP",
"route": 1,
"path": ["S", "E"]
},
{
"name": "Fire",
"pos": "C2",
"type": "Magic",
"price": "10 LP",
"path": ["N", "S", "W", "E"]
},
{
"name": "Checkpoint",
"pos": "C3",
"type": "Checkpoint",
"price": "Link x4",
"path": ["N", "S", "W", "E"]
},
{
"name": "Treasure Magnet",
"pos": "C4",
"type": "Support",
"price": "50 LP",
"path": ["N"]
},
{
"name": "Fire Screen",
"pos": "D1",
"type": "Stat",
"price": "100 LP",
"route": 1,
"path": ["W"]
},
{
"name": "Fire Boost",
"pos": "D2",
"type": "Stat",
"price": "30 LP",
"path": ["W", "E"]
},
{
"name": "Fire Windmill",
"pos": "D3",
"type": "Attack",
"price": "150 LP",
"path": ["W"]
},
{
"name": "Checkpoint",
"pos": "E2",
"type": "Checkpoint",
"price": "Level 10",
"path": ["W", "E"]
},
{
"name": "Fira",
"pos": "F2",
"type": "Magic",
"price": "100 LP",
"path": ["W", "E"]
},
{
"name": "Checkpoint",
"pos": "G2",
"type": "Checkpoint",
"price": "Level 20",
"path": ["W", "E"]
},
{
"name": "Firaga",
"pos": "H2",
"type": "Magic",
"price": "150 LP",
"path": ["W"]
}
]
}

View File

@ -1,4 +1,4 @@
use std::panic;
use std::{fmt::Display, panic};
use askama::Template;
use itertools::Itertools;
@ -6,6 +6,7 @@ use serde::{Deserialize, Deserializer};
#[derive(Debug, Deserialize, PartialEq, Eq)]
struct Board {
order: u32,
spirit: String,
routes: Vec<Route>,
abilities: Vec<Ability>,
@ -20,6 +21,37 @@ struct Board {
}
impl Board {
pub fn init_routes(&mut self) {
self.routes.iter_mut().for_each(|r| {
r.interaction = match r.color {
Color::Blue => Interaction::Poke,
Color::Purple => Interaction::Poke,
Color::Yellow => Interaction::Rub,
Color::Green => Interaction::Rub,
// Doesn't really matter but I didn't wanna turn this into an Option
Color::SecretGreen => Interaction::Poke,
Color::SecretRed => Interaction::Poke,
}
});
let routes = self
.routes
.clone()
.into_iter()
.filter(|r| r.id < 100)
.collect_vec();
self.routes.iter_mut().filter(|r| r.id < 100).for_each(|r| {
r.tips.iter_mut().for_each(|t| {
let route = routes.iter().find(|r| r.name == t.to);
if let Some(route) = route {
t.to_color = route.color.clone();
t.tip = format!("{} {}", route.interaction, t.tip);
}
});
});
}
pub fn init_stats(&mut self) {
let v = self
.abilities
@ -91,6 +123,10 @@ impl Board {
char::from_u32(64 + *i).unwrap_or('0')
}
pub fn get_dispositions(&self) -> Vec<&Route> {
self.routes.iter().filter(|r| r.id < 100).collect_vec()
}
pub fn get_supports(&self) -> Vec<&Ability> {
self.abilities
.iter()
@ -98,14 +134,18 @@ impl Board {
.collect_vec()
}
pub fn get_magics(&self) -> Vec<&Ability> {
pub fn get_commands(&self) -> Vec<&Ability> {
self.abilities
.iter()
.filter(|&ability| ability.r#type == AbilityType::Magic)
.filter(|&ability| {
ability.r#type == AbilityType::Magic
|| ability.r#type == AbilityType::Attack
|| ability.r#type == AbilityType::Support
})
.collect_vec()
}
pub fn get_spirit(&self) -> Vec<&Ability> {
pub fn get_spirits(&self) -> Vec<&Ability> {
self.abilities
.iter()
.filter(|&ability| ability.r#type == AbilityType::Spirit)
@ -113,11 +153,57 @@ impl Board {
}
}
#[derive(Debug, Deserialize, PartialEq, Eq)]
#[derive(Debug, Deserialize, PartialEq, Eq, Clone)]
struct Route {
id: u32,
name: String,
color: String,
color: Color,
tips: Vec<Tip>,
#[serde(skip_deserializing)]
interaction: Interaction,
}
#[derive(Debug, Deserialize, PartialEq, Eq, Clone)]
enum Color {
#[serde(alias = "blue")]
Blue,
#[serde(alias = "purple")]
Purple,
#[serde(alias = "yellow")]
Yellow,
#[serde(alias = "green")]
Green,
#[serde(alias = "secret1")]
SecretGreen,
#[serde(alias = "secret2")]
SecretRed,
}
impl Display for Color {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Color::Blue => f.write_str("blue"),
Color::Purple => f.write_str("purple"),
Color::Yellow => f.write_str("yellow"),
Color::Green => f.write_str("green"),
Color::SecretGreen => f.write_str("secret1"),
Color::SecretRed => f.write_str("secret2"),
}
}
}
#[derive(Debug, Deserialize, PartialEq, Eq, Clone)]
struct Tip {
to: String,
#[serde(skip_deserializing, default = "default_disposition_color")]
to_color: Color,
tip: String,
}
fn default_disposition_color() -> Color {
Color::Blue
}
#[derive(Debug, Deserialize, PartialEq, Eq)]
@ -130,6 +216,8 @@ enum AbilityType {
Support,
Attack,
Magic,
Reprisal,
Defense,
}
type BoardPosition = (u32, u32);
@ -216,24 +304,48 @@ enum Direction {
West,
}
#[derive(Debug, Default, Deserialize, PartialEq, Eq, Clone)]
enum Interaction {
#[default]
Poke,
Rub,
}
impl Display for Interaction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Interaction::Poke => f.write_str("Poke"),
Interaction::Rub => f.write_str("Rub"),
}
}
}
#[derive(Template)]
#[template(path = "pages/ddd-abilities.html", whitespace = "suppress")]
struct AbilitiesTemplate {
pub boards: Vec<Board>,
}
const ABILITIES_PATH: &str = "./input/ddd/abilities.json";
const ABILITIES_PATH: &str = "./input/ddd/abilities";
pub fn init() {
tracing::info!("Loading ability links json data from {}", ABILITIES_PATH);
let boards_str = std::fs::read_to_string(ABILITIES_PATH).unwrap();
let mut boards = serde_json::from_str::<Vec<Board>>(&boards_str).unwrap();
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).unwrap();
for path in paths.flatten() {
let board_str = std::fs::read_to_string(path.path()).unwrap();
let mut board = serde_json::from_str::<Board>(&board_str).unwrap();
for board in &mut boards {
board.init_routes();
board.init_total_lp();
board.init_max_level();
board.init_stats();
// dbg!(&board);
boards.push(board);
}
boards.sort_by(|a, b| a.order.cmp(&b.order));
tracing::info!("Generating the DDD ability boards template");
let template = AbilitiesTemplate { boards };

View File

@ -0,0 +1,48 @@
<div class="abilities">
<div>
<h2>Stats</h2>
<ul>
{% for val in board.stats %}
{% if val.0 > 1 %}
<li>x{{+ val.0 +}} {{+ val.1 +}}</li>
{% else %}
<li>{{+ val.1 +}}</li>
{% endif %}
{% endfor %}
</ul>
</div>
{% let supports = board.get_supports() %}
{% if supports.len() > 0 %}
<div>
<h2>Support</h2>
<ul>
{% for ability in supports %}
<li>{{ ability.name }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% let spirits = board.get_spirits() %}
{% if spirits.len() > 0 %}
<div>
<h2>Spirit</h2>
<ul>
{% for ability in spirits %}
<li>{{ ability.name }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
{% let commands = board.get_commands() %}
{% if commands.len() > 0 %}
<div>
<h2>Commands</h2>
<ul>
{% for ability in commands %}
<li>{{ ability.name }}</li>
{% endfor %}
</ul>
</div>
{% endif %}
</div>

View File

@ -0,0 +1,23 @@
<tr>
<td class="slot-h">{{ y }}</td>
{% for x in 1..board.get_size().0 + 1 %}
{% let ability = board.get_ability_at(x, y) %}
{% match ability %}
{% when Some with (val) %}
<td colspan="1" class="{{ val.get_slot_details(board) }}">
<div class="slot">
<span>{{ val.name }}</span>
{% match val.type %}
{% when AbilityType::Checkpoint %}
<br />
<span>{{ val.price }}</span>
{% when _ %}
{% endmatch %}
</div>
<div class="path"></div>
</td>
{% when None %}
<td colspan="1"></td>
{% endmatch %}
{% endfor %}
</tr>

View File

@ -0,0 +1,20 @@
<h2>Board</h2>
<ul>
<li>Total LP Needed: {{+ board.total_lp +}}</li>
<li>Max Level Needed: {{+ board.max_level +}}</li>
</ul>
<table class="board">
<tbody>
<tr>
<td class="slot-w slot-h"></td>
{% for x in 1..board.get_size().0 + 1 %}
<td class="slot-w">{{ board.get_char(x) }}</td>
{% endfor %}
</tr>
{% for y in 1..board.get_size().1 + 1 %}
{% include "components/ddd/board-row.html" %}
{% endfor %}
</tbody>
</table>

View File

@ -0,0 +1,18 @@
<h2>Dispositions</h2>
{% 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>
{% endfor %}

View File

@ -36,6 +36,10 @@
background-color: #252525;
}
}
ul {
line-height: 1.5;
}
</style>
{% block head %}{% endblock %}

View File

@ -4,7 +4,70 @@
{% block head %}
<style>
table {
.blue {
background-color: #35a0a8;
}
.purple {
background-color: #992a9b;
}
.green {
background-color: #7ecf50;
}
.yellow {
background-color: #d3c949;
}
.secret1 {
background-color: #497331;
}
.secret2 {
background-color: #881a22;
}
div.abilities {
display: flex;
& div {
margin-right: 60px;
}
}
div.route {
display: flex;
align-items: center;
& div {
display: flex;
align-items: center;
}
& .disposition {
width: 32px;
height: 32px;
margin-right: 5px;
display: inline-block;
vertical-align: middle;
}
& span {
font-size: 18px;
}
& ul {
list-style: disclosure-closed;
line-height: 2.5;
& li {
display: list-item;
}
}
}
table.board {
width: inherit;
td {
@ -42,18 +105,6 @@
background-color: #dcbf7e;
}
&.cyan {
background-color: #35a0a8;
}
&.purple {
background-color: #992a9b;
}
&.green {
background-color: #7ecf50;
}
&.north.east.south.west .path::after {
content: "┼";
}
@ -143,63 +194,9 @@
{% block content %}
{% for board in boards %}
Spirit: {{+ board.spirit +}}
<br />
Total LP Needed: {{+ board.total_lp +}}
<br />
Max Level Needed: {{+ board.max_level +}}
<br /><br />
Stats:
<ul>
{% for val in board.stats %}
<li>x{{+ val.0 +}} {{+ val.1 +}}</li>
{% endfor %}
</ul>
Support:
<ul>
{% for support in board.get_supports() %}
<li>{{ support.name }}</li>
{% endfor %}
</ul>
<table>
<tbody>
<tr>
<td class="slot-w slot-h"></td>
{% for x in 1..board.get_size().0 + 1 %}
<td class="slot-w">{{ board.get_char(x) }}</td>
{% endfor %}
</tr>
{% for y in 1..board.get_size().1 + 1 %}
<tr>
<td class="slot-h">{{ y }}</td>
{% for x in 1..board.get_size().0 + 1 %}
{% let ability = board.get_ability_at(x, y) %}
{% match ability %}
{% when Some with (val) %}
<td
colspan="1"
class="{{ val.get_slot_details(board) }}"
>
<div class="slot">
<span>{{ val.name }}</span>
{% match val.type %}
{% when AbilityType::Checkpoint %}
<br />
<span>{{ val.price }}</span>
{% when _ %}
{% endmatch %}
</div>
<div class="path"></div>
</td>
{% when None %}
<td colspan="1"></td>
{% endmatch %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
</table>
<h1>{{+ board.spirit +}}</h1>
{% include "components/ddd/abilities.html" %}
{% include "components/ddd/dispositions.html" %}
{% include "components/ddd/board.html" %}
{% endfor %}
{% endblock %}