From c19b6c64f3ee6d78faf844e4a6152fce2cc0dfc9 Mon Sep 17 00:00:00 2001 From: Rens Oliemans Date: Thu, 13 Jan 2022 16:02:23 +0100 Subject: [PATCH 01/10] Convert data to new format Before we stored the data in data/platinum.py in a LOCATIONS and ENTRANCE dict. The LOCATIONS referred to the grouping used to create the buttons, and ENTRANCE contained all data which was about the entrances: key and name. This commit creates classes Category, Location and Entrance, which hold the data. Category represents a collection of locations, to be stored under one button. Location represents a collection of entrances reachable from one another, and entrance is simply a key, name pair. Note that we have changed the data but not the logic handling it: so this is a breaking commit Related: #30 --- data/platinum.py | 1230 ++++++++++++++++++++++++--------------------- main.py | 4 +- util/locations.py | 37 ++ 3 files changed, 706 insertions(+), 565 deletions(-) create mode 100644 util/locations.py diff --git a/data/platinum.py b/data/platinum.py index e2d5810..c4c27f7 100644 --- a/data/platinum.py +++ b/data/platinum.py @@ -1,565 +1,669 @@ -LOCATIONS = { - 'poi': [ - ('places_of_interest', 'Places of Interest'), - ('pokecenters_1', 'Pokécenters 1'), - ('pokecenters_2', 'Pokécenters 2'), - ], - 'cities': [ - ('sandgem_jubilife', 'Sandgem/Jubilife'), - ('oreburgh', 'Oreburgh'), - ('floaroma', 'Floaroma'), - ('eterna', 'Eterna'), - ('hearthome', 'Hearthome'), - ('solaceon', 'Solaceon'), - ('veilstone', 'Veilstone'), - ('pastoria', 'Pastoria'), - ('celestic', 'Celestic'), - ('canalave', 'Canalave'), - ('snowpoint', 'Snowpoint'), - ('sunyshore', 'Sunyshore'), - ('fight_resort', 'Fight/Resort'), - ('survival', 'Survival Area'), - ], - 'hubs': [ - ('jubilife_tv', 'Jubilife TV'), - ('store', 'Department Store'), - ('galactic_eterna', 'Galactic Eterna'), - ('galactic_hq', 'Galactic HQ'), - ('old_chateau', 'Old Chateau'), - ('solaceon_ruins', 'Solaceon Ruins'), - ('pokemansion', 'Pokémon Mansion'), - ], - 'routes': [ - ('r208_forest_march', 'R208/Et.Forest/Marsh'), - ('r213_214_222', 'R213/R214/R222'), - ], - 'other': [ - ('mt_coronet', 'Mt Coronet'), - ('victory_road', 'Victory Road'), - ('iron_island', 'Iron Island'), - ('poketch_gts_gate', 'Pokétch/GTS/Oreb. Gate'), - ('surf_hub', 'Surf Hub'), - ] -} - -ENTRANCES = { - 'places_of_interest': [ - ('oreburgh_gym_interior', 'Oreburgh Gym Interior'), - ('eterna_gym_interior', 'Eterna Gym Interior'), - ('hearthome_gym_interior', 'Hearthome Gym Interior'), - ('veilstone_gym_interior', 'Veilstone Gym Interior'), - ('pastoria_gym_interior', 'Pastoria Gym Interior'), - ('canalave_gym_interior', 'Canalave Gym Interior'), - ('snowpoint_gym_interior', 'Snowpoint Gym Interior'), - ('sunyshore_gym_interior', 'Sunyshore Gym Interior'), - ('e4_aaron', 'E4 Aaron'), - ('e4_bertha', 'E4 Bertha'), - ('e4_flint', 'E4 Flint'), - ('e4_lucian', 'E4 Lucian'), - ('champion', 'Champion'), - ('dialga_palkia', 'Dialga/Palkia'), - ('cresselia', 'Cresselia'), - ('darkrai', 'Darkrai'), - ('heatran', 'Heatran'), - ('arceus', 'Arceus'), - ('azelf', 'Azelf'), - ('uxie', 'Uxie'), - ], - 'pokecenters_1': [ - ('sandgem_pc_w', 'Sandgem PC W'), - ('sandgem_pc_s', 'Sandgem PC S'), - ('sandgem_pc_e', 'Sandgem PC E'), - ('jubilife_pc_w', 'Jubilife PC W'), - ('jubilife_pc_s', 'Jubilife PC S'), - ('jubilife_pc_e', 'Jubilife PC E'), - ('oreburgh_pc_w', 'Oreburgh PC W'), - ('oreburgh_pc_s', 'Oreburgh PC S'), - ('oreburgh_pc_e', 'Oreburgh PC E'), - ('floaroma_pc_w', 'Floaroma PC W'), - ('floaroma_pc_s', 'Floaroma PC S'), - ('floaroma_pc_e', 'Floaroma PC E'), - ('eterna_pc_w', 'Eterna PC W'), - ('eterna_pc_s', 'Eterna PC S'), - ('eterna_pc_e', 'Eterna PC E'), - ('hearthome_pc_w', 'Hearthome PC W'), - ('hearthome_pc_s', 'Hearthome PC S'), - ('hearthome_pc_e', 'Hearthome PC E'), - ('solaceon_pc_w', 'Solaceon PC W'), - ('solaceon_pc_s', 'Solaceon PC S'), - ('solaceon_pc_e', 'Solaceon PC E'), - ('veilstone_pc_w', 'Veilstone PC W'), - ('veilstone_pc_s', 'Veilstone PC S'), - ('veilstone_pc_e', 'Veilstone PC E'), - ('pastoria_pc_w', 'Pastoria PC W'), - ('pastoria_pc_s', 'Pastoria PC S'), - ('pastoria_pc_e', 'Pastoria PC E'), - ], - 'pokecenters_2': [ - ('celestic_pc_w', 'Celestic PC W'), - ('celestic_pc_s', 'Celestic PC S'), - ('celestic_pc_e', 'Celestic PC E'), - ('canalave_pc_w', 'Canalave PC W'), - ('canalave_pc_s', 'Canalave PC S'), - ('canalave_pc_e', 'Canalave PC E'), - ('snowpoint_pc_w', 'Snowpoint PC W'), - ('snowpoint_pc_s', 'Snowpoint PC S'), - ('snowpoint_pc_e', 'Snowpoint PC E'), - ('sunyshore_pc_w', 'Sunyshore PC W'), - ('sunyshore_pc_s', 'Sunyshore PC S'), - ('sunyshore_pc_e', 'Sunyshore PC E'), - ('victory_road_pc_w', 'VR PC W'), - ('victory_road_pc_s', 'VR PC S'), - ('victory_road_pc_e', 'VR PC E'), - ('pokemon_league_up', 'League Up'), - ('pokemon_league_down', 'League Down'), - ('pokemon_league_n', 'League N'), - ('pokemon_league_s', 'League S'), - ('fight_area_pc_w', 'Fight Area PC W'), - ('fight_area_pc_s', 'Fight Area PC S'), - ('fight_area_pc_e', 'Fight Area PC E'), - ('survival_area_pc_w', 'Survival Area PC W'), - ('survival_area_pc_s', 'Survival Area PC S'), - ('survival_area_pc_e', 'Survival Area PC E'), - ('resort_area_pc_w', 'Resort Area PC W'), - ('resort_area_pc_s', 'Resort Area PC S'), - ('resort_area_pc_e', 'Resort Area PC E'), - ], - 'sandgem_jubilife': [ - ('verity_lakefront', 'Verity Lakefront'), - ('sandgem_sw', 'Sandgem SW'), - ('sandgem_s', 'Sandgem S'), - ('sandgem_mart', 'Sandgem Mart'), - ('sandgem_pokecenter', 'Sandgem Pokécenter'), - ('jubilife_pokecenter', 'Jubilife Pokécenter'), - ('jubilife_trainer_school', 'Jubilife Trainer School'), - ('jubilife_mart', 'Jubilife Mart'), - ('jubilife_s', 'Jubilife S'), - ('jubilife_sw', 'Jubilife SW'), - ('jubilife_ne', 'Jubilife NE'), - ('jubilife_gts', 'Jubilife GTS'), - ('jubilife_tv', 'Jubilife TV'), - ('jubilife_poketch_w', 'Jubilife Poketch W'), - ('jubilife_poketch_e', 'Jubilife Poketch E'), - ('jubilife_ravaged_path', 'Jubilife Ravaged Path'), - ('jubilife_oreburgh_gate', 'Jubilife Oreburgh Gate'), - ('jubilife_west_exit', 'Jubilife West Exit'), - ], - 'oreburgh': [ - ('oreburgh_gym', 'Oreburgh Gym'), - ('oreburgh_mart', 'Oreburgh Mart'), - ('oreburgh_pokecenter', 'Oreburgh Pokécenter'), - ('oreburgh_fossil_lab', 'Oreburgh Fossil Lab'), - ('oreburgh_mine', 'Oreburgh Mine'), - ('oreburgh_apartment_nw', 'Oreburgh Apartment NW'), - ('oreburgh_apartment_n', 'Oreburgh Apartment N'), - ('oreburgh_apartment_e', 'Oreburgh Apartment E'), - ('oreburgh_house_w', 'Oreburgh House W'), - ('oreburgh_house_c', 'Oreburgh House C'), - ('oreburgh_house_se', 'Oreburgh House SE'), - ('oreburgh_west_exit', 'Oreburgh West Exit'), - ('r206_cycle_path', 'R206 Cycle Path'), - ('r206_wayward_cave', 'R206 Wayward Cave'), - ('r206_wayward_cave_hidden', 'R206 Wayward Cave Hidden'), - ('r207_mt_coronet', 'R207 Mt Coronet'), - ], - 'floaroma': [ - ('floaroma_pokecenter', 'Floaroma Pokecenter'), - ('floaroma_mart', 'Floaroma Mart'), - ('floaroma_flower_shop', 'Floaroma Flower Shop'), - ('floaroma_nw', 'Floaroma NW'), - ('floaroma_se', 'Floaroma SE'), - ('floaroma_ravaged_path', 'Floaroma Ravaged Path'), - ('floaroma_meadow_entrance_floaroma', 'Meadow Entrance Floaroma'), - ('floaroma_meadow_exit_house', 'Meadow House'), - ('floaroma_meadow_exit_n', 'Meadow Exit N'), - ('floaroma_meadow_exit_s', 'Meadow Exit S'), - ('r205_ironworks', 'R205 Ironworks'), - ('floaroma_meadow_entrance_iron', 'R205 Meadow Entrance'), - ('r205_windworks', 'R205 Windworks'), - ('r205_eterna_forest', 'R205 Eterna Forest'), - ('r205_house', 'R205 House'), - ], - 'eterna': [ - ('eterna_pokecenter', 'Eterna Pokecenter'), - ('eterna_mart', 'Eterna Mart'), - ('eterna_gym', 'Eterna Gym'), - ('eterna_bike_shop', 'Eterna Bike Shop'), - ("eterna_spelunker's_house", "Spelunker's House"), - ('eterna_city_forest', 'Eterna City Forest'), - ('eterna_apartment', 'Eterna Apartment'), - ('eterna_galactic', 'Eterna Galactic Building'), - ('eterna_house_n', 'Eterna House N'), - ('eterna_house_s', 'Eterna House S'), - ('eterna_house_e', 'Eterna House E'), - ('eterna_mt_coronet', 'Eterna Mt Coronet'), - ('eterna_south_exit', 'Eterna South Exit'), - ], - 'hearthome': [ - ('hearthome_pokecenter', 'Hearthome Pokecenter'), - ('hearthome_mart', 'Hearthome Mart'), - ('hearthome_gym', 'Hearthome Gym'), - ('hearthome_contest', 'Hearthome Contest'), - ("hearthome_bebe's_house", "Bebe's house"), - ('hearthome_church', 'Hearthome Church'), - ('hearthome_poffin_house', 'Hearthome Poffin House'), - ('hearthome_fanclub', 'Hearthome Fanclub'), - ('hearthome_apartment_n', 'Hearthome Apartment N'), - ('hearthome_apartment_e', 'Hearthome Apartment E'), - ('hearthome_amity_square_west', 'Amity Square West'), - ('hearthome_amity_square_east', 'Amity Square East'), - ('hearthome_east_exit', 'Hearthome East Exit'), - ('hearthome_south_exit', 'Hearthome South Exit'), - ('hearthome_west_exit', 'Hearthome West Exit'), - ], - 'solaceon': [ - ('solaceon_pokecenter', 'Solaceon Pokecenter'), - ('solaceon_mart', 'Solaceon Mart'), - ('solaceon_daycare', 'Solaceon Daycare'), - ('solaceon_house_n', 'Solaceon House N'), - ('solaceon_house_ne', 'Solaceon House NE'), - ('solaceon_house_e', 'Solaceon House E'), - ('solaceon_house_c', 'Solaceon House C'), - ('solaceon_ruins', 'Solaceon Ruins'), - ('r209_lost_tower', 'R209 Lost Tower'), - ('r209_west_exit', 'R209 West Exit'), - ('r210_cafe_cabin', 'R210 Cafe Cabin'), - ('r215_east_exit', 'R215 East Exit'), - ], - 'veilstone': [ - ('veilstone_pokecenter', 'Veilstone Pokecenter'), - ('veilstone_mart', 'Veilstone Mart'), - ('veilstone_gym', 'Veilstone Gym'), - ('veilstone_casino', 'Veilstone Casino'), - ('veilstone_galactic_hq_1', 'Galactic HQ 1'), - ('veilstone_galactic_hq_2', 'Galactic HQ 2'), - ('veilstone_galactic_hq_3', 'Galactic HQ 3'), - ('veilstone_galactic_warehouse', 'Galactic Warehouse'), - ('veilstone_house_n', 'Veilstone House N'), - ('veilstone_house_ne', 'Veilstone House NE'), - ('veilstone_prize_exchange', 'Prize Exchange'), - ('veilstone_house_s', 'Veilstone House S'), - ('veilstone_house_sw', 'Veilstone House SW'), - ('veilstone_south_exit', 'Veilstone South Exit'), - ('veilstone_west_exit', 'Veilstone West Exit'), - ], - 'pastoria': [ - ('pastoria_pokecenter', 'Pastoria Pokecenter'), - ('pastoria_mart', 'Pastoria Mart'), - ('pastoria_gym', 'Pastoria Gym'), - ('pastoria_great_marsh', 'Pastoria Great Marsh'), - ('pastoria_house_ne', 'Pastoria House NE'), - ('pastoria_house_se', 'Pastoria House SE'), - ('pastoria_house_sw', 'Pastoria House SW'), - ('pastoria_house_n', 'Pastoria House N'), - ('pastoria_house_c', 'Pastoria House C'), - ('pastoria_east_exit', 'Pastoria East Exit'), - ('r212_move_tutor', 'R212 Move Tutor'), - ('r212_pokemon_mansion', 'R212 Pokemon Mansion'), - ('r212_north_exit', 'R212 North Exit'), - ], - 'celestic': [ - ('celestic_pokecenter', 'Celestic Pokecenter'), - ('celestic_ruins', 'Celestic Ruins'), - ('celestic_big_house', 'Celestic Big House'), - ('celestic_house_ne', 'Celestic House NE'), - ('celestic_house_nw', 'Celestic House NW'), - ('celestic_house_sw', 'Celestic House SW'), - ('celestic_mt_coronet', 'Celestic Mt Coronet'), - ("r210_grandma's_house", "R210 Grandma's House"), - ], - 'canalave': [ - ('canalave_pokecenter', 'Canalave Pokecenter'), - ('canalave_mart', 'Canalave Mart'), - ('canalave_gym', 'Canalave Gym'), - ('canalave_library', 'Canalave Library'), - ('canalave_house_e', 'Canalave House E'), - ('canalave_house_se', 'Canalave House SE'), - ('canalave_house_w', 'Canalave House W'), - ('canalave_house_sw', 'Canalave House SW'), - # ('canalave_iron_island?', 'Canalave Iron Island?'), - ('canalave_east_exit', 'Canalave East Exit'), - ], - 'snowpoint': [ - ('snowpoint_pokecenter', 'Snowpoint Pokecenter'), - ('snowpoint_mart', 'Snowpoint Mart'), - ('snowpoint_gym', 'Snowpoint Gym'), - ('snowpoint_house_nw', 'Snowpoint House NW'), - ('snowpoint_house_ne', 'Snowpoint House NE'), - ('snowpoint_temple', 'Snowpoint Temple'), - ('acuity_lakefront', 'Acuity Lakefront'), - ('r217_house_n', 'R217 House N'), - ('r217_house_w', 'R217 House W'), - ('r216_house_w', 'R216 House W'), - ('r216_mt_coronet', 'R216 Mt Coronet'), - ], - 'sunyshore': [ - ('sunyshore_pokecenter', 'Sunyshore Pokecenter'), - ('sunyshore_mart', 'Sunyshore Mart'), - ('sunyshore_gym', 'Sunyshore Gym'), - ('sunyshore_lighthouse', 'Sunyshore Lighthouse'), - ('sunyshore_market', 'Sunyshore Market'), - ('sunyshore_house_w', 'Sunyshore House W'), - ('sunyshore_house_n', 'Sunyshore House N'), - ('sunyshore_house_ne', 'Sunyshore House NE'), - ('sunyshore_house_e', 'Sunyshore House E'), - ('sunyshore_west_exit', 'Sunyshore West Exit'), - ], - 'fight_resort': [ - ('fight_area_pokecenter', 'Fight Area Pokecenter'), - ('fight_area_mart', 'Fight Area Mart'), - ('fight_area_s_house', 'Fight Area S House'), - ('fight_area_c_house', 'Fight Area C House'), - ('fight_area_north_exit', 'Fight Area North Exit'), - ('resort_area_pokecenter', 'Resort Area Pokecenter'), - ('resort_area_villa', 'Resort Area Villa'), - ('resort_area_ribbon_syndicate', 'Resort Area Ribbon Syndicate'), - ('resort_area_house', 'Resort Area House'), - ('r228_s_house', 'R228 S House'), - ('r228_c_house', 'R228 C House'), - ('r228_north_exit', 'R228 North Exit'), - ], - 'survival': [ - ('survival_area_pokecenter', 'Survival Area Pokecenter'), - ('survival_area_mart', 'Survival Area Mart'), - ('survival_area_n_house', 'Survival Area N House'), - ('survival_area_c_house', 'Survival Area C House'), - ('survival_area_s_house', 'Survival Area S House'), - ('r225_house', 'R225 House'), - ('r225_south_exit', 'R225 South Exit'), - ('r226_house', 'R226 House'), - ('r226_east_exit', 'R226 East Exit'), - ('r227_house', 'R227 House'), - ('r227_stark_mountain', 'R227 Stark Mountain'), - ], - 'jubilife_tv': [ - ('jubilife_tv_1f_up', 'TV 1F Up'), - ('jubilife_tv_1f_exit', 'TV 1F Exit'), - ('jubilife_tv_2f_n', 'TV 2F N'), - ('jubilife_tv_2f_up', 'TV 2F Up'), - ('jubilife_tv_2f_down', 'TV 2F Down'), - ('jubilife_tv_3f_nw', 'TV 3F NW'), - ('jubilife_tv_3f_n', 'TV 3F N'), - ('jubilife_tv_3f_up', 'TV 3F Up'), - ('jubilife_tv_3f_down', 'TV 3F Down'), - ('jubilife_tv_4f_down', 'TV 4F Down'), - ], - 'store': [ - ('department_store_b1f_up', 'Store B1F Up'), - ('department_store_1f_up', 'Store 1F Up'), - ('department_store_1f_down', 'Store 1F Down'), - ('department_store_1f_exit', 'Store 1F Exit'), - ('department_store_2f_up', 'Store 2F Up'), - ('department_store_2f_down', 'Store 2F Down'), - ('department_store_3f_up', 'Store 3F Up'), - ('department_store_3f_down', 'Store 3F Down'), - ('department_store_4f_up', 'Store 4F Up'), - ('department_store_4f_down', 'Store 4F Down'), - ('department_store_5f_down', 'Store 5F Down'), - ], - 'galactic_eterna': [ - ('galactic_eterna_1f_s', 'TG Eterna 1F Exit S'), - ('galactic_eterna_1f_nw', 'TG Eterna 1F NW'), - ('galactic_eterna_1f_stairs_n', 'TG Eterna 1F Stairs N'), - ('galactic_eterna_1f_stairs_ne', 'TG Eterna 1F Stairs NE'), - ('galactic_eterna_2f_w', 'TG Eterna 2F W'), - ('galactic_eterna_2f_n', 'TG Eterna 2F N'), - ('galactic_eterna_2f_e', 'TG Eterna 2F E'), - ('galactic_eterna_3f_w', 'TG Eterna 3F W'), - ('galactic_eterna_3f_n', 'TG Eterna 3F N'), - ('galactic_eterna_3f_e', 'TG Eterna 3F E'), - ], - 'galactic_hq': [ - ('galactic_warehouse_b2f_stairs_c', 'Warehouse Stairs C'), - ('galactic_warehouse_b2f_stairs_e', 'Warehouse Stairs E'), - ('galactic_warehouse_b2f_stairs_w', 'Warehouse Stairs W'), - - ('galactic_hq_1f_south_stairs', 'HQ 1F A Stairs'), - ('galactic_hq_1f_south_entrance_e', 'HQ 1F A East Exit'), - ('galactic_hq_1f_south_entrance_w', 'HQ 1F A West Exit'), - - ('galactic_hq_1f_ne_stairs', 'HQ 1F B Stairs'), - ('galactic_hq_1f_ne_warp_e', 'HQ 1F B Warp E'), - ('galactic_hq_1f_ne_warp_w', 'HQ 1F B Warp W'), - - ('galactic_hq_2f_s_stairs', 'HQ 2F A Stairs'), - ('galactic_hq_2f_s_warp_c', 'HQ 2F A Warp C'), - ('galactic_hq_2f_s_warp_ne', 'HQ 2F A Warp NE'), - ('galactic_hq_2f_s_warp_se', 'HQ 2F A Warp SE'), - - ('galactic_hq_2f_nw_warp', 'HQ 2F B Warp'), - ('galactic_hq_2f_nw_up', 'HQ 2F B Up'), - ('galactic_hq_2f_nw_down', 'HQ 2F B Down'), - - ('galactic_hq_3f_warp_1', 'HQ 3F Warp W'), - ('galactic_hq_3f_warp_2', 'HQ 3F Warp C'), - ('galactic_hq_3f_warp_3', 'HQ 3F Warp E'), - ('galactic_hq_3f_stairs', 'HQ 3F Stairs'), - - ('galactic_hq_4f_stairs', 'HQ 4F Stairs'), - ('galactic_hq_4f_warp_n', 'HQ 4F Warp N'), - ('galactic_hq_4f_warp_ne', 'HQ 4F Warp NE'), - ('galactic_hq_4f_warp_se', 'HQ 4F Warp SE'), - ], - 'old_chateau': [ - ('old_chateau_n', 'OC Entrance N'), - ('old_chateau_e', 'OC Entrance E'), - ('old_chateau_s', 'OC Entrance S'), - ('old_chateau_w', 'OC Entrance W'), - ('old_chateau_c', 'OC Entrance C'), - - ('old_chateau_2f_room_1', 'OC 2F Room 1'), - ('old_chateau_2f_room_2', 'OC 2F Room 2'), - ('old_chateau_2f_room_3', 'OC 2F Room 3'), - ('old_chateau_2f_room_4', 'OC 2F Room 4'), - ('old_chateau_2f_room_5', 'OC 2F Room 5'), - ('old_chateau_2f_exit', 'OC 2F Exit'), - ], - 'solaceon_ruins': [ - ('solaceon_ruins_1f_nw', 'SR 1F NW'), - ('solaceon_ruins_1f_ne', 'SR 1F NE'), - ('solaceon_ruins_1f_se', 'SR 1F SE'), - ('solaceon_ruins_1f_exit', 'SR 1F Exit'), - - ('solaceon_ruins_b1f_nw', 'SR B1F NW'), - ('solaceon_ruins_b1f_ne', 'SR B1F NE'), - ('solaceon_ruins_b1f_se', 'SR B1F SE'), - ('solaceon_ruins_b1f_sw', 'SR B1F SW'), - - ('solaceon_ruins_b2f_nw', 'SR B2F NW'), - ('solaceon_ruins_b2f_ne', 'SR B2F NE'), - ('solaceon_ruins_b2f_se', 'SR B2F SE'), - ('solaceon_ruins_b2f_sw', 'SR B2F SW'), - - ('solaceon_ruins_b3f_a_nw', 'SR B3F A NW'), - ('solaceon_ruins_b3f_a_ne', 'SR B3F A NE'), - ('solaceon_ruins_b3f_a_se', 'SR B3F A SE'), - ('solaceon_ruins_b3f_a_sw', 'SR B3F A SW'), - - ('solaceon_ruins_b3f_b_nw', 'SR B3F B NW'), - ('solaceon_ruins_b3f_b_se', 'SR B3F B SE'), - ('solaceon_ruins_b3f_b_sw', 'SR B3F B SW'), - - ('solaceon_ruins_b4f_nw', 'SR B4F NW'), - ('solaceon_ruins_b4f_ne', 'SR B4F NE'), - ('solaceon_ruins_b4f_se', 'SR B4F SE'), - ('solaceon_ruins_b4f_sw', 'SR B4F SW'), - ], - 'pokemansion': [ - ('poke_mansion_s', 'Pokémansion S'), - ('poke_mansion_w', 'Pokémansion W'), - ('poke_mansion_e', 'Pokémansion E'), - ('poke_mansion_n', 'Pokémansion N'), - ('poke_mansion_room_1', 'Pokémansion Room 1'), - ('poke_mansion_room_2', 'Pokémansion Room 2'), - ('poke_mansion_room_3', 'Pokémansion Room 3'), - ('poke_mansion_room_4', 'Pokémansion Room 4'), - ], - 'r208_forest_march': [ - ('r208_forest_march_berry_house', 'R208 Berry House'), - ('r208_forest_march_208_east_exit', 'R208 East Exit'), - ('r208_forest_march_208_west_exit', 'R208 West Exit'), - ('r208_forest_march_chateau', 'Eterna Forest Old Chateau'), - ('r208_forest_march_forest_east_exit', 'Eterna Forest East Exit'), - ('r208_forest_march_forest_west_exit', 'Eterna Forest South Exit'), - ('r208_forest_march_marsh_s', 'Great Marsh S'), - ('r208_forest_march_marsh_n', 'Great Marsh N'), - ('r208_forest_march_marsh_up', 'Great Marsh Up'), - ], - 'r213_214_222': [ - ('r213_hotel', 'R213 Hotel'), - ('r213_house', 'R213 House'), - ('r213_west_exit', 'R213 West Exit'), - ('r214_maniac_tunnel', 'R214 Maniac Tunnel'), - ('r214_sendoff_spring', 'R214 Sendoff Spring'), - ('r214_north_exit', 'R214 North Exit'), - ('valor_lakefront', 'Valor Lakefront'), - ('hotel_grand_lake_nw', 'Hotel Grand Lake NW'), - ('hotel_grand_lake_n', 'Hotel Grand Lake N'), - ('hotel_grand_lake_ne', 'Hotel Grand Lake NE'), - ('hotel_grand_lake_w', 'Hotel Grand Lake W'), - ('hotel_grand_lake_e', 'Hotel Grand Lake E'), - ('hotel_grand_lake_se', 'Hotel Grand Lake SE'), - ('hotel_grand_lake_s', 'Hotel Grand Lake S'), - ('r222_house_w', 'R222 House W'), - ('r222_house_e', 'R222 House E'), - ('r222_east_exit', 'R222 East Exit'), - ], - 'mt_coronet': [ - ('mt_coronet_1f_a_north_stairs', 'Coronet 1F A North Stairs'), - ('mt_coronet_1f_a_east_exit', 'Coronet 1F A East Exit'), - ('mt_coronet_1f_a_south_exit', 'Coronet 1F A South Exit'), - ('mt_coronet_1f_a_west_exit', 'Coronet 1F A West Exit'), - - ('mt_coronet_1f_2_south_stairs', 'Coronet 1F B South Stairs'), - ('mt_coronet_1f_2_regice_cave', 'Coronet 1F B Regice Cave'), - ('mt_coronet_1f_2_west_exit', 'Coronet 1F B West Exit'), - - ('mt_coronet_1f_3_ne_stairs', 'Coronet 1F C NE Stairs'), - ('mt_coronet_1f_3_east_exit', 'Coronet 1F C East Exit'), - ('mt_coronet_1f_3_west_exit', 'Coronet 1F C West Exit'), - - ('mt_coronet_2f_s_stairs', 'Coronet 2F E Stairs'), - ('mt_coronet_2f_n_cave', 'Coronet 2F N Cave'), - ('mt_coronet_2f_sw_exit', 'Coronet 2F SW Exit'), - - ('mt_coronet_3f_east_stairs', 'Coronet 3F East Stairs'), - ('mt_coronet_3f_west_stairs', 'Coronet 3F West Stairs'), - ('mt_coronet_3f_west_exit', 'Coronet 3F West Exit'), - - ('mt_coronet_summit_nw_cave', 'Coronet Summit NW Cave'), - ('mt_coronet_summit_ne_cave', 'Coronet Summit NE Cave'), - ('mt_coronet_summit_e_cave', 'Coronet Summit E Cave'), - ('mt_coronet_summit_se_cave', 'Coronet Summit SE Cave'), - ('mt_coronet_summit_w_cave', 'Coronet Summit W Cave'), - ('mt_coronet_summit_nw_cave', 'Coronet Summit NW Cave'), - ], - 'victory_road': [ - ('victory_road_1f_nw_stairs', 'VR 1F NW Stairs'), - ('victory_road_1f_w_stairs', 'VR 1F W Stairs'), - ('victory_road_1f_sw_stairs', 'VR 1F SW Stairs'), - ('victory_road_1f_ne_stairs', 'VR 1F NE Stairs'), - ('victory_road_1f_e_stairs', 'VR 1F E Stairs'), - ('victory_road_1f_se_stairs', 'VR 1F SE Stairs'), - ('victory_road_1f_north_exit', 'VR 1F North Exit'), - ('victory_road_1f_south_exit', 'VR 1F South Exit'), - - ('victory_road_b1f_nw_stairs', 'VR B1F NW Stairs'), - ('victory_road_b1f_w_stairs', 'VR B1F W Stairs'), - ('victory_road_b1f_sw_stairs', 'VR B1F SW Stairs'), - ], - 'iron_island': [ - ('iron_island_exterior_entrance', 'Iron Island Exterior Entrance'), - ('iron_island_exterior_house', 'Iron Island Exterior House'), - ('iron_island_exterior_exit', 'Iron Island Exterior Exit'), - - ('iron_island_1f_w', 'Iron Island 1F W'), - ('iron_island_1f_e', 'Iron Island 1F E'), - ('iron_island_1f_exit', 'Iron Island 1F Exit'), - - ('iron_island_b1f_nw', 'Iron Island B1F NW'), - ('iron_island_b1f_sw', 'Iron Island B1F SW'), - ('iron_island_b1f_se', 'Iron Island B1F SE'), +from util.locations import Category, Location, Entrance - ('iron_island_b3f_nw', 'Iron Island B3F NW'), - ('iron_island_b3f_registeel', 'Iron Island B3F N'), - ('iron_island_b3f_se', 'Iron Island B3F SE'), - ], - 'poketch_gts_gate': [ - ('poketch_interior_sw', 'Poketch Interior SW'), - ('poketch_interior_se', 'Poketch Interior SE'), - ('poketch_interior_up', 'Poketch Interior Up'), - ('gts_1f_warp_w', 'GTS 1F Warp W'), - ('gts_1f_warp_e', 'GTS 1F Warp E'), - ('gts_1f_exit', 'GTS 1F Exit'), - ('oreburgh_gate_stairs', 'Oreburgh Gate Stairs'), - ('oreburgh_gate_east_exit', 'Oreburgh Gate East Exit'), - ('oreburgh_gate_west_exit', 'Oreburgh Gate West Exit'), - ], - 'surf_hub': [ - ('lake_verity', 'Lake Verity'), - ('lake_valor', 'Lake Valor'), - ('lake_acuity', 'Lake Acuity'), - ('r221_house', 'R221 House'), - ('r221_pal_park', 'R221 Pal Park'), - ], +CATEGORIES = { + Category('poi', 'Places of Interest', [ + Location('oreburgh_gym_interior', 'Oreburgh Gym Interior', + [Entrance('oreburgh_gym_interior', 'Oreburgh Gym Interior')]), + Location('eterna_gym_interior', 'Eterna Gym Interior', + [Entrance('eterna_gym_interior', 'Eterna Gym Interior')]), + Location('hearthome_gym_interior', 'Hearthome Gym Interior', + [Entrance('hearthome_gym_interior', 'Hearthome Gym Interior')]), + Location('veilstone_gym_interior', 'Veilstone Gym Interior', + [Entrance('veilstone_gym_interior', 'Veilstone Gym Interior')]), + Location('pastoria_gym_interior', 'Pastoria Gym Interior', + [Entrance('pastoria_gym_interior', 'Pastoria Gym Interior')]), + Location('canalave_gym_interior', 'Canalave Gym Interior', + [Entrance('canalave_gym_interior', 'Canalave Gym Interior')]), + Location('snowpoint_gym_interior', 'Snowpoint Gym Interior', + [Entrance('snowpoint_gym_interior', 'Snowpoint Gym Interior')]), + Location('sunyshore_gym_interior', 'Sunyshore Gym Interior', + [Entrance('sunyshore_gym_interior', 'Sunyshore Gym Interior')]), + Location('e4_aaron', 'E4 Aaron', + [Entrance('e4_aaron', 'E4 Aaron')]), + Location('e4_bertha', 'E4 Bertha', + [Entrance('e4_bertha', 'E4 Bertha')]), + Location('e4_flint', 'E4 Flint', + [Entrance('e4_flint', 'E4 Flint')]), + Location('e4_lucian', 'E4 Lucian', + [Entrance('e4_lucian', 'E4 Lucian')]), + Location('champion', 'Champion', + [Entrance('champion', 'Champion')]), + Location('dialga_palkia', 'Dialga/Palkia', + [Entrance('dialga_palkia', 'Dialga/Palkia')]), + Location('cresselia', 'Cresselia', + [Entrance('cresselia', 'Cresselia')]), + Location('darkrai', 'Darkrai', + [Entrance('darkrai', 'Darkrai')]), + Location('heatran', 'Heatran', + [Entrance('heatran', 'Heatran')]), + Location('arceus', 'Arceus', + [Entrance('arceus', 'Arceus')]), + Location('azelf', 'Azelf', + [Entrance('azelf', 'Azelf')]), + Location('uxie', 'Uxie', + [Entrance('uxie', 'Uxie')]), + ]), + Category('pokecenters_1', 'Pokécenters 1', [ + Location('sandgem_pc', 'Sandgem PC', [ + Entrance('sandgem_pc_w', 'Sandgem PC W'), + Entrance('sandgem_pc_s', 'Sandgem PC S'), + Entrance('sandgem_pc_e', 'Sandgem PC E'), + ]), + Location('jubilife_pc', 'Jubilife PC', [ + Entrance('jubilife_pc_w', 'Jubilife PC W'), + Entrance('jubilife_pc_s', 'Jubilife PC S'), + Entrance('jubilife_pc_e', 'Jubilife PC E'), + ]), + Location('oreburgh_pc', 'Oreburgh PC', [ + Entrance('oreburgh_pc_w', 'Oreburgh PC W'), + Entrance('oreburgh_pc_s', 'Oreburgh PC S'), + Entrance('oreburgh_pc_e', 'Oreburgh PC E'), + ]), + Location('floaroma_pc', 'Floaroma PC', [ + Entrance('floaroma_pc_w', 'Floaroma PC W'), + Entrance('floaroma_pc_s', 'Floaroma PC S'), + Entrance('floaroma_pc_e', 'Floaroma PC E'), + ]), + Location('eterna_pc', 'Eterna PC', [ + Entrance('eterna_pc_w', 'Eterna PC W'), + Entrance('eterna_pc_s', 'Eterna PC S'), + Entrance('eterna_pc_e', 'Eterna PC E'), + ]), + Location('hearthome_pc', 'Hearthome PC', [ + Entrance('hearthome_pc_w', 'Hearthome PC W'), + Entrance('hearthome_pc_s', 'Hearthome PC S'), + Entrance('hearthome_pc_e', 'Hearthome PC E'), + ]), + Location('solaceon_pc', 'Solaceon PC', [ + Entrance('solaceon_pc_w', 'Solaceon PC W'), + Entrance('solaceon_pc_s', 'Solaceon PC S'), + Entrance('solaceon_pc_e', 'Solaceon PC E'), + ]), + Location('veilstone_pc', 'Veilstone PC', [ + Entrance('veilstone_pc_w', 'Veilstone PC W'), + Entrance('veilstone_pc_s', 'Veilstone PC S'), + Entrance('veilstone_pc_e', 'Veilstone PC E'), + ]), + Location('pastoria_pc', 'Pastoria PC', [ + Entrance('pastoria_pc_w', 'Pastoria PC W'), + Entrance('pastoria_pc_s', 'Pastoria PC S'), + Entrance('pastoria_pc_e', 'Pastoria PC E'), + ]), + ]), + Category('pokecenters_2', 'Pokécenters 2', [ + Location('celestic_pc', 'Celestic PC', [ + Entrance('celestic_pc_w', 'Celestic PC W'), + Entrance('celestic_pc_s', 'Celestic PC S'), + Entrance('celestic_pc_e', 'Celestic PC E'), + ]), + Location('canalave_pc', 'Canalave PC', [ + Entrance('canalave_pc_w', 'Canalave PC W'), + Entrance('canalave_pc_s', 'Canalave PC S'), + Entrance('canalave_pc_e', 'Canalave PC E'), + ]), + Location('snowpoint_pc', 'Snowpoint PC', [ + Entrance('snowpoint_pc_w', 'Snowpoint PC W'), + Entrance('snowpoint_pc_s', 'Snowpoint PC S'), + Entrance('snowpoint_pc_e', 'Snowpoint PC E'), + ]), + Location('sunyshore_pc', 'Sunyshore PC', [ + Entrance('sunyshore_pc_w', 'Sunyshore PC W'), + Entrance('sunyshore_pc_s', 'Sunyshore PC S'), + Entrance('sunyshore_pc_e', 'Sunyshore PC E'), + ]), + Location('victory_road_pc', 'VR PC', [ + Entrance('victory_road_pc_w', 'VR PC W'), + Entrance('victory_road_pc_s', 'VR PC S'), + Entrance('victory_road_pc_e', 'VR PC E'), + ]), + Location('pokemon_league_pc', 'League PC', [ + Entrance('pokemon_league_up', 'League PC Up'), + Entrance('pokemon_league_down', 'League PC Down'), + Entrance('pokemon_league_n', 'League PC N'), + Entrance('pokemon_league_s', 'League PC S'), + ]), + Location('fight_area_pc', 'Fight Area PC', [ + Entrance('fight_area_pc_w', 'Fight Area PC W'), + Entrance('fight_area_pc_s', 'Fight Area PC S'), + Entrance('fight_area_pc_e', 'Fight Area PC E'), + ]), + Location('survival_area_pc', 'Survival Area PC', [ + Entrance('survival_area_pc_w', 'Survival Area PC W'), + Entrance('survival_area_pc_s', 'Survival Area PC S'), + Entrance('survival_area_pc_e', 'Survival Area PC E'), + ]), + Location('resort_area_pc', 'Resort Area PC', [ + Entrance('resort_area_pc_w', 'Resort Area PC W'), + Entrance('resort_area_pc_s', 'Resort Area PC S'), + Entrance('resort_area_pc_e', 'Resort Area PC E'), + ]), + ]), + Category('sandgem_jubilife', 'Sandgem/Jubilife', [ + Location('sandgem_jubilife', 'Sandgem/Jubilife', [ + Entrance('verity_lakefront', 'Verity Lakefront'), + Entrance('sandgem_sw', 'Sandgem SW'), + Entrance('sandgem_s', 'Sandgem S'), + Entrance('sandgem_mart', 'Sandgem Mart'), + Entrance('sandgem_pokecenter', 'Sandgem Pokécenter'), + Entrance('jubilife_pokecenter', 'Jubilife Pokécenter'), + Entrance('jubilife_trainer_school', 'Jubilife Trainer School'), + Entrance('jubilife_mart', 'Jubilife Mart'), + Entrance('jubilife_s', 'Jubilife S'), + Entrance('jubilife_sw', 'Jubilife SW'), + Entrance('jubilife_ne', 'Jubilife NE'), + Entrance('jubilife_gts', 'Jubilife GTS'), + Entrance('jubilife_tv', 'Jubilife TV'), + Entrance('jubilife_poketch_w', 'Jubilife Poketch W'), + Entrance('jubilife_poketch_e', 'Jubilife Poketch E'), + Entrance('jubilife_ravaged_path', 'Jubilife Ravaged Path'), + Entrance('jubilife_oreburgh_gate', 'Jubilife Oreburgh Gate'), + Entrance('jubilife_west_exit', 'Jubilife West Exit'), + ]), + ]), + Category('oreburgh', 'Oreburgh', [ + Location('oreburgh', 'Oreburgh', [ + Entrance('oreburgh_gym', 'Oreburgh Gym'), + Entrance('oreburgh_mart', 'Oreburgh Mart'), + Entrance('oreburgh_pokecenter', 'Oreburgh Pokécenter'), + Entrance('oreburgh_fossil_lab', 'Oreburgh Fossil Lab'), + Entrance('oreburgh_mine', 'Oreburgh Mine'), + Entrance('oreburgh_apartment_nw', 'Oreburgh Apartment NW'), + Entrance('oreburgh_apartment_n', 'Oreburgh Apartment N'), + Entrance('oreburgh_apartment_e', 'Oreburgh Apartment E'), + Entrance('oreburgh_house_w', 'Oreburgh House W'), + Entrance('oreburgh_house_c', 'Oreburgh House C'), + Entrance('oreburgh_house_se', 'Oreburgh House SE'), + Entrance('oreburgh_west_exit', 'Oreburgh West Exit'), + Entrance('r206_cycle_path', 'R206 Cycle Path'), + Entrance('r206_wayward_cave', 'R206 Wayward Cave'), + Entrance('r206_wayward_cave_hidden', 'R206 Wayward Cave Hidden'), + Entrance('r207_mt_coronet', 'R207 Mt Coronet'), + ]), + ]), + Category('floaroma', 'Floaroma', [ + Location('floaroma', 'Floaroma', [ + Entrance('floaroma_pokecenter', 'Floaroma Pokecenter'), + Entrance('floaroma_mart', 'Floaroma Mart'), + Entrance('floaroma_flower_shop', 'Floaroma Flower Shop'), + Entrance('floaroma_nw', 'Floaroma NW'), + Entrance('floaroma_se', 'Floaroma SE'), + Entrance('floaroma_ravaged_path', 'Floaroma Ravaged Path'), + Entrance('floaroma_meadow_entrance_floaroma', 'Meadow Entrance Floaroma'), + Entrance('floaroma_meadow_exit_house', 'Meadow House'), + Entrance('floaroma_meadow_exit_n', 'Meadow Exit N'), + Entrance('floaroma_meadow_exit_s', 'Meadow Exit S'), + Entrance('r205_ironworks', 'R205 Ironworks'), + Entrance('floaroma_meadow_entrance_iron', 'R205 Meadow Entrance'), + Entrance('r205_windworks', 'R205 Windworks'), + Entrance('r205_eterna_forest', 'R205 Eterna Forest'), + Entrance('r205_house', 'R205 House'), + ]), + ]), + Category('eterna', 'Eterna', [ + Location('eterna', 'Eterna', [ + Entrance('eterna_pokecenter', 'Eterna Pokecenter'), + Entrance('eterna_mart', 'Eterna Mart'), + Entrance('eterna_gym', 'Eterna Gym'), + Entrance('eterna_bike_shop', 'Eterna Bike Shop'), + Entrance('eterna_spelunkers_house', 'Spelunker\'s House'), + Entrance('eterna_city_forest', 'Eterna City Forest'), + Entrance('eterna_apartment', 'Eterna Apartment'), + Entrance('eterna_galactic', 'Eterna Galactic Building'), + Entrance('eterna_house_n', 'Eterna House N'), + Entrance('eterna_house_s', 'Eterna House S'), + Entrance('eterna_house_e', 'Eterna House E'), + Entrance('eterna_mt_coronet', 'Eterna Mt Coronet'), + Entrance('eterna_south_exit', 'Eterna South Exit'), + ]), + ]), + Category('hearthome', 'Hearthome', [ + Location('hearthome', 'Hearthome', [ + Entrance('hearthome_pokecenter', 'Hearthome Pokecenter'), + Entrance('hearthome_mart', 'Hearthome Mart'), + Entrance('hearthome_gym', 'Hearthome Gym'), + Entrance('hearthome_contest', 'Hearthome Contest'), + Entrance('hearthome_bebes_house', 'Bebe\'s house'), + Entrance('hearthome_church', 'Hearthome Church'), + Entrance('hearthome_poffin_house', 'Hearthome Poffin House'), + Entrance('hearthome_fanclub', 'Hearthome Fanclub'), + Entrance('hearthome_apartment_n', 'Hearthome Apartment N'), + Entrance('hearthome_apartment_e', 'Hearthome Apartment E'), + Entrance('hearthome_amity_square_west', 'Amity Square West'), + Entrance('hearthome_amity_square_east', 'Amity Square East'), + Entrance('hearthome_east_exit', 'Hearthome East Exit'), + Entrance('hearthome_south_exit', 'Hearthome South Exit'), + Entrance('hearthome_west_exit', 'Hearthome West Exit'), + ]), + ]), + Category('solaceon', 'Solaceon', [ + Location('solaceon', 'Solaceon', [ + Entrance('solaceon_pokecenter', 'Solaceon Pokecenter'), + Entrance('solaceon_mart', 'Solaceon Mart'), + Entrance('solaceon_daycare', 'Solaceon Daycare'), + Entrance('solaceon_house_n', 'Solaceon House N'), + Entrance('solaceon_house_ne', 'Solaceon House NE'), + Entrance('solaceon_house_e', 'Solaceon House E'), + Entrance('solaceon_house_c', 'Solaceon House C'), + Entrance('solaceon_ruins', 'Solaceon Ruins'), + Entrance('r209_lost_tower', 'R209 Lost Tower'), + Entrance('r209_west_exit', 'R209 West Exit'), + Entrance('r210_cafe_cabin', 'R210 Cafe Cabin'), + Entrance('r215_east_exit', 'R215 East Exit'), + ]), + ]), + Category('veilstone', 'Veilstone', [ + Location('veilstone', 'Veilstone', [ + Entrance('veilstone_pokecenter', 'Veilstone Pokecenter'), + Entrance('veilstone_mart', 'Veilstone Mart'), + Entrance('veilstone_gym', 'Veilstone Gym'), + Entrance('veilstone_casino', 'Veilstone Casino'), + Entrance('veilstone_galactic_hq_1', 'Galactic HQ 1'), + Entrance('veilstone_galactic_hq_2', 'Galactic HQ 2'), + Entrance('veilstone_galactic_hq_3', 'Galactic HQ 3'), + Entrance('veilstone_galactic_warehouse', 'Galactic Warehouse'), + Entrance('veilstone_house_n', 'Veilstone House N'), + Entrance('veilstone_house_ne', 'Veilstone House NE'), + Entrance('veilstone_prize_exchange', 'Prize Exchange'), + Entrance('veilstone_house_s', 'Veilstone House S'), + Entrance('veilstone_house_sw', 'Veilstone House SW'), + Entrance('veilstone_south_exit', 'Veilstone South Exit'), + Entrance('veilstone_west_exit', 'Veilstone West Exit'), + ]), + ]), + Category('pastoria', 'Pastoria', [ + Location('pastoria', 'Pastoria', [ + Entrance('pastoria_pokecenter', 'Pastoria Pokecenter'), + Entrance('pastoria_mart', 'Pastoria Mart'), + Entrance('pastoria_gym', 'Pastoria Gym'), + Entrance('pastoria_great_marsh', 'Pastoria Great Marsh'), + Entrance('pastoria_house_ne', 'Pastoria House NE'), + Entrance('pastoria_house_se', 'Pastoria House SE'), + Entrance('pastoria_house_sw', 'Pastoria House SW'), + Entrance('pastoria_house_n', 'Pastoria House N'), + Entrance('pastoria_house_c', 'Pastoria House C'), + Entrance('pastoria_east_exit', 'Pastoria East Exit'), + Entrance('r212_move_tutor', 'R212 Move Tutor'), + Entrance('r212_pokemon_mansion', 'R212 Pokemon Mansion'), + Entrance('r212_north_exit', 'R212 North Exit'), + ]), + ]), + Category('celestic', 'Celestic', [ + Location('celestic', 'Celestic', [ + Entrance('celestic_pokecenter', 'Celestic Pokecenter'), + Entrance('celestic_ruins', 'Celestic Ruins'), + Entrance('celestic_big_house', 'Celestic Big House'), + Entrance('celestic_house_ne', 'Celestic House NE'), + Entrance('celestic_house_nw', 'Celestic House NW'), + Entrance('celestic_house_sw', 'Celestic House SW'), + Entrance('celestic_mt_coronet', 'Celestic Mt Coronet'), + Entrance('r210_grandmas_house', 'R210 Grandmas House'), + ]), + ]), + Category('canalave', 'Canalave', [ + Location('canalave', 'Canalave', [ + Entrance('canalave_pokecenter', 'Canalave Pokecenter'), + Entrance('canalave_mart', 'Canalave Mart'), + Entrance('canalave_gym', 'Canalave Gym'), + Entrance('canalave_library', 'Canalave Library'), + Entrance('canalave_house_e', 'Canalave House E'), + Entrance('canalave_house_se', 'Canalave House SE'), + Entrance('canalave_house_w', 'Canalave House W'), + Entrance('canalave_house_sw', 'Canalave House SW'), + Entrance('canalave_east_exit', 'Canalave East Exit'), + ]), + ]), + Category('snowpoint', 'Snowpoint', [ + Location('snowpoint', 'Snowpoint', [ + Entrance('snowpoint_pokecenter', 'Snowpoint Pokecenter'), + Entrance('snowpoint_mart', 'Snowpoint Mart'), + Entrance('snowpoint_gym', 'Snowpoint Gym'), + Entrance('snowpoint_house_nw', 'Snowpoint House NW'), + Entrance('snowpoint_house_ne', 'Snowpoint House NE'), + Entrance('snowpoint_temple', 'Snowpoint Temple'), + Entrance('acuity_lakefront', 'Acuity Lakefront'), + Entrance('r217_house_n', 'R217 House N'), + Entrance('r217_house_w', 'R217 House W'), + Entrance('r216_house_w', 'R216 House W'), + Entrance('r216_mt_coronet', 'R216 Mt Coronet'), + ]), + ]), + Category('sunyshore', 'Sunyshore', [ + Location('sunyshore', 'Sunyshore', [ + Entrance('sunyshore_pokecenter', 'Sunyshore Pokecenter'), + Entrance('sunyshore_mart', 'Sunyshore Mart'), + Entrance('sunyshore_gym', 'Sunyshore Gym'), + Entrance('sunyshore_lighthouse', 'Sunyshore Lighthouse'), + Entrance('sunyshore_market', 'Sunyshore Market'), + Entrance('sunyshore_house_w', 'Sunyshore House W'), + Entrance('sunyshore_house_n', 'Sunyshore House N'), + Entrance('sunyshore_house_ne', 'Sunyshore House NE'), + Entrance('sunyshore_house_e', 'Sunyshore House E'), + Entrance('sunyshore_west_exit', 'Sunyshore West Exit'), + ]), + ]), + Category('fight_resort', 'Fight/Resort', [ + Location('fight_resort', 'Fight/Resort', [ + Entrance('fight_area_pokecenter', 'Fight Area Pokecenter'), + Entrance('fight_area_mart', 'Fight Area Mart'), + Entrance('fight_area_s_house', 'Fight Area S House'), + Entrance('fight_area_c_house', 'Fight Area C House'), + Entrance('fight_area_north_exit', 'Fight Area North Exit'), + Entrance('resort_area_pokecenter', 'Resort Area Pokecenter'), + Entrance('resort_agroup-locations-together-that-you-can-reachrea_villa', 'Resort Area Villa'), + Entrance('resort_area_ribbon_syndicate', 'Resort Area Ribbon Syndicate'), + Entrance('resort_area_house', 'Resort Area House'), + Entrance('r228_s_house', 'R228 S House'), + Entrance('r228_c_house', 'R228 C House'), + Entrance('r228_north_exit', 'R228 North Exit'), + ]), + ]), + Category('survival', 'Survival', [ + Location('survival', 'Survival', [ + Entrance('survival_area_pokecenter', 'Survival Area Pokecenter'), + Entrance('survival_area_mart', 'Survival Area Mart'), + Entrance('survival_area_n_house', 'Survival Area N House'), + Entrance('survival_area_c_house', 'Survival Area C House'), + Entrance('survival_area_s_house', 'Survival Area S House'), + Entrance('r225_house', 'R225 House'), + Entrance('r225_south_exit', 'R225 South Exit'), + Entrance('r226_house', 'R226 House'), + Entrance('r226_east_exit', 'R226 East Exit'), + Entrance('r227_house', 'R227 House'), + Entrance('r227_stark_mountain', 'R227 Stark Mountain'), + ]), + ]), + Category('jubilife_tv', 'Jubilife TV', [ + Location('jubilife_tv', 'Jubilife TV', [ + Entrance('jubilife_tv_1f_up', 'TV 1F Up'), + Entrance('jubilife_tv_1f_exit', 'TV 1F Exit'), + Entrance('jubilife_tv_2f_n', 'TV 2F N'), + Entrance('jubilife_tv_2f_up', 'TV 2F Up'), + Entrance('jubilife_tv_2f_down', 'TV 2F Down'), + Entrance('jubilife_tv_3f_nw', 'TV 3F NW'), + Entrance('jubilife_tv_3f_n', 'TV 3F N'), + Entrance('jubilife_tv_3f_up', 'TV 3F Up'), + Entrance('jubilife_tv_3f_down', 'TV 3F Down'), + Entrance('jubilife_tv_4f_down', 'TV 4F Down'), + ]), + ]), + Category('department_store', 'Department Store', [ + Location('department_store', 'Department Store', [ + Entrance('department_store_b1f_up', 'Store B1F Up'), + Entrance('department_store_1f_up', 'Store 1F Up'), + Entrance('department_store_1f_down', 'Store 1F Down'), + Entrance('department_store_1f_exit', 'Store 1F Exit'), + Entrance('department_store_2f_up', 'Store 2F Up'), + Entrance('department_store_2f_down', 'Store 2F Down'), + Entrance('department_store_3f_up', 'Store 3F Up'), + Entrance('department_store_3f_down', 'Store 3F Down'), + Entrance('department_store_4f_up', 'Store 4F Up'), + Entrance('department_store_4f_down', 'Store 4F Down'), + Entrance('department_store_5f_down', 'Store 5F Down'), + ]), + ]), + Category('pokemansion', 'Pokémansion', [ + Location('pokemansion', 'Pokémansion', [ + Entrance('poke_mansion_s', 'Pokémansion S'), + Entrance('poke_mansion_w', 'Pokémansion W'), + Entrance('poke_mansion_e', 'Pokémansion E'), + Entrance('poke_mansion_n', 'Pokémansion N'), + Entrance('poke_mansion_room_1', 'Pokémansion Room 1'), + Entrance('poke_mansion_room_2', 'Pokémansion Room 2'), + Entrance('poke_mansion_room_3', 'Pokémansion Room 3'), + Entrance('poke_mansion_room_4', 'Pokémansion Room 4'), + ]), + ]), + Category('galactic_eterna', 'Galactic Eterna', [ + Location('galactic_eterna_1f', 'Galactic Eterna 1F', [ + Entrance('galactic_eterna_1f_s', 'TG Eterna 1F Exit S'), + Entrance('galactic_eterna_1f_nw', 'TG Eterna 1F NW'), + Entrance('galactic_eterna_1f_stairs_n', 'TG Eterna 1F Stairs N'), + Entrance('galactic_eterna_1f_stairs_ne', 'TG Eterna 1F Stairs NE'), + ]), + Location('galactic_eterna_2f', 'Galactic Eterna 2F', [ + Entrance('galactic_eterna_2f_w', 'TG Eterna 2F W'), + Entrance('galactic_eterna_2f_n', 'TG Eterna 2F N'), + Entrance('galactic_eterna_2f_e', 'TG Eterna 2F E'), + ]), + Location('galactic_eterna_3f', 'Galactic Eterna 3F', [ + Entrance('galactic_eterna_3f_w', 'TG Eterna 3F W'), + Entrance('galactic_eterna_3f_n', 'TG Eterna 3F N'), + Entrance('galactic_eterna_3f_e', 'TG Eterna 3F E'), + ]), + ]), + Category('galactic_hq', 'Galactic HQ', [ + Location('galactic_warehouse', 'Galactic Warehouse', [ + Entrance('galactic_warehouse_b2f_stairs_c', 'Warehouse Stairs C'), + Entrance('galactic_warehouse_b2f_stairs_e', 'Warehouse Stairs E'), + Entrance('galactic_warehouse_b2f_stairs_w', 'Warehouse Stairs W'), + ]), + Location('galactic_hq_1f_a', 'Galactic HQ 1F A', [ + Entrance('galactic_hq_1f_a_stairs', 'HQ 1F A Stairs'), + Entrance('galactic_hq_1f_a_entrance_e', 'HQ 1F A East Exit'), + Entrance('galactic_hq_1f_a_entrance_w', 'HQ 1F A West Exit'), + ]), + Location('galactic_hq_1f_b', 'Galactic HQ 1F B', [ + Entrance('galactic_hq_1f_b_stairs', 'HQ 1F B Stairs'), + Entrance('galactic_hq_1f_b_warp_e', 'HQ 1F B Warp E'), + Entrance('galactic_hq_1f_b_warp_w', 'HQ 1F B Warp W'), + ]), + Location('galactic_hq_2f_a', 'Galactic HQ 2F A', [ + Entrance('galactic_hq_2f_a_stairs', 'HQ 2F A Stairs'), + Entrance('galactic_hq_2f_a_warp_c', 'HQ 2F A Warp C'), + Entrance('galactic_hq_2f_a_warp_ne', 'HQ 2F A Warp NE'), + Entrance('galactic_hq_2f_a_warp_se', 'HQ 2F A Warp SE'), + ]), + Location('galactic_hq_2f_b', 'Galactic HQ 2F B', [ + Entrance('galactic_hq_2f_b_warp', 'HQ 2F B Warp'), + Entrance('galactic_hq_2f_b_up', 'HQ 2F B Up'), + Entrance('galactic_hq_2f_b_down', 'HQ 2F B Down'), + ]), + Location('galactic_hq_3f', 'Galactic HQ 3F', [ + Entrance('galactic_hq_3f_warp_1', 'HQ 3F Warp W'), + Entrance('galactic_hq_3f_warp_2', 'HQ 3F Warp C'), + Entrance('galactic_hq_3f_warp_3', 'HQ 3F Warp E'), + Entrance('galactic_hq_3f_stairs', 'HQ 3F Stairs'), + ]), + Location('galactic_hq_4f', 'Galactic HQ 4F', [ + Entrance('galactic_hq_4f_stairs', 'HQ 4F Stairs'), + Entrance('galactic_hq_4f_warp_n', 'HQ 4F Warp N'), + Entrance('galactic_hq_4f_warp_ne', 'HQ 4F Warp NE'), + Entrance('galactic_hq_4f_warp_se', 'HQ 4F Warp SE'), + ]), + ]), + Category('old_chateau', 'Old Chateau', [ + Location('old_chateau_1f', 'Old Chateau 1F', [ + Entrance('old_chateau_n', 'OC Entrance N'), + Entrance('old_chateau_e', 'OC Entrance E'), + Entrance('old_chateau_s', 'OC Entrance S'), + Entrance('old_chateau_w', 'OC Entrance W'), + Entrance('old_chateau_c', 'OC Entrance C'), + ]), + Location('old_chatea_2f', 'Old Chateau 2F', [ + Entrance('old_chateau_2f_room_1', 'OC 2F Room 1'), + Entrance('old_chateau_2f_room_2', 'OC 2F Room 2'), + Entrance('old_chateau_2f_room_3', 'OC 2F Room 3'), + Entrance('old_chateau_2f_room_4', 'OC 2F Room 4'), + Entrance('old_chateau_2f_room_5', 'OC 2F Room 5'), + Entrance('old_chateau_2f_exit', 'OC 2F Exit'), + ]), + ]), + Category('solaceon_ruins', 'Solaceon Ruins', [ + Location('solaceon_ruins_1f', 'Solaceon Ruins 1F', [ + Entrance('solaceon_ruins_1f_nw', 'SR 1F NW'), + Entrance('solaceon_ruins_1f_ne', 'SR 1F NE'), + Entrance('solaceon_ruins_1f_se', 'SR 1F SE'), + Entrance('solaceon_ruins_1f_exit', 'SR 1F Exit'), + ]), + Location('solaceon_ruins_b1f', 'Solaceon Ruins B1F', [ + Entrance('solaceon_ruins_b1f_nw', 'SR B1F NW'), + Entrance('solaceon_ruins_b1f_ne', 'SR B1F NE'), + Entrance('solaceon_ruins_b1f_se', 'SR B1F SE'), + Entrance('solaceon_ruins_b1f_sw', 'SR B1F SW'), + ]), + Location('solaceon_ruins_b2f', 'Solaceon Ruins B2F', [ + Entrance('solaceon_ruins_b2f_nw', 'SR B2F NW'), + Entrance('solaceon_ruins_b2f_ne', 'SR B2F NE'), + Entrance('solaceon_ruins_b2f_se', 'SR B2F SE'), + Entrance('solaceon_ruins_b2f_sw', 'SR B2F SW'), + ]), + Location('solaceon_ruins_b3f_a', 'Solaceon Ruins B3F A', [ + Entrance('solaceon_ruins_b3f_a_nw', 'SR B3F A NW'), + Entrance('solaceon_ruins_b3f_a_ne', 'SR B3F A NE'), + Entrance('solaceon_ruins_b3f_a_se', 'SR B3F A SE'), + Entrance('solaceon_ruins_b3f_a_sw', 'SR B3F A SW'), + ]), + Location('solaceon_ruins_b3f_b', 'Solaceon Ruins B3F B', [ + Entrance('solaceon_ruins_b3f_b_nw', 'SR B3F B NW'), + Entrance('solaceon_ruins_b3f_b_se', 'SR B3F B SE'), + Entrance('solaceon_ruins_b3f_b_sw', 'SR B3F B SW'), + ]), + Location('solaceon_ruins_b4f', 'Solaceon Ruins B4F', [ + Entrance('solaceon_ruins_b4f_nw', 'SR B4F NW'), + Entrance('solaceon_ruins_b4f_ne', 'SR B4F NE'), + Entrance('solaceon_ruins_b4f_se', 'SR B4F SE'), + Entrance('solaceon_ruins_b4f_sw', 'SR B4F SW'), + ]), + ]), + Category('r208_forest_marsh', 'R208/Et.Forest/Marsh', [ + Location('r208', 'Route 208', [ + Entrance('r208_berry_house', 'R208 Berry House'), + Entrance('r208_east_exit', 'R208 East Exit'), + Entrance('r208_west_exit', 'R208 West Exit'), + ]), + Location('eterna_forest', 'Eterna Forest', [ + Entrance('eterna_forest_chateau', 'Eterna Forest Old Chateau'), + Entrance('eterna_forest_east_exit', 'Eterna Forest East Exit'), + Entrance('eterna_forest_west_exit', 'Eterna Forest South Exit'), + ]), + Location('great_marsh', 'Great Marsh', [ + Entrance('great_marsh_s', 'Great Marsh S'), + Entrance('great_marsh_n', 'Great Marsh N'), + Entrance('great_marsh_up', 'Great Marsh Up'), + ]) + ]), + Category('r213_214_222', 'R213/R214/R222', [ + Location('r213', 'Route 213', [ + Entrance('r213_hotel', 'R213 Hotel'), + Entrance('r213_house', 'R213 House'), + Entrance('r213_west_exit', 'R213 West Exit'), + ]), + Location('r214_hotel_222', 'R214/222/Hotel', [ + Entrance('r214_maniac_tunnel', 'R214 Maniac Tunnel'), + Entrance('r214_sendoff_spring', 'R214 Sendoff Spring'), + Entrance('r214_north_exit', 'R214 North Exit'), + Entrance('valor_lakefront', 'Valor Lakefront'), + Entrance('hotel_grand_lake_nw', 'Hotel Grand Lake NW'), + Entrance('hotel_grand_lake_n', 'Hotel Grand Lake N'), + Entrance('hotel_grand_lake_ne', 'Hotel Grand Lake NE'), + Entrance('hotel_grand_lake_w', 'Hotel Grand Lake W'), + Entrance('hotel_grand_lake_e', 'Hotel Grand Lake E'), + Entrance('hotel_grand_lake_se', 'Hotel Grand Lake SE'), + Entrance('hotel_grand_lake_s', 'Hotel Grand Lake S'), + Entrance('r222_house_w', 'R222 House W'), + Entrance('r222_house_e', 'R222 House E'), + Entrance('r222_east_exit', 'R222 East Exit'), + ]) + ]), + Category('mt_coronet', 'Mt Coronet', [ + Location('mt_coronet_1f_a', 'Coronet 1F A', [ + Entrance('mt_coronet_1f_a_north_stairs', 'Coronet 1F A North Stairs'), + Entrance('mt_coronet_1f_a_east_exit', 'Coronet 1F A East Exit'), + Entrance('mt_coronet_1f_a_south_exit', 'Coronet 1F A South Exit'), + Entrance('mt_coronet_1f_a_west_exit', 'Coronet 1F A West Exit'), + ]), + Location('mt_coronet_1f_b', 'Coronet 1F B', [ + Entrance('mt_coronet_1f_b_south_stairs', 'Coronet 1F B South Stairs'), + Entrance('mt_coronet_1f_b_regice_cave', 'Coronet 1F B Regice Cave'), + Entrance('mt_coronet_1f_b_west_exit', 'Coronet 1F B West Exit'), + ]), + Location('mt_coronet_1f_c', 'Coronet 1F C', [ + Entrance('mt_coronet_1f_c_ne_stairs', 'Coronet 1F C NE Stairs'), + Entrance('mt_coronet_1f_c_east_exit', 'Coronet 1F C East Exit'), + Entrance('mt_coronet_1f_c_west_exit', 'Coronet 1F C West Exit'), + ]), + Location('mt_coronet_2f', 'Coronet 2F', [ + Entrance('mt_coronet_2f_s_stairs', 'Coronet 2F E Stairs'), + Entrance('mt_coronet_2f_n_cave', 'Coronet 2F N Cave'), + Entrance('mt_coronet_2f_sw_exit', 'Coronet 2F SW Exit'), + ]), + Location('mt_coronet_3f', 'Coronet 3F', [ + Entrance('mt_coronet_3f_east_stairs', 'Coronet 3F East Stairs'), + Entrance('mt_coronet_3f_west_stairs', 'Coronet 3F West Stairs'), + Entrance('mt_coronet_3f_west_exit', 'Coronet 3F West Exit'), + ]), + Location('mt_coronet_summit', 'Coronet Summit', [ + Entrance('mt_coronet_summit_nw_cave', 'Coronet Summit NW Cave'), + Entrance('mt_coronet_summit_ne_cave', 'Coronet Summit NE Cave'), + Entrance('mt_coronet_summit_e_cave', 'Coronet Summit E Cave'), + Entrance('mt_coronet_summit_se_cave', 'Coronet Summit SE Cave'), + Entrance('mt_coronet_summit_w_cave', 'Coronet Summit W Cave'), + Entrance('mt_coronet_summit_nw_cave', 'Coronet Summit NW Cave'), + ]), + ]), + Category('victory_road', 'Victory Road', [ + Location('victory_road_1f', 'Victory Road 1F', [ + Entrance('victory_road_1f_nw_stairs', 'VR 1F NW Stairs'), + Entrance('victory_road_1f_w_stairs', 'VR 1F W Stairs'), + Entrance('victory_road_1f_sw_stairs', 'VR 1F SW Stairs'), + Entrance('victory_road_1f_ne_stairs', 'VR 1F NE Stairs'), + Entrance('victory_road_1f_e_stairs', 'VR 1F E Stairs'), + Entrance('victory_road_1f_se_stairs', 'VR 1F SE Stairs'), + Entrance('victory_road_1f_north_exit', 'VR 1F North Exit'), + Entrance('victory_road_1f_south_exit', 'VR 1F South Exit'), + ]), + Location('victory_road_b1f', 'Victory Road B1F', [ + Entrance('victory_road_b1f_nw_stairs', 'VR B1F NW Stairs'), + Entrance('victory_road_b1f_w_stairs', 'VR B1F W Stairs'), + Entrance('victory_road_b1f_sw_stairs', 'VR B1F SW Stairs'), + ]), + ]), + Category('iron_island', 'Iron Island', [ + Location('iron_island_exterior', 'Iron Island Exterior', [ + Entrance('iron_island_exterior_entrance', 'Iron Island Exterior Entrance'), + Entrance('iron_island_exterior_house', 'Iron Island Exterior House'), + Entrance('iron_island_exterior_exit', 'Iron Island Exterior Exit'), + ]), + Location('iron_island_1f', 'Iron Island 1F', [ + Entrance('iron_island_1f_w', 'Iron Island 1F W'), + Entrance('iron_island_1f_e', 'Iron Island 1F E'), + Entrance('iron_island_1f_exit', 'Iron Island 1F Exit'), + ]), + Location('iron_island_b1f', 'Iron Island B1F', [ + Entrance('iron_island_b1f_nw', 'Iron Island B1F NW'), + Entrance('iron_island_b1f_sw', 'Iron Island B1F SW'), + Entrance('iron_island_b1f_se', 'Iron Island B1F SE'), + ]), + Location('iron_island_b3f', 'Iron Island B3F', [ + Entrance('iron_island_b3f_nw', 'Iron Island B3F NW'), + Entrance('iron_island_b3f_n', 'Iron Island B3F N'), + Entrance('iron_island_b3f_se', 'Iron Island B3F SE'), + ]), + ]), + Category('poketch_gts_gate', 'Pokétch/GTS/Oreb. Gate', [ + Location('poketch_interior', 'Poketch Interior', [ + Entrance('poketch_interior_sw', 'Poketch Interior SW'), + Entrance('poketch_interior_se', 'Poketch Interior SE'), + Entrance('poketch_interior_up', 'Poketch Interior Up'), + ]), + Location('gts_1f', 'GTS 1F', [ + Entrance('gts_1f_warp_w', 'GTS 1F Warp W'), + Entrance('gts_1f_warp_e', 'GTS 1F Warp E'), + Entrance('gts_1f_exit', 'GTS 1F Exit'), + ]), + Location('oreburgh_gate', 'Oreburgh Gate', [ + Entrance('oreburgh_gate_stairs', 'Oreburgh Gate Stairs'), + Entrance('oreburgh_gate_east_exit', 'Oreburgh Gate East Exit'), + Entrance('oreburgh_gate_west_exit', 'Oreburgh Gate West Exit'), + ]), + ]), + Category('surf_hub', 'Surf Hub', [ + Location('lake_verity', 'Lake Verity', [Entrance('lake_verity', 'Lake Verity')]), + Location('lake_valor', 'Lake Valor', [Entrance('lake_valor', 'Lake Valor')]), + Location('lake_acuity', 'Lake Acuity', [Entrance('lake_acuity', 'Lake Acuity')]), + Location('r221', 'Route 221', [ + Entrance('r221_house', 'R221 House'), + Entrance('r221_pal_park', 'R221 Pal Park'), + ]), + ]), } diff --git a/main.py b/main.py index 07c9a94..3123b79 100644 --- a/main.py +++ b/main.py @@ -2,10 +2,10 @@ import sys import logging from os.path import join -from PySide6.QtCore import QCoreApplication, Qt, QTimer +from PySide6.QtCore import QCoreApplication, Qt from PySide6.QtWidgets import QApplication -from data.platinum import LOCATIONS, ENTRANCES +from util.locations import LOCATIONS, ENTRANCES from pokerandom import PokeRandom from links.db import Db from timer import connect_shift diff --git a/util/locations.py b/util/locations.py new file mode 100644 index 0000000..47bb8d4 --- /dev/null +++ b/util/locations.py @@ -0,0 +1,37 @@ +class Category: + """ + A group of locations that together forms 1 unit, for example 'Places of Interest'. These are not necessarily + logically linked, but are grouped together for visual reasons. + """ + + def __init__(self, key, name, locations): + self.key = key + self.name = name + self.locations = locations + + +class Location: + """ + A logically connected group of entrances. From each of these entrances, you can warp + to every other entrance in-game. + """ + + def __init__(self, key, name, entrances): + self.category = None + self.key = key + self.name = name + self.entrances = entrances + + def __eq__(self, other): + return (isinstance(other, Location) + and self.category == other.category and self.key == other.key and self.name == other.name) + + +class Entrance: + def __init__(self, key, name): + self.key = key + self.name = name + + def __eq__(self, other): + return (isinstance(other, Entrance) + and self.key == other.key and self.name == other.name) -- GitLab From 8aca5c1671798107417a9adfc30c214a7c90c115 Mon Sep 17 00:00:00 2001 From: Rens Oliemans Date: Thu, 13 Jan 2022 16:30:03 +0100 Subject: [PATCH 02/10] Refactor locationgrid to use new data structure We changed the internal data structure before, this commit refactors locationgrid.py to create buttons fitting with the new data structure --- data/platinum.py | 6 ++++-- links/linkmanager.py | 16 ++++++++-------- main.py | 5 ++--- pokerandom.py | 8 ++++---- util/locations.py | 6 ++++-- widgets/locationgrid.py | 11 +++++------ 6 files changed, 27 insertions(+), 25 deletions(-) diff --git a/data/platinum.py b/data/platinum.py index c4c27f7..6c4acb8 100644 --- a/data/platinum.py +++ b/data/platinum.py @@ -1,6 +1,8 @@ from util.locations import Category, Location, Entrance -CATEGORIES = { +INITIAL_LOCATION = 'sandgem_jubilife' + +CATEGORIES = [ Category('poi', 'Places of Interest', [ Location('oreburgh_gym_interior', 'Oreburgh Gym Interior', [Entrance('oreburgh_gym_interior', 'Oreburgh Gym Interior')]), @@ -666,4 +668,4 @@ CATEGORIES = { Entrance('r221_pal_park', 'R221 Pal Park'), ]), ]), -} +] diff --git a/links/linkmanager.py b/links/linkmanager.py index 31fd4fa..5bcdf6a 100644 --- a/links/linkmanager.py +++ b/links/linkmanager.py @@ -1,14 +1,14 @@ from links.db import Db from links.link import Link +from util.locations import Category class LinkManager: - def __init__(self, locations, entrances, database: Db): - self.locations = locations - self.entrances = entrances + def __init__(self, categories, database: Db): + self.categories = categories - self.all_locations = flatten_dict(self.entrances) - self.all_keys = {x[0] for x in self.all_locations} + self.all_locations = flatten_dict(self.categories) + self.all_keys = {x.key for x in self.all_locations} self._db = database def add_link(self, link: Link): @@ -34,6 +34,6 @@ class LinkManager: raise ValueError(f'{link.destination} not in the known locations.') -def flatten_dict(d): - sublists = [d[x] for x in d.keys()] - return {i for sub in sublists for i in sub} +def flatten_dict(d: [Category]): + entrances = [loc.entrances for sub in d for loc in sub.locations] + return {i for sub in entrances for i in sub} diff --git a/main.py b/main.py index 3123b79..61dc520 100644 --- a/main.py +++ b/main.py @@ -5,7 +5,7 @@ from os.path import join from PySide6.QtCore import QCoreApplication, Qt from PySide6.QtWidgets import QApplication -from util.locations import LOCATIONS, ENTRANCES +from data.platinum import CATEGORIES, INITIAL_LOCATION from pokerandom import PokeRandom from links.db import Db from timer import connect_shift @@ -20,8 +20,7 @@ if __name__ == '__main__': QCoreApplication.setAttribute(Qt.AA_UseHighDpiPixmaps) app = QApplication() with Db(database) as db: - pokerandom = PokeRandom(locations=LOCATIONS, initial_location=LOCATIONS['cities'][0], - entrances=ENTRANCES, db=db) + pokerandom = PokeRandom(categories=CATEGORIES, initial_location=INITIAL_LOCATION, db=db) timer = connect_shift(app, pokerandom.connections.show_double_connections, pokerandom.connections.hide_double_connections) diff --git a/pokerandom.py b/pokerandom.py index d1f9c59..072bb21 100644 --- a/pokerandom.py +++ b/pokerandom.py @@ -8,18 +8,18 @@ from links.linkmanager import LinkManager class PokeRandom(QWidget): - def __init__(self, locations, initial_location, entrances, db): + def __init__(self, categories, initial_location, db): super().__init__() self.setWindowTitle("Pokémon Platinum Randomizer Tracker") - self.link_manager = LinkManager(locations, entrances, db) + self.link_manager = LinkManager(categories, db) self.current_location = initial_location[0] - self.entrances = entrances + self.entrances = categories self._highlighting_entrances = [] self.locations = widgets.LocationGrid( - locations, on_click=self.set_current_location, on_enter=self.show_connections, + categories, on_click=self.set_current_location, on_enter=self.show_connections, on_leave=self.hide_connections, get_parent=self.get_location_of_entrance, max_rows=15 ) self.connections = widgets.ConnectionGrid( diff --git a/util/locations.py b/util/locations.py index 47bb8d4..f3fe515 100644 --- a/util/locations.py +++ b/util/locations.py @@ -17,14 +17,13 @@ class Location: """ def __init__(self, key, name, entrances): - self.category = None self.key = key self.name = name self.entrances = entrances def __eq__(self, other): return (isinstance(other, Location) - and self.category == other.category and self.key == other.key and self.name == other.name) + and self.key == other.key and self.name == other.name) class Entrance: @@ -35,3 +34,6 @@ class Entrance: def __eq__(self, other): return (isinstance(other, Entrance) and self.key == other.key and self.name == other.name) + + def __hash__(self): + return hash((self.key, self.name)) diff --git a/widgets/locationgrid.py b/widgets/locationgrid.py index 6a4ad74..45673bb 100644 --- a/widgets/locationgrid.py +++ b/widgets/locationgrid.py @@ -10,7 +10,7 @@ class LocationGrid(QGroupBox): def __init__(self, elements, on_click, on_enter, on_leave, get_parent, max_rows): super().__init__() - self.elements = elements + self.categories = elements self.on_click = on_click self.on_enter = on_enter self.on_leave = on_leave @@ -63,9 +63,8 @@ class LocationGrid(QGroupBox): widget.widget.setPalette(colors.default) def _create_widgets(self): - for category in self.elements.keys(): - for location_key, location_name in self.elements[category]: - yield Widget(location_key, - create_button(location_key, location_name, self.on_click, - on_enter=self.on_enter, on_leave=self.on_leave)) + for category in self.categories: + yield Widget(category.key, + create_button(category.key, category.name, self.on_click, + on_enter=self.on_enter, on_leave=self.on_leave)) -- GitLab From efd487f6341b11159de34b2f415ac0a518b4c5b7 Mon Sep 17 00:00:00 2001 From: Rens Oliemans Date: Thu, 13 Jan 2022 16:44:32 +0100 Subject: [PATCH 03/10] Make database and button creation use new data We can now create the location buttons with the new data --- links/db.py | 6 +++--- pokerandom.py | 17 +++++++++++++---- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/links/db.py b/links/db.py index d1dd947..267e071 100644 --- a/links/db.py +++ b/links/db.py @@ -13,11 +13,11 @@ class Db: self._cursor.execute("INSERT INTO link VALUES (?, ?, ?, ?, ?)", (link.entrance, link.destination, link.one_way, block, link.note)) - def get(self, locations=None): - if locations is None: + def get(self, entrances=None): + if entrances is None: self._cursor.execute("SELECT * FROM link") else: - args = [locations[0] for locations in locations] + args = [entrance.key for entrance in entrances] self._cursor.execute('SELECT * FROM link WHERE entrance IN ({seq}) OR destination IN ({seq})' .format(seq=','.join(['?']*len(args))), args*2) diff --git a/pokerandom.py b/pokerandom.py index 072bb21..4c6e29f 100644 --- a/pokerandom.py +++ b/pokerandom.py @@ -13,7 +13,7 @@ class PokeRandom(QWidget): self.setWindowTitle("Pokémon Platinum Randomizer Tracker") self.link_manager = LinkManager(categories, db) - self.current_location = initial_location[0] + self.current_location = initial_location self.entrances = categories self._highlighting_entrances = [] @@ -56,7 +56,7 @@ class PokeRandom(QWidget): self.redraw_location() def redraw_location(self): - links = self.link_manager.get_links(self.entrances[self.current_location]) + links = self.link_manager.get_links(self._get_keys_of_current_category()) self.locations.change_location(self.current_location, links) self.connections.set_buttons(self.current_location, links) @@ -68,8 +68,8 @@ class PokeRandom(QWidget): self.redraw_location() def get_location_of_entrance(self, key): - for category, entrances in self.entrances.items(): - if key in [entrance[0] for entrance in entrances]: + for category in self.entrances: + if key in [locations.entrances for locations in category.locations]: return category def get_name_of_location(self, key): @@ -141,5 +141,14 @@ class PokeRandom(QWidget): link = self.link_manager.get_link(key) return link.other(key) if link is not None else None + def _get_keys_of_current_category(self): + category = [x for x in self.entrances if x.key == self.current_location][0] + return self._get_keys_of_locations(category.locations) + + def _get_keys_of_locations(self, locations): + for x in locations: + for e in x.entrances: + yield e + def show_help(self): self.help.show() -- GitLab From a62abba9a9e98522d57d1f9a808dc5e4597b81cd Mon Sep 17 00:00:00 2001 From: Rens Oliemans Date: Thu, 13 Jan 2022 17:09:16 +0100 Subject: [PATCH 04/10] Correctly draw all buttons Connectiongrid is now refactored as well, so that it can use the new data structure. Hovering and selecting still does not work --- pokerandom.py | 12 ++---------- util/locations.py | 11 +++++++++++ widgets/connectiongrid.py | 16 +++++++++------- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/pokerandom.py b/pokerandom.py index 4c6e29f..3c4edee 100644 --- a/pokerandom.py +++ b/pokerandom.py @@ -5,6 +5,7 @@ from PySide6.QtWidgets import QWidget, QVBoxLayout, QGridLayout import widgets from links.link import Link from links.linkmanager import LinkManager +from util.locations import get_keys_of_category class PokeRandom(QWidget): @@ -56,7 +57,7 @@ class PokeRandom(QWidget): self.redraw_location() def redraw_location(self): - links = self.link_manager.get_links(self._get_keys_of_current_category()) + links = self.link_manager.get_links(get_keys_of_category(self.entrances, self.current_location)) self.locations.change_location(self.current_location, links) self.connections.set_buttons(self.current_location, links) @@ -141,14 +142,5 @@ class PokeRandom(QWidget): link = self.link_manager.get_link(key) return link.other(key) if link is not None else None - def _get_keys_of_current_category(self): - category = [x for x in self.entrances if x.key == self.current_location][0] - return self._get_keys_of_locations(category.locations) - - def _get_keys_of_locations(self, locations): - for x in locations: - for e in x.entrances: - yield e - def show_help(self): self.help.show() diff --git a/util/locations.py b/util/locations.py index f3fe515..a919ccf 100644 --- a/util/locations.py +++ b/util/locations.py @@ -37,3 +37,14 @@ class Entrance: def __hash__(self): return hash((self.key, self.name)) + + +def get_keys_of_category(categories, key): + category = [x for x in categories if x.key == key][0] + return _get_keys_of_locations(category.locations) + + +def _get_keys_of_locations(locations): + for x in locations: + for e in x.entrances: + yield e diff --git a/widgets/connectiongrid.py b/widgets/connectiongrid.py index 2d35a2e..03550df 100644 --- a/widgets/connectiongrid.py +++ b/widgets/connectiongrid.py @@ -3,6 +3,7 @@ from PySide6.QtWidgets import QGridLayout, QGroupBox, QApplication from util.button import create_button, EntranceButton from util.gridutils import compute_cols, divide_widgets_per_column, create_grid +from util.locations import get_keys_of_category from util.widget import Widget @@ -65,13 +66,14 @@ class ConnectionGrid(QGroupBox): self.buttons.addWidget(widget.widget, row, column) def _create_widgets(self, location, links): - elements = self.elements[location] - for key, name in elements: - link = get_link_of_button(key, links) - name = self._create_name(key, name, link) - yield Widget(key, create_button(key, name, self.on_click, on_ctrl_click=self.on_ctrl_click, - on_enter=self.on_enter, on_leave=self.on_leave, link=link, - get_location_name=self.get_location_name)) + entrances = get_keys_of_category(self.elements, location) + for entrance in entrances: + link = get_link_of_button(entrance.key, links) + name = self._create_name(entrance.key, entrance.name, link) + yield Widget(entrance.key, + create_button(entrance.key, name, self.on_click, on_ctrl_click=self.on_ctrl_click, + on_enter=self.on_enter, on_leave=self.on_leave, link=link, + get_location_name=self.get_location_name)) def _create_name(self, key, name, link): if not link or link.blocked: -- GitLab From ab4a2acbec8a6e86dd5a063d607d6ddb3d0a98ab Mon Sep 17 00:00:00 2001 From: Rens Oliemans Date: Thu, 13 Jan 2022 18:20:18 +0100 Subject: [PATCH 05/10] Make everything work except ctrl+click Ctrl+click needs a refactor of the Link class to support the new Entrances. However, all of the remaining functionality is working again. --- data/platinum.py | 2 +- pokerandom.py | 39 +++++++++-------- test/location_test.py | 89 +++++++++++++++++++++++++++++++++++++++ util/button.py | 30 ++++++------- util/locations.py | 21 +++++++-- widgets/connectiongrid.py | 14 +++--- widgets/locationgrid.py | 2 +- widgets/status.py | 13 +++--- 8 files changed, 156 insertions(+), 54 deletions(-) create mode 100644 test/location_test.py diff --git a/data/platinum.py b/data/platinum.py index 6c4acb8..46c6187 100644 --- a/data/platinum.py +++ b/data/platinum.py @@ -1,6 +1,6 @@ from util.locations import Category, Location, Entrance -INITIAL_LOCATION = 'sandgem_jubilife' +INITIAL_LOCATION = Category('sandgem_jubilife', 'Sandgem/Jubilife', []) CATEGORIES = [ Category('poi', 'Places of Interest', [ diff --git a/pokerandom.py b/pokerandom.py index 3c4edee..02aa739 100644 --- a/pokerandom.py +++ b/pokerandom.py @@ -5,7 +5,7 @@ from PySide6.QtWidgets import QWidget, QVBoxLayout, QGridLayout import widgets from links.link import Link from links.linkmanager import LinkManager -from util.locations import get_keys_of_category +from util.locations import get_keys_of_category, get_name_of_key, get_location_of_entrance class PokeRandom(QWidget): @@ -52,12 +52,12 @@ class PokeRandom(QWidget): super(PokeRandom, self).setVisible(visible) def set_current_location(self, location): - self.current_location = location - self.image.set_image(location) + self.current_location = location.key + self.image.set_image(self.current_location) self.redraw_location() def redraw_location(self): - links = self.link_manager.get_links(get_keys_of_category(self.entrances, self.current_location)) + links = self.link_manager.get_links(self.get_keys_of_category()) self.locations.change_location(self.current_location, links) self.connections.set_buttons(self.current_location, links) @@ -69,32 +69,26 @@ class PokeRandom(QWidget): self.redraw_location() def get_location_of_entrance(self, key): - for category in self.entrances: - if key in [locations.entrances for locations in category.locations]: - return category + return get_location_of_entrance(self.entrances, key) def get_name_of_location(self, key): - all_entrances = [self.entrances[x] for x in self.entrances.keys()] - flattened = [i for sub in all_entrances for i in sub] - try: - return [x[1] for x in flattened if key == x[0]][0] - except IndexError: - logging.error('Could not find key %s, when I really expected it.', key) + return get_name_of_key(self.entrances, key) - def show_connection(self, key): - destination = self._get_destination(key) + def show_connection(self, entrance): + destination = self._get_destination(entrance.key) self.locations.show_destination(self.get_location_of_entrance(destination)) self.connections.show_destination(destination) - def hide_connection(self, key): - destination = self._get_destination(key) + def hide_connection(self, entrance): + destination = self._get_destination(entrance.key) self.locations.set_buttons() self.connections.hide_destination(destination) - def show_connections(self, key): - self._highlighting_entrances = self.link_manager.get_links(self.entrances[key]) + def show_connections(self, category): + key = category.key + self._highlighting_entrances = self.link_manager.get_links(self.get_keys_of_category(key)) for link in self._highlighting_entrances: if self.get_location_of_entrance(link.entrance) == key: self.connections.show_destination(link.destination) @@ -127,7 +121,7 @@ class PokeRandom(QWidget): return location = self.get_location_of_entrance(destination) - destinations_of_destination = self.link_manager.get_links(self.entrances[location]) + destinations_of_destination = self.link_manager.get_links(self.get_keys_of_category(location)) for link in destinations_of_destination: loc = link.destination if self.get_location_of_entrance(link.entrance) == location else link.entrance @@ -142,5 +136,10 @@ class PokeRandom(QWidget): link = self.link_manager.get_link(key) return link.other(key) if link is not None else None + def get_keys_of_category(self, key=None): + if key is None: + key = self.current_location + return get_keys_of_category(self.entrances, key) + def show_help(self): self.help.show() diff --git a/test/location_test.py b/test/location_test.py new file mode 100644 index 0000000..81ac369 --- /dev/null +++ b/test/location_test.py @@ -0,0 +1,89 @@ +import unittest + +from util.locations import Category, Location, Entrance, get_keys_of_category, get_name_of_key, get_location_of_entrance + +simple_categories = [ + Category('test', 'name', [ + Location('loc1', 'location 1', [ + Entrance('e1', 'E1'), + Entrance('e2', 'E2') + ]), + ]), +] + +medium_categories = [ + Category('test', 'name', [ + Location('loc1', 'location 1', [ + Entrance('e1', 'E1'), + Entrance('e2', 'E2') + ]), + Location('loc2', 'location 2', [ + Entrance('e12', 'E12') + ]) + ]) +] + +complex_categories = [ + Category('test', 'name', [ + Location('loc1', 'location 1', [ + Entrance('e1', 'E1'), + Entrance('e2', 'E2') + ]), + ]), + Category('second', 'Second', [ + Location('abc', 'ABC', [ + Entrance('entrance_1', 'Entrance 1'), + Entrance('entrance_2', 'Entrance 2') + ]), + Location('def', 'DEF', [ + Entrance('entrance_12', 'Entrance 12') + ]) + ]), + Category('third', 'Second', [ + Location('ghi', 'GHI', [ + Entrance('entrance_4', 'Entrance 4') + ]), + ]) +] + + +class TestGetKeysOfCategory(unittest.TestCase): + def test_first_category(self): + expected = [ + Entrance('e1', 'E1'), + Entrance('e2', 'E2'), + Entrance('e12', 'E12'), + ] + self.assertEqual(expected, list(get_keys_of_category(medium_categories, 'test'))) + + def test_complex_category(self): + expected = [ + Entrance('entrance_1', 'Entrance 1'), + Entrance('entrance_2', 'Entrance 2'), + Entrance('entrance_12', 'Entrance 12'), + ] + self.assertEqual(expected, list(get_keys_of_category(complex_categories, 'second'))) + + +class TestGetNameOfKey(unittest.TestCase): + def test_get_name_of_first_key(self): + expected = 'E1' + self.assertEqual(expected, get_name_of_key(simple_categories, 'e1')) + + def test_get_name_of_later_key(self): + expected = 'Entrance 12' + self.assertEqual(expected, get_name_of_key(complex_categories, 'entrance_12')) + + +class TestGetCategoryOfEntrance(unittest.TestCase): + def test_get_category_of_first_key(self): + expected = 'test' + self.assertEqual(expected, get_location_of_entrance(simple_categories, 'e1')) + + def test_get_category_of_later_key(self): + expected = 'second' + self.assertEqual(expected, get_location_of_entrance(simple_categories, 'entrance_12')) + + +if __name__ == '__main__': + unittest.main() diff --git a/util/button.py b/util/button.py index ad32755..5fb88d4 100644 --- a/util/button.py +++ b/util/button.py @@ -7,18 +7,17 @@ from util.blocked import Blocked class EntranceButton(QPushButton): - def __init__(self, key, name, on_click, on_ctrl_click=None, on_enter=None, on_leave=None, link=None, - get_location_name=None): - super().__init__(name) - self.key = key + def __init__(self, entrance, on_click, on_ctrl_click=None, on_enter=None, on_leave=None, link=None, text=None): + super().__init__(text or entrance.name) + self.entrance = entrance + self.key = entrance.key self.link = link self.on_click = on_click self.on_ctrl_click = on_ctrl_click self.on_enter = on_enter self.on_leave = on_leave - self.get_location_name = get_location_name - self.clicked.connect(lambda: self.call(key)) + self.clicked.connect(lambda: self.call(entrance)) self.draw() def mousePressEvent(self, e: QMouseEvent) -> None: @@ -27,9 +26,9 @@ class EntranceButton(QPushButton): super().mousePressEvent(e) - def call(self, key): - self.on_leave(key) - self.on_click(key) + def call(self, entrance): + self.on_leave(entrance) + self.on_click(entrance) def draw(self, active=False, selected=False): if selected: @@ -44,7 +43,7 @@ class EntranceButton(QPushButton): elif self.link.has_note: self.change_color(colors.note) else: - self.change_color(colors.existing_link, tooltip=self.get_location_name(self.link.other(self.key))) + self.change_color(colors.existing_link, tooltip=self.link.other(self.key)) def draw_blocked(self): if self.link.dead_end: @@ -79,16 +78,15 @@ class EntranceButton(QPushButton): def enterEvent(self, event: QEnterEvent) -> None: if self.on_enter: - self.on_enter(self.key) + self.on_enter(self.entrance) def leaveEvent(self, event: QEvent) -> None: if self.on_leave: - self.on_leave(self.key) + self.on_leave(self.entrance) def __repr__(self): - return f"" + return f"" -def create_button(key, name, on_click, *, on_ctrl_click=None, on_enter=None, on_leave=None, link=None, - get_location_name=None): - return EntranceButton(key, name, on_click, on_ctrl_click, on_enter, on_leave, link, get_location_name) +def create_button(entrance, on_click, *, on_ctrl_click=None, on_enter=None, on_leave=None, link=None, text=None): + return EntranceButton(entrance, on_click, on_ctrl_click, on_enter, on_leave, link, text) diff --git a/util/locations.py b/util/locations.py index a919ccf..b5c762b 100644 --- a/util/locations.py +++ b/util/locations.py @@ -44,7 +44,22 @@ def get_keys_of_category(categories, key): return _get_keys_of_locations(category.locations) +def get_name_of_key(categories, key): + for category in categories: + for location in category.locations: + for entrance in location.entrances: + if entrance.key == key: + return entrance.name + + +def get_location_of_entrance(categories, key): + for category in categories: + for location in category.locations: + if key in [e.key for e in location.entrances]: + return category.key + + def _get_keys_of_locations(locations): - for x in locations: - for e in x.entrances: - yield e + for loc in locations: + for entrance in loc.entrances: + yield entrance diff --git a/widgets/connectiongrid.py b/widgets/connectiongrid.py index 03550df..05cf47f 100644 --- a/widgets/connectiongrid.py +++ b/widgets/connectiongrid.py @@ -69,20 +69,20 @@ class ConnectionGrid(QGroupBox): entrances = get_keys_of_category(self.elements, location) for entrance in entrances: link = get_link_of_button(entrance.key, links) - name = self._create_name(entrance.key, entrance.name, link) + name = self._create_name(entrance, link) yield Widget(entrance.key, - create_button(entrance.key, name, self.on_click, on_ctrl_click=self.on_ctrl_click, + create_button(entrance, self.on_click, on_ctrl_click=self.on_ctrl_click, on_enter=self.on_enter, on_leave=self.on_leave, link=link, - get_location_name=self.get_location_name)) + text=name)) - def _create_name(self, key, name, link): + def _create_name(self, entrance, link): if not link or link.blocked: - return name + return entrance.name if link.has_note: - return f'{name} — {link.note}' + return f'{entrance.name} — {link.note}' - return f'{name} -> {self.get_location_name(link.other(key))}' + return f'{entrance.name} -> {self.get_location_name(link.other(entrance.key))}' def show_double_connections(self): w = QApplication.widgetAt(QCursor.pos(self.screen())) diff --git a/widgets/locationgrid.py b/widgets/locationgrid.py index 45673bb..5d2d3bb 100644 --- a/widgets/locationgrid.py +++ b/widgets/locationgrid.py @@ -65,6 +65,6 @@ class LocationGrid(QGroupBox): def _create_widgets(self): for category in self.categories: yield Widget(category.key, - create_button(category.key, category.name, self.on_click, + create_button(category, self.on_click, on_enter=self.on_enter, on_leave=self.on_leave)) diff --git a/widgets/status.py b/widgets/status.py index 6d95afd..523559b 100644 --- a/widgets/status.py +++ b/widgets/status.py @@ -23,13 +23,13 @@ class Status(QGroupBox): self.layout.addWidget(self.one_way_widget, 1, 0) self.layout.addWidget(self.note, 0, 1) - def select_item(self, key): + def select_item(self, entrance): if self.entrance is None: - self.entrance = key - elif self.entrance == key: + self.entrance = entrance + elif self.entrance == entrance: return else: - self.save(destination=key, one_way=self.one_way) + self.save(destination=entrance, one_way=self.one_way) def cancel(self): self.entrance = None @@ -56,7 +56,8 @@ class Status(QGroupBox): self.note.clear() def save(self, *, destination=None, one_way=False, block=None, note=None): - self.add_link_callback(self.entrance, destination, one_way=one_way, block=block, note=note) + destination = destination.key if destination else None + self.add_link_callback(self.entrance.key, destination, one_way=one_way, block=block, note=note) self.cancel() @property @@ -81,5 +82,5 @@ class Status(QGroupBox): if value is None: self.entrance_widget.setText('Select a location') else: - self.entrance_widget.setText(f"Selected '{self.get_name_of_location(value)}'") + self.entrance_widget.setText(f"Selected '{value.name}'") self.selected_callback(value, selected=value is not None) -- GitLab From a453eae0eb8cd96a2179f22df83fa490bba6140c Mon Sep 17 00:00:00 2001 From: Rens Oliemans Date: Thu, 13 Jan 2022 19:33:32 +0100 Subject: [PATCH 06/10] Make last things working with Entrances We still need to show the actually reachable locations with shift-hover, but all old functionality works with the new data structure. --- links/link.py | 8 ++++---- pokerandom.py | 32 ++++++++++++++++++++------------ test/location_test.py | 10 +++++----- util/button.py | 5 ++--- util/locations.py | 4 ++-- widgets/connectiongrid.py | 4 ++-- widgets/locationgrid.py | 20 +++++++++++++------- 7 files changed, 48 insertions(+), 35 deletions(-) diff --git a/links/link.py b/links/link.py index 30c5ffb..5d161b5 100644 --- a/links/link.py +++ b/links/link.py @@ -24,10 +24,10 @@ class Link: def has_note(self): return self.note is not None - def other(self, key): - if key not in self: - logging.error('Key %s was not found in link %s', key, self) - if key == self.entrance: + def other(self, entrance): + if entrance not in self: + logging.error('Key %s was not found in link %s', entrance, self) + if entrance == self.entrance: return self.destination return self.entrance diff --git a/pokerandom.py b/pokerandom.py index 02aa739..fdc2db1 100644 --- a/pokerandom.py +++ b/pokerandom.py @@ -5,7 +5,7 @@ from PySide6.QtWidgets import QWidget, QVBoxLayout, QGridLayout import widgets from links.link import Link from links.linkmanager import LinkManager -from util.locations import get_keys_of_category, get_name_of_key, get_location_of_entrance +from util.locations import get_keys_of_category, get_name_of_key, get_category_of_entrance class PokeRandom(QWidget): @@ -21,7 +21,7 @@ class PokeRandom(QWidget): self.locations = widgets.LocationGrid( categories, on_click=self.set_current_location, on_enter=self.show_connections, - on_leave=self.hide_connections, get_parent=self.get_location_of_entrance, max_rows=15 + on_leave=self.hide_connections, get_parent=self.get_category_of_entrance, max_rows=15 ) self.connections = widgets.ConnectionGrid( self.entrances, on_click=self.select_connection, on_ctrl_click=self._change_location_by_entrance, @@ -68,8 +68,8 @@ class PokeRandom(QWidget): self.link_manager.add_link(Link(entrance, destination, one_way, block, note)) self.redraw_location() - def get_location_of_entrance(self, key): - return get_location_of_entrance(self.entrances, key) + def get_category_of_entrance(self, key): + return get_category_of_entrance(self.entrances, key) def get_name_of_location(self, key): return get_name_of_key(self.entrances, key) @@ -77,7 +77,7 @@ class PokeRandom(QWidget): def show_connection(self, entrance): destination = self._get_destination(entrance.key) - self.locations.show_destination(self.get_location_of_entrance(destination)) + self.locations.show_destination(self.get_category_of_entrance(destination)) self.connections.show_destination(destination) def hide_connection(self, entrance): @@ -90,9 +90,17 @@ class PokeRandom(QWidget): key = category.key self._highlighting_entrances = self.link_manager.get_links(self.get_keys_of_category(key)) for link in self._highlighting_entrances: - if self.get_location_of_entrance(link.entrance) == key: + x = self.get_category_of_entrance(link.entrance) + if x is None: + pass + if x.key == key: self.connections.show_destination(link.destination) - if self.get_location_of_entrance(link.destination) == key: + + destination = self.get_category_of_entrance(link.destination) + if destination is None: + return + + if destination.key == key: self.connections.show_destination(link.entrance) def hide_connections(self, key): @@ -120,15 +128,15 @@ class PokeRandom(QWidget): if destination is None: return - location = self.get_location_of_entrance(destination) - destinations_of_destination = self.link_manager.get_links(self.get_keys_of_category(location)) + location = self.get_category_of_entrance(destination) + destinations_of_destination = self.link_manager.get_links(self.get_keys_of_category(location.key)) for link in destinations_of_destination: - loc = link.destination if self.get_location_of_entrance(link.entrance) == location else link.entrance + loc = link.destination if self.get_category_of_entrance(link.entrance) == location else link.entrance - self.locations.show_second_destination(self.get_location_of_entrance(loc)) + self.locations.show_second_destination(self.get_category_of_entrance(loc)) def _change_location_by_entrance(self, key): - location = self.get_location_of_entrance(key) + location = self.get_category_of_entrance(key) if location: self.set_current_location(location) diff --git a/test/location_test.py b/test/location_test.py index 81ac369..be68d38 100644 --- a/test/location_test.py +++ b/test/location_test.py @@ -1,6 +1,6 @@ import unittest -from util.locations import Category, Location, Entrance, get_keys_of_category, get_name_of_key, get_location_of_entrance +from util.locations import Category, Location, Entrance, get_keys_of_category, get_name_of_key, get_category_of_entrance simple_categories = [ Category('test', 'name', [ @@ -77,12 +77,12 @@ class TestGetNameOfKey(unittest.TestCase): class TestGetCategoryOfEntrance(unittest.TestCase): def test_get_category_of_first_key(self): - expected = 'test' - self.assertEqual(expected, get_location_of_entrance(simple_categories, 'e1')) + expected = simple_categories[0] + self.assertEqual(expected, get_category_of_entrance(simple_categories, 'e1')) def test_get_category_of_later_key(self): - expected = 'second' - self.assertEqual(expected, get_location_of_entrance(simple_categories, 'entrance_12')) + expected = complex_categories[1] + self.assertEqual(expected, get_category_of_entrance(complex_categories, 'entrance_12')) if __name__ == '__main__': diff --git a/util/button.py b/util/button.py index 5fb88d4..1d9b219 100644 --- a/util/button.py +++ b/util/button.py @@ -10,7 +10,6 @@ class EntranceButton(QPushButton): def __init__(self, entrance, on_click, on_ctrl_click=None, on_enter=None, on_leave=None, link=None, text=None): super().__init__(text or entrance.name) self.entrance = entrance - self.key = entrance.key self.link = link self.on_click = on_click self.on_ctrl_click = on_ctrl_click @@ -22,7 +21,7 @@ class EntranceButton(QPushButton): def mousePressEvent(self, e: QMouseEvent) -> None: if e.modifiers() == Qt.ControlModifier and self.on_ctrl_click is not None: - return self.on_ctrl_click(self.link.other(self.key)) + return self.on_ctrl_click(self.link.other(self.entrance.key)) super().mousePressEvent(e) @@ -43,7 +42,7 @@ class EntranceButton(QPushButton): elif self.link.has_note: self.change_color(colors.note) else: - self.change_color(colors.existing_link, tooltip=self.link.other(self.key)) + self.change_color(colors.existing_link, tooltip=self.link.other(self.entrance.key)) def draw_blocked(self): if self.link.dead_end: diff --git a/util/locations.py b/util/locations.py index b5c762b..a1aee21 100644 --- a/util/locations.py +++ b/util/locations.py @@ -52,11 +52,11 @@ def get_name_of_key(categories, key): return entrance.name -def get_location_of_entrance(categories, key): +def get_category_of_entrance(categories, key): for category in categories: for location in category.locations: if key in [e.key for e in location.entrances]: - return category.key + return category def _get_keys_of_locations(locations): diff --git a/widgets/connectiongrid.py b/widgets/connectiongrid.py index 05cf47f..26161fc 100644 --- a/widgets/connectiongrid.py +++ b/widgets/connectiongrid.py @@ -87,8 +87,8 @@ class ConnectionGrid(QGroupBox): def show_double_connections(self): w = QApplication.widgetAt(QCursor.pos(self.screen())) if type(w) is EntranceButton: - if not self.double_information == w.key: - self.double_information = w.key + if not self.double_information == w.entrance.key: + self.double_information = w.entrance.key self.show_double(self.double_information) else: self.double_information = None diff --git a/widgets/locationgrid.py b/widgets/locationgrid.py index 5d2d3bb..c4b169c 100644 --- a/widgets/locationgrid.py +++ b/widgets/locationgrid.py @@ -31,18 +31,17 @@ class LocationGrid(QGroupBox): def set_buttons(self): self._clear_colors() - locations = [self.get_parent(link.entrance) - if self.get_parent(link.destination) == self.location else self.get_parent(link.destination) - for link in self.links] + categories = self._get_linked_categories() + categories = [category.key for category in categories if category] for widget in self.widgets: - if widget.key in locations: + if widget.key in categories: widget.widget.setPalette(colors.existing_link) - def show_destination(self, key): - if key is None: + def show_destination(self, category): + if category is None: return - widgets_to_change = [w for w in self.widgets if w.key == key] + widgets_to_change = [w for w in self.widgets if w.key == category.key] for widget in widgets_to_change: widget.widget.setPalette(colors.linked) @@ -68,3 +67,10 @@ class LocationGrid(QGroupBox): create_button(category, self.on_click, on_enter=self.on_enter, on_leave=self.on_leave)) + def _get_linked_categories(self): + for link in self.links: + dest_parent = self.get_parent(link.destination) + if dest_parent and dest_parent.key == self.location: + yield self.get_parent(link.entrance) + else: + yield self.get_parent(link.destination) -- GitLab From 8660164e654286270836d2ed77eaf762c5884217 Mon Sep 17 00:00:00 2001 From: Rens Oliemans Date: Thu, 13 Jan 2022 19:34:59 +0100 Subject: [PATCH 07/10] Remove testing code --- pokerandom.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/pokerandom.py b/pokerandom.py index fdc2db1..90a9547 100644 --- a/pokerandom.py +++ b/pokerandom.py @@ -90,10 +90,7 @@ class PokeRandom(QWidget): key = category.key self._highlighting_entrances = self.link_manager.get_links(self.get_keys_of_category(key)) for link in self._highlighting_entrances: - x = self.get_category_of_entrance(link.entrance) - if x is None: - pass - if x.key == key: + if self.get_category_of_entrance(link.entrance).key == key: self.connections.show_destination(link.destination) destination = self.get_category_of_entrance(link.destination) -- GitLab From 7f517808b1162f8d0d6d952229cc2bfb6cbec458 Mon Sep 17 00:00:00 2001 From: Rens Oliemans Date: Thu, 13 Jan 2022 19:37:20 +0100 Subject: [PATCH 08/10] Add functionality to get location by an entrance Needed for new shift-hover functionality. --- pokerandom.py | 6 +++--- test/location_test.py | 13 ++++++++++++- util/locations.py | 7 +++++++ 3 files changed, 22 insertions(+), 4 deletions(-) diff --git a/pokerandom.py b/pokerandom.py index 90a9547..d2c16ae 100644 --- a/pokerandom.py +++ b/pokerandom.py @@ -125,10 +125,10 @@ class PokeRandom(QWidget): if destination is None: return - location = self.get_category_of_entrance(destination) - destinations_of_destination = self.link_manager.get_links(self.get_keys_of_category(location.key)) + category = self.get_category_of_entrance(destination) + destinations_of_destination = self.link_manager.get_links(self.get_keys_of_category(category.key)) for link in destinations_of_destination: - loc = link.destination if self.get_category_of_entrance(link.entrance) == location else link.entrance + loc = link.destination if self.get_category_of_entrance(link.entrance) == category else link.entrance self.locations.show_second_destination(self.get_category_of_entrance(loc)) diff --git a/test/location_test.py b/test/location_test.py index be68d38..a40d9a4 100644 --- a/test/location_test.py +++ b/test/location_test.py @@ -1,6 +1,7 @@ import unittest -from util.locations import Category, Location, Entrance, get_keys_of_category, get_name_of_key, get_category_of_entrance +from util.locations import Category, Location, Entrance, get_keys_of_category, get_name_of_key, \ + get_category_of_entrance, get_location_of_entrance simple_categories = [ Category('test', 'name', [ @@ -85,5 +86,15 @@ class TestGetCategoryOfEntrance(unittest.TestCase): self.assertEqual(expected, get_category_of_entrance(complex_categories, 'entrance_12')) +class TestGetLocationOfEntrance(unittest.TestCase): + def test_get_location_of_first_key(self): + expected = simple_categories[0].locations[0] + self.assertEqual(expected, get_location_of_entrance(simple_categories, 'e1')) + + def test_get_location_of_later_key(self): + expected = complex_categories[1].locations[1] + self.assertEqual(expected, get_location_of_entrance(complex_categories, 'entrance_12')) + + if __name__ == '__main__': unittest.main() diff --git a/util/locations.py b/util/locations.py index a1aee21..bb75a8b 100644 --- a/util/locations.py +++ b/util/locations.py @@ -59,6 +59,13 @@ def get_category_of_entrance(categories, key): return category +def get_location_of_entrance(categories, key): + for category in categories: + for location in category.locations: + if key in [e.key for e in location.entrances]: + return location + + def _get_keys_of_locations(locations): for loc in locations: for entrance in loc.entrances: -- GitLab From e886598b121506376b974f60b91d2633eba61fe0 Mon Sep 17 00:00:00 2001 From: Rens Oliemans Date: Thu, 13 Jan 2022 19:41:06 +0100 Subject: [PATCH 09/10] Show only locations reachable by actual connection We might later choose a more efficient way to loop over all categories and locations, but this seems sufficient for now. Related: #30. --- pokerandom.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/pokerandom.py b/pokerandom.py index d2c16ae..04b914d 100644 --- a/pokerandom.py +++ b/pokerandom.py @@ -5,7 +5,7 @@ from PySide6.QtWidgets import QWidget, QVBoxLayout, QGridLayout import widgets from links.link import Link from links.linkmanager import LinkManager -from util.locations import get_keys_of_category, get_name_of_key, get_category_of_entrance +from util.locations import get_keys_of_category, get_name_of_key, get_category_of_entrance, get_location_of_entrance class PokeRandom(QWidget): @@ -68,12 +68,15 @@ class PokeRandom(QWidget): self.link_manager.add_link(Link(entrance, destination, one_way, block, note)) self.redraw_location() - def get_category_of_entrance(self, key): - return get_category_of_entrance(self.entrances, key) - def get_name_of_location(self, key): return get_name_of_key(self.entrances, key) + def get_location_of_entrance(self, key): + return get_location_of_entrance(self.entrances, key) + + def get_category_of_entrance(self, key): + return get_category_of_entrance(self.entrances, key) + def show_connection(self, entrance): destination = self._get_destination(entrance.key) @@ -126,9 +129,10 @@ class PokeRandom(QWidget): return category = self.get_category_of_entrance(destination) + location = self.get_location_of_entrance(destination) destinations_of_destination = self.link_manager.get_links(self.get_keys_of_category(category.key)) for link in destinations_of_destination: - loc = link.destination if self.get_category_of_entrance(link.entrance) == category else link.entrance + loc = link.destination if self.get_location_of_entrance(link.entrance) == location else link.entrance self.locations.show_second_destination(self.get_category_of_entrance(loc)) -- GitLab From 982b7f0a0c8752441efed5f8317d2f550133a04f Mon Sep 17 00:00:00 2001 From: Rens Oliemans Date: Thu, 13 Jan 2022 21:14:02 +0100 Subject: [PATCH 10/10] Show reachable locations for all links Previous commit only showed it one direction (when the hovering link was an entrance), now it works fully. Further refactors can try to make the code a bit more readable, or decrease the amount of loops that we have to do when checking for neighbouring locations/connections. Fixes #30 --- data/platinum.py | 9 ++++++--- pokerandom.py | 16 ++++++++++------ test/location_test.py | 24 ++++++++++++++++++++---- util/locations.py | 13 ++++++++++--- widgets/connectiongrid.py | 4 ++-- 5 files changed, 48 insertions(+), 18 deletions(-) diff --git a/data/platinum.py b/data/platinum.py index 46c6187..9026f59 100644 --- a/data/platinum.py +++ b/data/platinum.py @@ -660,9 +660,12 @@ CATEGORIES = [ ]), ]), Category('surf_hub', 'Surf Hub', [ - Location('lake_verity', 'Lake Verity', [Entrance('lake_verity', 'Lake Verity')]), - Location('lake_valor', 'Lake Valor', [Entrance('lake_valor', 'Lake Valor')]), - Location('lake_acuity', 'Lake Acuity', [Entrance('lake_acuity', 'Lake Acuity')]), + Location('lake_verity', 'Lake Verity', + [Entrance('lake_verity', 'Lake Verity')]), + Location('lake_valor', 'Lake Valor', + [Entrance('lake_valor', 'Lake Valor')]), + Location('lake_acuity', 'Lake Acuity', + [Entrance('lake_acuity', 'Lake Acuity')]), Location('r221', 'Route 221', [ Entrance('r221_house', 'R221 House'), Entrance('r221_pal_park', 'R221 Pal Park'), diff --git a/pokerandom.py b/pokerandom.py index 04b914d..f5c192d 100644 --- a/pokerandom.py +++ b/pokerandom.py @@ -5,7 +5,8 @@ from PySide6.QtWidgets import QWidget, QVBoxLayout, QGridLayout import widgets from links.link import Link from links.linkmanager import LinkManager -from util.locations import get_keys_of_category, get_name_of_key, get_category_of_entrance, get_location_of_entrance +from util.locations import get_entrances_of_category, get_name_of_key, get_category_of_entrance, \ + get_location_of_entrance, get_entrances_of_location class PokeRandom(QWidget): @@ -57,7 +58,7 @@ class PokeRandom(QWidget): self.redraw_location() def redraw_location(self): - links = self.link_manager.get_links(self.get_keys_of_category()) + links = self.link_manager.get_links(self.get_entrances_of_category()) self.locations.change_location(self.current_location, links) self.connections.set_buttons(self.current_location, links) @@ -91,7 +92,7 @@ class PokeRandom(QWidget): def show_connections(self, category): key = category.key - self._highlighting_entrances = self.link_manager.get_links(self.get_keys_of_category(key)) + self._highlighting_entrances = self.link_manager.get_links(self.get_entrances_of_category(key)) for link in self._highlighting_entrances: if self.get_category_of_entrance(link.entrance).key == key: self.connections.show_destination(link.destination) @@ -130,7 +131,7 @@ class PokeRandom(QWidget): category = self.get_category_of_entrance(destination) location = self.get_location_of_entrance(destination) - destinations_of_destination = self.link_manager.get_links(self.get_keys_of_category(category.key)) + destinations_of_destination = self.link_manager.get_links(self.get_entrances_of_location(location.key)) for link in destinations_of_destination: loc = link.destination if self.get_location_of_entrance(link.entrance) == location else link.entrance @@ -145,10 +146,13 @@ class PokeRandom(QWidget): link = self.link_manager.get_link(key) return link.other(key) if link is not None else None - def get_keys_of_category(self, key=None): + def get_entrances_of_category(self, key=None): if key is None: key = self.current_location - return get_keys_of_category(self.entrances, key) + return get_entrances_of_category(self.entrances, key) + + def get_entrances_of_location(self, key): + return get_entrances_of_location(self.entrances, key) def show_help(self): self.help.show() diff --git a/test/location_test.py b/test/location_test.py index a40d9a4..53a661f 100644 --- a/test/location_test.py +++ b/test/location_test.py @@ -1,7 +1,7 @@ import unittest -from util.locations import Category, Location, Entrance, get_keys_of_category, get_name_of_key, \ - get_category_of_entrance, get_location_of_entrance +from util.locations import Category, Location, Entrance, get_entrances_of_category, get_name_of_key, \ + get_category_of_entrance, get_location_of_entrance, get_entrances_of_location simple_categories = [ Category('test', 'name', [ @@ -55,7 +55,7 @@ class TestGetKeysOfCategory(unittest.TestCase): Entrance('e2', 'E2'), Entrance('e12', 'E12'), ] - self.assertEqual(expected, list(get_keys_of_category(medium_categories, 'test'))) + self.assertEqual(expected, list(get_entrances_of_category(medium_categories, 'test'))) def test_complex_category(self): expected = [ @@ -63,7 +63,23 @@ class TestGetKeysOfCategory(unittest.TestCase): Entrance('entrance_2', 'Entrance 2'), Entrance('entrance_12', 'Entrance 12'), ] - self.assertEqual(expected, list(get_keys_of_category(complex_categories, 'second'))) + self.assertEqual(expected, list(get_entrances_of_category(complex_categories, 'second'))) + + +class TestGetKeysOfLocation(unittest.TestCase): + def test_first_location(self): + expected = [ + Entrance('e1', 'E1'), + Entrance('e2', 'E2'), + ] + self.assertEqual(expected, list(get_entrances_of_location(medium_categories, 'loc1'))) + + def test_middle_location(self): + expected = [ + Entrance('entrance_1', 'Entrance 1'), + Entrance('entrance_2', 'Entrance 2') + ] + self.assertEqual(expected, list(get_entrances_of_location(complex_categories, 'abc'))) class TestGetNameOfKey(unittest.TestCase): diff --git a/util/locations.py b/util/locations.py index bb75a8b..9de06fa 100644 --- a/util/locations.py +++ b/util/locations.py @@ -39,9 +39,16 @@ class Entrance: return hash((self.key, self.name)) -def get_keys_of_category(categories, key): +def get_entrances_of_category(categories, key): category = [x for x in categories if x.key == key][0] - return _get_keys_of_locations(category.locations) + return _get_entrances_of_locations(category.locations) + + +def get_entrances_of_location(categories, key): + for category in categories: + for location in category.locations: + if location.key == key: + return _get_entrances_of_locations([location]) def get_name_of_key(categories, key): @@ -66,7 +73,7 @@ def get_location_of_entrance(categories, key): return location -def _get_keys_of_locations(locations): +def _get_entrances_of_locations(locations): for loc in locations: for entrance in loc.entrances: yield entrance diff --git a/widgets/connectiongrid.py b/widgets/connectiongrid.py index 26161fc..268deba 100644 --- a/widgets/connectiongrid.py +++ b/widgets/connectiongrid.py @@ -3,7 +3,7 @@ from PySide6.QtWidgets import QGridLayout, QGroupBox, QApplication from util.button import create_button, EntranceButton from util.gridutils import compute_cols, divide_widgets_per_column, create_grid -from util.locations import get_keys_of_category +from util.locations import get_entrances_of_category from util.widget import Widget @@ -66,7 +66,7 @@ class ConnectionGrid(QGroupBox): self.buttons.addWidget(widget.widget, row, column) def _create_widgets(self, location, links): - entrances = get_keys_of_category(self.elements, location) + entrances = get_entrances_of_category(self.elements, location) for entrance in entrances: link = get_link_of_button(entrance.key, links) name = self._create_name(entrance, link) -- GitLab