from json import JSONDecodeError from typing import List, Dict, Optional from pathlib import Path from pydantic import BaseModel, ValidationError from model.card_validator import CardParser, EffectParser from model.card import Effect, Card from .card_behaviour import create_effect_behaviour class CardContainerFile(BaseModel): cards: List[CardParser] def load_cards() -> List[CardParser]: cards: List[CardParser] = [] for p in Path("./src/cards").glob("**/*.json"): print("loading " + p.name) with open(p, encoding="UTF-8") as f_in: try: data = CardContainerFile.model_validate_json(f_in.read()) for c in data.cards: cards.append(c) except JSONDecodeError as e: print("Not a valid JSON file : " + p.name + " : " + str(e)) except ValidationError as e: print("Incorrect or missing JSON data : " + p.name + " : " + str(e)) return cards def create_card(card_parser: CardParser) -> tuple[Card, list[Effect], list[Effect]]: card_effects, all_effects = create_card_effects(card_parser) card = Card( card_id=card_parser.id, card_type=card_parser.card_type, cost=card_parser.cost, effects=card_effects, faction=card_parser.faction, name=card_parser.name, sprite="spritetest", guard=card_parser.guard, defense=card_parser.defense, card_role=card_parser.role, ) for e in all_effects: e.card = card return card, all_effects def create_card_effects( card: CardParser, all_effects: Optional[List[Effect]] = None ) -> (List[Effect], List[Effect]): if all_effects is None: all_effects: List[Effect] = [] combined: List[Effect] = [] mutexes: Dict[int, List[Effect]] = {} for mutex in set([c.mutex for c in card.effects if c.mutex is not None]): mutexes[mutex] = [] for effect in card.effects: real_effect, sub_effects = create_effect_and_subeffects(effect) for e in sub_effects: all_effects.append(e) all_effects.append(real_effect) combined.append(real_effect) if effect.mutex in mutexes: mutexes[effect.mutex].append(real_effect) for index, effect in enumerate(card.effects): if effect.mutex in mutexes: combined[index].mutex = mutexes[effect.mutex] return combined, all_effects def create_effect_and_subeffects( effect: EffectParser, all_effects: Optional[List[Effect]] = None ) -> (Effect, List[Effect]): if all_effects is None: all_effects: List[Effect] = [] sub_effects: List[Effect] = [] mutexes: Dict[int, List[Effect]] = {} for mutex in set([c.mutex for c in effect.sub_effects if c.mutex is not None]): mutexes[mutex] = [] for s in effect.sub_effects: real_effect, all_effects2 = create_effect_and_subeffects(s, all_effects) for e in all_effects2: all_effects.append(e) all_effects.append(real_effect) sub_effects.append(real_effect) if s.mutex in mutexes: mutexes[s.mutex].append(real_effect) for index, s in enumerate(effect.sub_effects): if s.mutex in mutexes: sub_effects[index].mutex = mutexes[s.mutex] actual_effect = Effect( effect=effect.effect, amount=effect.amount, effect_type=effect.effect_type, sub_effects=sub_effects, times=effect.times, activate=lambda *args, **kwargs: create_effect_behaviour(effect=effect)( actual_effect, *args, **kwargs ), ) return actual_effect, all_effects