Exemplo n.º 1
0
def test_decode(location_with_data):
    # Setup
    data, expected = location_with_data

    # Run
    decoder = BitPackDecoder(data)
    result = StartingLocation.bit_pack_unpack(decoder, {
        "reference":
        StartingLocation.with_elements([], RandovaniaGame.PRIME2)
    })

    # Assert
    assert result == expected
Exemplo n.º 2
0
def test_distribute_command_logic(mock_generate_list: MagicMock, ):
    # Setup
    args = MagicMock()
    args.trick_level = LayoutTrickLevel.HARD.value
    args.major_items_mode = False
    args.sky_temple_keys = LayoutSkyTempleKeyMode.ALL_BOSSES.value
    args.skip_item_loss = True
    args.seed = 15000
    args.output_file = "asdfasdf/qwerqwerqwer/zxcvzxcv.json"

    # Run
    echoes.distribute_command_logic(args)

    # Assert
    mock_generate_list.assert_called_once_with(permalink=Permalink(
        seed_number=args.seed,
        spoiler=True,
        patcher_configuration=PatcherConfiguration.default(),
        layout_configuration=LayoutConfiguration.from_params(
            trick_level=LayoutTrickLevel.HARD,
            sky_temple_keys=LayoutSkyTempleKeyMode.ALL_BOSSES,
            elevators=LayoutRandomizedFlag.VANILLA,
            pickup_quantities={},
            starting_location=StartingLocation.default(),
            starting_resources=StartingResources.from_non_custom_configuration(
                StartingResourcesConfiguration.VANILLA_ITEM_LOSS_DISABLED),
        ),
    ),
                                               status_update=ANY)

    save_file_mock: MagicMock = mock_generate_list.return_value.save_to_file
    save_file_mock.assert_called_once_with(Path(args.output_file))
def test_create_permalink_logic(mock_print: MagicMock, ):
    # Setup
    args = MagicMock()
    args.trick_level = LayoutTrickLevel.HARD.value
    args.major_items_mode = False
    args.sky_temple_keys = LayoutSkyTempleKeyMode.ALL_BOSSES.value
    args.skip_item_loss = True
    args.seed = 15000
    args.menu_mod = False
    args.warp_to_start = False

    # Run
    randovania.cli.commands.create_permalink.create_permalink_logic(args)

    # Assert
    permalink = Permalink(
        seed_number=args.seed,
        spoiler=True,
        patcher_configuration=PatcherConfiguration(
            menu_mod=args.menu_mod,
            warp_to_start=args.warp_to_start,
        ),
        layout_configuration=LayoutConfiguration.from_params(
            trick_level_configuration=TrickLevelConfiguration(
                LayoutTrickLevel.HARD),
            sky_temple_keys=LayoutSkyTempleKeyMode.ALL_BOSSES,
            elevators=LayoutElevators.VANILLA,
            starting_location=StartingLocation.default(),
        ),
    )

    # Assert
    mock_print.assert_called_once_with(permalink)
 def _update_starting_location(self):
     if self._has_valid_starting_location():
         with self._options as options:
             options.set_layout_configuration_field(
                 "starting_location",
                 StartingLocation(self.startingarea_combo.currentData(),
                                  self.current_starting_area_location))
Exemplo n.º 5
0
 def from_json_dict(cls, json_dict: dict) -> "LayoutConfiguration":
     return LayoutConfiguration(
         trick_level_configuration=TrickLevelConfiguration.from_json(
             json_dict["trick_level"]),
         damage_strictness=LayoutDamageStrictness(
             json_dict["damage_strictness"]),
         sky_temple_keys=LayoutSkyTempleKeyMode(
             json_dict["sky_temple_keys"]),
         elevators=LayoutElevators(json_dict["elevators"]),
         starting_location=StartingLocation.from_json(
             json_dict["starting_location"]),
         available_locations=AvailableLocationsConfiguration.from_json(
             json_dict["available_locations"]),
         major_items_configuration=MajorItemsConfiguration.from_json(
             json_dict["major_items_configuration"],
             default_prime2_item_database(),
         ),
         ammo_configuration=AmmoConfiguration.from_json(
             json_dict["ammo_configuration"],
             default_prime2_item_database(),
         ),
         translator_configuration=TranslatorConfiguration.from_json(
             json_dict["translator_configuration"]),
         hints=HintConfiguration.from_json(json_dict["hints"]),
         beam_configuration=BeamConfiguration.from_json(
             json_dict["beam_configuration"]),
         skip_final_bosses=json_dict["skip_final_bosses"],
         energy_per_tank=json_dict["energy_per_tank"],
         split_beam_ammo=json_dict["split_beam_ammo"],
     )
