summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--db/_generated/areas/candy-town.json2
-rw-r--r--db/_generated/areas/city-park.json2
-rw-r--r--db/_generated/areas/cotton-town.json2
-rw-r--r--db/_generated/areas/dryads-grove.json2
-rw-r--r--db/_generated/areas/hospital-floor-1.json1
-rw-r--r--db/_generated/areas/hospital-floor-2.json1
-rw-r--r--db/_generated/areas/hospital-floor-3.json1
-rw-r--r--db/_generated/areas/hospital.json1
-rw-r--r--db/_generated/areas/lion-mountain.json2
-rw-r--r--db/_generated/areas/mansion-basement.json1
-rw-r--r--db/_generated/areas/mansion-top-floor.json1
-rw-r--r--db/_generated/areas/mansion.json1
-rw-r--r--db/_generated/areas/paper-town.json2
-rw-r--r--db/_generated/areas/route1.json2
-rw-r--r--db/_generated/areas/route2.json2
-rw-r--r--db/_generated/areas/route3.json2
-rw-r--r--db/_generated/areas/route4.json2
-rw-r--r--db/_generated/areas/route5.json2
-rw-r--r--db/_generated/areas/route6.json2
-rw-r--r--db/_generated/areas/route7.json2
-rw-r--r--db/_generated/areas/sea-route-c.json2
-rw-r--r--db/_generated/areas/side-route-a.json2
-rw-r--r--db/_generated/areas/tunnel-b-underground.json1
-rw-r--r--db/_generated/areas/tunnel-b.json2
-rw-r--r--db/areas.php26
-rw-r--r--db/areas/candy-town.json5
-rw-r--r--db/areas/city-park.json11
-rw-r--r--db/areas/cotton-town.json6
-rw-r--r--db/areas/dryads-grove.json103
-rw-r--r--db/areas/hospital-floor-1.json29
-rw-r--r--db/areas/hospital-floor-2.json47
-rw-r--r--db/areas/hospital-floor-3.json35
-rw-r--r--db/areas/hospital.json20
-rw-r--r--db/areas/lion-mountain.json28
-rw-r--r--db/areas/mansion-basement.json41
-rw-r--r--db/areas/mansion-top-floor.json73
-rw-r--r--db/areas/mansion.json42
-rw-r--r--db/areas/paper-town.json2
-rw-r--r--db/areas/sea-route-c.json11
-rw-r--r--db/areas/side-route-a.json45
-rw-r--r--db/areas/tunnel-b-underground.json151
-rw-r--r--db/areas/tunnel-b.json93
-rw-r--r--db/maps/Abandoned_Mansion.pngbin0 -> 12981 bytes
-rw-r--r--db/maps/Abandoned_Mansion_Basement.pngbin0 -> 19352 bytes
-rw-r--r--db/maps/Abandoned_Mansion_Top_Floor.pngbin0 -> 15178 bytes
-rw-r--r--db/maps/Dryads_Grove.pngbin0 -> 46033 bytes
-rw-r--r--db/maps/candy-town.svg2
-rw-r--r--db/maps/dryads-grove.svg9
-rw-r--r--db/maps/hospital-floor-1.pngbin0 -> 15108 bytes
-rw-r--r--db/maps/hospital-floor-1.svg7
-rw-r--r--db/maps/hospital-floor-2.pngbin0 -> 13634 bytes
-rw-r--r--db/maps/hospital-floor-2.svg7
-rw-r--r--db/maps/hospital-floor-3.pngbin0 -> 7678 bytes
-rw-r--r--db/maps/hospital-floor-3.svg7
-rw-r--r--db/maps/hospital.pngbin0 -> 6501 bytes
-rw-r--r--db/maps/hospital.svg9
-rw-r--r--db/maps/mansion-basement.svg7
-rw-r--r--db/maps/mansion-top-floor.svg7
-rw-r--r--db/maps/mansion.svg9
-rw-r--r--index.html8
-rw-r--r--resources/css/menu.css10
-rw-r--r--resources/css/page.css4
-rw-r--r--resources/css/town.css15
-rw-r--r--resources/js/classes/Area.js12
-rw-r--r--resources/js/db.js39
-rw-r--r--resources/js/game.js34
-rw-r--r--resources/js/memory.js1
-rw-r--r--resources/js/ui.js51
68 files changed, 965 insertions, 81 deletions
diff --git a/db/_generated/areas/candy-town.json b/db/_generated/areas/candy-town.json
index 1a165e8..4991f3a 100644
--- a/db/_generated/areas/candy-town.json
+++ b/db/_generated/areas/candy-town.json
@@ -1 +1 @@
-{"locations":{"hospital":{"type":"healingCenter","price":30},"scoop_store":{"type":"shop","items":[{"item_name":"potion","price":20,"cost":5},{"item_name":"revive","price":100,"cost":20},{"item_name":"tuxeball","price":50,"cost":10}],"modules\/tuxemon.economy":"spyder_candy_scoop"}},"connections":{"route6":{"conditions":[],"modules\/tuxemon.slug":"route6"},"sea-route-c":{"conditions":[],"modules\/tuxemon.slug":"routec"}},"modules\/tuxemon.slug":"candy_town","encounters":[],"requiredEncounters":0,"trainers":[],"environment":null,"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 640\"\n>\n <image href=\"\/db\/maps\/Candy_Town.png\" \/>\n\n <rect data-location=\"hospital\" x=\"127\" y=\"431\" width=\"210\" height=\"130\" stroke=\"red\" fill=\"transparent\" \/>\n <rect data-location=\"scoop_store\" x=\"17\" y=\"144\" width=\"80\" height=\"64\" stroke=\"red\" fill=\"transparent\" \/>\n<\/svg>\n"} \ No newline at end of file
+{"locations":{"scoop_store":{"type":"shop","items":[{"item_name":"potion","price":20,"cost":5},{"item_name":"revive","price":100,"cost":20},{"item_name":"tuxeball","price":50,"cost":10}],"modules\/tuxemon.economy":"spyder_candy_scoop"}},"connections":{"route6":{"conditions":[],"modules\/tuxemon.slug":"route6"},"sea-route-c":{"conditions":[],"modules\/tuxemon.slug":"routec"}},"modules\/tuxemon.slug":"candy_town","encounters":[],"requiredEncounters":0,"trainers":[],"environment":null,"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 640\"\n>\n <image href=\"\/db\/maps\/Candy_Town.png\" \/>\n\n <rect data-location=\"scoop_store\" x=\"17\" y=\"144\" width=\"80\" height=\"64\" stroke=\"red\" fill=\"transparent\" \/>\n <rect data-area=\"hospital\" x=\"127\" y=\"431\" width=\"210\" height=\"130\" stroke=\"red\" fill=\"transparent\" \/>\n<\/svg>\n"} \ No newline at end of file
diff --git a/db/_generated/areas/city-park.json b/db/_generated/areas/city-park.json
index f7dbd7d..eb780bc 100644
--- a/db/_generated/areas/city-park.json
+++ b/db/_generated/areas/city-park.json
@@ -1 +1 @@
-{"requiredEncounters":10,"trainers":[{"name":"Frances","sprite":"florist.png","monsters":[{"slug":"shybulb","level":8},{"slug":"shybulb","level":8}]}],"connections":{"route2":{"conditions":[],"modules\/tuxemon.slug":"route2"},"leather-town":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"leather_town"}},"modules\/tuxemon.slug":"citypark","modules\/tuxemon.encounter":"citypark","modules\/tuxemon.environment":"forest","encounters":[{"monster":"cardiling","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[5,8]},{"monster":"cardiwing","encounter_rate":1,"daytime":true,"exp_req_mod":1,"level_range":[8,11]},{"monster":"cataspike","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[6,9]},{"monster":"eyenemy","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[5,8]},{"monster":"axylightl","encounter_rate":3,"daytime":false,"exp_req_mod":1,"level_range":[8,12]},{"monster":"tourbidi","encounter_rate":1,"daytime":false,"exp_req_mod":1,"level_range":[8,12]},{"monster":"squabbit","encounter_rate":3,"daytime":false,"exp_req_mod":1,"level_range":[8,12]},{"monster":"puparmor","encounter_rate":1,"daytime":false,"exp_req_mod":1,"level_range":[9,14]}],"environment":{"slug":"forest","battle_graphics":{"island_back":"woodland_island.png","island_front":"woodland_island.png","background":"forest_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 640\"\n>\n <image href=\"\/db\/maps\/City_park.png\" \/>\n<\/svg>\n"} \ No newline at end of file
+{"requiredEncounters":10,"encounters":[{"monster":"budaye","encounter_percent":5,"level_range":[2,5]},{"monster":"cardiling","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[5,8],"encounter_percent":16},{"monster":"cardiwing","encounter_rate":1,"daytime":true,"exp_req_mod":1,"level_range":[8,11],"encounter_percent":5},{"monster":"cataspike","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[6,9],"encounter_percent":16},{"monster":"eyenemy","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[5,8],"encounter_percent":16},{"monster":"axylightl","encounter_rate":3,"daytime":false,"exp_req_mod":1,"level_range":[8,12],"encounter_percent":16},{"monster":"tourbidi","encounter_rate":1,"daytime":false,"exp_req_mod":1,"level_range":[8,12],"encounter_percent":5},{"monster":"squabbit","encounter_rate":3,"daytime":false,"exp_req_mod":1,"level_range":[8,12],"encounter_percent":16},{"monster":"puparmor","encounter_rate":1,"daytime":false,"exp_req_mod":1,"level_range":[9,14],"encounter_percent":5}],"trainers":[{"name":"Frances","sprite":"florist.png","monsters":[{"slug":"shybulb","level":8},{"slug":"shybulb","level":8}]}],"connections":{"route2":{"conditions":[],"modules\/tuxemon.slug":"route2"},"leather-town":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"leather_town"}},"modules\/tuxemon.slug":"citypark","modules\/tuxemon.encounter":"citypark","modules\/tuxemon.environment":"forest","encounter_percent_total":100,"environment":{"slug":"forest","battle_graphics":{"island_back":"woodland_island.png","island_front":"woodland_island.png","background":"forest_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 640\"\n>\n <image href=\"\/db\/maps\/City_park.png\" \/>\n<\/svg>\n","locations":[]} \ No newline at end of file
diff --git a/db/_generated/areas/cotton-town.json b/db/_generated/areas/cotton-town.json
index c6bf453..1cd83cc 100644
--- a/db/_generated/areas/cotton-town.json
+++ b/db/_generated/areas/cotton-town.json
@@ -1 +1 @@
-{"locations":{"healing_center":{"type":"healingCenter","price":10},"cotton_scoop":{"type":"shop","modules\/tuxemon.economy":"cotton_scoop","items":[{"item_name":"potion","price":20,"cost":5},{"item_name":"revive","price":100,"cost":20},{"item_name":"tuxeball","price":50,"cost":10}]}},"events":{"dryads-grove":false},"connections":{"route1":{"conditions":[],"modules\/tuxemon.slug":"route1"},"route2":{"conditions":[],"modules\/tuxemon.slug":"route2"},"dryads-grove":{"conditions":["event.dryads-grove"],"modules\/tuxemon.slug":"dryadsgrove"}},"modules\/tuxemon.slug":"cotton_town","encounters":[],"requiredEncounters":0,"trainers":[],"environment":null,"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 640\"\n>\n <image href=\"\/db\/maps\/Cotton_town.png\" \/>\n\n <text x=\"275\" y=\"445\">Healing Center<\/text>\n <rect data-location=\"healing_center\" x=\"288\" y=\"368\" width=\"80\" height=\"64\" stroke=\"red\" fill=\"transparent\" \/>\n\n <text x=\"470\" y=\"573\">Shop<\/text>\n <rect data-location=\"cotton_scoop\" x=\"448\" y=\"496\" width=\"80\" height=\"64\" stroke=\"red\" fill=\"transparent\" \/>\n<\/svg>\n"} \ No newline at end of file
+{"locations":{"healing_center":{"type":"healingCenter","price":10},"cotton_scoop":{"type":"shop","modules\/tuxemon.economy":"cotton_scoop","items":[{"item_name":"potion","price":20,"cost":5},{"item_name":"revive","price":100,"cost":20},{"item_name":"tuxeball","price":50,"cost":10}]}},"connections":{"route1":{"conditions":[],"modules\/tuxemon.slug":"route1"},"route2":{"conditions":[],"modules\/tuxemon.slug":"route2"},"dryads-grove":{"conditions":["area.hospital-floor-3.complete"],"modules\/tuxemon.slug":"dryadsgrove"}},"modules\/tuxemon.slug":"cotton_town","encounters":[],"requiredEncounters":0,"trainers":[],"environment":null,"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 640\"\n>\n <image href=\"\/db\/maps\/Cotton_town.png\" \/>\n\n <text x=\"275\" y=\"445\">Healing Center<\/text>\n <rect data-location=\"healing_center\" x=\"288\" y=\"368\" width=\"80\" height=\"64\" stroke=\"red\" fill=\"transparent\" \/>\n\n <text x=\"470\" y=\"573\">Shop<\/text>\n <rect data-location=\"cotton_scoop\" x=\"448\" y=\"496\" width=\"80\" height=\"64\" stroke=\"red\" fill=\"transparent\" \/>\n<\/svg>\n"} \ No newline at end of file
diff --git a/db/_generated/areas/dryads-grove.json b/db/_generated/areas/dryads-grove.json
index d487005..1bc743f 100644
--- a/db/_generated/areas/dryads-grove.json
+++ b/db/_generated/areas/dryads-grove.json
@@ -1 +1 @@
-{"connections":[],"modules\/tuxemon.slug":"dryadsgrove","encounters":[],"requiredEncounters":0,"trainers":[],"environment":null,"map":false} \ No newline at end of file
+{"trainers":[{"name":"Water Nymph","sprite":"waternymph.png","monsters":[{"slug":"noctalo","level":50},{"slug":"nudimind","level":50},{"slug":"vivisource","level":50}]},{"name":"Fire Nymph","sprite":"firenymph.png","monsters":[{"slug":"criniotherme","level":50},{"slug":"masknake","level":50},{"slug":"vivicinder","level":50}]},{"name":"Earth Nymph","sprite":"earthnymph.png","monsters":[{"slug":"exapode","level":50},{"slug":"sumchon","level":50},{"slug":"vividactil","level":50}]},{"name":"Metal Nymph","sprite":"metalnymph.png","monsters":[{"slug":"araignee","level":50},{"slug":"allagon","level":50},{"slug":"viviteel","level":50}]},{"name":"Wood Nymph","sprite":"woodnymph.png","monsters":[{"slug":"narcileaf","level":50},{"slug":"dandylion","level":50},{"slug":"viviphyta","level":50}]}],"connections":{"cotton-town":{"conditions":[],"modules\/tuxemon.slug":"cotton_town"}},"modules\/tuxemon.slug":"dryadsgrove","modules\/tuxemon.encounter":"dryadsgrove","modules\/tuxemon.environment":"forest","encounters":[{"monster":"coleorus","encounter_rate":1,"daytime":true,"exp_req_mod":1,"level_range":[25,28],"encounter_percent":8},{"monster":"tourbidi","encounter_rate":1,"daytime":true,"exp_req_mod":1,"level_range":[20,25],"encounter_percent":8},{"monster":"shybulb","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[25,28],"encounter_percent":25},{"monster":"narcileaf","encounter_rate":3,"daytime":false,"exp_req_mod":1,"level_range":[25,28],"encounter_percent":25},{"monster":"sapsnap","encounter_rate":3,"daytime":false,"exp_req_mod":1,"level_range":[28,30],"encounter_percent":25},{"monster":"lambert","encounter_rate":1,"daytime":false,"exp_req_mod":1,"level_range":[25,28],"encounter_percent":8}],"encounter_percent_total":99,"requiredEncounters":0,"environment":{"slug":"forest","battle_graphics":{"island_back":"woodland_island.png","island_front":"woodland_island.png","background":"forest_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 320\"\n>\n <image href=\"\/db\/maps\/Dryads_Grove.png\" \/>\n\n <rect data-encounter=\"volcoli\" data-encounter-level=\"55\" x=\"544\" y=\"207\" width=\"16\" height=\"16\" stroke=\"red\" fill=\"transparent\" \/>\n<\/svg>\n","locations":[]} \ No newline at end of file
diff --git a/db/_generated/areas/hospital-floor-1.json b/db/_generated/areas/hospital-floor-1.json
new file mode 100644
index 0000000..ed0c0fe
--- /dev/null
+++ b/db/_generated/areas/hospital-floor-1.json
@@ -0,0 +1 @@
+{"trainers":[{"name":"Spyder Boss Aurora","sprite":"spyder_boss.png","monsters":[{"slug":"exclawvate","level":40}]}],"connections":{"hospital":{"conditions":[],"modules\/tuxemon.slug":"hospital"},"hospital-floor-2":{"conditions":["trainers"],"modules\/tuxemon.slug":"hospital2"}},"modules\/tuxemon.slug":"hospital1","modules\/tuxemon.environment":"interior","encounters":[],"requiredEncounters":0,"environment":{"slug":"interior","battle_graphics":{"island_back":"paper_back_island.png","island_front":"paper_front_island.png","background":"battle_bg03.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 320 320\"\n>\n <image href=\"\/db\/maps\/hospital-floor-1.png\" \/>\n<\/svg>\n","locations":[]} \ No newline at end of file
diff --git a/db/_generated/areas/hospital-floor-2.json b/db/_generated/areas/hospital-floor-2.json
new file mode 100644
index 0000000..e306172
--- /dev/null
+++ b/db/_generated/areas/hospital-floor-2.json
@@ -0,0 +1 @@
+{"trainers":[{"name":"Spyder Boss Luzia","sprite":"spyder_boss.png","monsters":[{"slug":"galnec","level":36},{"slug":"exclawvate","level":36}]},{"name":"Profressor Rhizome","sprite":"professor.png","monsters":[{"slug":"flacono","level":33},{"slug":"fancair","level":33}]}],"connections":{"hospital-floor-1":{"conditions":[],"modules\/tuxemon.slug":"hospital1"},"hospital-floor-3":{"conditions":["trainers"],"modules\/tuxemon.slug":"hospital3"}},"modules\/tuxemon.slug":"hospital2","modules\/tuxemon.environment":"interior","encounters":[],"requiredEncounters":0,"environment":{"slug":"interior","battle_graphics":{"island_back":"paper_back_island.png","island_front":"paper_front_island.png","background":"battle_bg03.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 320 320\"\n>\n <image href=\"\/db\/maps\/hospital-floor-2.png\" \/>\n<\/svg>\n","locations":[]} \ No newline at end of file
diff --git a/db/_generated/areas/hospital-floor-3.json b/db/_generated/areas/hospital-floor-3.json
new file mode 100644
index 0000000..4a57c1c
--- /dev/null
+++ b/db/_generated/areas/hospital-floor-3.json
@@ -0,0 +1 @@
+{"trainers":[{"name":"Rival Billie","sprite":"fashionista.png","monsters":[{"slug":"cardinale","level":40},{"slug":"eyesore","level":40},{"slug":"viviphyta","level":40},{"slug":"STARTER","level":40}]}],"connections":{"hospital-floor-2":{"conditions":[],"modules\/tuxemon.slug":"hospital2"}},"modules\/tuxemon.slug":"hospital3","modules\/tuxemon.environment":"interior","encounters":[],"requiredEncounters":0,"environment":{"slug":"interior","battle_graphics":{"island_back":"paper_back_island.png","island_front":"paper_front_island.png","background":"battle_bg03.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 192 320\"\n>\n <image href=\"\/db\/maps\/hospital-floor-3.png\" \/>\n<\/svg>\n","locations":[]} \ No newline at end of file
diff --git a/db/_generated/areas/hospital.json b/db/_generated/areas/hospital.json
new file mode 100644
index 0000000..d4b35a9
--- /dev/null
+++ b/db/_generated/areas/hospital.json
@@ -0,0 +1 @@
+{"locations":{"hospital":{"type":"healingCenter","price":30}},"connections":{"candy-town":{"conditions":[],"modules\/tuxemon.slug":"candy_town"},"hospital-floor-1":{"conditions":[],"modules\/tuxemon.slug":"hospital1"}},"modules\/tuxemon.slug":"hospital","encounters":[],"requiredEncounters":0,"trainers":[],"environment":null,"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 320 176\"\n>\n <image href=\"\/db\/maps\/hospital.png\" \/>\n\n <rect data-location=\"hospital\" x=\"64\" y=\"43\" width=\"32\" height=\"21\" stroke=\"red\" fill=\"transparent\" \/>\n<\/svg>\n"} \ No newline at end of file
diff --git a/db/_generated/areas/lion-mountain.json b/db/_generated/areas/lion-mountain.json
index 5590dce..58ea2ae 100644
--- a/db/_generated/areas/lion-mountain.json
+++ b/db/_generated/areas/lion-mountain.json
@@ -1 +1 @@
-{"requiredEncounters":10,"trainers":[{"name":"Miner Jacques","sprite":"monk.png","monsters":[{"slug":"heronquak","level":55},{"slug":"jemuar","level":60}]}],"connections":{"sphalian-town":{"conditions":[],"modules\/tuxemon.slug":"sphalian_town"}},"modules\/tuxemon.slug":"lion_mountain","modules\/tuxemon.encounter":"lion_mountain","modules\/tuxemon.environment":"snow","encounters":[{"monster":"snowrilla","encounter_rate":3.5,"daytime":true,"exp_req_mod":1,"level_range":[55,65]},{"monster":"snowrilla","encounter_rate":3.5,"daytime":false,"exp_req_mod":1,"level_range":[65,75]},{"monster":"tadcool","encounter_rate":3.5,"daytime":true,"exp_req_mod":1,"level_range":[55,65]},{"monster":"tadcool","encounter_rate":3.5,"daytime":false,"exp_req_mod":1,"level_range":[65,75]},{"monster":"chillimp","encounter_rate":3.5,"daytime":true,"exp_req_mod":1,"level_range":[55,65]},{"monster":"chillimp","encounter_rate":3.5,"daytime":false,"exp_req_mod":1,"level_range":[65,75]},{"monster":"tux","encounter_rate":3.5,"daytime":true,"exp_req_mod":1,"level_range":[55,65]},{"monster":"tux","encounter_rate":3.5,"daytime":false,"exp_req_mod":1,"level_range":[65,75]}],"environment":{"slug":"snow","battle_graphics":{"island_back":"snow_island.png","island_front":"snow_island.png","background":"snow_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 720 1600\"\n>\n <image href=\"\/db\/maps\/Buddha_mountain.png\" \/>\n<\/svg>\n"} \ No newline at end of file
+{"requiredEncounters":10,"trainers":[{"name":"Miner Jacques","sprite":"monk.png","monsters":[{"slug":"heronquak","level":55},{"slug":"jemuar","level":60}]},{"name":"Bruder Mikki","sprite":"adventurer.png","monsters":[{"slug":"miaownolith","level":75},{"slug":"pyraminx","level":76},{"slug":"mauai","level":77},{"slug":"jelillow","level":80}],"inventory":[{"slug":"super_potion","quantity":4}]}],"connections":{"sphalian-town":{"conditions":[],"modules\/tuxemon.slug":"sphalian_town"}},"modules\/tuxemon.slug":"lion_mountain","modules\/tuxemon.encounter":"lion_mountain","modules\/tuxemon.environment":"snow","encounters":[{"monster":"snowrilla","encounter_rate":3.5,"daytime":true,"exp_req_mod":1,"level_range":[55,65],"encounter_percent":25},{"monster":"tadcool","encounter_rate":3.5,"daytime":true,"exp_req_mod":1,"level_range":[55,65],"encounter_percent":25},{"monster":"chillimp","encounter_rate":3.5,"daytime":true,"exp_req_mod":1,"level_range":[55,65],"encounter_percent":25},{"monster":"tux","encounter_rate":3.5,"daytime":true,"exp_req_mod":1,"level_range":[55,65],"encounter_percent":25}],"encounter_percent_total":100,"environment":{"slug":"snow","battle_graphics":{"island_back":"snow_island.png","island_front":"snow_island.png","background":"snow_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 720 1600\"\n>\n <image href=\"\/db\/maps\/Buddha_mountain.png\" \/>\n<\/svg>\n","locations":[]} \ No newline at end of file
diff --git a/db/_generated/areas/mansion-basement.json b/db/_generated/areas/mansion-basement.json
new file mode 100644
index 0000000..d0730cf
--- /dev/null
+++ b/db/_generated/areas/mansion-basement.json
@@ -0,0 +1 @@
+{"requiredEncounters":10,"encounters":[{"monster":"ignibus","encounter_percent":5,"level_range":[2,5]},{"monster":"cairfrey","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[13,16],"encounter_percent":30},{"monster":"polyrock","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[13,16],"encounter_percent":30},{"monster":"djinnbo","encounter_rate":1,"daytime":true,"exp_req_mod":1,"level_range":[14,17],"encounter_percent":10},{"monster":"pigabyte","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[13,16],"encounter_percent":30}],"trainers":[{"name":"Dancer Coralli","sprite":"dancer.png","monsters":[{"slug":"tumbleworm","level":22},{"slug":"elofly","level":22}]}],"connections":{"mansion":{"conditions":[],"modules\/tuxemon.slug":"mansion"}},"modules\/tuxemon.slug":"mansion_basement","modules\/tuxemon.encounter":"mansion","modules\/tuxemon.environment":"cave","encounter_percent_total":105,"environment":{"slug":"cave","battle_graphics":{"island_back":"cave_island.png","island_front":"cave_island.png","background":"cave_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 384 352\"\n>\n <image href=\"\/db\/maps\/Abandoned_Mansion_Basement.png\" \/>\n<\/svg>\n","locations":[]} \ No newline at end of file
diff --git a/db/_generated/areas/mansion-top-floor.json b/db/_generated/areas/mansion-top-floor.json
new file mode 100644
index 0000000..a6eb8f8
--- /dev/null
+++ b/db/_generated/areas/mansion-top-floor.json
@@ -0,0 +1 @@
+{"requiredEncounters":10,"encounters":[{"monster":"memnomnom","encounter_percent":5,"level_range":[2,5]},{"monster":"cairfrey","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[13,16],"encounter_percent":30},{"monster":"polyrock","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[13,16],"encounter_percent":30},{"monster":"djinnbo","encounter_rate":1,"daytime":true,"exp_req_mod":1,"level_range":[14,17],"encounter_percent":10},{"monster":"pigabyte","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[13,16],"encounter_percent":30}],"trainers":[{"name":"Mage Russell","sprite":"mage.png","monsters":[{"slug":"av8r","level":22},{"slug":"mrmoswitch","level":22},{"slug":"k9","level":22}]},{"name":"Bruder Mikki","sprite":"adventurer.png","monsters":[{"slug":"memnomnom","level":25},{"slug":"memnomnom","level":26},{"slug":"memnomnom","level":27},{"slug":"jelillow","level":30}],"inventory":[{"slug":"super_potion","quantity":2}]}],"connections":{"mansion":{"conditions":[],"modules\/tuxemon.slug":"mansion"}},"modules\/tuxemon.slug":"mansion_top_floor","modules\/tuxemon.encounter":"mansion","modules\/tuxemon.environment":"cave","encounter_percent_total":105,"environment":{"slug":"cave","battle_graphics":{"island_back":"cave_island.png","island_front":"cave_island.png","background":"cave_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 368 304\"\n>\n <image href=\"\/db\/maps\/Abandoned_Mansion_Top_Floor.png\" \/>\n<\/svg>\n","locations":[]} \ No newline at end of file
diff --git a/db/_generated/areas/mansion.json b/db/_generated/areas/mansion.json
new file mode 100644
index 0000000..4f372f8
--- /dev/null
+++ b/db/_generated/areas/mansion.json
@@ -0,0 +1 @@
+{"requiredEncounters":10,"trainers":[{"name":"Magician Gillette","sprite":"magician.png","monsters":[{"slug":"djinnbo","level":22},{"slug":"ghosteeth","level":22}]}],"connections":{"side-route-a":{"conditions":[],"modules\/tuxemon.slug":"routea"},"mansion-top-floor":{"conditions":["area.mansion-basement.completed"],"modules\/tuxemon.slug":"mansion_top_floor"},"mansion-basement":{"conditions":["area.mansion-basement"],"modules\/tuxemon.slug":"mansion_basement"}},"modules\/tuxemon.slug":"mansion","modules\/tuxemon.encounter":"mansion","modules\/tuxemon.environment":"cave","encounters":[{"monster":"cairfrey","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[13,16],"encounter_percent":30},{"monster":"polyrock","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[13,16],"encounter_percent":30},{"monster":"djinnbo","encounter_rate":1,"daytime":true,"exp_req_mod":1,"level_range":[14,17],"encounter_percent":10},{"monster":"pigabyte","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[13,16],"encounter_percent":30}],"encounter_percent_total":100,"environment":{"slug":"cave","battle_graphics":{"island_back":"cave_island.png","island_front":"cave_island.png","background":"cave_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 288 288\"\n>\n <image href=\"\/db\/maps\/Abandoned_Mansion.png\" \/>\n\n <rect data-area=\"mansion-basement\" x=\"239\" y=\"45\" width=\"35\" height=\"23\" stroke=\"red\" fill=\"transparent\" \/>\n<\/svg>\n","locations":[]} \ No newline at end of file
diff --git a/db/_generated/areas/paper-town.json b/db/_generated/areas/paper-town.json
index 304459b..e8881e4 100644
--- a/db/_generated/areas/paper-town.json
+++ b/db/_generated/areas/paper-town.json
@@ -1 +1 @@
-{"locations":{"home":{"type":"healingCenter","price":0},"scoop_store":{"type":"shop","items":[{"item_name":"potion","price":20,"cost":5},{"item_name":"revive","price":100,"cost":20},{"item_name":"tuxeball","price":50,"cost":10}],"modules\/tuxemon.economy":"spyder_paper_mart"}},"connections":{"route1":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"route1"},"sea-route-c":{"conditions":["area.sea-route-c"],"modules\/tuxemon.slug":"routec"}},"modules\/tuxemon.slug":"paper_town","encounters":[],"requiredEncounters":0,"trainers":[],"environment":null,"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 320\"\n>\n <image href=\"\/db\/maps\/Paper_town.png\" \/>\n\n <rect data-location=\"home\" x=\"113\" y=\"21\" width=\"78\" height=\"92\" stroke=\"red\" fill=\"transparent\" \/>\n <rect data-location=\"scoop_store\" x=\"272\" y=\"144\" width=\"80\" height=\"64\" stroke=\"red\" fill=\"transparent\" \/>\n<\/svg>\n"} \ No newline at end of file
+{"locations":{"home":{"type":"healingCenter","price":0},"scoop_store":{"type":"shop","items":[{"item_name":"potion","price":20,"cost":5},{"item_name":"revive","price":100,"cost":20},{"item_name":"tuxeball","price":50,"cost":10}],"modules\/tuxemon.economy":"spyder_paper_mart"}},"connections":{"route1":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"route1"},"sea-route-c":{"conditions":["area.sea-route-c.completed"],"modules\/tuxemon.slug":"routec"}},"modules\/tuxemon.slug":"paper_town","encounters":[],"requiredEncounters":0,"trainers":[],"environment":null,"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 320\"\n>\n <image href=\"\/db\/maps\/Paper_town.png\" \/>\n\n <rect data-location=\"home\" x=\"113\" y=\"21\" width=\"78\" height=\"92\" stroke=\"red\" fill=\"transparent\" \/>\n <rect data-location=\"scoop_store\" x=\"272\" y=\"144\" width=\"80\" height=\"64\" stroke=\"red\" fill=\"transparent\" \/>\n<\/svg>\n"} \ No newline at end of file
diff --git a/db/_generated/areas/route1.json b/db/_generated/areas/route1.json
index c79da8e..ed3abf2 100644
--- a/db/_generated/areas/route1.json
+++ b/db/_generated/areas/route1.json
@@ -1 +1 @@
-{"requiredEncounters":10,"trainers":[{"name":"Bruder Mikki","sprite":"adventurer.png","monsters":[{"slug":"memnomnom","level":5},{"slug":"jelillow","level":5}],"inventory":[{"slug":"potion","quantity":2}]}],"items":[],"connections":{"paper-town":{"conditions":[],"modules\/tuxemon.slug":"paper_town"},"cotton-town":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"cotton_town"}},"modules\/tuxemon.slug":"route1","modules\/tuxemon.encounter":"route1","modules\/tuxemon.environment":"forest","encounters":[{"monster":"pairagrin","encounter_rate":3.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4]},{"monster":"aardorn","encounter_rate":3.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4]},{"monster":"cataspike","encounter_rate":3.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4]},{"monster":"pairagrin","encounter_rate":3.5,"daytime":false,"exp_req_mod":1,"level_range":[3,5]},{"monster":"aardorn","encounter_rate":3.5,"daytime":false,"exp_req_mod":1,"level_range":[3,5]},{"monster":"cataspike","encounter_rate":3.5,"daytime":false,"exp_req_mod":1,"level_range":[3,5]}],"environment":{"slug":"forest","battle_graphics":{"island_back":"woodland_island.png","island_front":"woodland_island.png","background":"forest_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 320\"\n>\n <image href=\"\/db\/maps\/Route_1.png\" \/>\n<\/svg>\n"} \ No newline at end of file
+{"requiredEncounters":10,"trainers":[{"name":"Bruder Mikki","sprite":"adventurer.png","monsters":[{"slug":"memnomnom","level":5},{"slug":"jelillow","level":5}],"inventory":[{"slug":"potion","quantity":2}]}],"items":[],"connections":{"paper-town":{"conditions":[],"modules\/tuxemon.slug":"paper_town"},"cotton-town":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"cotton_town"}},"modules\/tuxemon.slug":"route1","modules\/tuxemon.encounter":"route1","modules\/tuxemon.environment":"forest","encounters":[{"monster":"pairagrin","encounter_rate":3.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"encounter_percent":33},{"monster":"aardorn","encounter_rate":3.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"encounter_percent":33},{"monster":"cataspike","encounter_rate":3.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"encounter_percent":33}],"encounter_percent_total":99,"environment":{"slug":"forest","battle_graphics":{"island_back":"woodland_island.png","island_front":"woodland_island.png","background":"forest_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 320\"\n>\n <image href=\"\/db\/maps\/Route_1.png\" \/>\n<\/svg>\n","locations":[]} \ No newline at end of file
diff --git a/db/_generated/areas/route2.json b/db/_generated/areas/route2.json
index c9467de..0866c16 100644
--- a/db/_generated/areas/route2.json
+++ b/db/_generated/areas/route2.json
@@ -1 +1 @@
-{"requiredEncounters":10,"trainers":[{"name":"Rival Billie","sprite":"fashionista.png","monsters":[{"slug":"cardiling","level":3},{"slug":"eyenemy","level":6},{"slug":"STARTER","level":6}]}],"connections":{"cotton-town":{"conditions":[],"modules\/tuxemon.slug":"cotton_town"},"city-park":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"citypark"}},"modules\/tuxemon.slug":"route2","modules\/tuxemon.encounter":"route2","modules\/tuxemon.environment":"forest","encounters":[{"monster":"cardiling","encounter_rate":2.5,"daytime":true,"exp_req_mod":1,"level_range":[3,6]},{"monster":"aardorn","encounter_rate":2.5,"daytime":true,"exp_req_mod":1,"level_range":[3,6]},{"monster":"eyenemy","encounter_rate":2.5,"daytime":true,"exp_req_mod":1,"level_range":[3,6]},{"monster":"axylightl","encounter_rate":1,"daytime":true,"exp_req_mod":1,"level_range":[4,7]},{"monster":"cataspike","encounter_rate":2.5,"daytime":true,"exp_req_mod":1,"level_range":[3,6]},{"monster":"cardiling","encounter_rate":2.5,"daytime":false,"exp_req_mod":1,"level_range":[3,6]},{"monster":"aardorn","encounter_rate":2.5,"daytime":false,"exp_req_mod":1,"level_range":[4,8]},{"monster":"eyenemy","encounter_rate":2.5,"daytime":false,"exp_req_mod":1,"level_range":[4,8]},{"monster":"axylightl","encounter_rate":1,"daytime":false,"exp_req_mod":1,"level_range":[5,8]},{"monster":"cataspike","encounter_rate":2.5,"daytime":false,"exp_req_mod":1,"level_range":[4,8]}],"environment":{"slug":"forest","battle_graphics":{"island_back":"woodland_island.png","island_front":"woodland_island.png","background":"forest_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 320\"\n>\n <image href=\"\/db\/maps\/Route_2.png\" \/>\n<\/svg>\n"} \ No newline at end of file
+{"requiredEncounters":10,"trainers":[{"name":"Rival Billie","sprite":"fashionista.png","monsters":[{"slug":"cardiling","level":3},{"slug":"eyenemy","level":6},{"slug":"STARTER","level":6}]}],"connections":{"cotton-town":{"conditions":[],"modules\/tuxemon.slug":"cotton_town"},"city-park":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"citypark"}},"modules\/tuxemon.slug":"route2","modules\/tuxemon.encounter":"route2","modules\/tuxemon.environment":"forest","encounters":[{"monster":"cardiling","encounter_rate":2.5,"daytime":true,"exp_req_mod":1,"level_range":[3,6],"encounter_percent":22},{"monster":"aardorn","encounter_rate":2.5,"daytime":true,"exp_req_mod":1,"level_range":[3,6],"encounter_percent":22},{"monster":"eyenemy","encounter_rate":2.5,"daytime":true,"exp_req_mod":1,"level_range":[3,6],"encounter_percent":22},{"monster":"axylightl","encounter_rate":1,"daytime":true,"exp_req_mod":1,"level_range":[4,7],"encounter_percent":9},{"monster":"cataspike","encounter_rate":2.5,"daytime":true,"exp_req_mod":1,"level_range":[3,6],"encounter_percent":22}],"encounter_percent_total":97,"environment":{"slug":"forest","battle_graphics":{"island_back":"woodland_island.png","island_front":"woodland_island.png","background":"forest_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 320\"\n>\n <image href=\"\/db\/maps\/Route_2.png\" \/>\n<\/svg>\n","locations":[]} \ No newline at end of file
diff --git a/db/_generated/areas/route3.json b/db/_generated/areas/route3.json
index 2e12a52..4ab8030 100644
--- a/db/_generated/areas/route3.json
+++ b/db/_generated/areas/route3.json
@@ -1 +1 @@
-{"requiredEncounters":10,"trainers":[{"name":"Miner Roxby","sprite":"miner.png","monsters":[{"slug":"rockitten","level":13},{"slug":"ignibus","level":13}]}],"connections":{"leather-town":{"conditions":[],"modules\/tuxemon.slug":"leather_town"},"route4":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"route4"}},"modules\/tuxemon.slug":"route3","modules\/tuxemon.encounter":"route3","modules\/tuxemon.environment":"forest","encounters":[{"monster":"cardiling","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[7,10]},{"monster":"elofly","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[7,10]},{"monster":"squabbit","encounter_rate":1,"daytime":true,"exp_req_mod":1,"level_range":[8,11]},{"monster":"shybulb","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[7,10]},{"monster":"cardiling","encounter_rate":3,"daytime":false,"exp_req_mod":1,"level_range":[9,12]},{"monster":"elofly","encounter_rate":3,"daytime":false,"exp_req_mod":1,"level_range":[9,12]},{"monster":"squabbit","encounter_rate":1,"daytime":false,"exp_req_mod":1,"level_range":[9,12]},{"monster":"shybulb","encounter_rate":3,"daytime":false,"exp_req_mod":1,"level_range":[9,12]}],"environment":{"slug":"forest","battle_graphics":{"island_back":"woodland_island.png","island_front":"woodland_island.png","background":"forest_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 640\"\n>\n <image href=\"\/db\/maps\/Route_3.png\" \/>\n<\/svg>\n"} \ No newline at end of file
+{"requiredEncounters":10,"trainers":[{"name":"Miner Roxby","sprite":"miner.png","monsters":[{"slug":"rockitten","level":13},{"slug":"ignibus","level":13}]}],"connections":{"leather-town":{"conditions":[],"modules\/tuxemon.slug":"leather_town"},"route4":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"route4"}},"modules\/tuxemon.slug":"route3","modules\/tuxemon.encounter":"route3","modules\/tuxemon.environment":"forest","encounters":[{"monster":"cardiling","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[7,10],"encounter_percent":30},{"monster":"elofly","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[7,10],"encounter_percent":30},{"monster":"squabbit","encounter_rate":1,"daytime":true,"exp_req_mod":1,"level_range":[8,11],"encounter_percent":10},{"monster":"shybulb","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[7,10],"encounter_percent":30}],"encounter_percent_total":100,"environment":{"slug":"forest","battle_graphics":{"island_back":"woodland_island.png","island_front":"woodland_island.png","background":"forest_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 640\"\n>\n <image href=\"\/db\/maps\/Route_3.png\" \/>\n<\/svg>\n","locations":[]} \ No newline at end of file
diff --git a/db/_generated/areas/route4.json b/db/_generated/areas/route4.json
index 0a0165a..c925bf6 100644
--- a/db/_generated/areas/route4.json
+++ b/db/_generated/areas/route4.json
@@ -1 +1 @@
-{"requiredEncounters":10,"trainers":[{"name":"Soldier Marshall","sprite":"soldier.png","monsters":[{"slug":"puparmor","level":16},{"slug":"puparmor","level":16}]},{"name":"Rival Billie","sprite":"fashionista.png","monsters":[{"slug":"cardiwing","level":16},{"slug":"eyesore","level":16},{"slug":"viviphyta","level":16},{"slug":"STARTER","level":18}]}],"connections":{"route3":{"conditions":[],"modules\/tuxemon.slug":"route3"},"flower-city":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"flower_city"}},"modules\/tuxemon.slug":"route4","modules\/tuxemon.encounter":"route4","modules\/tuxemon.environment":"forest","encounters":[{"monster":"elofly","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[11,14]},{"monster":"sapsnap","encounter_rate":1,"daytime":true,"exp_req_mod":1,"level_range":[12,15]},{"monster":"aardorn","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[11,14]},{"monster":"katapill","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[11,14]},{"monster":"elofly","encounter_rate":3,"daytime":false,"exp_req_mod":1,"level_range":[13,16]},{"monster":"sapsnap","encounter_rate":1,"daytime":false,"exp_req_mod":1,"level_range":[13,16]},{"monster":"aardorn","encounter_rate":3,"daytime":false,"exp_req_mod":1,"level_range":[13,16]},{"monster":"katapill","encounter_rate":3,"daytime":false,"exp_req_mod":1,"level_range":[13,16]}],"environment":{"slug":"forest","battle_graphics":{"island_back":"woodland_island.png","island_front":"woodland_island.png","background":"forest_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 320 640\"\n>\n <image href=\"\/db\/maps\/Route_4.png\" \/>\n<\/svg>\n"} \ No newline at end of file
+{"requiredEncounters":10,"trainers":[{"name":"Soldier Marshall","sprite":"soldier.png","monsters":[{"slug":"puparmor","level":16},{"slug":"puparmor","level":16}]},{"name":"Rival Billie","sprite":"fashionista.png","monsters":[{"slug":"cardiwing","level":16},{"slug":"eyesore","level":16},{"slug":"viviphyta","level":16},{"slug":"STARTER","level":18}]}],"connections":{"route3":{"conditions":[],"modules\/tuxemon.slug":"route3"},"flower-city":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"flower_city"}},"modules\/tuxemon.slug":"route4","modules\/tuxemon.encounter":"route4","modules\/tuxemon.environment":"forest","encounters":[{"monster":"elofly","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[11,14],"encounter_percent":30},{"monster":"sapsnap","encounter_rate":1,"daytime":true,"exp_req_mod":1,"level_range":[12,15],"encounter_percent":10},{"monster":"aardorn","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[11,14],"encounter_percent":30},{"monster":"katapill","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[11,14],"encounter_percent":30}],"encounter_percent_total":100,"environment":{"slug":"forest","battle_graphics":{"island_back":"woodland_island.png","island_front":"woodland_island.png","background":"forest_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 320 640\"\n>\n <image href=\"\/db\/maps\/Route_4.png\" \/>\n<\/svg>\n","locations":[]} \ No newline at end of file
diff --git a/db/_generated/areas/route5.json b/db/_generated/areas/route5.json
index 47adfaf..cd816fc 100644
--- a/db/_generated/areas/route5.json
+++ b/db/_generated/areas/route5.json
@@ -1 +1 @@
-{"requiredEncounters":10,"trainers":[{"name":"Soldier Hunter","sprite":"soldier.png","monsters":[{"slug":"elofly","level":16},{"slug":"elofly","level":16},{"slug":"elowind","level":18}]}],"connections":{"flower-city":{"conditions":[],"modules\/tuxemon.slug":"flower_city"},"timber-town":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"timber_town"}},"modules\/tuxemon.slug":"route5","modules\/tuxemon.encounter":"route5","modules\/tuxemon.environment":"forest","encounters":[{"monster":"foofle","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[19,23]},{"monster":"vamporm","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[16,20]},{"monster":"dracune","encounter_rate":1,"daytime":true,"exp_req_mod":1,"level_range":[18,22]},{"monster":"anoleaf","encounter_rate":3,"daytime":false,"exp_req_mod":1,"level_range":[18,22]},{"monster":"gectile","encounter_rate":1,"daytime":false,"exp_req_mod":1,"level_range":[22,26]}],"environment":{"slug":"forest","battle_graphics":{"island_back":"woodland_island.png","island_front":"woodland_island.png","background":"forest_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 320\"\n>\n <image href=\"\/db\/maps\/Route_5.png\" \/>\n<\/svg>\n"} \ No newline at end of file
+{"requiredEncounters":10,"trainers":[{"name":"Soldier Hunter","sprite":"soldier.png","monsters":[{"slug":"elofly","level":16},{"slug":"elofly","level":16},{"slug":"elowind","level":18}]}],"connections":{"flower-city":{"conditions":[],"modules\/tuxemon.slug":"flower_city"},"timber-town":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"timber_town"}},"modules\/tuxemon.slug":"route5","modules\/tuxemon.encounter":"route5","modules\/tuxemon.environment":"forest","encounters":[{"monster":"foofle","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[19,23],"encounter_percent":27},{"monster":"vamporm","encounter_rate":3,"daytime":true,"exp_req_mod":1,"level_range":[16,20],"encounter_percent":27},{"monster":"dracune","encounter_rate":1,"daytime":true,"exp_req_mod":1,"level_range":[18,22],"encounter_percent":9},{"monster":"anoleaf","encounter_rate":3,"daytime":false,"exp_req_mod":1,"level_range":[18,22],"encounter_percent":27},{"monster":"gectile","encounter_rate":1,"daytime":false,"exp_req_mod":1,"level_range":[22,26],"encounter_percent":9}],"encounter_percent_total":99,"environment":{"slug":"forest","battle_graphics":{"island_back":"woodland_island.png","island_front":"woodland_island.png","background":"forest_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 320\"\n>\n <image href=\"\/db\/maps\/Route_5.png\" \/>\n<\/svg>\n","locations":[]} \ No newline at end of file
diff --git a/db/_generated/areas/route6.json b/db/_generated/areas/route6.json
index c30cc96..54cea72 100644
--- a/db/_generated/areas/route6.json
+++ b/db/_generated/areas/route6.json
@@ -1 +1 @@
-{"requiredEncounters":10,"trainers":[{"name":"Florist Frances","sprite":"florist.png","monsters":[{"slug":"narcileaf","level":30},{"slug":"shybulb","level":30},{"slug":"shybulb","level":30}]}],"connections":{"tunnel-b":{"conditions":[],"modules\/tuxemon.slug":"tunnel"},"candy-town":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"candy_town"}},"modules\/tuxemon.slug":"route6","modules\/tuxemon.encounter":"route6","modules\/tuxemon.environment":"forest","encounters":[{"monster":"dandicub","encounter_rate":10,"daytime":true,"exp_req_mod":1,"level_range":[19,20]},{"monster":"dandylion","encounter_rate":5,"daytime":true,"exp_req_mod":1,"level_range":[21,23]},{"monster":"capiti","encounter_rate":10,"daytime":true,"exp_req_mod":1,"level_range":[19,22]},{"monster":"dandicub","encounter_rate":10,"daytime":false,"exp_req_mod":1,"level_range":[20,24]},{"monster":"dandylion","encounter_rate":5,"daytime":false,"exp_req_mod":1,"level_range":[22,24]},{"monster":"capiti","encounter_rate":10,"daytime":false,"exp_req_mod":1,"level_range":[20,24]}],"environment":{"slug":"forest","battle_graphics":{"island_back":"woodland_island.png","island_front":"woodland_island.png","background":"forest_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 320\"\n>\n <image href=\"\/db\/maps\/Route_6.png\" \/>\n<\/svg>\n"} \ No newline at end of file
+{"requiredEncounters":10,"trainers":[{"name":"Florist Frances","sprite":"florist.png","monsters":[{"slug":"narcileaf","level":30},{"slug":"shybulb","level":30},{"slug":"shybulb","level":30}]}],"connections":{"tunnel-b":{"conditions":[],"modules\/tuxemon.slug":"tunnel"},"candy-town":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"candy_town"}},"modules\/tuxemon.slug":"route6","modules\/tuxemon.encounter":"route6","modules\/tuxemon.environment":"forest","encounters":[{"monster":"dandicub","encounter_rate":10,"daytime":true,"exp_req_mod":1,"level_range":[19,20],"encounter_percent":40},{"monster":"dandylion","encounter_rate":5,"daytime":true,"exp_req_mod":1,"level_range":[21,23],"encounter_percent":20},{"monster":"capiti","encounter_rate":10,"daytime":true,"exp_req_mod":1,"level_range":[19,22],"encounter_percent":40}],"encounter_percent_total":100,"environment":{"slug":"forest","battle_graphics":{"island_back":"woodland_island.png","island_front":"woodland_island.png","background":"forest_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 320\"\n>\n <image href=\"\/db\/maps\/Route_6.png\" \/>\n<\/svg>\n","locations":[]} \ No newline at end of file
diff --git a/db/_generated/areas/route7.json b/db/_generated/areas/route7.json
index 7f27141..4834a88 100644
--- a/db/_generated/areas/route7.json
+++ b/db/_generated/areas/route7.json
@@ -1 +1 @@
-{"requiredEncounters":10,"trainers":[{"name":"Monk Statius","sprite":"monk.png","monsters":[{"slug":"aardart","level":30},{"slug":"pairagrim","level":30},{"slug":"bolt","level":30},{"slug":"fribbit","level":30}]}],"environment_slug":"forest","connections":{"side-route-a":{"conditions":[],"modules\/tuxemon.slug":"routea"},"sphalian-town":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"sphalian_town"}},"modules\/tuxemon.slug":"route7","modules\/tuxemon.encounter":"route7","modules\/tuxemon.environment":"forest","encounters":[{"monster":"pairagrim","encounter_rate":3.5,"daytime":true,"exp_req_mod":1,"level_range":[35,40]},{"monster":"aardart","encounter_rate":3.5,"daytime":true,"exp_req_mod":1,"level_range":[35,40]},{"monster":"weavifly","encounter_rate":3.5,"daytime":true,"exp_req_mod":1,"level_range":[35,40]},{"monster":"pantherafira","encounter_rate":3.5,"daytime":false,"exp_req_mod":1,"level_range":[35,40]},{"monster":"flacono","encounter_rate":3.5,"daytime":false,"exp_req_mod":1,"level_range":[35,40]},{"monster":"slichen","encounter_rate":3.5,"daytime":false,"exp_req_mod":1,"level_range":[35,40]}],"environment":{"slug":"forest","battle_graphics":{"island_back":"woodland_island.png","island_front":"woodland_island.png","background":"forest_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 640\"\n>\n <image href=\"\/db\/maps\/Route_7.png\" \/>\n<\/svg>\n"} \ No newline at end of file
+{"requiredEncounters":10,"trainers":[{"name":"Monk Statius","sprite":"monk.png","monsters":[{"slug":"aardart","level":30},{"slug":"pairagrim","level":30},{"slug":"bolt","level":30},{"slug":"fribbit","level":30}]}],"environment_slug":"forest","connections":{"side-route-a":{"conditions":[],"modules\/tuxemon.slug":"routea"},"sphalian-town":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"sphalian_town"}},"modules\/tuxemon.slug":"route7","modules\/tuxemon.encounter":"route7","modules\/tuxemon.environment":"forest","encounters":[{"monster":"pairagrim","encounter_rate":3.5,"daytime":true,"exp_req_mod":1,"level_range":[35,40],"encounter_percent":16},{"monster":"aardart","encounter_rate":3.5,"daytime":true,"exp_req_mod":1,"level_range":[35,40],"encounter_percent":16},{"monster":"weavifly","encounter_rate":3.5,"daytime":true,"exp_req_mod":1,"level_range":[35,40],"encounter_percent":16},{"monster":"pantherafira","encounter_rate":3.5,"daytime":false,"exp_req_mod":1,"level_range":[35,40],"encounter_percent":16},{"monster":"flacono","encounter_rate":3.5,"daytime":false,"exp_req_mod":1,"level_range":[35,40],"encounter_percent":16},{"monster":"slichen","encounter_rate":3.5,"daytime":false,"exp_req_mod":1,"level_range":[35,40],"encounter_percent":16}],"encounter_percent_total":96,"environment":{"slug":"forest","battle_graphics":{"island_back":"woodland_island.png","island_front":"woodland_island.png","background":"forest_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 640\"\n>\n <image href=\"\/db\/maps\/Route_7.png\" \/>\n<\/svg>\n","locations":[]} \ No newline at end of file
diff --git a/db/_generated/areas/sea-route-c.json b/db/_generated/areas/sea-route-c.json
index 4b83f12..31c1883 100644
--- a/db/_generated/areas/sea-route-c.json
+++ b/db/_generated/areas/sea-route-c.json
@@ -1 +1 @@
-{"requiredEncounters":10,"trainers":[{"name":"Dragonrider Nigel","sprite":"dragonrider.png","monsters":[{"slug":"agnigon","level":36}]}],"environment_slug":"sea","connections":{"candy-town":{"conditions":[],"modules\/tuxemon.slug":"candy_town"},"paper-town":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"paper_town"}},"modules\/tuxemon.slug":"routec","modules\/tuxemon.encounter":"default_encounter","modules\/tuxemon.environment":"sea","encounters":[{"encounter_rate":0.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"monster":"eyenemy"},{"encounter_rate":0.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"monster":"dandicub"},{"encounter_rate":0.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"monster":"cardiling"},{"encounter_rate":0.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"monster":"budaye"},{"encounter_rate":0.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"monster":"cataspike"},{"encounter_rate":0.5,"daytime":false,"exp_req_mod":1,"level_range":[3,6],"monster":"elofly"},{"encounter_rate":0.5,"daytime":false,"exp_req_mod":1,"level_range":[3,6],"monster":"aardorn"},{"encounter_rate":0.5,"daytime":false,"exp_req_mod":1,"level_range":[3,6],"monster":"nut"},{"encounter_rate":0.5,"daytime":false,"exp_req_mod":1,"level_range":[3,6],"monster":"grimachin"},{"encounter_rate":0.5,"daytime":false,"exp_req_mod":1,"level_range":[3,6],"monster":"spighter"}],"environment":{"slug":"sea","battle_graphics":{"island_back":"water_island.png","island_front":"water_island.png","background":"sea_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 640\"\n>\n <image href=\"\/db\/maps\/Sea_Route_C.png\" \/>\n<\/svg>\n"} \ No newline at end of file
+{"requiredEncounters":10,"encounters":[{"monster":"dollfin","encounter_percent":5,"level_range":[2,5]},{"encounter_rate":0.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"monster":"eyenemy","encounter_percent":10},{"encounter_rate":0.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"monster":"dandicub","encounter_percent":10},{"encounter_rate":0.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"monster":"cardiling","encounter_percent":10},{"encounter_rate":0.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"monster":"budaye","encounter_percent":10},{"encounter_rate":0.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"monster":"cataspike","encounter_percent":10},{"encounter_rate":0.5,"daytime":false,"exp_req_mod":1,"level_range":[3,6],"monster":"elofly","encounter_percent":10},{"encounter_rate":0.5,"daytime":false,"exp_req_mod":1,"level_range":[3,6],"monster":"aardorn","encounter_percent":10},{"encounter_rate":0.5,"daytime":false,"exp_req_mod":1,"level_range":[3,6],"monster":"nut","encounter_percent":10},{"encounter_rate":0.5,"daytime":false,"exp_req_mod":1,"level_range":[3,6],"monster":"grimachin","encounter_percent":10},{"encounter_rate":0.5,"daytime":false,"exp_req_mod":1,"level_range":[3,6],"monster":"spighter","encounter_percent":10}],"trainers":[{"name":"Dragonrider Nigel","sprite":"dragonrider.png","monsters":[{"slug":"agnigon","level":36}]}],"environment_slug":"sea","connections":{"candy-town":{"conditions":[],"modules\/tuxemon.slug":"candy_town"},"paper-town":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"paper_town"}},"modules\/tuxemon.slug":"routec","modules\/tuxemon.encounter":"default_encounter","modules\/tuxemon.environment":"sea","encounter_percent_total":105,"environment":{"slug":"sea","battle_graphics":{"island_back":"water_island.png","island_front":"water_island.png","background":"sea_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 640 640\"\n>\n <image href=\"\/db\/maps\/Sea_Route_C.png\" \/>\n<\/svg>\n","locations":[]} \ No newline at end of file
diff --git a/db/_generated/areas/side-route-a.json b/db/_generated/areas/side-route-a.json
index 55b246e..1c844eb 100644
--- a/db/_generated/areas/side-route-a.json
+++ b/db/_generated/areas/side-route-a.json
@@ -1 +1 @@
-{"requiredEncounters":10,"trainers":[{"name":"Rival Billie","sprite":"fashionista.png","monsters":[{"slug":"cardiwing","level":17},{"slug":"eyesore","level":17},{"slug":"viviphyta","level":17},{"slug":"STARTER","level":20}]}],"environment_slug":"forest","connections":{"flower-city":{"conditions":[],"modules\/tuxemon.slug":"flower_city"},"route7":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"route7"}},"modules\/tuxemon.slug":"routea","modules\/tuxemon.encounter":"default_encounter","modules\/tuxemon.environment":"forest","encounters":[{"encounter_rate":0.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"monster":"eyenemy"},{"encounter_rate":0.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"monster":"dandicub"},{"encounter_rate":0.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"monster":"cardiling"},{"encounter_rate":0.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"monster":"budaye"},{"encounter_rate":0.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"monster":"cataspike"},{"encounter_rate":0.5,"daytime":false,"exp_req_mod":1,"level_range":[3,6],"monster":"elofly"},{"encounter_rate":0.5,"daytime":false,"exp_req_mod":1,"level_range":[3,6],"monster":"aardorn"},{"encounter_rate":0.5,"daytime":false,"exp_req_mod":1,"level_range":[3,6],"monster":"nut"},{"encounter_rate":0.5,"daytime":false,"exp_req_mod":1,"level_range":[3,6],"monster":"grimachin"},{"encounter_rate":0.5,"daytime":false,"exp_req_mod":1,"level_range":[3,6],"monster":"spighter"}],"environment":{"slug":"forest","battle_graphics":{"island_back":"woodland_island.png","island_front":"woodland_island.png","background":"forest_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 320 640\"\n>\n <image href=\"\/db\/maps\/Side_Route_A.png\" \/>\n<\/svg>\n"} \ No newline at end of file
+{"requiredEncounters":10,"encounters":[{"monster":"shybulb","encounter_percent":25,"level_range":[12,14]},{"monster":"katapill","encounter_percent":25,"level_range":[12,14]},{"monster":"vamporm","encounter_percent":25,"level_range":[12,14]},{"monster":"anoleaf","encounter_percent":25,"level_range":[12,14]}],"trainers":[{"name":"Rival Billie","sprite":"fashionista.png","monsters":[{"slug":"cardiwing","level":17},{"slug":"eyesore","level":17},{"slug":"viviphyta","level":17},{"slug":"STARTER","level":20}]}],"connections":{"flower-city":{"conditions":[],"modules\/tuxemon.slug":"flower_city"},"mansion":{"conditions":["encounters"],"modules\/tuxemon.slug":"mansion"},"route7":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"route7"}},"modules\/tuxemon.slug":"routea","modules\/tuxemon.encounter":"","modules\/tuxemon.environment":"forest","encounter_percent_total":100,"environment":{"slug":"forest","battle_graphics":{"island_back":"woodland_island.png","island_front":"woodland_island.png","background":"forest_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 320 640\"\n>\n <image href=\"\/db\/maps\/Side_Route_A.png\" \/>\n<\/svg>\n","locations":[]} \ No newline at end of file
diff --git a/db/_generated/areas/tunnel-b-underground.json b/db/_generated/areas/tunnel-b-underground.json
new file mode 100644
index 0000000..e41f1c0
--- /dev/null
+++ b/db/_generated/areas/tunnel-b-underground.json
@@ -0,0 +1 @@
+{"requiredEncounters":10,"encounters":[{"monster":"grintot","encounter_percent":5,"level_range":[2,5]},{"monster":"ignibus","encounter_percent":2,"level_range":[2,5]},{"monster":"toufigel","encounter_percent":20,"level_range":[15,18]},{"monster":"pipis","encounter_percent":30,"level_range":[15,16]},{"monster":"strella","encounter_percent":10,"level_range":[18,20]},{"monster":"noctula","encounter_percent":30,"level_range":[15,16]},{"monster":"noctalo","encounter_percent":10,"level_range":[18,20]},{"monster":"cairfrey","encounter_percent":20,"level_range":[15,18]},{"monster":"possessun","encounter_percent":10,"level_range":[18,20]},{"monster":"rockitten","encounter_percent":20,"level_range":[15,18]}],"trainers":[{"name":"Scientist Beryll","sprite":"scientist.png","monsters":[{"slug":"rockat","level":20},{"slug":"ignibus","level":20},{"slug":"grintot","level":20}]},{"name":"Scientist Lute","sprite":"scientist.png","monsters":[{"slug":"noctula","level":16},{"slug":"noctalo","level":18},{"slug":"pipis","level":16},{"slug":"strella","level":20}]},{"name":"Scientist Meitner","sprite":"scientist.png","monsters":[{"slug":"masknake","level":22}]}],"connections":{"tunnel-b":{"conditions":[],"modules\/tuxemon.slug":"tunnel"}},"modules\/tuxemon.slug":"tunnel-underground","modules\/tuxemon.encounter":"","modules\/tuxemon.environment":"cavern","encounter_percent_total":157,"environment":{"slug":"cavern","battle_graphics":{"island_back":"cave_island.png","island_front":"cave_island.png","background":"cavern_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 320 640\"\n>\n <image href=\"\/db\/maps\/Tunnel_Route_B_-_Below.png\" \/>\n<\/svg>\n","locations":[]} \ No newline at end of file
diff --git a/db/_generated/areas/tunnel-b.json b/db/_generated/areas/tunnel-b.json
index ddf7e85..b2a082e 100644
--- a/db/_generated/areas/tunnel-b.json
+++ b/db/_generated/areas/tunnel-b.json
@@ -1 +1 @@
-{"requiredEncounters":10,"trainers":[{"name":"Florist Iris","sprite":"florist.png","monsters":[{"slug":"tourbidi","level":18},{"slug":"tourbidi","level":18},{"slug":"tourbidi","level":18}]}],"environment_slug":"forest","connections":{"timber-town":{"conditions":[],"modules\/tuxemon.slug":"timber_town"},"route6":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"route6"}},"modules\/tuxemon.slug":"tunnel","modules\/tuxemon.encounter":"default_encounter","modules\/tuxemon.environment":"forest","encounters":[{"encounter_rate":0.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"monster":"eyenemy"},{"encounter_rate":0.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"monster":"dandicub"},{"encounter_rate":0.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"monster":"cardiling"},{"encounter_rate":0.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"monster":"budaye"},{"encounter_rate":0.5,"daytime":true,"exp_req_mod":1,"level_range":[2,4],"monster":"cataspike"},{"encounter_rate":0.5,"daytime":false,"exp_req_mod":1,"level_range":[3,6],"monster":"elofly"},{"encounter_rate":0.5,"daytime":false,"exp_req_mod":1,"level_range":[3,6],"monster":"aardorn"},{"encounter_rate":0.5,"daytime":false,"exp_req_mod":1,"level_range":[3,6],"monster":"nut"},{"encounter_rate":0.5,"daytime":false,"exp_req_mod":1,"level_range":[3,6],"monster":"grimachin"},{"encounter_rate":0.5,"daytime":false,"exp_req_mod":1,"level_range":[3,6],"monster":"spighter"}],"environment":{"slug":"forest","battle_graphics":{"island_back":"woodland_island.png","island_front":"woodland_island.png","background":"forest_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 320 640\"\n>\n <image href=\"\/db\/maps\/Tunnel_Route_B.png\" \/>\n<\/svg>\n"} \ No newline at end of file
+{"requiredEncounters":10,"encounters":[{"monster":"tourbidi","encounter_percent":50,"level_range":[12,18]},{"monster":"capiti","encounter_percent":15,"level_range":[15,16]},{"monster":"dandicub","encounter_percent":15,"level_range":[15,16]},{"monster":"toufigel","encounter_percent":10,"level_range":[15,18]},{"monster":"rockitten","encounter_percent":10,"level_range":[15,18]}],"trainers":[{"name":"Florist Iris","sprite":"florist.png","monsters":[{"slug":"tourbidi","level":18},{"slug":"tourbidi","level":18},{"slug":"tourbidi","level":18}]},{"name":"Picnicker Greta","sprite":"picnicker.png","monsters":[{"slug":"foofle","level":16},{"slug":"foofle","level":16},{"slug":"foofle","level":16},{"slug":"foofle","level":16},{"slug":"foofle","level":16},{"slug":"foofle","level":16}]},{"name":"Yellow Belt Tommy","sprite":"yellowbelt.png","monsters":[{"slug":"zunna","level":22}]}],"connections":{"timber-town":{"conditions":[],"modules\/tuxemon.slug":"timber_town"},"tunnel-b-underground":{"conditions":[],"modules\/tuxemon.slug":"tunnel-underground"},"route6":{"conditions":["encounters","trainers"],"modules\/tuxemon.slug":"route6"}},"modules\/tuxemon.slug":"tunnel","modules\/tuxemon.encounter":"","modules\/tuxemon.environment":"grass","encounter_percent_total":100,"environment":{"slug":"grass","battle_graphics":{"island_back":"grass_island.png","island_front":"grass_island.png","background":"grass_background.png"},"battle_music":"music_battle_loop"},"map":"<svg\n version=\"1.1\"\n xmlns=\"http:\/\/www.w3.org\/2000\/svg\"\n viewbox=\"0 0 320 640\"\n>\n <image href=\"\/db\/maps\/Tunnel_Route_B.png\" \/>\n<\/svg>\n","locations":[]} \ No newline at end of file
diff --git a/db/areas.php b/db/areas.php
index c1d97e0..d2c9af9 100644
--- a/db/areas.php
+++ b/db/areas.php
@@ -7,14 +7,33 @@ foreach (scandir(__DIR__ . '/areas') as $file) {
$fileName = pathinfo($file, PATHINFO_FILENAME);
$area = json_decode(file_get_contents($filePath), true);
+
$encounterSlug = $area['modules/tuxemon.encounter'] ?? '';
- $environmentSlug = $area['modules/tuxemon.environment'] ?? '';
$encounters = json_decode(@file_get_contents(dirname(__DIR__) . "/modules/tuxemon/mods/tuxemon/db/encounter/$encounterSlug.json") ?? '', true);
+
+ $environmentSlug = $area['modules/tuxemon.environment'] ?? '';
$environment = json_decode(@file_get_contents(dirname(__DIR__) . "/modules/tuxemon/mods/tuxemon/db/environment/$environmentSlug.json") ?? '', true);
+
$map = @file_get_contents(__DIR__ . "/maps/$fileName.svg");
$area['encounters'] ??= [];
array_push($area['encounters'], ...$encounters['monsters'] ?? []);
+ if (! empty($area['encounters'])) {
+ // filter out duplicates, because day/night is ignored for now
+ $duplicates = [];
+ $area['encounters'] = array_values(array_filter($area['encounters'], function ($item) use (&$duplicates) {
+ $isNotDuplicate = ! in_array($item['monster'], $duplicates);
+ $duplicates[] = $item['monster'];
+ return $isNotDuplicate;
+ }));
+
+ $encounterRateTotal = array_sum(array_column($area['encounters'], 'encounter_rate'));
+ foreach ($area['encounters'] as &$encounter) {
+ if (empty($encounter['encounter_rate'])) continue;
+ $encounter['encounter_percent'] = intval(100 / ($encounterRateTotal / $encounter['encounter_rate']));
+ }
+ $area['encounter_percent_total'] = array_sum(array_column($area['encounters'], 'encounter_percent'));
+ }
$area['requiredEncounters'] ??= 0;
$area['trainers'] ??= [];
@@ -23,10 +42,11 @@ foreach (scandir(__DIR__ . '/areas') as $file) {
$area['map'] = $map;
foreach ($area['connections'] as $areaSlug => $connection) {
- $area['connections'][$areaSlug]['modules/tuxemon.slug'] = json_decode(file_get_contents(__DIR__ . "/areas/$areaSlug.json"), true)['modules/tuxemon.slug'];
+ $area['connections'][$areaSlug]['modules/tuxemon.slug'] = json_decode(@file_get_contents(__DIR__ . "/areas/$areaSlug.json") ?? '', true)['modules/tuxemon.slug'] ?? '';
}
- foreach ($area['locations'] ?? [] as $locationId => $location) {
+ $area['locations'] ??= [];
+ foreach ($area['locations'] as $locationId => $location) {
if ($location['type'] == 'shop') {
$economySlug = $location['modules/tuxemon.economy'];
$scoop = json_decode(file_get_contents(dirname(__DIR__) . "/modules/tuxemon/mods/tuxemon/db/economy/$economySlug.json"), true);
diff --git a/db/areas/candy-town.json b/db/areas/candy-town.json
index f89370b..abdd488 100644
--- a/db/areas/candy-town.json
+++ b/db/areas/candy-town.json
@@ -1,10 +1,5 @@
{
"locations": {
- "hospital": {
- "type": "healingCenter",
- "price": 30
- },
-
"scoop_store": {
"type": "shop",
"items": [],
diff --git a/db/areas/city-park.json b/db/areas/city-park.json
index 3579342..802018c 100644
--- a/db/areas/city-park.json
+++ b/db/areas/city-park.json
@@ -1,6 +1,17 @@
{
"requiredEncounters": 10,
+ "encounters": [
+ {
+ "monster": "budaye",
+ "encounter_percent": 5,
+ "level_range": [
+ 2,
+ 5
+ ]
+ }
+ ],
+
"trainers": [
{
"name": "Frances",
diff --git a/db/areas/cotton-town.json b/db/areas/cotton-town.json
index cd83eae..6c55b07 100644
--- a/db/areas/cotton-town.json
+++ b/db/areas/cotton-town.json
@@ -11,10 +11,6 @@
}
},
- "events": {
- "dryads-grove": false
- },
-
"connections": {
"route1": {
"conditions": []
@@ -26,7 +22,7 @@
"dryads-grove": {
"conditions": [
- "event.dryads-grove"
+ "area.hospital-floor-3.complete"
]
}
},
diff --git a/db/areas/dryads-grove.json b/db/areas/dryads-grove.json
index 0842384..25d5326 100644
--- a/db/areas/dryads-grove.json
+++ b/db/areas/dryads-grove.json
@@ -1,5 +1,104 @@
{
- "connections": {},
+ "trainers": [
+ {
+ "name": "Water Nymph",
+ "sprite": "waternymph.png",
+ "monsters": [
+ {
+ "slug": "noctalo",
+ "level": 50
+ },
+ {
+ "slug": "nudimind",
+ "level": 50
+ },
+ {
+ "slug": "vivisource",
+ "level": 50
+ }
+ ]
+ },
+ {
+ "name": "Fire Nymph",
+ "sprite": "firenymph.png",
+ "monsters": [
+ {
+ "slug": "criniotherme",
+ "level": 50
+ },
+ {
+ "slug": "masknake",
+ "level": 50
+ },
+ {
+ "slug": "vivicinder",
+ "level": 50
+ }
+ ]
+ },
+ {
+ "name": "Earth Nymph",
+ "sprite": "earthnymph.png",
+ "monsters": [
+ {
+ "slug": "exapode",
+ "level": 50
+ },
+ {
+ "slug": "sumchon",
+ "level": 50
+ },
+ {
+ "slug": "vividactil",
+ "level": 50
+ }
+ ]
+ },
+ {
+ "name": "Metal Nymph",
+ "sprite": "metalnymph.png",
+ "monsters": [
+ {
+ "slug": "araignee",
+ "level": 50
+ },
+ {
+ "slug": "allagon",
+ "level": 50
+ },
+ {
+ "slug": "viviteel",
+ "level": 50
+ }
+ ]
+ },
+ {
+ "name": "Wood Nymph",
+ "sprite": "woodnymph.png",
+ "monsters": [
+ {
+ "slug": "narcileaf",
+ "level": 50
+ },
+ {
+ "slug": "dandylion",
+ "level": 50
+ },
+ {
+ "slug": "viviphyta",
+ "level": 50
+ }
+ ]
+ }
+ ],
- "modules/tuxemon.slug": "dryadsgrove"
+ "connections": {
+ "cotton-town": {
+ "conditions": []
+ }
+ },
+
+ "modules/tuxemon.slug": "dryadsgrove",
+ "modules/tuxemon.encounter": "dryadsgrove",
+ "modules/tuxemon.environment": "forest"
}
diff --git a/db/areas/hospital-floor-1.json b/db/areas/hospital-floor-1.json
new file mode 100644
index 0000000..f89e5a3
--- /dev/null
+++ b/db/areas/hospital-floor-1.json
@@ -0,0 +1,29 @@
+{
+ "trainers": [
+ {
+ "name": "Spyder Boss Aurora",
+ "sprite": "spyder_boss.png",
+ "monsters": [
+ {
+ "slug": "exclawvate",
+ "level": 40
+ }
+ ]
+ }
+ ],
+
+ "connections": {
+ "hospital": {
+ "conditions": []
+ },
+
+ "hospital-floor-2": {
+ "conditions": [
+ "trainers"
+ ]
+ }
+ },
+
+ "modules/tuxemon.slug": "hospital1",
+ "modules/tuxemon.environment": "interior"
+}
diff --git a/db/areas/hospital-floor-2.json b/db/areas/hospital-floor-2.json
new file mode 100644
index 0000000..2e6fc42
--- /dev/null
+++ b/db/areas/hospital-floor-2.json
@@ -0,0 +1,47 @@
+{
+ "trainers": [
+ {
+ "name": "Spyder Boss Luzia",
+ "sprite": "spyder_boss.png",
+ "monsters": [
+ {
+ "slug": "galnec",
+ "level": 36
+ },
+ {
+ "slug": "exclawvate",
+ "level": 36
+ }
+ ]
+ },
+ {
+ "name": "Profressor Rhizome",
+ "sprite": "professor.png",
+ "monsters": [
+ {
+ "slug": "flacono",
+ "level": 33
+ },
+ {
+ "slug": "fancair",
+ "level": 33
+ }
+ ]
+ }
+ ],
+
+ "connections": {
+ "hospital-floor-1": {
+ "conditions": []
+ },
+
+ "hospital-floor-3": {
+ "conditions": [
+ "trainers"
+ ]
+ }
+ },
+
+ "modules/tuxemon.slug": "hospital2",
+ "modules/tuxemon.environment": "interior"
+}
diff --git a/db/areas/hospital-floor-3.json b/db/areas/hospital-floor-3.json
new file mode 100644
index 0000000..de16bc2
--- /dev/null
+++ b/db/areas/hospital-floor-3.json
@@ -0,0 +1,35 @@
+{
+ "trainers": [
+ {
+ "name": "Rival Billie",
+ "sprite": "fashionista.png",
+ "monsters": [
+ {
+ "slug": "cardinale",
+ "level": 40
+ },
+ {
+ "slug": "eyesore",
+ "level": 40
+ },
+ {
+ "slug": "viviphyta",
+ "level": 40
+ },
+ {
+ "slug": "STARTER",
+ "level": 40
+ }
+ ]
+ }
+ ],
+
+ "connections": {
+ "hospital-floor-2": {
+ "conditions": []
+ }
+ },
+
+ "modules/tuxemon.slug": "hospital3",
+ "modules/tuxemon.environment": "interior"
+}
diff --git a/db/areas/hospital.json b/db/areas/hospital.json
new file mode 100644
index 0000000..0617d78
--- /dev/null
+++ b/db/areas/hospital.json
@@ -0,0 +1,20 @@
+{
+ "locations": {
+ "hospital": {
+ "type": "healingCenter",
+ "price": 30
+ }
+ },
+
+ "connections": {
+ "candy-town": {
+ "conditions": []
+ },
+
+ "hospital-floor-1": {
+ "conditions": []
+ }
+ },
+
+ "modules/tuxemon.slug": "hospital"
+}
diff --git a/db/areas/lion-mountain.json b/db/areas/lion-mountain.json
index e1b5081..c187d2f 100644
--- a/db/areas/lion-mountain.json
+++ b/db/areas/lion-mountain.json
@@ -15,6 +15,34 @@
"level": 60
}
]
+ },
+ {
+ "name": "Bruder Mikki",
+ "sprite": "adventurer.png",
+ "monsters": [
+ {
+ "slug": "miaownolith",
+ "level": 75
+ },
+ {
+ "slug": "pyraminx",
+ "level": 76
+ },
+ {
+ "slug": "mauai",
+ "level": 77
+ },
+ {
+ "slug": "jelillow",
+ "level": 80
+ }
+ ],
+ "inventory": [
+ {
+ "slug": "super_potion",
+ "quantity": 4
+ }
+ ]
}
],
diff --git a/db/areas/mansion-basement.json b/db/areas/mansion-basement.json
new file mode 100644
index 0000000..1a90497
--- /dev/null
+++ b/db/areas/mansion-basement.json
@@ -0,0 +1,41 @@
+{
+ "requiredEncounters": 10,
+
+ "encounters": [
+ {
+ "monster": "ignibus",
+ "encounter_percent": 5,
+ "level_range": [
+ 2,
+ 5
+ ]
+ }
+ ],
+
+ "trainers": [
+ {
+ "name": "Dancer Coralli",
+ "sprite": "dancer.png",
+ "monsters": [
+ {
+ "slug": "tumbleworm",
+ "level": 22
+ },
+ {
+ "slug": "elofly",
+ "level": 22
+ }
+ ]
+ }
+ ],
+
+ "connections": {
+ "mansion": {
+ "conditions": []
+ }
+ },
+
+ "modules/tuxemon.slug": "mansion_basement",
+ "modules/tuxemon.encounter": "mansion",
+ "modules/tuxemon.environment": "cave"
+}
diff --git a/db/areas/mansion-top-floor.json b/db/areas/mansion-top-floor.json
new file mode 100644
index 0000000..02bf87e
--- /dev/null
+++ b/db/areas/mansion-top-floor.json
@@ -0,0 +1,73 @@
+{
+ "requiredEncounters": 10,
+
+ "encounters": [
+ {
+ "monster": "memnomnom",
+ "encounter_percent": 5,
+ "level_range": [
+ 2,
+ 5
+ ]
+ }
+ ],
+
+ "trainers": [
+ {
+ "name": "Mage Russell",
+ "sprite": "mage.png",
+ "monsters": [
+ {
+ "slug": "av8r",
+ "level": 22
+ },
+ {
+ "slug": "mrmoswitch",
+ "level": 22
+ },
+ {
+ "slug": "k9",
+ "level": 22
+ }
+ ]
+ },
+ {
+ "name": "Bruder Mikki",
+ "sprite": "adventurer.png",
+ "monsters": [
+ {
+ "slug": "memnomnom",
+ "level": 25
+ },
+ {
+ "slug": "memnomnom",
+ "level": 26
+ },
+ {
+ "slug": "memnomnom",
+ "level": 27
+ },
+ {
+ "slug": "jelillow",
+ "level": 30
+ }
+ ],
+ "inventory": [
+ {
+ "slug": "super_potion",
+ "quantity": 2
+ }
+ ]
+ }
+ ],
+
+ "connections": {
+ "mansion": {
+ "conditions": []
+ }
+ },
+
+ "modules/tuxemon.slug": "mansion_top_floor",
+ "modules/tuxemon.encounter": "mansion",
+ "modules/tuxemon.environment": "cave"
+}
diff --git a/db/areas/mansion.json b/db/areas/mansion.json
new file mode 100644
index 0000000..82de65a
--- /dev/null
+++ b/db/areas/mansion.json
@@ -0,0 +1,42 @@
+{
+ "requiredEncounters": 10,
+
+ "trainers": [
+ {
+ "name": "Magician Gillette",
+ "sprite": "magician.png",
+ "monsters": [
+ {
+ "slug": "djinnbo",
+ "level": 22
+ },
+ {
+ "slug": "ghosteeth",
+ "level": 22
+ }
+ ]
+ }
+ ],
+
+ "connections": {
+ "side-route-a": {
+ "conditions": []
+ },
+
+ "mansion-top-floor": {
+ "conditions": [
+ "area.mansion-basement.completed"
+ ]
+ },
+
+ "mansion-basement": {
+ "conditions": [
+ "area.mansion-basement"
+ ]
+ }
+ },
+
+ "modules/tuxemon.slug": "mansion",
+ "modules/tuxemon.encounter": "mansion",
+ "modules/tuxemon.environment": "cave"
+}
diff --git a/db/areas/paper-town.json b/db/areas/paper-town.json
index cc897b9..9b487e3 100644
--- a/db/areas/paper-town.json
+++ b/db/areas/paper-town.json
@@ -22,7 +22,7 @@
"sea-route-c": {
"conditions": [
- "area.sea-route-c"
+ "area.sea-route-c.completed"
]
}
},
diff --git a/db/areas/sea-route-c.json b/db/areas/sea-route-c.json
index e6082db..bba5858 100644
--- a/db/areas/sea-route-c.json
+++ b/db/areas/sea-route-c.json
@@ -1,6 +1,17 @@
{
"requiredEncounters": 10,
+ "encounters": [
+ {
+ "monster": "dollfin",
+ "encounter_percent": 5,
+ "level_range": [
+ 2,
+ 5
+ ]
+ }
+ ],
+
"trainers": [
{
"name": "Dragonrider Nigel",
diff --git a/db/areas/side-route-a.json b/db/areas/side-route-a.json
index 78514b8..7d2d621 100644
--- a/db/areas/side-route-a.json
+++ b/db/areas/side-route-a.json
@@ -1,6 +1,41 @@
{
"requiredEncounters": 10,
+ "encounters": [
+ {
+ "monster": "shybulb",
+ "encounter_percent": 25,
+ "level_range": [
+ 12,
+ 14
+ ]
+ },
+ {
+ "monster": "katapill",
+ "encounter_percent": 25,
+ "level_range": [
+ 12,
+ 14
+ ]
+ },
+ {
+ "monster": "vamporm",
+ "encounter_percent": 25,
+ "level_range": [
+ 12,
+ 14
+ ]
+ },
+ {
+ "monster": "anoleaf",
+ "encounter_percent": 25,
+ "level_range": [
+ 12,
+ 14
+ ]
+ }
+ ],
+
"trainers": [
{
"name": "Rival Billie",
@@ -26,13 +61,17 @@
}
],
- "environment_slug": "forest",
-
"connections": {
"flower-city": {
"conditions": []
},
+ "mansion": {
+ "conditions": [
+ "encounters"
+ ]
+ },
+
"route7": {
"conditions": [
"encounters",
@@ -42,6 +81,6 @@
},
"modules/tuxemon.slug": "routea",
- "modules/tuxemon.encounter": "default_encounter",
+ "modules/tuxemon.encounter": "",
"modules/tuxemon.environment": "forest"
}
diff --git a/db/areas/tunnel-b-underground.json b/db/areas/tunnel-b-underground.json
new file mode 100644
index 0000000..907cb09
--- /dev/null
+++ b/db/areas/tunnel-b-underground.json
@@ -0,0 +1,151 @@
+{
+ "requiredEncounters": 10,
+
+ "encounters": [
+ {
+ "monster": "grintot",
+ "encounter_percent": 5,
+ "level_range": [
+ 2,
+ 5
+ ]
+ },
+ {
+ "monster": "ignibus",
+ "encounter_percent": 2,
+ "level_range": [
+ 2,
+ 5
+ ]
+ },
+
+
+ {
+ "monster": "toufigel",
+ "encounter_percent": 20,
+ "level_range": [
+ 15,
+ 18
+ ]
+ },
+ {
+ "monster": "pipis",
+ "encounter_percent": 30,
+ "level_range": [
+ 15,
+ 16
+ ]
+ },
+ {
+ "monster": "strella",
+ "encounter_percent": 10,
+ "level_range": [
+ 18,
+ 20
+ ]
+ },
+ {
+ "monster": "noctula",
+ "encounter_percent": 30,
+ "level_range": [
+ 15,
+ 16
+ ]
+ },
+ {
+ "monster": "noctalo",
+ "encounter_percent": 10,
+ "level_range": [
+ 18,
+ 20
+ ]
+ },
+ {
+ "monster": "cairfrey",
+ "encounter_percent": 20,
+ "level_range": [
+ 15,
+ 18
+ ]
+ },
+ {
+ "monster": "possessun",
+ "encounter_percent": 10,
+ "level_range": [
+ 18,
+ 20
+ ]
+ },
+ {
+ "monster": "rockitten",
+ "encounter_percent": 20,
+ "level_range": [
+ 15,
+ 18
+ ]
+ }
+ ],
+
+ "trainers": [
+ {
+ "name": "Scientist Beryll",
+ "sprite": "scientist.png",
+ "monsters": [
+ {
+ "slug": "rockat",
+ "level": 20
+ },
+ {
+ "slug": "ignibus",
+ "level": 20
+ },
+ {
+ "slug": "grintot",
+ "level": 20
+ }
+ ]
+ },
+ {
+ "name": "Scientist Lute",
+ "sprite": "scientist.png",
+ "monsters": [
+ {
+ "slug": "noctula",
+ "level": 16
+ },
+ {
+ "slug": "noctalo",
+ "level": 18
+ },
+ {
+ "slug": "pipis",
+ "level": 16
+ },
+ {
+ "slug": "strella",
+ "level": 20
+ }
+ ]
+ },
+ {
+ "name": "Scientist Meitner",
+ "sprite": "scientist.png",
+ "monsters": [
+ {
+ "slug": "masknake",
+ "level": 22
+ }
+ ]
+ }
+ ],
+
+ "connections": {
+ "tunnel-b": {
+ "conditions": []
+ }
+ },
+
+ "modules/tuxemon.slug": "tunnel-underground",
+ "modules/tuxemon.encounter": "",
+ "modules/tuxemon.environment": "cavern"
+}
diff --git a/db/areas/tunnel-b.json b/db/areas/tunnel-b.json
index be85c96..e125c05 100644
--- a/db/areas/tunnel-b.json
+++ b/db/areas/tunnel-b.json
@@ -1,6 +1,49 @@
{
"requiredEncounters": 10,
+ "encounters": [
+ {
+ "monster": "tourbidi",
+ "encounter_percent": 50,
+ "level_range": [
+ 12,
+ 18
+ ]
+ },
+ {
+ "monster": "capiti",
+ "encounter_percent": 15,
+ "level_range": [
+ 15,
+ 16
+ ]
+ },
+ {
+ "monster": "dandicub",
+ "encounter_percent": 15,
+ "level_range": [
+ 15,
+ 16
+ ]
+ },
+ {
+ "monster": "toufigel",
+ "encounter_percent": 10,
+ "level_range": [
+ 15,
+ 18
+ ]
+ },
+ {
+ "monster": "rockitten",
+ "encounter_percent": 10,
+ "level_range": [
+ 15,
+ 18
+ ]
+ }
+ ],
+
"trainers": [
{
"name": "Florist Iris",
@@ -19,16 +62,58 @@
"level": 18
}
]
+ },
+ {
+ "name": "Picnicker Greta",
+ "sprite": "picnicker.png",
+ "monsters": [
+ {
+ "slug": "foofle",
+ "level": 16
+ },
+ {
+ "slug": "foofle",
+ "level": 16
+ },
+ {
+ "slug": "foofle",
+ "level": 16
+ },
+ {
+ "slug": "foofle",
+ "level": 16
+ },
+ {
+ "slug": "foofle",
+ "level": 16
+ },
+ {
+ "slug": "foofle",
+ "level": 16
+ }
+ ]
+ },
+ {
+ "name": "Yellow Belt Tommy",
+ "sprite": "yellowbelt.png",
+ "monsters": [
+ {
+ "slug": "zunna",
+ "level": 22
+ }
+ ]
}
],
- "environment_slug": "forest",
-
"connections": {
"timber-town": {
"conditions": []
},
+ "tunnel-b-underground": {
+ "conditions": []
+ },
+
"route6": {
"conditions": [
"encounters",
@@ -38,6 +123,6 @@
},
"modules/tuxemon.slug": "tunnel",
- "modules/tuxemon.encounter": "default_encounter",
- "modules/tuxemon.environment": "forest"
+ "modules/tuxemon.encounter": "",
+ "modules/tuxemon.environment": "grass"
}
diff --git a/db/maps/Abandoned_Mansion.png b/db/maps/Abandoned_Mansion.png
new file mode 100644
index 0000000..46b9e13
--- /dev/null
+++ b/db/maps/Abandoned_Mansion.png
Binary files differ
diff --git a/db/maps/Abandoned_Mansion_Basement.png b/db/maps/Abandoned_Mansion_Basement.png
new file mode 100644
index 0000000..455ad23
--- /dev/null
+++ b/db/maps/Abandoned_Mansion_Basement.png
Binary files differ
diff --git a/db/maps/Abandoned_Mansion_Top_Floor.png b/db/maps/Abandoned_Mansion_Top_Floor.png
new file mode 100644
index 0000000..54564cf
--- /dev/null
+++ b/db/maps/Abandoned_Mansion_Top_Floor.png
Binary files differ
diff --git a/db/maps/Dryads_Grove.png b/db/maps/Dryads_Grove.png
new file mode 100644
index 0000000..a0f4464
--- /dev/null
+++ b/db/maps/Dryads_Grove.png
Binary files differ
diff --git a/db/maps/candy-town.svg b/db/maps/candy-town.svg
index 2dab5f3..28a2671 100644
--- a/db/maps/candy-town.svg
+++ b/db/maps/candy-town.svg
@@ -5,6 +5,6 @@
>
<image href="/db/maps/Candy_Town.png" />
- <rect data-location="hospital" x="127" y="431" width="210" height="130" stroke="red" fill="transparent" />
<rect data-location="scoop_store" x="17" y="144" width="80" height="64" stroke="red" fill="transparent" />
+ <rect data-area="hospital" x="127" y="431" width="210" height="130" stroke="red" fill="transparent" />
</svg>
diff --git a/db/maps/dryads-grove.svg b/db/maps/dryads-grove.svg
new file mode 100644
index 0000000..ada9703
--- /dev/null
+++ b/db/maps/dryads-grove.svg
@@ -0,0 +1,9 @@
+<svg
+ version="1.1"
+ xmlns="http://www.w3.org/2000/svg"
+ viewbox="0 0 640 320"
+>
+ <image href="/db/maps/Dryads_Grove.png" />
+
+ <rect data-encounter="volcoli" data-encounter-level="55" x="544" y="207" width="16" height="16" stroke="red" fill="transparent" />
+</svg>
diff --git a/db/maps/hospital-floor-1.png b/db/maps/hospital-floor-1.png
new file mode 100644
index 0000000..276f303
--- /dev/null
+++ b/db/maps/hospital-floor-1.png
Binary files differ
diff --git a/db/maps/hospital-floor-1.svg b/db/maps/hospital-floor-1.svg
new file mode 100644
index 0000000..2b49afb
--- /dev/null
+++ b/db/maps/hospital-floor-1.svg
@@ -0,0 +1,7 @@
+<svg
+ version="1.1"
+ xmlns="http://www.w3.org/2000/svg"
+ viewbox="0 0 320 320"
+>
+ <image href="/db/maps/hospital-floor-1.png" />
+</svg>
diff --git a/db/maps/hospital-floor-2.png b/db/maps/hospital-floor-2.png
new file mode 100644
index 0000000..3430fba
--- /dev/null
+++ b/db/maps/hospital-floor-2.png
Binary files differ
diff --git a/db/maps/hospital-floor-2.svg b/db/maps/hospital-floor-2.svg
new file mode 100644
index 0000000..d37bd10
--- /dev/null
+++ b/db/maps/hospital-floor-2.svg
@@ -0,0 +1,7 @@
+<svg
+ version="1.1"
+ xmlns="http://www.w3.org/2000/svg"
+ viewbox="0 0 320 320"
+>
+ <image href="/db/maps/hospital-floor-2.png" />
+</svg>
diff --git a/db/maps/hospital-floor-3.png b/db/maps/hospital-floor-3.png
new file mode 100644
index 0000000..8db6e16
--- /dev/null
+++ b/db/maps/hospital-floor-3.png
Binary files differ
diff --git a/db/maps/hospital-floor-3.svg b/db/maps/hospital-floor-3.svg
new file mode 100644
index 0000000..bdcccbb
--- /dev/null
+++ b/db/maps/hospital-floor-3.svg
@@ -0,0 +1,7 @@
+<svg
+ version="1.1"
+ xmlns="http://www.w3.org/2000/svg"
+ viewbox="0 0 192 320"
+>
+ <image href="/db/maps/hospital-floor-3.png" />
+</svg>
diff --git a/db/maps/hospital.png b/db/maps/hospital.png
new file mode 100644
index 0000000..2d62dac
--- /dev/null
+++ b/db/maps/hospital.png
Binary files differ
diff --git a/db/maps/hospital.svg b/db/maps/hospital.svg
new file mode 100644
index 0000000..4a5bc16
--- /dev/null
+++ b/db/maps/hospital.svg
@@ -0,0 +1,9 @@
+<svg
+ version="1.1"
+ xmlns="http://www.w3.org/2000/svg"
+ viewbox="0 0 320 176"
+>
+ <image href="/db/maps/hospital.png" />
+
+ <rect data-location="hospital" x="64" y="43" width="32" height="21" stroke="red" fill="transparent" />
+</svg>
diff --git a/db/maps/mansion-basement.svg b/db/maps/mansion-basement.svg
new file mode 100644
index 0000000..fad9122
--- /dev/null
+++ b/db/maps/mansion-basement.svg
@@ -0,0 +1,7 @@
+<svg
+ version="1.1"
+ xmlns="http://www.w3.org/2000/svg"
+ viewbox="0 0 384 352"
+>
+ <image href="/db/maps/Abandoned_Mansion_Basement.png" />
+</svg>
diff --git a/db/maps/mansion-top-floor.svg b/db/maps/mansion-top-floor.svg
new file mode 100644
index 0000000..814d208
--- /dev/null
+++ b/db/maps/mansion-top-floor.svg
@@ -0,0 +1,7 @@
+<svg
+ version="1.1"
+ xmlns="http://www.w3.org/2000/svg"
+ viewbox="0 0 368 304"
+>
+ <image href="/db/maps/Abandoned_Mansion_Top_Floor.png" />
+</svg>
diff --git a/db/maps/mansion.svg b/db/maps/mansion.svg
new file mode 100644
index 0000000..84413e7
--- /dev/null
+++ b/db/maps/mansion.svg
@@ -0,0 +1,9 @@
+<svg
+ version="1.1"
+ xmlns="http://www.w3.org/2000/svg"
+ viewbox="0 0 288 288"
+>
+ <image href="/db/maps/Abandoned_Mansion.png" />
+
+ <rect data-area="mansion-basement" x="239" y="45" width="35" height="23" stroke="red" fill="transparent" />
+</svg>
diff --git a/index.html b/index.html
index ae9befb..78addfc 100644
--- a/index.html
+++ b/index.html
@@ -189,7 +189,7 @@
<template id="tpl___shop">
<div class="shop">
<div data-template-slot="items" class="shop__items"></div>
- <div data-template-slot="modes">
+ <div data-template-slot="modes" class="shop__selection-modes">
<button data-template-slot="modeBuy" data-selection-mode="buy" data-i18n-msgid="ui:shop:mode:buy" class="menu-button"></button>
<button data-template-slot="modeInfo" data-selection-mode="info" data-i18n-msgid="ui:shop:mode:info" class="menu-button"></button>
</div>
@@ -199,8 +199,10 @@
<template id="tpl___shop__item">
<div class="shop__item">
<img data-template-slot="sprite" src="" />
- <span data-template-slot="name"></span>
- <span data-template-slot="price"></span>
+ <div>
+ <span data-template-slot="name"></span>
+ <span data-template-slot="price"></span>
+ </div>
</div>
</template>
diff --git a/resources/css/menu.css b/resources/css/menu.css
index c79eebc..eb718f8 100644
--- a/resources/css/menu.css
+++ b/resources/css/menu.css
@@ -148,6 +148,7 @@
.map {
width: 100vw;
max-width: 750px;
+ background-color: #000;
}
@@ -289,6 +290,10 @@
grid-template-columns: 1fr 1fr 1fr;
}
+.item-info {
+ padding: 1rem;
+}
+
@@ -355,7 +360,10 @@
.setting-highlight {
border: 2px solid yellow !important;
}
-.setting-highlight--map svg [data-location] {
+
+.setting-highlight--map svg [data-location],
+.setting-highlight--map svg [data-area],
+.setting-highlight--map svg [data-encounter] {
stroke: yellow;
stroke-width: 2px;
}
diff --git a/resources/css/page.css b/resources/css/page.css
index 635a160..d16e542 100644
--- a/resources/css/page.css
+++ b/resources/css/page.css
@@ -34,6 +34,8 @@ svg {
display: block;
}
-svg [data-location] {
+svg [data-location],
+svg [data-area],
+svg [data-encounter] {
cursor: pointer;
}
diff --git a/resources/css/town.css b/resources/css/town.css
index 75a95d0..06f6f02 100644
--- a/resources/css/town.css
+++ b/resources/css/town.css
@@ -10,18 +10,21 @@
-.shop {
- padding: 1rem;
-}
+.shop {}
.shop__items {
display: grid;
+ grid-template-columns: 1fr 1fr 1fr;
grid-gap: 1rem;
+ padding: 1rem;
}
.shop__item {
- display: flex;
- justify-content: space-between;
- align-items: center;
+ text-align: center;
cursor: pointer;
}
+
+.shop__selection-modes {
+ padding: 1rem;
+ padding-top: 0;
+}
diff --git a/resources/js/classes/Area.js b/resources/js/classes/Area.js
index f518f22..5a3a062 100644
--- a/resources/js/classes/Area.js
+++ b/resources/js/classes/Area.js
@@ -3,7 +3,6 @@ class Area {
monsterProgress = 0;
trainerProgress = 0;
- isCompleted = false;
constructor (slug) {
this.slug = slug;
@@ -15,14 +14,25 @@ class Area {
return translate(this.alternateSlug) || slugToName(this.slug);
}
+ get isCompleted () {
+ return this.monsterProgress >= this.requiredEncounters && this.trainerProgress >= this.trainers.length;
+ }
+
get alternateSlug () {
return DB.areas[this.slug]['modules/tuxemon.slug'];
}
+ /**
+ * @returns {Object[]}
+ */
get encounters () {
return DB.areas[this.slug].encounters;
}
+ get encounterPercentTotal () {
+ return DB.areas[this.slug].encounter_percent_total;
+ }
+
get requiredEncounters () {
return DB.areas[this.slug].requiredEncounters;
}
diff --git a/resources/js/db.js b/resources/js/db.js
index a04d32e..54fc751 100644
--- a/resources/js/db.js
+++ b/resources/js/db.js
@@ -76,20 +76,35 @@ const DB = {
};
async function initializeDB () {
- DB.allMonsters = await fetch('/db/_generated/all-monsters.json').then((response) => response.json());
- DB.allAnimations = await fetch('/db/_generated/animations.json').then((response) => response.json());
- DB.allItems = await fetch('/db/_generated/all-items.json').then((response) => response.json());
+ DB.allMonsters = await fetchDBData('/db/_generated/all-monsters.json').then((response) => response.json());
+ DB.allAnimations = await fetchDBData('/db/_generated/animations.json').then((response) => response.json());
+ DB.allItems = await fetchDBData('/db/_generated/all-items.json').then((response) => response.json());
- DB.shapes = await fetch('/modules/tuxemon/mods/tuxemon/db/shape/shapes.json').then((response) => response.json());
+ DB.shapes = await fetchDBData('/modules/tuxemon/mods/tuxemon/db/shape/shapes.json').then((response) => response.json());
for (const element of Object.keys(ElementType)) {
- DB.elements[element] = await fetch(`/modules/tuxemon/mods/tuxemon/db/element/${element}.json`).then((response) => response.json());
+ DB.elements[element] = await fetchDBData(`/modules/tuxemon/mods/tuxemon/db/element/${element}.json`).then((response) => response.json());
}
await fetchTranslation(Memory.state.Settings.language);
applyTranslation();
- DB.currencies = await fetch('/db/_generated/currencies.json').then((response) => response.json());
+ DB.currencies = await fetchDBData('/db/_generated/currencies.json').then((response) => response.json());
+}
+
+/**
+ * @param arguments
+ *
+ * @returns {Promise<Response>}
+ */
+async function fetchDBData (...arguments) {
+ const response = await fetch(...arguments);
+
+ if (!response.ok) {
+ throw new Error(`"${response.url}": ${response.statusText}`);
+ }
+
+ return response;
}
/**
@@ -99,7 +114,7 @@ async function initializeDB () {
*/
async function fetchMonster (slug) {
if (! DB.monsters[slug]) {
- DB.monsters[slug] = await fetch(`/modules/tuxemon/mods/tuxemon/db/monster/${slug}.json`).then((response) => response.json());
+ DB.monsters[slug] = await fetchDBData(`/modules/tuxemon/mods/tuxemon/db/monster/${slug}.json`).then((response) => response.json());
}
const monster = new Monster(slug);
@@ -115,7 +130,7 @@ async function fetchMonster (slug) {
*/
async function fetchTechnique (slug) {
if (! DB.techniques[slug]) {
- DB.techniques[slug] = await fetch(`/modules/tuxemon/mods/tuxemon/db/technique/${slug}.json`).then((response) => response.json());
+ DB.techniques[slug] = await fetchDBData(`/modules/tuxemon/mods/tuxemon/db/technique/${slug}.json`).then((response) => response.json());
}
return new Technique(slug);
@@ -128,7 +143,7 @@ async function fetchTechnique (slug) {
*/
async function fetchStatusEffect (slug) {
if (! DB.statusEffects[slug]) {
- DB.statusEffects[slug] = await fetch(`/modules/tuxemon/mods/tuxemon/db/technique/status_${slug}.json`).then((response) => response.json());
+ DB.statusEffects[slug] = await fetchDBData(`/modules/tuxemon/mods/tuxemon/db/technique/status_${slug}.json`).then((response) => response.json());
}
return new StatusEffect(slug);
@@ -141,7 +156,7 @@ async function fetchStatusEffect (slug) {
*/
async function fetchItem (slug) {
if (! DB.items[slug]) {
- DB.items[slug] = await fetch(`/modules/tuxemon/mods/tuxemon/db/item/${slug}.json`).then((response) => response.json());
+ DB.items[slug] = await fetchDBData(`/modules/tuxemon/mods/tuxemon/db/item/${slug}.json`).then((response) => response.json());
}
return new Item(slug);
@@ -154,7 +169,7 @@ async function fetchItem (slug) {
*/
async function fetchTranslation (locale) {
if (! DB.translations[locale]) {
- DB.translations[locale] = await fetch(`/db/_generated/i18n/${locale}.json`).then((response) => response.json());
+ DB.translations[locale] = await fetchDBData(`/db/_generated/i18n/${locale}.json`).then((response) => response.json());
}
return DB.translations[locale];
@@ -171,7 +186,7 @@ async function fetchArea (slug) {
}
if (! DB.areas[slug]) {
- DB.areas[slug] = await fetch(`/db/_generated/areas/${slug}.json`).then((response) => response.json());
+ DB.areas[slug] = await fetchDBData(`/db/_generated/areas/${slug}.json`).then((response) => response.json());
}
const area = new Area(slug);
diff --git a/resources/js/game.js b/resources/js/game.js
index c463ab8..3e7a4c8 100644
--- a/resources/js/game.js
+++ b/resources/js/game.js
@@ -593,11 +593,11 @@ const Game = {
Game.opponentActionTimeout = null;
}), Math.max(levelDifference < 10 ? 500 : 50, Math.min(2000 - (speedDifference * 10) - (levelDifference * 100), 3000)));
- console.log(
+ /* console.log(
'Opponent Attack Timeout',
Memory.state.opponent.activeMonster.stats.speed, Memory.state.player.activeMonster.stats.speed,
2000 - (speedDifference * 10) - (levelDifference * 100)
- );
+ ); */
}
},
@@ -680,16 +680,36 @@ const Game = {
/* Progression */
async encounterWildMonster () {
- const randomMonster = Memory.state.currentArea.encounters[Math.floor(Math.random() * Memory.state.currentArea.encounters.length)];
+ let randomMonster = null;
+ const randomNumber = Math.random() * Memory.state.currentArea.encounterPercentTotal;
+ let accumulator = 0;
+ for (const encounter of Memory.state.currentArea.encounters) {
+ const lowerBounds = accumulator;
+ accumulator += encounter.encounter_percent;
+ const upperBounds = accumulator;
+
+ if (randomNumber >= lowerBounds && randomNumber <= upperBounds) {
+ randomMonster = encounter;
+ break;
+ }
+ }
+
const randomLevel = Math.floor(Math.random() * (randomMonster.level_range[1] - randomMonster.level_range[0]) + randomMonster.level_range[0]);
const monster = await fetchMonster(randomMonster.monster);
monster.level = randomLevel;
- const wildMonster = new Trainer({ monsters: [monster] });
- wildMonster.type = 'monster';
- await wildMonster.initialize();
- Memory.state.opponent = wildMonster;
+ Game.encounterMonster(monster);
+ },
+
+ /**
+ * @param {Monster} monster
+ */
+ async encounterMonster (monster) {
+ const encounterMonster = new Trainer({ monsters: [monster] });
+ encounterMonster.type = 'monster';
+ await encounterMonster.initialize();
+ Memory.state.opponent = encounterMonster;
UI.drawOpponentMonster();
},
diff --git a/resources/js/memory.js b/resources/js/memory.js
index 1511c25..709a084 100644
--- a/resources/js/memory.js
+++ b/resources/js/memory.js
@@ -89,7 +89,6 @@ const Memory = {
area.monsterProgress = areaData.monsterProgress;
area.trainerProgress = areaData.trainerProgress;
- area.isCompleted = areaData.isCompleted;
return area;
};
diff --git a/resources/js/ui.js b/resources/js/ui.js
index 089a3c3..e69fd83 100644
--- a/resources/js/ui.js
+++ b/resources/js/ui.js
@@ -531,7 +531,7 @@ const UI = {
drawArea () {
if (Game.isTown(Memory.state.currentArea)) {
- UI.elements.sceneTown.querySelector('[data-template-slot="map"]').replaceChildren(UI.createMap());
+ UI.drawTown();
UI.closeLog();
@@ -689,7 +689,9 @@ const UI = {
/* Town */
- drawTown () {},
+ drawTown () {
+ UI.elements.sceneTown.querySelector('[data-template-slot="map"]').replaceChildren(UI.createMap());
+ },
/* Map */
@@ -721,6 +723,23 @@ const UI = {
}
}
+ template.querySelectorAll('[data-area]').forEach((node) => node.addEventListener('click', UI.wrapCallback(async () => {
+ await Game.goToArea(node.dataset.area);
+ UI.closeAllPopups();
+ })));
+
+ template.querySelectorAll('[data-encounter]').forEach((node) => node.addEventListener('click', UI.wrapCallback(async () => {
+ if (!Memory.state.Game.isInBattle) {
+ const monster = await fetchMonster(node.dataset.encounter);
+ monster.level = parseInt(node.dataset.encounterLevel);
+
+ Game.encounterMonster(monster);
+ Memory.state.Game.isInBattle = true;
+
+ UI.closeAllPopups();
+ }
+ })));
+
return template;
},
@@ -973,7 +992,7 @@ const UI = {
if (!Game.isTown(currentArea)) {
if (
Memory.state.Game.isInBattle ||
- (Memory.state.opponent && Memory.state.opponent.type === 'trainer')
+ (Memory.state.opponent && Memory.state.opponent.type === 'trainer' && Memory.state.opponent.activeMonster !== Memory.state.opponent.monsters[0])
) {
changeAreaButton.disabled = true;
} else {
@@ -1027,11 +1046,9 @@ const UI = {
return;
}
- const popup = UI.createPopup();
- const template = UI.createMap();
-
- popup.querySelector('.popup').appendChild(template);
- UI.drawPopup(popup);
+ UI.drawTown();
+ UI.elements.sceneBattle.classList.toggle('hidden');
+ UI.elements.sceneTown.classList.toggle('hidden');
},
openAreaSelection () {
@@ -1057,7 +1074,22 @@ const UI = {
}
else if (condition.startsWith('area.')) {
- canGo = Memory.state.areaProgress.hasOwnProperty(condition.replace('area.', ''));
+ const areaCondition = condition.replace('area.', '');
+ const areaSlug = areaCondition.split('.')[0];
+ const area = Memory.state.areaProgress[areaSlug] || null;
+
+ if (!area) {
+ canGo = false;
+ continue;
+ }
+
+ if (areaCondition.includes('completed')) {
+ canGo = canGo && area.isCompleted;
+ }
+
+ else { // doesn't have any extra properties and exists in progress => visited
+ canGo = canGo && true;
+ }
}
else if (condition.startsWith('event.')) {
@@ -1679,6 +1711,7 @@ const UI = {
const popup = UI.createPopup();
const template = document.createElement('div');
+ template.classList.add('item-info');
template.textContent = item.description;
popup.querySelector('.popup').appendChild(template);