You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

278 lines
10 KiB

import json
from PyQt6.QtCore import Qt, QTimer, QThreadPool
from PyQt6.QtWidgets import QMenu
from PyQt6.QtGui import QAction
import os
from routes.pokemon_game_desc import PokemonGameDesc
from ui.workers.calculate_origin_mark_worker import CalculateOriginMarkWorker
from ui.workers.gather_baby_form_status import GatherBabyStatusWorker
from ui.workers.gather_encounter_locations import GatherEncountersWorker
from ui.workers.gather_home_storage_status_worker import GatherHomeStorageStatus
from ui.workers.gather_pokemon_forms_worker import GatherPokemonFormsWorker
from ui.workers.gather_evolutions_worker import GatherEvolutions
from ui.workers.generate_PDDLs_worker import GeneratePDDLsWorker
from ui.workers.generate_plan_worker import GeneratePlanWorker
from ui.workers.route_solve_worker import SolveRouteWorker
from ui.workers.solve_pddl_route import SolvePDDLsWorker
from utility.functions import get_display_name, sanitize_filename
from db import db
class MainWindowController:
def __init__(self, view):
self.view = view
self.pokemon_data_cache = []
self.filter_timer = QTimer()
self.filter_timer.setInterval(300) # 300 ms delay to wait for user to stop typing
self.filter_timer.setSingleShot(True)
self.filter_timer.timeout.connect(self.apply_filters)
self.thread_pool = QThreadPool()
def initialize_pokemon_list(self, data):
self.pokemon_data_cache = data
self.view.update_pokemon_forms(data)
self.apply_filters()
def filter_pokemon_list(self):
self.filter_timer.start()
def apply_filters(self):
search_text = self.view.search_bar.text().lower()
show_only_home_storable = self.view.filter_home_storable.isChecked()
show_only_missing_encounters = self.view.highlight_no_encounters.isChecked()
gender_relevant = False
filtered_data = []
for pokemon in self.pokemon_data_cache:
display_name = get_display_name(pokemon)
pfic = pokemon["pfic"]
# Check if the item matches the search text
text_match = search_text in display_name.lower()
# Check if the item is storable in Home (if the filter is active)
home_storable = True
if show_only_home_storable:
# TODO: update the call to correctly filter the data, or better yet update the data at the source to include this info.
home_storable = True #event_system.call_sync('get_home_storable', pfic)
home_storable = db.get_pokemon_details(pfic, ["storable_in_home"])["storable_in_home"]
# Check to see if the pokemon has encounters
has_encounters = True
if show_only_missing_encounters:
# TODO: reimplement this check.
has_encounters = True
include_gender = True
if gender_relevant == False and pokemon["gender_relevant"] == False:
include_gender = not any(item["pfic"][:-2] == pfic[:-2] for item in filtered_data)
# If both conditions are met, add to filtered data
if text_match and home_storable and include_gender:
filtered_data.append(pokemon)
# Update the view with the filtered data
self.view.update_pokemon_forms(filtered_data)
def show_pokemon_context_menu(self, position):
item = self.view.pokemon_list.itemAt(position)
if item is not None:
context_menu = QMenu(self)
refresh_action = QAction("Refresh Encounters", self)
refresh_action.triggered.connect(lambda: self.refresh_pokemon_encounters(item))
context_menu.addAction(refresh_action)
context_menu.exec(self.pokemon_list.viewport().mapToGlobal(position))
def on_pokemon_selected(self, item):
if item:
pfic = item.data(Qt.ItemDataRole.UserRole)
self.refresh_pokemon_details_panel(pfic)
def edit_encounter(self):
pass
def add_new_encounter(self):
pass
def add_new_evolution(self):
pass
def save_changes(self):
db.save_changes()
pass
def export_database(self):
pass
def gather_pokemon_forms(self):
worker = GatherPokemonFormsWorker()
worker.signals.finished.connect(self.on_forms_gathered)
self.thread_pool.start(worker)
def on_forms_gathered(self, data):
# This method will be called in the main thread when the worker finishes
# Update the UI with the gathered forms
for pokemon in data:
db.add_pokemon_form(pokemon["pfic"], pokemon["name"], pokemon["form_name"], pokemon["national_dex"], pokemon["generation"], pokemon["sprite_url"], pokemon["gender_relevant"])
self.pokemon_data_cache = data
self.view.update_pokemon_forms(data)
self.apply_filters()
db.save_changes()
def gather_home_storage_info(self):
worker = GatherHomeStorageStatus()
worker.signals.finished.connect(self.on_home_status_gathered)
self.thread_pool.start(worker)
def on_home_status_gathered(self, data):
print("Works Done!")
for pfic in data:
db.update_home_status(pfic, True)
def gather_evolution_info(self):
worker = GatherEvolutions()
worker.signals.finished.connect(self.on_evolutions_gathered)
self.thread_pool.start(worker)
def on_evolutions_gathered(self, data):
print("Works Done!")
db.update_evolution_graph(data)
def gather_baby_status(self):
worker = GatherBabyStatusWorker()
worker.signals.finished.connect(self.on_baby_status_gathered)
self.thread_pool.start(worker)
def on_baby_status_gathered(self, data):
print("Works Done!")
for pfic in data:
db.update_baby_status(pfic, True)
def reinitialize_database(self):
pass
def gather_encounter_info(self):
worker = GatherEncountersWorker()
worker.signals.finished.connect(self.on_encounters_gathered)
self.thread_pool.start(worker)
def on_encounters_gathered(self, data):
print("Works Done!")
db.update_encounter_locations(data)
def gather_marks_info(self):
worker = CalculateOriginMarkWorker()
worker.signals.finished.connect(self.on_marks_calculated)
self.thread_pool.start(worker)
def on_marks_calculated(self, data):
for key in data:
db.update_mark(key, data[key])
print("Works Done!")
def load_shiftable_forms(self):
pass
def on_exclusive_set_selected(self):
pass
def add_new_exclusive_set(self):
pass
def show_encounter_context_menu(self):
pass
def add_encounter_to_set(self):
pass
def refresh_pokemon_details_panel(self, pfic):
details = db.get_pokemon_details(pfic)
if details:
self.view.name_label.setText(details["name"])
self.view.form_name_label.setText(details["form_name"] if details["form_name"] else "")
self.view.national_dex_label.setText(str(details["national_dex"]))
self.view.generation_label.setText(str(details["generation"]))
self.view.home_checkbox.setChecked(bool(details["storable_in_home"]))
#self.view.home_checkbox.stateChanged.connect(self.update_home_storable)
self.view.is_baby_form_checkbox.setChecked(bool(details["is_baby_form"]))
image_path = f"images-new/{pfic}.png"
if os.path.exists(image_path):
pixmap = QPixmap(image_path)
self.view.image_label.setPixmap(pixmap.scaled(150, 150, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation))
else:
self.view.image_label.setText("Image not found")
self.load_evolution_chain(pfic)
self.load_encounter_locations(pfic)
self.current_pfic = pfic
def load_evolution_chain(self, pfic):
chain = db.get_full_evolution_paths(pfic)
self.view.update_evolution_tree(chain, pfic)
def load_encounter_locations(self, pfic):
encounters = db.get_encounters(pfic)
self.view.update_encounter_list(encounters, pfic)
def generate_plan(self):
worker = GeneratePlanWorker()
worker.signals.finished.connect(self.on_plan_generated)
self.thread_pool.start(worker)
def on_plan_generated(self, data):
print("Plans Done!")
full_plan = []
family_map = {}
for game_plan in data:
obj = {}
obj["game_name"] = game_plan["game_name"]
family_map = {}
for key in game_plan["pokemon_to_catch"]:
pokemon_to_catch = game_plan["pokemon_to_catch"][key]
family_key = key[:-2]
if family_key not in family_map:
family_map[family_key] = {}
family_map[family_key]["representative"] = key
family_map[family_key]["catch_count"] = 0
family_map[family_key]["evolve_to"] = []
family_map[family_key]["breed_for"] = []
catch_count = family_map[family_key]["catch_count"]
for catch_key in pokemon_to_catch:
family_map[family_key][catch_key] = pokemon_to_catch[catch_key]
catch_count += pokemon_to_catch[catch_key]
family_map[family_key]["catch_count"] = catch_count
catch_details = game_plan["other_map"][key]
family_map[family_key]["evolve_to"].extend(catch_details["EvolveTo"])
family_map[family_key]["breed_for"].extend(catch_details["BreedFor"])
pass
obj["pokemon"] = family_map
full_plan.append(obj)
output_file = "./temp/plan.json"
with open(output_file, 'w', encoding='utf-8') as f:
json.dump(full_plan, f, indent=4, ensure_ascii=False)
def generate_pddls(self):
worker = GeneratePDDLsWorker()
worker.signals.finished.connect(self.on_pddls_generated)
self.thread_pool.start(worker)
def on_pddls_generated(self, data):
self.view.update_route_list(data)
def solve_route(self, data: PokemonGameDesc):
#worker = SolvePDDLsWorker(data)
worker = SolveRouteWorker(data)
worker.signals.finished.connect(self.on_route_solved)
self.thread_pool.start(worker)
def on_route_solved(self, data):
pass