Exemplo n.º 6
0
def test_invalid_constructor_location_should_be_missing():
    with pytest.raises(ValueError) as err:
        StartingLocation(StartingLocationConfiguration.SHIP,
                         AreaLocation(0, 0))

    assert str(err.value) == "custom_location set to world 0/area 0, " \
                             "but configuration is StartingLocationConfiguration.SHIP instead of CUSTOM"
Exemplo n.º 7
0
 def default(cls) -> "LayoutConfiguration":
     return cls.from_params(
         trick_level=LayoutTrickLevel.NO_TRICKS,
         sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
         elevators=LayoutRandomizedFlag.VANILLA,
         pickup_quantities={},
         starting_location=StartingLocation.default(),
         starting_resources=StartingResources.default(),
     )
Exemplo n.º 8
0
def get_layout_configuration_from_args(args) -> LayoutConfiguration:
    return LayoutConfiguration.from_params(
        trick_level=LayoutTrickLevel(args.trick_level),
        sky_temple_keys=LayoutSkyTempleKeyMode(args.sky_temple_keys),
        elevators=LayoutRandomizedFlag.VANILLA,
        pickup_quantities={},
        starting_location=StartingLocation.default(),
        starting_resources=StartingResources.from_item_loss(
            not args.skip_item_loss),
    )
Exemplo n.º 9
0
    def _starting_location_on_select_save_station(self):
        world_list = self.game_description.world_list
        save_stations = [world_list.node_to_area_location(node)
                         for node in world_list.all_nodes if node.name == "Save Station"]

        with self._editor as editor:
            editor.set_layout_configuration_field(
                "starting_location",
                StartingLocation.with_elements(save_stations)
            )
def test_decode(location_with_data):
    # Setup
    data, expected = location_with_data

    # Run
    decoder = BitPackDecoder(data)
    result = StartingLocation.bit_pack_unpack(decoder, {})

    # Assert
    assert result == expected
Exemplo n.º 11
0
 def from_json_dict(cls, json_dict: dict) -> "LayoutConfiguration":
     return cls.from_params(
         trick_level=LayoutTrickLevel(json_dict["trick_level"]),
         sky_temple_keys=LayoutSkyTempleKeyMode(
             json_dict["sky_temple_keys"]),
         elevators=LayoutRandomizedFlag(json_dict["elevators"]),
         pickup_quantities=json_dict["pickup_quantities"],
         starting_location=StartingLocation.from_json(
             json_dict["starting_location"]),
         starting_resources=StartingResources.from_json(
             json_dict["starting_resources"]),
     )
def _location_with_data(request, mocker, echoes_game_description):
    world_list = echoes_game_description.world_list
    areas = list(
        itertools.islice(
            (AreaLocation(world.world_asset_id, area.area_asset_id)
             for world in world_list.worlds
             for area in world.areas if area.valid_starting_location), 15))

    mocker.patch("randovania.layout.starting_location._areas_list",
                 return_value=list(sorted(areas)))
    return request.param["encoded"], StartingLocation.from_json(
        request.param["json"])
