def test_database_collectable(preset_manager, game_enum, preset_name, ignore_events, ignore_pickups): game, initial_state, permalink = run_bootstrap( preset_manager.included_preset_with(game_enum, preset_name).get_preset()) all_pickups = set(filter_pickup_nodes(game.world_list.all_nodes)) pool_results = pool_creator.calculate_pool_results( permalink.get_preset(0).configuration, game.resource_database) add_resources_into_another(initial_state.resources, pool_results.initial_resources) 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[trick] = LayoutTrickLevel.maximum().as_number expected_events = [ event for event in game.resource_database.event if event.index not in ignore_events ] 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(collectable_resource_nodes(reach.nodes, reach)): reach.act_on(next(iter(collectable_resource_nodes(reach.nodes, reach)))) reach = advance_reach_with_possible_unsafe_resources(reach) # print("\nCurrent reach:") # 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))) collected_indices = { resource for resource, quantity in reach.state.resources.items() if quantity > 0 and isinstance(resource, PickupIndex) } collected_events = { resource for resource, quantity in reach.state.resources.items() if quantity > 0 and resource.resource_type == ResourceType.EVENT } assert list(collectable_resource_nodes(reach.nodes, reach)) == [] assert sorted(collected_indices) == expected_pickups assert sorted(collected_events, key=lambda it: it.index) == expected_events
def trick_resources_for_configuration( 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 test_reach_size_from_start_echoes(small_echoes_game_description, default_layout_configuration): # Setup game = small_echoes_game_description 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) def nodes(*names): result = [game.world_list.node_from_name(name) for name in names] result.sort(key=lambda it: it.index) return result layout_configuration = dataclasses.replace( default_layout_configuration, trick_level=TrickLevelConfiguration( minimal_logic=False, specific_levels=specific_levels, game=default_layout_configuration.game), starting_location=StartingLocationList.with_elements( [game.starting_location], game=RandovaniaGame.PRIME2, )) patches = base_patches_factory.create_base_patches(layout_configuration, Random(15000), game, False, player_index=0) state = bootstrap.calculate_starting_state(game, patches, 100) state.resources[item("Combat Visor")] = 1 state.resources[item("Amber Translator")] = 1 state.resources[item("Scan Visor")] = 1 state.resources[item("Morph Ball")] = 1 state.resources[item("Power Beam")] = 1 state.resources[item("Charge Beam")] = 1 state.resources[item("Grapple Beam")] = 1 state.resources[item("Dark Beam")] = 1 state.resources[item("Dark Ammo")] = 50 state.resources[item("Missile")] = 5 # Run reach = GeneratorReach.reach_from_state(game, state) # 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/Transport to Torvus Bog/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)) == 20