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
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
|