Exemplo n.º 13
0
def test_create_patches(
    mock_random: MagicMock,
    mock_calculate_item_pool: MagicMock,
    mock_create_base_patches: MagicMock,
    mock_retcon_playthrough_filler: MagicMock,
    mock_indices_for_unassigned_pickups: MagicMock,
):
    # Setup
    seed_number: int = 91319
    game = default_prime2_game_description()
    status_update: Union[MagicMock, Callable[[str], None]] = MagicMock()
    configuration = LayoutConfiguration.from_params(
        trick_level=LayoutTrickLevel.NO_TRICKS,
        sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
        elevators=LayoutRandomizedFlag.VANILLA,
        pickup_quantities={},
        starting_location=StartingLocation.default(),
        starting_resources=StartingResources.from_item_loss(False),
    )
    permalink = Permalink(
        seed_number=seed_number,
        spoiler=True,
        patcher_configuration=PatcherConfiguration.default(),
        layout_configuration=configuration,
    )
    mock_calculate_item_pool.return_value = list(
        sorted(game.pickup_database.original_pickup_mapping.values()))
    mock_create_base_patches.return_value.starting_location = game.starting_location
    mock_create_base_patches.return_value.custom_initial_items = None

    filler_patches = mock_retcon_playthrough_filler.return_value

    # Run
    result = generator._create_patches(permalink, game, status_update)

    # Assert
    mock_random.assert_called_once_with(permalink.as_str)
    mock_calculate_item_pool.assert_called_once_with(permalink, game)

    mock_create_base_patches.assert_called_once_with(mock_random.return_value,
                                                     game, permalink, ANY)

    mock_retcon_playthrough_filler.assert_called_once_with(
        ANY, ANY, ANY, mock_random.return_value, status_update)

    mock_indices_for_unassigned_pickups.assert_called_once_with(
        mock_random.return_value, game, filler_patches.pickup_assignment, ANY)
    filler_patches.assign_new_pickups.assert_called_once_with(
        mock_indices_for_unassigned_pickups.return_value)

    assert result == filler_patches.assign_new_pickups.return_value
Exemplo n.º 14
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.º 15
0
 def from_json_dict(cls, json_dict: dict) -> "LayoutConfiguration":
     return cls.from_params(
         trick_level_configuration=TrickLevelConfiguration.from_json(json_dict["trick_level"]),
         sky_temple_keys=LayoutSkyTempleKeyMode(json_dict["sky_temple_keys"]),
         elevators=LayoutElevators(json_dict["elevators"]),
         starting_location=StartingLocation.from_json(json_dict["starting_location"]),
         randomization_mode=RandomizationMode(json_dict["randomization_mode"]),
         major_items_configuration=MajorItemsConfiguration.from_json(
             json_dict["major_items_configuration"],
             default_prime2_item_database(),
         ),
         ammo_configuration=AmmoConfiguration.from_json(
             json_dict["ammo_configuration"],
             default_prime2_item_database(),
         ),
         translator_configuration=TranslatorConfiguration.from_json(json_dict["translator_configuration"]),
         hints=HintConfiguration.from_json(json_dict["hints"]),
         split_beam_ammo=json_dict["split_beam_ammo"],
     )
Exemplo n.º 16
0
def _test_data():
    data = default_data.decode_default_prime2()
    game = data_reader.decode_data(data, False)
    configuration = LayoutConfiguration.from_params(
        trick_level=LayoutTrickLevel.NO_TRICKS,
        sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
        elevators=LayoutRandomizedFlag.VANILLA,
        pickup_quantities={},
        starting_location=StartingLocation.default(),
        starting_resources=StartingResources.default(),
    )
    permalink = Permalink(
        seed_number=15000,
        spoiler=True,
        patcher_configuration=PatcherConfiguration.default(),
        layout_configuration=configuration,
    )
    logic, state = logic_bootstrap(configuration, game,
                                   GamePatches.with_game(game))

    return logic, state, permalink
Exemplo n.º 17
0
def test_generate_seed_with_invalid_quantity_configuration():
    # Setup
    status_update = MagicMock()

    configuration = LayoutConfiguration.from_params(
        trick_level=LayoutTrickLevel.NO_TRICKS,
        sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
        elevators=LayoutRandomizedFlag.VANILLA,
        pickup_quantities={"Light Suit": 5},
        starting_location=StartingLocation.default(),
        starting_resources=StartingResources.default(),
    )

    permalink = Permalink(
        seed_number=50,
        spoiler=True,
        patcher_configuration=PatcherConfiguration.default(),
        layout_configuration=configuration,
    )

    # Run
    with pytest.raises(randovania.resolver.exceptions.GenerationFailure):
        generator.generate_list(permalink, status_update=status_update)
