def _add_box_with_requirements(self, alternative: RequirementList):
        group_box = self._create_box_in_grid()
        group_box.rows = []

        vertical_layout = QVBoxLayout(group_box)
        vertical_layout.setObjectName(f"Layout with index {self._current_last_index - 1}")
        vertical_layout.setAlignment(Qt.AlignTop)

        empty = True
        trick_level = LayoutTrickLevel.NO_TRICKS

        for item in sorted(alternative.items):
            if self.edit_mode:
                ItemRow(group_box, vertical_layout, self.resource_database, item, group_box.rows)
            else:
                if item.resource.resource_type == ResourceType.DIFFICULTY:
                    trick_level = LayoutTrickLevel.from_number(item.amount)
                else:
                    empty = False
                    label = QLabel(group_box)
                    if item.resource.resource_type == ResourceType.TRICK:
                        label.setText(f"{item.resource} ({LayoutTrickLevel.from_number(item.amount).long_name})")
                    else:
                        label.setText(item.pretty_text)

                    vertical_layout.addWidget(label)

        if self.edit_mode:
            tools_layout = QHBoxLayout(group_box)
            tools_layout.setObjectName(f"Tools layout with index {self._current_last_index - 1}")
            vertical_layout.addLayout(tools_layout)

            add_new_button = QPushButton(group_box)
            add_new_button.setText("New Requirement")
            tools_layout.addWidget(add_new_button)

            delete_button = QPushButton(group_box)
            delete_button.setText("Delete")
            delete_button.clicked.connect(partial(self._delete_alternative, group_box))
            tools_layout.addWidget(delete_button)

            def _new_row():
                empty_item = IndividualRequirement(
                    self.resource_database.get_by_type(ResourceType.ITEM)[0],
                    1, False
                )
                ItemRow(group_box, vertical_layout, self.resource_database, empty_item, group_box.rows)
                vertical_layout.removeItem(tools_layout)
                vertical_layout.addLayout(tools_layout)

            add_new_button.clicked.connect(_new_row)

        else:
            group_box.setTitle(f"Difficulty: {trick_level.long_name}")
            if empty:
                label = QLabel(group_box)
                label.setText("No requirements.")
                vertical_layout.addWidget(label)

        return group_box
Exemplo n.º 2
0
 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)))
Exemplo n.º 3
0
def pretty_print_resource_requirement(requirement: ResourceRequirement) -> str:
    if requirement.resource.resource_type == ResourceType.TRICK:
        return f"{requirement.resource} ({LayoutTrickLevel.from_number(requirement.amount).long_name})"
    elif requirement.resource.resource_type == ResourceType.DIFFICULTY:
        trick_level = LayoutTrickLevel.from_number(requirement.amount)
        return f"Difficulty: {trick_level.long_name}"
    else:
        return requirement.pretty_text
def _difficulties_for_trick(world_list: WorldList, trick: SimpleResourceInfo):
    result = set()

    for area in world_list.all_areas:
        for _, _, requirements in area.all_connections:
            for individual in requirements.all_individual:
                if individual.resource == trick:
                    result.add(LayoutTrickLevel.from_number(individual.amount))

    return result
Exemplo n.º 5
0
 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,
     )
Exemplo n.º 6
0
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
Exemplo n.º 7
0
def difficulties_for_trick(world_list: WorldList, trick: TrickResourceInfo):
    result = set()

    for area in world_list.all_areas:
        for _, _, requirement in area.all_connections:
            for resource_requirement in requirement.iterate_resource_requirements(
            ):
                if resource_requirement.resource == trick:
                    result.add(
                        LayoutTrickLevel.from_number(
                            resource_requirement.amount))

    return result
Exemplo n.º 8
0
def get_layout_configuration_from_args(args) -> LayoutConfiguration:
    try:
        sky_temple_keys = int(args.sky_temple_keys)
    except ValueError:
        sky_temple_keys = args.sky_temple_keys

    # TODO: support for item loss
    return LayoutConfiguration.from_params(
        trick_level_configuration=TrickLevelConfiguration(
            LayoutTrickLevel(args.trick_level)),
        sky_temple_keys=LayoutSkyTempleKeyMode(sky_temple_keys),
        elevators=LayoutElevators.VANILLA,
        starting_location=StartingLocation.default(),
    )
Exemplo n.º 9
0
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
Exemplo n.º 10
0
 def process(req: Requirement, result: Set[LayoutTrickLevel]):
     for resource_requirement in req.iterate_resource_requirements():
         if resource_requirement.resource == trick:
             result.add(
                 LayoutTrickLevel.from_number(resource_requirement.amount))
Exemplo n.º 11
0
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