def _on_slide_trick_slider(self, trick: TrickResourceInfo, value: int): if self._slider_for_trick[trick].isEnabled(): with self._editor as options: options.set_configuration_field( "trick_level", options.configuration.trick_level.set_level_for_trick( trick, LayoutTrickLevel.from_number(value)))
def test_database_collectable(preset_manager, game_enum: RandovaniaGame, ignore_events: set[str], ignore_pickups: set[int]): game, initial_state, permalink = run_bootstrap( preset_manager.default_preset_for_game(game_enum).get_preset()) all_pickups = set( reach_lib.filter_pickup_nodes(game.world_list.iterate_nodes())) pool_results = pool_creator.calculate_pool_results( permalink.get_preset(0).configuration, game.resource_database) initial_state.resources.add_resource_gain( pool_results.initial_resources.as_resource_gain()) for pickup in pool_results.pickups: add_pickup_to_state(initial_state, pickup) for pickup in pool_results.assignment.values(): add_pickup_to_state(initial_state, pickup) for trick in game.resource_database.trick: initial_state.resources.set_resource( trick, LayoutTrickLevel.maximum().as_number) expected_events = sorted([ event for event in game.resource_database.event if event.short_name not in ignore_events ], key=lambda it: it.short_name) expected_pickups = sorted(it.pickup_index for it in all_pickups if it.pickup_index.index not in ignore_pickups) reach = _create_reach_with_unsafe(game, initial_state.heal()) while list(reach_lib.collectable_resource_nodes(reach.nodes, reach)): reach.act_on( next(iter(reach_lib.collectable_resource_nodes(reach.nodes, reach)))) reach = advance_reach_with_possible_unsafe_resources(reach) # print("\nCurrent reach:") # print(game.world_list.node_name(reach.state.node, with_world=True)) # for world in game.world_list.worlds: # print(f"\n>> {world.name}") # for node in world.all_nodes: # print("[{!s:>5}, {!s:>5}, {!s:>5}] {}".format( # reach.is_reachable_node(node), reach.is_safe_node(node), # reach.state.resources.get(node.resource(), 0) > 0 # if isinstance(node, ResourceNode) else "", # game.world_list.node_name(node, with_world=True))) collected_indices = set(reach.state.collected_pickup_indices) collected_events = { resource for resource, quantity in reach.state.resources.as_resource_gain() if quantity > 0 and resource.resource_type == ResourceType.EVENT } assert list(reach_lib.collectable_resource_nodes(reach.nodes, reach)) == [] assert sorted(collected_indices) == expected_pickups assert sorted(collected_events, key=lambda it: it.short_name) == expected_events
def from_json(cls, value: dict, game: RandovaniaGame): minimal_logic = value["minimal_logic"] specific_levels = { trick_short_name: LayoutTrickLevel(level) for trick_short_name, level in value["specific_levels"].items() if level != LayoutTrickLevel.DISABLED.value } return cls( minimal_logic=minimal_logic, specific_levels={} if minimal_logic else specific_levels, game=game, )
def generate_world_html(name, areas): body = "" toc = """ <div id="toc_container"> <ul class="toc_list"> """ TOC_AREA_FORMAT = ''' <li><strong><a>%s</a></strong> <ul> %s </ul> </li> ''' TOC_CONNECTION_FORMAT = ''' <li><a href="#%s">%s</a></li>\n ''' for area in sorted(areas): area_body = HTML_AREA_FORMAT % (area, area) nodes = areas[area] toc_connections = "" for node in sorted(nodes): connections = nodes[node] for connection in sorted(connections): connection_name = "%s -> %s" % (node, connection) area_body += HTML_CONNECTION_FORMAT % (connection_name, connection_name) yt_ids = connections[connection] for (id, start_time, highest_diff) in sorted(yt_ids, key=lambda x: x[2]): if "https://www.youtube.com/embed/%s?start=%d" % ( id, start_time) in area_body: continue area_body += HTML_VIDEO_FORMAT % ( LayoutTrickLevel.from_number(highest_diff).long_name, id, start_time) toc_connections += TOC_CONNECTION_FORMAT % (connection_name, connection_name) toc += TOC_AREA_FORMAT % (area, toc_connections) body += area_body toc += """ </ul> </div> """ header = HTML_HEADER_FORMAT % (name, name, get_date()) return header + toc + body + HTML_FOOTER
def trick_resources_for_configuration( self, configuration: TrickLevelConfiguration, resource_database: ResourceDatabase, ) -> CurrentResources: """ :param configuration: :param resource_database: :return: """ static_resources = {} for trick in resource_database.trick: if configuration.minimal_logic: level = LayoutTrickLevel.maximum() else: level = configuration.level_for_trick(trick) static_resources[trick] = level.as_number return static_resources
def process(req: Requirement, result: set[LayoutTrickLevel]): for resource_requirement in req.iterate_resource_requirements(game.resource_database): if resource_requirement.resource == trick: result.add(LayoutTrickLevel.from_number(resource_requirement.amount))
def test_reach_size_from_start_echoes(small_echoes_game_description, default_echoes_configuration, mocker): # Setup game = derived_nodes.remove_inactive_layers( small_echoes_game_description, default_echoes_configuration.active_layers()).get_mutable() mocker.patch( "randovania.game_description.default_database.game_description_for", return_value=game) generator = game.game.generator specific_levels = { trick.short_name: LayoutTrickLevel.maximum() for trick in game.resource_database.trick } def item(name: str): return find_resource_info_with_long_name(game.resource_database.item, name) ni = NodeIdentifier.create def nodes(*names: str): def get_index(n: Node): return n.node_index result = [ game.world_list.node_by_identifier(ni(*name.split("/"))) for name in names ] result.sort(key=get_index) return result layout_configuration = dataclasses.replace( default_echoes_configuration, trick_level=TrickLevelConfiguration( minimal_logic=False, specific_levels=specific_levels, game=default_echoes_configuration.game), starting_location=StartingLocationList.with_elements( [game.starting_location], game=RandovaniaGame.METROID_PRIME_ECHOES, )) patches = generator.base_patches_factory.create_base_patches( layout_configuration, Random(15000), game, False, player_index=0) state = generator.bootstrap.calculate_starting_state( game, patches, default_echoes_configuration) state.resources.add_resource_gain([ (item("Combat Visor"), 1), (item("Amber Translator"), 1), (item("Scan Visor"), 1), (item("Morph Ball"), 1), (item("Power Beam"), 1), (item("Charge Beam"), 1), (item("Grapple Beam"), 1), (item("Dark Beam"), 1), (item("Dark Ammo"), 50), (item("Missile"), 5), ]) # Run reach = OldGeneratorReach.reach_from_state(game, state) reach_lib.collect_all_safe_resources_in_reach(reach) # Assert assert list(reach.nodes) == nodes( "Temple Grounds/Path of Eyes/Front of Translator Gate", "Temple Grounds/Path of Eyes/Lore Scan", "Temple Grounds/Path of Eyes/Translator Gate", "Temple Grounds/Path of Eyes/Door to Torvus Transport Access", "Temple Grounds/Torvus Transport Access/Door to Path of Eyes", "Temple Grounds/Torvus Transport Access/Door to Transport to Torvus Bog", "Temple Grounds/Torvus Transport Access/Lock - Door to Transport to Torvus Bog", "Temple Grounds/Transport to Torvus Bog/Door to Torvus Transport Access", "Temple Grounds/Transport to Torvus Bog/Lock - Door to Torvus Transport Access", "Temple Grounds/Transport to Torvus Bog/Elevator to Torvus Bog - Transport to Temple Grounds", "Torvus Bog/Transport to Temple Grounds/Elevator to Temple Grounds - Transport to Torvus Bog", "Torvus Bog/Transport to Temple Grounds/Door to Temple Transport Access", "Torvus Bog/Temple Transport Access/Door to Transport to Temple Grounds", "Torvus Bog/Temple Transport Access/Door to Torvus Lagoon", "Torvus Bog/Torvus Lagoon/Door to Temple Transport Access", "Torvus Bog/Torvus Lagoon/Door to Path of Roots", "Torvus Bog/Torvus Lagoon/Keybearer Corpse (S-Dly)", "Torvus Bog/Path of Roots/Door to Torvus Lagoon", "Torvus Bog/Path of Roots/Door to Great Bridge", "Torvus Bog/Path of Roots/Pickup (Missile)", "Torvus Bog/Path of Roots/Next to Pickup", "Torvus Bog/Path of Roots/Under Lore Scan", "Torvus Bog/Path of Roots/Lore Scan", "Torvus Bog/Great Bridge/Door to Path of Roots", ) assert len(list(reach.safe_nodes)) == 22