def from_data(cls, data: Dict[str, Any], translations: Dict[str, Dict[str, Any]], game_contents: GameContents) -> 'SlotSpecification': s = cls() s.element = game_contents.get_element(data['id']) s.label = get(data, 'label', s.element.element_id, translations=translations) s.description = get(data, 'description', '', translations=translations) s.required = [ SlotSpecificationItem( element=game_contents.get_element(element_id), quantity=quantity) for element_id, quantity in get(data, 'required', {}).items() ] s.forbidden = [ SlotSpecificationItem( element=game_contents.get_element(element_id), quantity=quantity) for element_id, quantity in get(data, 'forbidden', {}).items() ] s.greedy = get(data, 'greedy', False, to_bool) s.consumes = get(data, 'consumes', False, to_bool) s.no_animation = get(data, 'noanim', False, to_bool) s.for_verb = game_contents.get_verb(get(data, 'actionId', None)) return s
def from_data(cls, file: File, data: Dict[str, Any], game_contents: GameContents) -> 'Element': e = game_contents.get_element(data['id']) e.file = file e.label = get(data, 'label') e.description = get(data, 'description') e.animation_frames = get(data, 'animFrames', 0, int) e.icon = get(data, 'icon') e.lifetime = get(data, 'lifetime', 0.0, float) e.decay_to = game_contents.get_element(get(data, 'decayTo', None)) e.is_aspect = get(data, 'isAspect', False, to_bool) e.unique = get(data, 'unique', False, to_bool) e.uniqueness_group = get(data, 'uniquenessgroup') e.aspects = [ ElementAspect(element=e, aspect=game_contents.get_element(aspect_id), quantity=int(quantity)) for aspect_id, quantity in get(data, 'aspects', {}).items() ] e.induces = [ ElementLinkedRecipeDetails.from_data(v, game_contents) for v in get(data, 'induces', []) ] e.child_slots = [ ElementSlotSpecification.from_data(v, game_contents) for v in get(data, 'slots', []) ] e.x_triggers = [ ElementXTrigger(trigger=game_contents.get_element(trigger_id), result=game_contents.get_element(result_id)) for trigger_id, result_id in get(data, 'xtriggers', {}).items() ] e.no_art_needed = get(data, 'noartneeded', False, to_bool) e.comments = get(data, 'comments', None) return e
def from_data(cls, file: File, data: Dict[str, Any], translations: Dict[str, Dict[str, Any]], game_contents: GameContents) -> 'Deck': d = game_contents.get_deck(data['id']) d.file = file d._cards = [ DeckCard(element=game_contents.get_element(c)) for c in get(data, 'spec', []) ] d.default_card = game_contents.get_element( get(data, 'defaultcard', None)) d.reset_on_exhaustion = get(data, 'resetonexhaustion', False, to_bool) d.label = get(data, 'label', None, translations=translations) d.description = get(data, 'description', None, translations=translations) d.all_draw_messages = [ DeckDrawMessage(element=game_contents.get_element(element_id), message=message + cls._get_draw_message_loc( translations, element_id)) for element_id, message in get(data, 'drawmessages', {}).items() ] + [ DeckDrawMessage(element=game_contents.get_element(element_id), message=message + cls._get_draw_message_loc( translations, element_id), default=True) for element_id, message in get( data, 'defaultdrawmessages', {}).items() ] d.comments = get(data, 'comments', None) return d
def from_data(cls, val: List[Dict[str, str]], game_contents: GameContents): return [ MutationEffect( filter_on_aspect=game_contents.get_element( v['filterOnAspectId']), mutate_aspect=game_contents.get_element(v['mutateAspectId']), mutation_level=int(v['mutationLevel']), additive=get(v, 'additive', False, to_bool)) for v in val ]
def from_data( cls, val: Union[str, Dict[str, str]], game_contents: GameContents ) -> List['LinkedRecipeChallengeRequirement']: return [ cls(element=game_contents.get_element(element_id), convention=convention) for element_id, convention in val.items() ] if isinstance(val, dict) else [ cls(element=game_contents.get_element(val), convention='base') ]
def from_data(cls, file: File, data: Dict[str, Any], game_contents: GameContents) -> 'Recipe': r = game_contents.get_recipe(data['id']) r.file = file r.label = get(data, 'label', data['id']) r.start_description = get(data, 'startdescription') r.description = get(data, 'description') r.action = game_contents.get_verb(get(data, 'actionId')) r.requirements = RecipeRequirement.from_data( get(data, 'requirements', {}), game_contents) r.effects = RecipeEffect.from_data(get(data, 'effects', {}), game_contents) if 'aspects' in data: # TODO Remove this when fixed if isinstance(data['aspects'], str): logging.error('Invalid value for aspects for recipe {}'.format( data['id'])) else: r.aspects = RecipeAspect.from_data(get(data, 'aspects', {}), game_contents) r.mutation_effects = MutationEffect.from_data( get(data, 'mutations', []), game_contents) r.signal_ending_flavour = EndingFlavour( get(data, 'signalEndingFlavour', 'none').lower()) r.craftable = get(data, 'craftable', False, to_bool) r.hint_only = get(data, 'hintonly', False, to_bool) r.warmup = get(data, 'warmup', 0, int) r.deck_effect = RecipeDeckEffect.from_data(get(data, 'deckeffect', {}), game_contents) r.alternative_recipes = [ RecipeAlternativeRecipeDetails.from_data(lrd, game_contents) for lrd in get(data, 'alternativerecipes', []) ] r.linked_recipes = [ RecipeLinkedRecipeDetails.from_data(lrd, game_contents) for lrd in get(data, 'linked', []) ] r.ending_flag = get(data, 'ending') r.max_executions = get(data, 'maxexecutions', 0, int) r.burn_image = get(data, 'burnimage') r.portal_effect = PortalEffect( get(data, 'portaleffect', 'none').lower()) r.slot_specifications = [ RecipeSlotSpecification.from_data(v, game_contents) for v in get(data, 'slots', []) ] r.signal_important_loop = get(data, 'signalimportantloop', False, to_bool) return r
def import_game_data(game_dir: str): assets_dir = join(game_dir, 'cultistsimulator_Data', 'StreamingAssets') content_dir = join(assets_dir, 'content') with get_session() as session: game_contents = GameContents() for group in FileGroup: decks = _load_content(Deck, content_dir, group, FileCategory.DECKS, game_contents) elements = _load_content(Element, content_dir, group, FileCategory.ELEMENTS, game_contents) legacies = _load_content(Legacy, content_dir, group, FileCategory.LEGACIES, game_contents) recipes = _load_content(Recipe, content_dir, group, FileCategory.RECIPES, game_contents) verbs = _load_content(Verb, content_dir, group, FileCategory.VERBS, game_contents) # Create the dynamically generated secondary tables Base.metadata.create_all() session.add_all(decks) session.add_all(elements) session.add_all(legacies) session.add_all(recipes) session.add_all(verbs)
def import_game_data(game_dir: str): assets_dir = Path(game_dir) / DATA_DIR / 'StreamingAssets' content_dir = assets_dir / 'content' with get_session() as session: # Load the content from the regular files game_contents = GameContents() for group in FileGroup: decks = _load_content(Deck, content_dir, group, FileCategory.DECKS, game_contents) elements = _load_content(Element, content_dir, group, FileCategory.ELEMENTS, game_contents) endings = _load_content(Ending, content_dir, group, FileCategory.ENDINGS, game_contents) legacies = _load_content(Legacy, content_dir, group, FileCategory.LEGACIES, game_contents) recipes = _load_content(Recipe, content_dir, group, FileCategory.RECIPES, game_contents) verbs = _load_content(Verb, content_dir, group, FileCategory.VERBS, game_contents) # Create the dynamically generated secondary tables Base.metadata.create_all() session.add_all(decks) session.add_all(elements) session.add_all(endings) session.add_all(legacies) session.add_all(recipes) session.add_all(verbs)
def from_data(cls, data: Dict[str, Any], game_contents: GameContents) -> 'LinkedRecipeDetails': lr = cls() lr.recipe = game_contents.get_recipe(data['id']) lr.chance = int(data['chance']) lr.additional = get(data, 'additional', False, to_bool) return lr
def from_data(cls, val: Dict[str, str], game_contents: GameContents): return [ cls( deck=game_contents.get_deck(deck_id), quantity=int(quantity) ) for deck_id, quantity in val.items() ]
def from_data(cls, val: Dict[str, str], game_contents: GameContents): return [ cls( element=game_contents.get_element(element_id), quantity=int(quantity) ) for element_id, quantity in val.items() ]
def from_data(cls, data: Dict[str, Any], challenge_cls: Type['LinkedRecipeChallengeRequirement'], game_contents: GameContents) -> 'LinkedRecipeDetails': lr = cls() lr.recipe = game_contents.get_recipe(data['id']) lr.chance = int(data['chance']) if 'chance' in data else 100 lr.additional = get(data, 'additional', False, to_bool) lr.challenges = challenge_cls.from_data(get(data, 'challenges', {}), game_contents) return lr
def from_data(cls, file: File, data: Dict[str, Any], translations: Dict[str, Dict[str, Any]], game_contents: GameContents) -> 'Element': e = game_contents.get_element(data['id']) e.file = file e.label = get(data, 'label', translations=translations) e.description = get(data, 'description', translations=translations) e.animation_frames = get(data, 'animFrames', 0, int) e.icon = get(data, 'icon') e.lifetime = get(data, 'lifetime', 0.0, float) e.decay_to = game_contents.get_element(get(data, 'decayTo', None)) e.is_aspect = get(data, 'isAspect', False, to_bool) e.unique = get(data, 'unique', False, to_bool) e.uniqueness_group = get(data, 'uniquenessgroup') e.aspects = [ ElementAspect(element=e, aspect=game_contents.get_element(aspect_id), quantity=int(quantity)) for aspect_id, quantity in get(data, 'aspects', {}).items() ] e.induces = [ ElementLinkedRecipeDetails.from_data( v, ElementLinkedRecipeDetailsChallengeRequirement, game_contents) for v in get(data, 'induces', []) ] e.child_slots = [ ElementSlotSpecification.from_data( v, { c: c_transformation["slots"][i] for c, c_transformation in translations.items() if "slots" in c_transformation }, game_contents) for i, v in enumerate(get(data, 'slots', [])) ] for trigger_id, result in get(data, 'xtriggers', {}).items(): if isinstance(result, str): e.x_triggers.append( ElementXTrigger( trigger=game_contents.get_element(trigger_id), result=game_contents.get_element(result))) else: for x_trigger_def in result: e.x_triggers.append( ElementXTrigger( trigger=game_contents.get_element(trigger_id), result=game_contents.get_element( x_trigger_def['id']), morph_effect=x_trigger_def.get('morpheffect'), morph_effect_level=int(x_trigger_def['level']) if 'level' in x_trigger_def else None, morph_effect_chance=int(x_trigger_def['chance']) if 'chance' in x_trigger_def else None, )) e.is_hidden = get(data, 'isHidden', False, to_bool) e.no_art_needed = get(data, 'noartneeded', False, to_bool) e.resaturate = get(data, 'resaturate', False, to_bool) e.verb_icon = get(data, 'verbicon') e.comments = get(data, 'comments', None) return e
def from_data(cls, file: File, data: Dict[str, Any], game_contents: GameContents): r = game_contents.get_verb(data['id']) r.file = file r.label = get(data, 'label') r.description = get(data, 'description') r.at_start = get(data, 'atStart', False, to_bool) if 'slots' in data and data['slots']: r.primary_slot_specification = VerbSlotSpecification.from_data( data['slots'][0], game_contents) r.comments = get(data, 'comments', None) return r
def from_data(cls, file: File, data: Dict[str, Any], translations: Dict[str, Dict[str, Any]], game_contents: GameContents) -> 'Legacy': lg = game_contents.get_legacy(data['id']) lg.file = file lg.label = get(data, 'label', translations=translations) lg.description = get(data, 'description', translations=translations) lg.start_description = get(data, 'startdescription', translations=translations) lg.image = get(data, 'image') lg.from_ending = get(data, 'fromEnding') lg.excludes_on_ending = [ LegacyExcludes(legacy=lg, exclude=game_contents.get_legacy(l)) for l in get(data, 'excludesOnEnding', []) ] lg.available_without_ending_match = get(data, 'availableWithoutEndingMatch', False, to_bool) lg.starting_verb_id = get(data, 'startingVerbId') lg.effects = LegacyEffect.from_data(get(data, 'effects', {}), game_contents) return lg
def from_data(cls, file: File, data: Dict[str, Any], translations: Dict[str, Dict[str, Any]], game_contents: GameContents) -> 'Ending': e = game_contents.get_ending(get(data, 'id')) e.file = file e.title = get(data, 'label', translations=translations) e.description = get(data, 'description', translations=translations) e.image = get(data, 'image') flavour = get(data, 'flavour', 'None') e.flavour = EndingFlavour(flavour[0].upper() + flavour[1:] # Workaround for a broken ending ) e.animation = get(data, 'anim') e.achievement = get(data, 'achievement') return e
def from_data(cls, file: File, data: Dict[str, Any], translations: Dict[str, Dict[str, Any]], game_contents: GameContents): r = game_contents.get_verb(data['id']) r.file = file r.label = get(data, 'label', translations=translations) r.description = get(data, 'description', translations=translations) r.at_start = get(data, 'atStart', False, to_bool) if 'slots' in data and data['slots']: r.primary_slot_specification = VerbSlotSpecification.from_data( data['slots'][0], { c: c_transformation["slots"][0] for c, c_transformation in translations.items() if "slots" in c_transformation }, game_contents) r.comments = get(data, 'comments', None) return r
def from_data( cls, file: File, data: Dict[str, Any], game_contents: GameContents ) -> 'Legacy': lg = game_contents.get_legacy(data['id']) lg.file = file lg.label = get(data, 'label') lg.description = get(data, 'description') lg.start_description = get(data, 'startdescription') lg.image = get(data, 'image') lg.from_ending = get(data, 'fromEnding') lg.available_without_ending_match = get( data, 'availableWithoutEndingMatch', False, to_bool ) lg.effects = LegacyEffect.from_data( get(data, 'effects', {}), game_contents ) return lg
def from_data(cls, file: File, data: Dict[str, Any], translations: Dict[str, Dict[str, Any]], game_contents: GameContents) -> 'Recipe': r = game_contents.get_recipe(data['id']) r.file = file r.label = get(data, 'label', data['id'], translations=translations) r.start_description = get(data, 'startdescription', translations=translations) r.description = get(data, 'description', translations=translations) r.action = game_contents.get_verb(get(data, 'actionId')) r.requirements = RecipeRequirement.from_data( get(data, 'requirements', {}), game_contents) r.table_requirements = RecipeTableRequirement.from_data( get(data, 'tablereqs', {}), game_contents) r.extant_requirements = RecipeExtantRequirement.from_data( get(data, 'extantreqs', {}), game_contents) r.effects = RecipeEffect.from_data(get(data, 'effects', {}), game_contents) if 'aspects' in data: # TODO Remove this when fixed if isinstance(data['aspects'], str): logging.error('Invalid value for aspects for recipe {}'.format( data['id'])) else: r.aspects = RecipeAspect.from_data(get(data, 'aspects', {}), game_contents) r.mutation_effects = MutationEffect.from_data( get(data, 'mutations', []), game_contents) r.purge = RecipePurge.from_data(get(data, 'purge', {}), game_contents) r.halt_verb = RecipeHaltVerb.from_data(get(data, 'haltverb', {}), game_contents) r.delete_verb = RecipeDeleteVerb.from_data(get(data, 'deleteverb', {}), game_contents) r.signal_ending_flavour = EndingFlavour( get(data, 'signalEndingFlavour', 'None')) r.craftable = get(data, 'craftable', False, to_bool) r.hint_only = get(data, 'hintonly', False, to_bool) r.warmup = get(data, 'warmup', 0, int) r.deck_effect = RecipeDeckEffect.from_data(get(data, 'deckeffect', {}), game_contents) internal_deck = get(data, 'internaldeck') if internal_deck: internal_deck['id'] = "internal:" + r.recipe_id r.internal_deck = Deck.from_data(file, internal_deck, {}, game_contents) alternative_recipes = get(data, 'alternativerecipes', []) if not alternative_recipes: alternative_recipes = get(data, 'alt', []) r.alternative_recipes = [ RecipeAlternativeRecipeDetails.from_data( lrd, RecipeAlternativeRecipeDetailsChallengeRequirement, game_contents) for lrd in alternative_recipes ] r.linked_recipes = [ RecipeLinkedRecipeDetails.from_data( lrd, RecipeLinkedRecipeDetailsChallengeRequirement, game_contents) for lrd in get(data, 'linked', []) ] r.ending_flag = get(data, 'ending') r.max_executions = get(data, 'maxexecutions', 0, int) r.burn_image = get(data, 'burnimage') r.portal_effect = PortalEffect( get(data, 'portaleffect', 'none').lower()) r.slot_specifications = [ RecipeSlotSpecification.from_data( v, { c: c_transformation["slots"][i] for c, c_transformation in translations.items() if "slots" in c_transformation }, game_contents) for i, v in enumerate(get(data, 'slots', [])) ] r.signal_important_loop = get(data, 'signalimportantloop', False, to_bool) r.comments = get(data, 'comments', None) if not r.comments: r.comments = get(data, 'comment', None) return r