Exemplo n.º 18
0
def test_decode_v1(mock_dictionary_byte_hash: MagicMock):
    mock_dictionary_byte_hash.return_value = 120
    # We're mocking the database hash to avoid breaking tests every single time we change the database

    # This test should break whenever we change how permalinks are created
    # When this happens, we must bump the permalink version and change the tests
    encoded = "IAAAfReNPArRHMClxLYgIID3"

    expected = Permalink(
        seed_number=1000,
        spoiler=True,
        patcher_configuration=PatcherConfiguration(
            disable_hud_popup=True,
            menu_mod=True,
            speed_up_credits=False,
        ),
        layout_configuration=LayoutConfiguration.from_params(
            trick_level=LayoutTrickLevel.HARD,
            sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
            elevators=LayoutRandomizedFlag.RANDOMIZED,
            pickup_quantities={
                "Missile Expansion": 10,
                "Light Suit": 9,
            },
            starting_location=StartingLocation.default(),
            starting_resources=StartingResources.default(),
        ),
    )

    # Uncomment this line to quickly get the new encoded permalink
    # assert expected.as_str == ""

    # Run
    link = Permalink.from_str(encoded)

    # Assert
    assert link == expected
Exemplo n.º 19
0
    PatcherConfiguration(
        menu_mod=True,
        warp_to_start=False,
    ),
])
@pytest.mark.parametrize("layout", [
    LayoutConfiguration.default(),
    LayoutConfiguration.from_params(
        trick_level=LayoutTrickLevel.HARD,
        sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
        elevators=LayoutRandomizedFlag.RANDOMIZED,
        pickup_quantities={
            "Missile Expansion": 10,
            "Light Suit": 9,
        },
        starting_location=StartingLocation.default(),
        starting_resources=StartingResources.default(),
    ),
])
def test_round_trip(spoiler: bool, patcher: PatcherConfiguration,
                    layout: LayoutConfiguration):
    # Setup
    link = Permalink(
        seed_number=1000,
        spoiler=spoiler,
        patcher_configuration=patcher,
        layout_configuration=layout,
    )

    # Run
    after = Permalink.from_str(link.as_str)
Exemplo n.º 20
0
    result = option._serialize_fields()

    # Assert
    assert result == {
        "version": 4,
        "options": {}
    }


_sample_layout_configurations = [
    {
        "trick_level": trick_level,
        "sky_temple_keys": LayoutSkyTempleKeyMode.FULLY_RANDOM,
        "elevators": LayoutRandomizedFlag.RANDOMIZED,
        "pickup_quantities": {},
        "starting_location": StartingLocation.default(),
        "starting_resources": StartingResources.from_item_loss(item_loss),
    }
    for trick_level in [LayoutTrickLevel.NO_TRICKS, LayoutTrickLevel.HARD, LayoutTrickLevel.MINIMAL_RESTRICTIONS]
    for item_loss in (False, True)
]


@pytest.fixture(params=_sample_layout_configurations, name="initial_layout_configuration_params")
def _initial_layout_configuration_params(request) -> dict:
    return request.param


@pytest.mark.parametrize("new_trick_level",
                         [LayoutTrickLevel.NO_TRICKS, LayoutTrickLevel.TRIVIAL, LayoutTrickLevel.HYPERMODE])
def test_edit_layout_trick_level(option: Options,
Exemplo n.º 21
0
def test_invalid_constructor_missing_location():
    with pytest.raises(ValueError) as err:
        StartingLocation(StartingLocationConfiguration.CUSTOM, None)

    assert str(
        err.value) == "Configuration is CUSTOM, but not custom_location set"
Exemplo n.º 22
0
def test_round_trip_json_all_custom_location(custom_starting_location):
    # Run
    round_trip = StartingLocation.from_json(custom_starting_location.as_json)

    # Assert
    assert custom_starting_location == round_trip
Exemplo n.º 23
0
def test_round_trip_json_simple(simple_starting_location):
    # Run
    round_trip = StartingLocation.from_json(simple_starting_location.as_json)

    # Assert
    assert simple_starting_location == round_trip
Exemplo n.º 24
0
def test_default():
    value = StartingLocation.default()

    # Assert
    assert value.configuration == StartingLocationConfiguration.SHIP
Exemplo n.º 25
0
def _custom_starting_location():
    return StartingLocation(StartingLocationConfiguration.CUSTOM,
                            AreaLocation(2252328306, 3417147547))
Exemplo n.º 26
0
def _simple_starting_location(request):
    yield StartingLocation(request.param, None)
Exemplo n.º 27
0
        "options": {
            "last_changelog_displayed":
            str(update_checker.strict_current_version()),
        }
    }


_sample_layout_configurations = [{
    "trick_level_configuration":
    TrickLevelConfiguration(trick_level),
    "sky_temple_keys":
    LayoutSkyTempleKeyMode.default(),
    "elevators":
    LayoutElevators.RANDOMIZED,
    "starting_location":
    StartingLocation.default(),
} for trick_level in [
    LayoutTrickLevel.NO_TRICKS, LayoutTrickLevel.HARD,
    LayoutTrickLevel.MINIMAL_RESTRICTIONS
]]


