diff --git a/DBEditor/DBEditor.py b/DBEditor/DBEditor.py index bf0ec90..81c413c 100644 --- a/DBEditor/DBEditor.py +++ b/DBEditor/DBEditor.py @@ -437,6 +437,25 @@ class DBEditor(QMainWindow): self.logger.info("Database reinitialized successfully.") QMessageBox.information(self, 'Database Reinitialized', 'The database has been cleared and reinitialized.') + def determine_origin_mark(self, pfic, target_generation): + encounters = event_system.call_sync('get_encounter_locations', pfic) + if encounters: + generation_encounters = [] + for encounter in encounters: + game_generation = event_system.call_sync('get_game_generation', encounter[0]) + if game_generation == target_generation: + generation_encounters.append(encounter) + if len(generation_encounters) > 0: + form_info = event_system.call_sync('get_pokemon_data', pfic) + mark_id = event_system.call_sync('get_mark_for_game_name', generation_encounters[0][0]) + if mark_id == None: + self.logger.info(f"No mark found for {form_info[0]} {form_info[1]}") + else: + mark_details = event_system.call_sync('get_mark_details', mark_id) + self.logger.info(f"Mark for {form_info[0]} {form_info[1]} is {mark_details[0]} - {mark_details[1]}") + return mark_id + return None + def gather_marks_info(self, data): event_system.emit_sync('clear_log_display') self.logger.info("Starting to gather marks information...") @@ -445,32 +464,118 @@ class DBEditor(QMainWindow): for pfic, name, form_name, national_dex in pokemon_list: pokemon_data = event_system.call_sync('get_pokemon_data', pfic) + + if pokemon_data[4] == False: + continue; + + self.logger.info(f"Determining mark for {name} {form_name if form_name else ''}") + + target_generation = pokemon_data[3] #Rule 1 # 1. If a pokemon form has a previous evolution from within the same generation, # use the mark of the previous evolution. This should be recursive within the same generation. chain = event_system.call_sync('get_evolution_chain', pfic) if chain: - find_me = lambda x: x[0] == pfic - target_index = next((i for i, item in enumerate(chain) if find_me(item)), -1) base_form_in_generation = None + last_pfic = pfic current_pfic = pfic while True: - current_pfic = event_system.call_sync('get_evolution_parent', current_pfic) + current_pfic = event_system.call_sync('get_evolution_parent', last_pfic) if current_pfic == None: - base_form_in_generation = current_pfic + base_form_in_generation = last_pfic break - chain_pokemon_data = event_system.call_sync('get_pokemon_data', current_pfic) - if chain_pokemon_data[3] == pokemon_data[3]: - base_form_in_generation = current_pfic + chain_pokemon_data = event_system.call_sync('get_pokemon_data', current_pfic[0]) + if chain_pokemon_data[3] == target_generation: + base_form_in_generation = current_pfic[0] + else: + base_form_in_generation = last_pfic break + last_pfic = current_pfic[0] - if base_form_in_generation: + if base_form_in_generation and base_form_in_generation != pfic: self.logger.info(f"Base form in generation for {name} {form_name if form_name else ''} is {base_form_in_generation}") - - - - - + mark_id = self.determine_origin_mark(base_form_in_generation, target_generation) + if mark_id != None: + event_system.emit_sync('assign_mark_to_form', (pfic, mark_id)) + continue; + elif base_form_in_generation == pfic: + mark_id = self.determine_origin_mark(pfic, target_generation) + if mark_id != None: + event_system.emit_sync('assign_mark_to_form', (pfic, mark_id)) + continue; + #Rule 2 + # If a pokemon form has no previous evolution from within the same generation, + # look at the encounters of the pokemon form from this generation and use the mark of the earliest + # game you can encounter that form in from that generation + mark_id = self.determine_origin_mark(pfic, target_generation) + if mark_id != None: + event_system.emit_sync('assign_mark_to_form', (pfic, mark_id)) + continue; + + + # this bit doesn't work as we exclude eveolve encounters from our dataset. + # this needs to change so we do include them, but filter them out of all our current queries + # then make a new API that includes them to solve this problem. + # We then find the earliest encounter in the for the base pokemon, that gets uus a game id + # we then use that game id to get the generation and run the determine_origin_mark using that generation + # for its evolution line. + + #Rule 3 + # If there are no encounters for the pokemon form from this generation, + # look to see if a previous evolution has an encounter from this generation, and use the mark of the earliest + # game from this generation that the previous evolution is encounterable in. + if chain: + last_pfic = pfic + mark_identified = False + should_continue = True + while should_continue: + encounters = event_system.call_sync('get_encounter_locations', last_pfic) + if encounters: + earliest_game = 100 + for encounter in encounters: + game_id = event_system.call_sync('get_game_id_for_name', encounter[0]) + if game_id <= earliest_game: + earliest_game = game_id + if earliest_game < 100: + form_info = event_system.call_sync('get_pokemon_data', last_pfic) + mark_id = event_system.call_sync('get_mark_for_game', earliest_game) + if mark_id == None: + self.logger.info(f"No mark found for {form_info[0]} {form_info[1]}") + else: + mark_details = event_system.call_sync('get_mark_details', mark_id) + self.logger.info(f"Mark for {form_info[0]} {form_info[1]} is {mark_details[0]} - {mark_details[1]}") + event_system.emit_sync('assign_mark_to_form', (pfic, mark_id)) + should_continue = False + mark_identified = True + break; + + last_pfic = event_system.call_sync('get_evolution_parent', last_pfic) + if last_pfic == None: + should_continue = False + break + if mark_identified: + continue; + + #Rule 4 + # If there are no encounters for the pokemon form or its evolution line from this generation, + # use the mark of the earliest game of the generation is marked as being introducted in. + encounters = event_system.call_sync('get_encounter_locations', pfic) + if encounters: + earliest_game = 100 + for encounter in encounters: + game_id = event_system.call_sync('get_game_id_for_name', encounter[0]) + if game_id <= earliest_game: + earliest_game = game_id + if earliest_game < 100: + form_info = event_system.call_sync('get_pokemon_data', pfic) + mark_id = event_system.call_sync('get_mark_for_game', earliest_game) + if mark_id == None: + self.logger.info(f"No mark found for {form_info[0]} {form_info[1]}") + else: + mark_details = event_system.call_sync('get_mark_details', mark_id) + self.logger.info(f"Mark for {form_info[0]} {form_info[1]} is {mark_details[0]} - {mark_details[1]}") + event_system.emit_sync('assign_mark_to_form', (pfic, mark_id)) + continue; def qt_message_handler(mode, context, message): print(f"Qt Message: {mode} {context} {message}") diff --git a/DBEditor/db_controller.py b/DBEditor/db_controller.py index 2baa8cc..0bd980e 100644 --- a/DBEditor/db_controller.py +++ b/DBEditor/db_controller.py @@ -35,6 +35,9 @@ class DBController: event_system.add_listener('save_changes', self.save_changes) event_system.add_listener('export_database', self.export_database) event_system.add_listener('assign_mark_to_form', self.assign_mark_to_form) + event_system.add_listener('get_mark_for_game', self.get_mark_for_game) + event_system.add_listener('get_mark_for_game_name', self.get_mark_for_game_name) + event_system.add_listener('get_mark_details', self.get_mark_details) def init_database(self): disk_conn = sqlite3.connect('pokemon_forms.db') @@ -484,6 +487,32 @@ class DBController: def assign_mark_to_form(self, data): pfic, mark_id = data - self.cursor.execute('INSERT INTO form_marks (pfic, mark_id) VALUES (?, ?)', (pfic, mark_id)) + self.cursor.execute(''' + INSERT OR REPLACE INTO form_marks (pfic, mark_id) + VALUES (?, ?) + ''', (pfic, mark_id)) self.conn.commit() + def get_mark_for_game(self, data): + game_id = data + self.cursor.execute('SELECT mark_id FROM mark_game_associations WHERE game_id = ?', (game_id,)) + result = self.cursor.fetchone() + return result[0] if result else None + + def get_mark_for_game_name(self, data): + game_name = data + self.cursor.execute(''' + SELECT m.id + FROM marks m + JOIN mark_game_associations mga ON m.id = mga.mark_id + JOIN games g ON mga.game_id = g.id + WHERE g.name = ? + ''', (game_name,)) + result = self.cursor.fetchone() + return result[0] if result else None + + def get_mark_details(self, data): + mark_id = data + self.cursor.execute('SELECT name, icon_path FROM marks WHERE id = ?', (mark_id,)) + return self.cursor.fetchone() + diff --git a/Site/OriginDex.py b/Site/OriginDex.py index a1f415e..9d6cf77 100644 --- a/Site/OriginDex.py +++ b/Site/OriginDex.py @@ -18,97 +18,13 @@ def load_pokemon_data(): ps.storable_in_home FROM pokemon_forms pf JOIN pokemon_storage ps ON pf.PFIC = ps.PFIC + WHERE ps.storable_in_home = 1 ORDER BY pf.PFIC ''') pokemon_data = cursor.fetchall() - # Function to get the origin mark for a Pokémon - def get_origin_mark(pfic, generation): - # Step 1: Check for previous evolution in the same generation - cursor.execute(''' - WITH RECURSIVE EvolutionChain AS ( - SELECT ec.to_pfic, ec.from_pfic, pf_to.generation as to_gen, pf_from.generation as from_gen - FROM evolution_chains ec - JOIN pokemon_forms pf_to ON ec.to_pfic = pf_to.PFIC - JOIN pokemon_forms pf_from ON ec.from_pfic = pf_from.PFIC - WHERE ec.to_pfic = ? AND pf_to.generation = ? - UNION ALL - SELECT ec.to_pfic, ec.from_pfic, pf_to.generation, pf_from.generation - FROM evolution_chains ec - JOIN EvolutionChain e ON ec.to_pfic = e.from_pfic - JOIN pokemon_forms pf_to ON ec.to_pfic = pf_to.PFIC - JOIN pokemon_forms pf_from ON ec.from_pfic = pf_from.PFIC - WHERE pf_to.generation = ? AND pf_from.generation = ? - ) - SELECT from_pfic - FROM EvolutionChain - WHERE from_pfic IS NOT NULL AND from_gen = ? - ORDER BY from_pfic - LIMIT 1 - ''', (pfic, generation, generation, generation, generation)) - base_pfic = cursor.fetchone() - - if base_pfic: - pfic = base_pfic[0] - - # Step 2: Look for the earliest encounter for this form in the current generation - cursor.execute(''' - SELECT g.name, m.icon_path, m.id - FROM encounters e - JOIN games g ON e.game_id = g.id - LEFT JOIN mark_game_associations mga ON g.id = mga.game_id - LEFT JOIN marks m ON mga.mark_id = m.id - WHERE e.pfic = ? AND g.generation = ? - ORDER BY g.id - LIMIT 1 - ''', (pfic, generation)) - encounter_data = cursor.fetchone() - - if encounter_data: - return encounter_data - - # Step 3: Look for encounters of previous evolutions in the current generation - cursor.execute(''' - WITH RECURSIVE EvolutionChain AS ( - SELECT ec.to_pfic, ec.from_pfic - FROM evolution_chains ec - WHERE ec.to_pfic = ? - UNION ALL - SELECT ec.to_pfic, ec.from_pfic - FROM evolution_chains ec - JOIN EvolutionChain e ON ec.to_pfic = e.from_pfic - ) - SELECT g.name, m.icon_path, m.id - FROM EvolutionChain ec - JOIN encounters e ON ec.from_pfic = e.pfic - JOIN games g ON e.game_id = g.id - LEFT JOIN mark_game_associations mga ON g.id = mga.game_id - LEFT JOIN marks m ON mga.mark_id = m.id - WHERE g.generation = ? - ORDER BY g.id - LIMIT 1 - ''', (pfic, generation)) - evolution_encounter_data = cursor.fetchone() - - if evolution_encounter_data: - return evolution_encounter_data - - # Step 4: Use the mark of the earliest game of the generation - cursor.execute(''' - SELECT g.name, m.icon_path, m.id - FROM games g - LEFT JOIN mark_game_associations mga ON g.id = mga.game_id - LEFT JOIN marks m ON mga.mark_id = m.id - WHERE g.generation = ? - ORDER BY g.id - LIMIT 1 - ''', (generation,)) - generation_data = cursor.fetchone() - - return generation_data if generation_data else (None, None, None) - # Process the data current_group = [] current_generation = None @@ -117,8 +33,26 @@ def load_pokemon_data(): for row in pokemon_data: national_dex, name, form_name, pfic, generation, storable_in_home = row + + mark_id = None + mark_icon = None - earliest_game, mark_icon, mark_id = get_origin_mark(pfic, generation) + cursor.execute(''' + SELECT mark_id + FROM form_marks + WHERE pfic = ? + ''', (pfic,)) + result = cursor.fetchone() + mark_id = result[0] if result else None + + if mark_id: + cursor.execute(''' + SELECT icon_path + FROM marks + WHERE id = ? + ''', (mark_id,)) + result = cursor.fetchone() + mark_icon = result[0] if result else None pokemon = { 'pfic': pfic, @@ -128,7 +62,6 @@ def load_pokemon_data(): 'Image': f"images/pokemon/{pfic}.png", 'IsDefault': form_name is None or form_name == '', 'Generation': generation, - 'EarliestGame': earliest_game, 'StorableInHome': storable_in_home, 'MarkIcon': mark_icon, 'MarkID': mark_id diff --git a/pokemon_forms.db b/pokemon_forms.db index cc7f947..a97bbad 100644 Binary files a/pokemon_forms.db and b/pokemon_forms.db differ