# dialogue_system.py from dataclasses import dataclass from typing import Dict, List import random from game_engine import GauchoCharacter @dataclass class DialogNode: id: str text: str options: List[Dict[str, str]] cultural_requirement: str = None crystal_trigger: str = None class DynamicNarrative: """Sistema de diálogos que se adapta a los valores recolectados""" def __init__(self): self.dialog_tree = self._build_cultural_dialog_tree() self.current_node = "root" def _build_cultural_dialog_tree(self) -> Dict[str, DialogNode]: return { "root": DialogNode( id="root", text="¡Che, ¿viste lo que pasa con estos algoritmos?¡Están desdibujando nuestra esencia!", options=[ {"text": "Voy a recuperar los cristales", "target": "mision_principal"}, {"text": "¿Tenés algún dato útil?", "target": "pistas_culturales"}, {"text": "Hablemos de nuestra identidad", "target": "reflexion_filosofica"} ] ), "mision_principal": DialogNode( id="mision_principal", text="Cada cristal que recuperés fortalecerá nuestra resistencia cultural. ¿Por cuál querés empezar?", options=[ {"text": "Solidaridad", "target": "solidaridad_quest"}, {"text": "Creatividad", "target": "creatividad_quest"}, {"text": "Volver", "target": "root"} ], cultural_requirement="basic" ), "solidaridad_quest": DialogNode( id="solidaridad_quest", text="Para recuperar la Solidaridad, necesitás ayudar a tres comunidades diferentes. ¿Listo para el desafío?", options=[ {"text": "Acepto el reto", "target": "solidaridad_1"}, {"text": "Necesito prepararme", "target": "mision_principal"} ], crystal_trigger="Solidaridad" ) } def get_current_dialog(self, player: GauchoCharacter) -> DialogNode: node = self.dialog_tree[self.current_node] return self._filter_options(node, player) def _filter_options(self, node: DialogNode, player: GauchoCharacter) -> DialogNode: """Filtra opciones basadas en progreso del jugador""" filtered_options = [] for option in node.options: target_node = self.dialog_tree.get(option['target'], None) if target_node: if target_node.cultural_requirement == "basic" and not any(player.inventory['cristales'].values()): continue if target_node.crystal_trigger and not player.inventory['cristales'][target_node.crystal_trigger]: continue filtered_options.append(option) return DialogNode( id=node.id, text=node.text, options=filtered_options, cultural_requirement=node.cultural_requirement, crystal_trigger=node.crystal_trigger ) def select_option(self, option_index: int, player: GauchoCharacter) -> str: current_node = self.get_current_dialog(player) if 0 <= option_index < len(current_node.options): self.current_node = current_node.options[option_index]['target'] return self.get_current_dialog(player).text return current_node.text