@pytest.fixture(params=_sample_layout_configurations,
                name="initial_layout_configuration_params")
def _initial_layout_configuration_params(request) -> dict:
    return request.param


@pytest.mark.parametrize("new_trick_level", [
    LayoutTrickLevel.NO_TRICKS, LayoutTrickLevel.TRIVIAL,
    LayoutTrickLevel.HYPERMODE
Exemplo n.º 28
0
def _location_with_data(request):
    return request.param["encoded"], StartingLocation.from_json(
        request.param["json"])
Exemplo n.º 29
0
def test_apply_layout(mock_run_with_args: MagicMock,
                      mock_base_args: MagicMock,
                      mock_ensure_no_menu_mod: MagicMock,
                      mock_create_pak_backups: MagicMock,
                      mock_calculate_indices: MagicMock,
                      mock_add_menu_mod_to_files: MagicMock,
                      mock_create_progress_update_from_successive_messages: MagicMock,
                      mock_save_to_file: MagicMock,
                      seed_number: int,
                      item_loss: bool,
                      elevators: bool,
                      warp_to_start: bool,
                      include_menu_mod: bool,
                      speed_up_credits: bool,
                      ):
    # Setup
    hud_memo_popup_removal: bool = MagicMock()
    cosmetic_patches = CosmeticPatches(disable_hud_popup=hud_memo_popup_removal,
                                       speed_up_credits=speed_up_credits,
                                       )
    description = LayoutDescription(
        version=randovania.VERSION,
        permalink=Permalink(
            seed_number=seed_number,
            spoiler=False,
            patcher_configuration=PatcherConfiguration(
                menu_mod=include_menu_mod,
                warp_to_start=warp_to_start,
            ),
            layout_configuration=LayoutConfiguration.from_params(
                trick_level=MagicMock(),
                sky_temple_keys=MagicMock(),
                elevators=LayoutRandomizedFlag.RANDOMIZED if elevators else LayoutRandomizedFlag.VANILLA,
                pickup_quantities={},
                starting_location=StartingLocation.default(),
                starting_resources=StartingResources.from_item_loss(item_loss),
            )
        ),
        patches=None,
        solver_path=(),
    )

    game_root = MagicMock(spec=Path())
    backup_files_path = MagicMock()
    progress_update = MagicMock()
    status_update = mock_create_progress_update_from_successive_messages.return_value

    mock_calculate_indices.return_value = [10, 25, 1, 2, 5, 1]
    mock_base_args.return_value = []
    expected_args = [
        "-s", str(seed_number),
        "-p", "10,25,1,2,5,1"
    ]
    if not item_loss:
        expected_args.append("-i")
    if elevators:
        expected_args.append("-v")
    if speed_up_credits:
        expected_args.append("-c")
    if warp_to_start:
        expected_args.append("-t")

    # Run
    claris_randomizer.apply_layout(description, cosmetic_patches, backup_files_path, progress_update, game_root)

    # Assert
    mock_base_args.assert_called_once_with(game_root, hud_memo_popup_removal=hud_memo_popup_removal)
    mock_create_progress_update_from_successive_messages.assert_called_once_with(
        progress_update,
        400 if include_menu_mod else 100
    )
    mock_ensure_no_menu_mod.assert_called_once_with(game_root, backup_files_path, status_update)
    mock_create_pak_backups.assert_called_once_with(game_root, backup_files_path, status_update)
    mock_calculate_indices.assert_called_once_with(description)
    game_root.joinpath.assert_called_once_with("files", "randovania.json")
    mock_save_to_file.assert_called_once_with(description, game_root.joinpath.return_value)
    mock_run_with_args.assert_called_once_with(expected_args, "Randomized!", status_update)
    if include_menu_mod:
        mock_add_menu_mod_to_files.assert_called_once_with(game_root, status_update)
    else:
        mock_add_menu_mod_to_files.assert_not_called()
Exemplo n.º 30
0
 def _starting_location_on_select_ship(self):
     with self._editor as editor:
         editor.set_layout_configuration_field(
             "starting_location",
             StartingLocation.with_elements(
                 [self.game_description.starting_location]))