Exemplo n.º 1
0
def test_create_message_for_hint_relative_item(echoes_game_patches,
                                               blank_pickup, players_config,
                                               distance_precise, distance_text,
                                               reference_precision,
                                               reference_name):
    patches = echoes_game_patches.assign_new_pickups([
        (PickupIndex(5), PickupTarget(blank_pickup, 0)),
        (PickupIndex(15),
         PickupTarget(
             dataclasses.replace(blank_pickup, name="Reference Pickup"), 0)),
    ])

    hint = Hint(
        HintType.LOCATION,
        PrecisionPair(HintLocationPrecision.RELATIVE_TO_INDEX,
                      HintItemPrecision.DETAILED,
                      include_owner=False,
                      relative=RelativeDataItem(distance_precise,
                                                PickupIndex(15),
                                                reference_precision)),
        PickupIndex(5))

    namer = EchoesHintNamer({0: patches}, PlayersConfiguration(0, {0: "You"}))
    exporter = HintExporter(namer, random.Random(0), ["A Joke"])

    # Run
    result = exporter.create_message_for_hint(hint, {0: patches},
                                              players_config, True)

    # Assert
    assert result == (
        f'The &push;&main-color=#FF6705B3;Blank Pickup&pop; can be found '
        f'&push;&main-color=#FF3333;{distance_text} {7 + (distance_precise or 0)} '
        f'rooms&pop; away from {reference_name}.')
Exemplo n.º 2
0
def test_create_hints_item_dark_temple_keys_cross_game(
    blank_pickup,
    echoes_resource_database,
    echoes_game_patches,
    default_echoes_configuration,
    prime_game_patches,
    default_prime_configuration,
):
    # Setup
    players_config = PlayersConfiguration(
        player_index=0,
        player_names={
            0: "Player 1",
            1: "Player 2",
        },
    )

    keys = [
        dataclasses.replace(
            blank_pickup,
            progression=((echoes_resource_database.get_item(item), 1), ))
        for item in echoes_items.DARK_TEMPLE_KEY_ITEMS[1]
    ]

    echoes_patches = dataclasses.replace(
        echoes_game_patches,
        configuration=default_echoes_configuration,
        pickup_assignment={
            PickupIndex(14): PickupTarget(keys[0], 0),
            PickupIndex(80): PickupTarget(keys[2], 0),
        })
    prime_patches = dataclasses.replace(
        prime_game_patches,
        configuration=default_prime_configuration,
        pickup_assignment={
            PickupIndex(23): PickupTarget(keys[1], 0),
        })

    hint = Hint(HintType.RED_TEMPLE_KEY_SET,
                None,
                dark_temple=HintDarkTemple.TORVUS_BOG)

    namer = EchoesHintNamer({
        0: echoes_patches,
        1: prime_patches
    }, players_config)
    exporter = HintExporter(namer, random.Random(0), ["A Joke"])

    # Run
    result = exporter.create_message_for_hint(hint, {
        0: echoes_patches,
        1: prime_patches
    }, players_config, True)

    # Assert
    assert result == (
        'The keys to &push;&main-color=#FF6705B3;Dark Torvus Temple&pop; can be found '
        'in &push;&main-color=#FF3333;Chozo Ruins&pop;, '
        '&push;&main-color=#FF3333;Dark Torvus Bog&pop; and '
        '&push;&main-color=#FF3333;Temple Grounds&pop;.')
Exemplo n.º 3
0
def test_create_hints_light_suit_location(empty_patches, pickup, item,
                                          location):
    # Setup
    asset_id = 1000
    pickup_index = PickupIndex(50)

    logbook_node, _, world_list = _create_world_list(asset_id, pickup_index)

    patches = dataclasses.replace(empty_patches,
                                  pickup_assignment={
                                      pickup_index: PickupTarget(pickup, 0),
                                  },
                                  hints={
                                      logbook_node.resource():
                                      Hint(HintType.LIGHT_SUIT_LOCATION,
                                           PrecisionPair(location, item[0]),
                                           pickup_index)
                                  })
    rng = MagicMock()

    # Run
    result = item_hints.create_hints(patches, world_list, rng)

    # Assert
    if location is HintLocationPrecision.WRONG_GAME and item[
            0] is HintItemPrecision.WRONG_GAME:
        message = "&push;&main-color=#45F731;Warning! Dark Aether's atmosphere is dangerous!" \
                  " Energized Safe Zones don't last forever!&pop;"
    else:
        message = f"U-Mos's reward for returning the Sanctuary energy is {item[1]}."
    assert result == [{
        'asset_id': asset_id,
        'strings': [message, '', message]
    }]
Exemplo n.º 4
0
def test_pickup_data_for_pb_expansion_unlocked(echoes_item_database, echoes_resource_database):
    # Setup
    pickup = pickup_creator.create_ammo_expansion(
        echoes_item_database.ammo["Power Bomb Expansion"],
        [2],
        False,
        echoes_resource_database,
    )
    creator = pickup_exporter.PickupExporterSolo(patch_data_factory._simplified_memo_data())

    # Run
    details = creator.export(PickupIndex(0), PickupTarget(pickup, 0), pickup, PickupModelStyle.ALL_VISIBLE)
    result = patch_data_factory.echoes_pickup_details_to_patcher(details, MagicMock())

    # Assert
    assert result == {
        "pickup_index": 0,
        "scan": "Power Bomb Expansion. Provides 2 Power Bombs and 1 Item Percentage",
        "model": {"game": "prime2", "name": "PowerBombExpansion"},
        "hud_text": ["Power Bomb Expansion acquired!"],
        'resources': [{'amount': 2, 'index': 43},
                      {'amount': 1, 'index': 47}],
        "conditional_resources": [],
        "convert": [],
    }
Exemplo n.º 5
0
def test_game_session_request_pickups_one_action(
        mock_session_description: PropertyMock,
        mock_get_resource_database: MagicMock,
        mock_get_pickup_target: MagicMock, flask_app, two_player_session,
        echoes_resource_database):
    # Setup
    sio = MagicMock()
    sio.get_current_user.return_value = database.User.get_by_id(1234)

    pickup = PickupEntry("A",
                         PickupModel(echoes_resource_database.game_enum,
                                     "AmmoModel"),
                         ItemCategory.TEMPLE_KEY,
                         ItemCategory.KEY,
                         progression=((echoes_resource_database.item[0], 1), ))
    mock_get_pickup_target.return_value = PickupTarget(pickup=pickup, player=0)
    mock_get_resource_database.return_value = echoes_resource_database

    # Run
    result = game_session.game_session_request_pickups(sio, 1)

    # Assert
    mock_get_resource_database.assert_called_once_with(
        mock_session_description.return_value, 0)
    mock_get_pickup_target.assert_called_once_with(
        mock_session_description.return_value, 1, 0)
    assert result == {
        "game":
        "prime2",
        "pickups": [{
            'provider_name': 'Other Name',
            'pickup': 'C@fSK*4Fga_C{94xPb='
        }]
    }
Exemplo n.º 6
0
def test_multi_create_pickup_data_for_self(pickup_for_create_pickup_data):
    # Setup
    solo = pickup_exporter.PickupExporterSolo(
        pickup_exporter.GenericAcquiredMemo())
    creator = pickup_exporter.PickupExporterMulti(
        solo, MagicMock(), PlayersConfiguration(0, {
            0: "You",
            1: "Someone"
        }))
    model = MagicMock()
    resource_a = ItemResourceInfo(1, "A", "A", 10, None)
    resource_b = ItemResourceInfo(2, "B", "B", 10, None)

    # Run
    data = creator.create_details(
        PickupIndex(10), PickupTarget(pickup_for_create_pickup_data,
                                      0), pickup_for_create_pickup_data,
        PickupModelStyle.ALL_VISIBLE, "Scan Text", model)

    # Assert
    assert data == pickup_exporter.ExportedPickupDetails(
        index=PickupIndex(10),
        scan_text="Your Scan Text",
        hud_text=['A acquired!', 'B acquired!'],
        conditional_resources=[
            ConditionalResources("A", None, ((resource_a, 1), )),
            ConditionalResources("B", resource_a, ((resource_b, 1), )),
        ],
        conversion=[],
        model=model,
    )
Exemplo n.º 7
0
def test_game_session_collect_pickup_for_self(
        mock_session_description: PropertyMock,
        mock_get_resource_database: MagicMock,
        mock_get_pickup_target: MagicMock, mock_emit: MagicMock, flask_app,
        two_player_session, echoes_resource_database):
    sio = MagicMock()
    sio.get_current_user.return_value = database.User.get_by_id(1234)

    pickup = PickupEntry(
        "A", 1, ItemCategory.TEMPLE_KEY, ItemCategory.KEY,
        (ConditionalResources(None, None,
                              ((echoes_resource_database.item[0], 1), )), ))
    mock_get_resource_database.return_value = echoes_resource_database
    mock_get_pickup_target.return_value = PickupTarget(pickup, 0)

    # Run
    with flask_app.test_request_context():
        result = game_session.game_session_collect_locations(sio, 1, (0, ))

    # Assert
    assert result is None
    mock_emit.assert_not_called()
    mock_get_pickup_target.assert_called_once_with(
        mock_session_description.return_value, 0, 0)
    with pytest.raises(peewee.DoesNotExist):
        database.GameSessionTeamAction.get(session=two_player_session,
                                           provider_row=0,
                                           provider_location_index=0)
Exemplo n.º 8
0
def test_create_hints_item_dark_temple_keys(empty_patches, players_config,
                                            echoes_game_description, pickup,
                                            indices, expected_message):
    # Setup
    db = echoes_game_description.resource_database
    keys = [
        (PickupIndex(index),
         dataclasses.replace(pickup,
                             resources=(ConditionalResources(
                                 None, None, ((db.get_item(item), 1), )), )))
        for index, item in zip(indices, echoes_items.DARK_TEMPLE_KEY_ITEMS[1])
    ]

    patches = dataclasses.replace(empty_patches,
                                  pickup_assignment={
                                      pickup_index: PickupTarget(key, 0)
                                      for pickup_index, key in keys
                                  })

    hint = Hint(HintType.RED_TEMPLE_KEY_SET,
                None,
                dark_temple=HintDarkTemple.TORVUS_BOG)

    # Run
    result = item_hints.create_message_for_hint(
        hint, {0: patches}, players_config, None, {},
        echoes_game_description.world_list)

    # Assert
    assert result == expected_message
Exemplo n.º 9
0
def test_create_hints_item_location(empty_patches, players_config, pickup,
                                    item, location):
    # Setup
    asset_id = 1000
    pickup_index = PickupIndex(50)
    logbook_node, _, world_list = _create_world_list(asset_id, pickup_index)

    patches = dataclasses.replace(empty_patches,
                                  pickup_assignment={
                                      pickup_index: PickupTarget(pickup, 0),
                                  },
                                  hints={
                                      logbook_node.resource():
                                      Hint(HintType.LOCATION,
                                           PrecisionPair(location[0], item[0]),
                                           pickup_index)
                                  })
    rng = MagicMock()

    # Run
    result = item_hints.create_hints({0: patches}, players_config, world_list,
                                     rng)

    # Assert
    message = "{} can be found in {}.".format(item[1][0].upper() + item[1][1:],
                                              location[1])
    # message = "The Flying Ing Cache in {} contains {}.".format(location[1], item[1])
    assert result == [{
        'asset_id': asset_id,
        'strings': [message, '', message]
    }]
Exemplo n.º 10
0
def test_create_hints_light_suit_location(empty_patches, players_config,
                                          pickup, item):
    # Setup
    asset_id = 1000
    pickup_index = PickupIndex(50)

    logbook_node, _, world_list = _create_world_list(asset_id, pickup_index)

    patches = dataclasses.replace(
        empty_patches,
        pickup_assignment={
            pickup_index: PickupTarget(pickup, 0),
        },
        hints={
            logbook_node.resource():
            Hint(
                HintType.LOCATION,
                PrecisionPair(HintLocationPrecision.LIGHT_SUIT_LOCATION,
                              item[0]), pickup_index)
        })
    rng = MagicMock()

    # Run
    result = item_hints.create_hints({0: patches}, players_config, world_list,
                                     rng)

    # Assert
    message = f"U-Mos's reward for returning the Sanctuary energy is {item[1]}."
    assert result == [{
        'asset_id': asset_id,
        'strings': [message, '', message]
    }]
Exemplo n.º 11
0
def _create_pickup_list(cosmetic_patches: EchoesCosmeticPatches,
                        configuration: BaseConfiguration,
                        game: GameDescription, patches: GamePatches,
                        players_config: PlayersConfiguration, rng: Random):
    useless_target = PickupTarget(
        pickup_creator.create_echoes_useless_pickup(game.resource_database),
        players_config.player_index)

    if cosmetic_patches.disable_hud_popup:
        memo_data = _simplified_memo_data()
    else:
        memo_data = default_prime2_memo_data()

    pickup_list = pickup_exporter.export_all_indices(
        patches,
        useless_target,
        game.world_list,
        rng,
        configuration.pickup_model_style,
        configuration.pickup_model_data_source,
        exporter=pickup_exporter.create_pickup_exporter(
            game, memo_data, players_config),
        visual_etm=pickup_creator.create_visual_etm(),
    )

    return [
        echoes_pickup_details_to_patcher(details, rng)
        for details in pickup_list
    ]
Exemplo n.º 12
0
def test_multi_create_pickup_data_for_other(pickup_for_create_pickup_data):
    # Setup
    multi = ItemResourceInfo(10, "Multiworld", "Multiworld", 30, None)
    solo = pickup_exporter.PickupExporterSolo(
        pickup_exporter.GenericAcquiredMemo())
    creator = pickup_exporter.PickupExporterMulti(
        solo, multi, PlayersConfiguration(0, {
            0: "You",
            1: "Someone"
        }))
    model = MagicMock()
    resource_a = ItemResourceInfo(1, "A", "A", 10, None)
    resource_b = ItemResourceInfo(2, "B", "B", 10, None)

    # Run
    data = creator.create_details(
        PickupIndex(10), PickupTarget(pickup_for_create_pickup_data,
                                      1), pickup_for_create_pickup_data,
        PickupModelStyle.ALL_VISIBLE, "Scan Text", model)

    # Assert
    assert data == pickup_exporter.ExportedPickupDetails(
        index=PickupIndex(10),
        scan_text="Someone's Scan Text",
        hud_text=['Sent Cake to Someone!'],
        conditional_resources=[
            ConditionalResources(None, None, ((multi, 11), )),
        ],
        conversion=[],
        model=model,
    )
Exemplo n.º 13
0
def _distribute_remaining_items(rng: Random,
                                filler_results: Dict[int, FillerPlayerResult],
                                ) -> Dict[int, GamePatches]:
    unassigned_pickup_nodes = []
    all_remaining_pickups = []
    assignments: Dict[int, PickupAssignment] = {}

    for player, filler_result in filler_results.items():
        for pickup_node in filter_unassigned_pickup_nodes(filler_result.game.world_list.all_nodes,
                                                          filler_result.patches.pickup_assignment):
            unassigned_pickup_nodes.append((player, pickup_node))

        all_remaining_pickups.extend(zip([player] * len(filler_result.unassigned_pickups),
                                         filler_result.unassigned_pickups))
        assignments[player] = {}

    rng.shuffle(unassigned_pickup_nodes)
    rng.shuffle(all_remaining_pickups)

    if len(all_remaining_pickups) > len(unassigned_pickup_nodes):
        raise InvalidConfiguration(
            "Received {} remaining pickups, but there's only {} unassigned locations.".format(
                len(all_remaining_pickups),
                len(unassigned_pickup_nodes)
            ))

    for (node_player, node), (pickup_player, pickup) in zip(unassigned_pickup_nodes, all_remaining_pickups):
        assignments[node_player][node.pickup_index] = PickupTarget(pickup, pickup_player)

    return {
        index: filler_results[index].patches.assign_pickup_assignment(assignment)
        for index, assignment in assignments.items()
    }
Exemplo n.º 14
0
def test_multi_create_pickup_data_for_other(pickup_for_create_pickup_data):
    # Setup
    creator = patcher_file.PickupCreatorMulti(
        MagicMock(), patcher_file._SimplifiedMemo(),
        PlayersConfiguration(0, {
            0: "You",
            1: "Someone"
        }))

    # Run
    data = creator.create_pickup_data(
        PickupIndex(10), PickupTarget(pickup_for_create_pickup_data,
                                      1), pickup_for_create_pickup_data,
        PickupModelStyle.ALL_VISIBLE, "Scan Text")

    # Assert
    assert data == {
        'conditional_resources': [],
        'convert': [],
        'hud_text': ['Sent Cake to Someone!'],
        'resources': [
            {
                'amount': 11,
                'index': 74
            },
        ],
        'scan': "Someone's Scan Text",
    }
Exemplo n.º 15
0
def test_create_message_for_hint_relative_area(echoes_game_description, pickup,
                                               players_config,
                                               distance_precise,
                                               distance_text):
    world_list = echoes_game_description.world_list
    patches = echoes_game_description.create_game_patches(
    ).assign_pickup_assignment({
        PickupIndex(5): PickupTarget(pickup, 0),
    })

    hint_name_creator = LocationHintCreator(world_list, None, None)
    location_formatters = {
        HintLocationPrecision.RELATIVE_TO_AREA:
        RelativeAreaFormatter(world_list, patches)
    }
    hint = Hint(
        HintType.LOCATION,
        PrecisionPair(
            HintLocationPrecision.RELATIVE_TO_AREA, HintItemPrecision.DETAILED,
            RelativeDataArea(distance_precise,
                             AreaLocation(1039999561, 3822429534),
                             HintRelativeAreaName.NAME)), PickupIndex(5))

    # Run
    result = item_hints.create_message_for_hint(hint, {0: patches},
                                                players_config,
                                                hint_name_creator,
                                                location_formatters,
                                                world_list)

    # Assert
    assert result == (
        f'The &push;&main-color=#FF6705B3;Pickup&pop; can be found '
        f'&push;&main-color=#FF3333;{distance_text} 10 rooms&pop; away from Torvus Bog - Great Bridge.'
    )
Exemplo n.º 16
0
def test_game_session_collect_pickup_other(flask_app, two_player_session, echoes_resource_database,
                                           locations_to_collect, exists, mock_emit_session_update, mocker):
    mock_emit: MagicMock = mocker.patch("flask_socketio.emit", autospec=True)
    mock_get_pickup_target: MagicMock = mocker.patch("randovania.server.game_session._get_pickup_target", autospec=True)
    mock_session_description: PropertyMock = mocker.patch("randovania.server.database.GameSession.layout_description",
                                                          new_callable=PropertyMock)

    sio = MagicMock()
    sio.get_current_user.return_value = database.User.get_by_id(1234)
    mock_get_pickup_target.return_value = PickupTarget(MagicMock(), 1)

    for existing_id in exists:
        database.GameSessionTeamAction.create(session=two_player_session, provider_row=0,
                                              provider_location_index=existing_id, receiver_row=0)

    # Run
    with flask_app.test_request_context():
        result = game_session.game_session_collect_locations(sio, 1, locations_to_collect)

    # Assert
    assert result is None
    mock_get_pickup_target.assert_has_calls([
        call(mock_session_description.return_value, 0, location)
        for location in locations_to_collect
    ])
    for location in locations_to_collect:
        database.GameSessionTeamAction.get(session=two_player_session, provider_row=0,
                                           provider_location_index=location)
    if exists == locations_to_collect:
        mock_emit.assert_not_called()
        mock_emit_session_update.assert_not_called()
    else:
        mock_emit.assert_called_once_with("game_has_update", {"session": 1, "row": 1, },
                                          room=f"game-session-1-1235")
        mock_emit_session_update.assert_called_once_with(database.GameSession.get(id=1))
Exemplo n.º 17
0
def test_solo_create_pickup_data(pickup_for_create_pickup_data):
    # Setup
    creator = patcher_file.PickupCreatorSolo(MagicMock(),
                                             patcher_file._SimplifiedMemo())

    # Run
    data = creator.create_pickup_data(
        PickupIndex(10), PickupTarget(pickup_for_create_pickup_data,
                                      0), pickup_for_create_pickup_data,
        PickupModelStyle.ALL_VISIBLE, "Scan Text")

    # Assert
    assert data == {
        'conditional_resources': [{
            'item': 1,
            'resources': [{
                'amount': 1,
                'index': 2
            }]
        }],
        'convert': [],
        'hud_text': ['Sugar acquired!', 'Salt acquired!'],
        'resources': [{
            'amount': 1,
            'index': 1
        }],
        'scan':
        'Scan Text',
    }
Exemplo n.º 18
0
def _distribute_remaining_items(
    rng: Random,
    filler_results: Dict[int, FillerPlayerResult],
) -> Dict[int, GamePatches]:
    unassigned_pickup_nodes = []
    all_remaining_pickups = []
    assignments: Dict[int, PickupAssignment] = {}

    for index, filler_result in filler_results.items():
        for pickup_node in filter_unassigned_pickup_nodes(
                filler_result.game.world_list.all_nodes,
                filler_result.patches.pickup_assignment):
            unassigned_pickup_nodes.append((index, pickup_node))

        all_remaining_pickups.extend(
            zip([index] * len(filler_result.unassigned_pickups),
                filler_result.unassigned_pickups))
        assignments[index] = {}

    rng.shuffle(unassigned_pickup_nodes)
    rng.shuffle(all_remaining_pickups)

    for (node_player, node), (pickup_player,
                              pickup) in zip(unassigned_pickup_nodes,
                                             all_remaining_pickups):
        assignments[node_player][node.pickup_index] = PickupTarget(
            pickup, pickup_player)

    return {
        index:
        filler_results[index].patches.assign_pickup_assignment(assignment)
        for index, assignment in assignments.items()
    }
Exemplo n.º 19
0
def test_game_session_request_pickups_one_action(
        mock_session_description: PropertyMock,
        mock_get_resource_database: MagicMock,
        mock_get_pickup_target: MagicMock, flask_app, two_player_session,
        echoes_resource_database):
    # Setup
    sio = MagicMock()
    sio.get_current_user.return_value = database.User.get_by_id(1234)

    pickup = PickupEntry(
        "A", 1, ItemCategory.TEMPLE_KEY, ItemCategory.KEY,
        (ConditionalResources(None, None,
                              ((echoes_resource_database.item[0], 1), )), ))
    mock_get_pickup_target.return_value = PickupTarget(pickup=pickup, player=0)
    mock_get_resource_database.return_value = echoes_resource_database

    # Run
    result = game_session.game_session_request_pickups(sio, 1)

    # Assert
    mock_get_resource_database.assert_called_once_with(
        mock_session_description.return_value, 0)
    mock_get_pickup_target.assert_called_once_with(
        mock_session_description.return_value, 1, 0)
    assert result == [{'provider_name': 'Other Name', 'pickup': '6c8P51ON~'}]
Exemplo n.º 20
0
def test_create_message_for_hint_relative_area(echoes_game_patches,
                                               blank_pickup, players_config,
                                               echoes_hint_exporter, offset,
                                               distance_text):
    patches = echoes_game_patches.assign_new_pickups([
        (PickupIndex(5), PickupTarget(blank_pickup, 0)),
    ])

    hint = Hint(
        HintType.LOCATION,
        PrecisionPair(HintLocationPrecision.RELATIVE_TO_AREA,
                      HintItemPrecision.DETAILED,
                      include_owner=False,
                      relative=RelativeDataArea(
                          offset, AreaIdentifier("Torvus Bog", "Great Bridge"),
                          HintRelativeAreaName.NAME)), PickupIndex(5))

    namer = EchoesHintNamer({0: patches}, PlayersConfiguration(0, {0: "You"}))
    exporter = HintExporter(namer, random.Random(0), ["A Joke"])

    # Run
    result = exporter.create_message_for_hint(hint, {0: patches},
                                              players_config, True)

    # Assert
    assert result == (
        f'The &push;&main-color=#FF6705B3;Blank Pickup&pop; can be found '
        f'&push;&main-color=#FF3333;{distance_text} {10 + (offset or 0)} rooms&pop; away from '
        f'Torvus Bog - Great Bridge.')
Exemplo n.º 21
0
def test_create_hints_guardians(empty_patches, pickup_index_and_guardian,
                                pickup, item, players_config):
    # Setup
    asset_id = 1000
    pickup_index, guardian = pickup_index_and_guardian

    logbook_node, _, world_list = _create_world_list(asset_id, pickup_index)

    patches = dataclasses.replace(
        empty_patches,
        pickup_assignment={
            pickup_index: PickupTarget(pickup, 0),
        },
        hints={
            logbook_node.resource():
            Hint(HintType.LOCATION,
                 PrecisionPair(HintLocationPrecision.GUARDIAN, item[0]),
                 pickup_index)
        })
    rng = MagicMock()

    # Run
    result = item_hints.create_hints({0: patches}, players_config, world_list,
                                     rng)

    # Assert
    message = f"{guardian} is guarding {item[1]}."
    assert result == [{
        'asset_id': asset_id,
        'strings': [message, '', message]
    }]
Exemplo n.º 22
0
def test_solo_create_pickup_data(pickup_for_create_pickup_data):
    # Setup
    creator = pickup_exporter.PickupExporterSolo(pickup_exporter.GenericAcquiredMemo())
    model = MagicMock()
    resource_a = ItemResourceInfo(0, "A", "A", 10)
    resource_b = ItemResourceInfo(1, "B", "B", 10)

    # Run
    data = creator.create_details(PickupIndex(10), PickupTarget(pickup_for_create_pickup_data, 0),
                                  pickup_for_create_pickup_data, PickupModelStyle.ALL_VISIBLE,
                                  "Scan Text", model)

    # Assert
    assert data == pickup_exporter.ExportedPickupDetails(
        index=PickupIndex(10),
        scan_text="Scan Text",
        hud_text=['A acquired!', 'B acquired!'],
        conditional_resources=[
            ConditionalResources("A", None, ((resource_a, 1),)),
            ConditionalResources("B", resource_a, ((resource_b, 1),)),
        ],
        conversion=[],
        model=model,
        other_player=False,
        original_pickup=pickup_for_create_pickup_data,
    )
Exemplo n.º 23
0
def create_pickup_hint(
    pickup_assignment: PickupAssignment,
    world_list: WorldList,
    precision: HintItemPrecision,
    target: Optional[PickupTarget],
    players_config: PlayersConfiguration,
    include_owner: bool,
) -> PickupHint:
    """

    :param pickup_assignment:
    :param world_list:
    :param precision:
    :param target:
    :param players_config:
    :param include_owner:
    :return:
    """
    if target is None:
        target = PickupTarget(
            pickup=PickupEntry(
                name="Energy Transfer Module",
                progression=tuple(),
                model=PickupModel(
                    game=RandovaniaGame.METROID_PRIME_ECHOES,
                    name="EnergyTransferModule",
                ),
                item_category=USELESS_ITEM_CATEGORY,
                broad_category=USELESS_ITEM_CATEGORY,
            ),
            player=players_config.player_index,
        )

    if precision is HintItemPrecision.GENERAL_CATEGORY:
        details = target.pickup.item_category.general_details

    elif precision is HintItemPrecision.PRECISE_CATEGORY:
        details = target.pickup.item_category.hint_details

    elif precision is HintItemPrecision.BROAD_CATEGORY:
        details = target.pickup.broad_category.hint_details

    elif precision is HintItemPrecision.DETAILED:
        details = _calculate_determiner(pickup_assignment, target.pickup,
                                        world_list), target.pickup.name

    elif precision is HintItemPrecision.NOTHING:
        details = "an ", "item"

    else:
        raise ValueError(f"Unknown precision: {precision}")

    determiner = Determiner(details[0])
    player = None

    if include_owner and players_config.is_multiworld:
        player = players_config.player_names[target.player]

    return PickupHint(determiner, player, details[1])
Exemplo n.º 24
0
def _assign_pickup_somewhere(action: PickupEntry,
                             current_player: PlayerState,
                             player_states: List[PlayerState],
                             rng: Random,
                             all_locations_weighted: WeightedLocations,
                             ) -> str:
    """
    Assigns a PickupEntry to a free, collected PickupIndex or as a starting item.
    :param action:
    :param current_player:
    :param player_states:
    :param rng:
    :return:
    """
    assert action in current_player.pickups_left

    if all_locations_weighted and (current_player.num_random_starting_items_placed
                                   >= current_player.configuration.minimum_random_starting_items):

        index_owner_state, pickup_index = select_element_with_weight(all_locations_weighted, rng)
        index_owner_state.assign_pickup(pickup_index, PickupTarget(action, current_player.index))

        # Place a hint for the new item
        hint_location = _calculate_hint_location_for_action(
            action,
            UncollectedState.from_reach(index_owner_state.reach),
            pickup_index,
            rng,
            index_owner_state.scan_asset_initial_pickups,
        )
        if hint_location is not None:
            index_owner_state.reach.state.patches = index_owner_state.reach.state.patches.assign_hint(
                hint_location, Hint(HintType.LOCATION, None, pickup_index))

        if pickup_index in index_owner_state.reach.state.collected_pickup_indices:
            current_player.reach.advance_to(current_player.reach.state.assign_pickup_resources(action))
        else:
            # FIXME: isn't that condition always true?
            pass

        spoiler_entry = pickup_placement_spoiler_entry(current_player.index, action, index_owner_state.game,
                                                       pickup_index, hint_location, index_owner_state.index,
                                                       len(player_states) > 1)

    else:
        current_player.num_random_starting_items_placed += 1
        if (current_player.num_random_starting_items_placed
                > current_player.configuration.maximum_random_starting_items):
            raise UnableToGenerate("Attempting to place more extra starting items than the number allowed.")

        spoiler_entry = f"{action.name} as starting item"
        if len(player_states) > 1:
            spoiler_entry += f" for Player {current_player.index + 1}"
        current_player.reach.advance_to(current_player.reach.state.assign_pickup_to_starting_items(action))

    return spoiler_entry
Exemplo n.º 25
0
def test_create_message_for_hint_relative_item(echoes_game_description, pickup,
                                               players_config,
                                               distance_precise, distance_text,
                                               reference_precision,
                                               reference_name):
    world_list = echoes_game_description.world_list
    patches = echoes_game_description.create_game_patches(
    ).assign_pickup_assignment({
        PickupIndex(5):
        PickupTarget(pickup, 0),
        PickupIndex(15):
        PickupTarget(dataclasses.replace(pickup, name="Reference Pickup"), 0),
    })

    hint_name_creator = LocationHintCreator(world_list, None, None)
    location_formatters = {
        HintLocationPrecision.RELATIVE_TO_INDEX:
        RelativeItemFormatter(world_list, patches, players_config),
    }
    hint = Hint(
        HintType.LOCATION,
        PrecisionPair(HintLocationPrecision.RELATIVE_TO_INDEX,
                      HintItemPrecision.DETAILED,
                      include_owner=False,
                      relative=RelativeDataItem(distance_precise,
                                                PickupIndex(15),
                                                reference_precision)),
        PickupIndex(5))

    # Run
    result = item_hints.create_message_for_hint(hint, {0: patches},
                                                players_config,
                                                hint_name_creator,
                                                location_formatters,
                                                world_list)

    # Assert
    assert result == (
        f'The &push;&main-color=#FF6705B3;Pickup&pop; can be found '
        f'&push;&main-color=#FF3333;{distance_text} {7 + distance_precise} rooms&pop; away from {reference_name}.'
    )
Exemplo n.º 26
0
    def bit_pack_unpack(cls, decoder: BitPackDecoder, metadata) -> "BitPackPickupEntryList":
        result = []
        index_mapping = metadata["index_mapping"]
        num_players = metadata["num_players"]

        for _ in range(len(index_mapping)):
            index = PickupIndex(decoder.decode_single(255))
            target_player = bitpacking.decode_int_with_limits(decoder, (num_players,))
            pickup = BitPackPickupEntry.bit_pack_unpack(decoder, index_mapping[index], metadata["database"])
            result.append((index, PickupTarget(pickup, target_player)))

        return BitPackPickupEntryList(result, num_players, metadata["database"])
Exemplo n.º 27
0
    def create_data(self) -> dict:
        db = self.game
        useless_target = PickupTarget(pickup_creator.create_nothing_pickup(db.resource_database),
                                      self.players_config.player_index)

        pickup_list = pickup_exporter.export_all_indices(
            self.patches,
            useless_target,
            db.world_list,
            self.rng,
            self.configuration.pickup_model_style,
            self.configuration.pickup_model_data_source,
            exporter=pickup_exporter.create_pickup_exporter(db, pickup_exporter.GenericAcquiredMemo(),
                                                            self.players_config),
            visual_etm=pickup_creator.create_visual_etm(),
        )

        gameplay_patch_list = [field.name for field in dataclasses.fields(self.configuration.patches)]
        cosmetic_patch_list = [field.name for field in dataclasses.fields(self.cosmetic_patches)]

        cosmetic_patch_list.remove("music")
        specific_patches = {}

        for patch in gameplay_patch_list:
            specific_patches[patch] = getattr(self.configuration.patches, patch)
        for patch in cosmetic_patch_list:
            specific_patches[patch] = getattr(self.cosmetic_patches, patch)
        if self.cosmetic_patches.music != MusicMode.VANILLA:
            specific_patches[self.cosmetic_patches.music.value] = True

        starting_point = self.patches.starting_location

        starting_area = db.world_list.area_by_area_location(starting_point)

        starting_save_index = starting_area.extra["save_index"]

        starting_location_info = {
            "starting_region": starting_point.world_name,
            "starting_save_station_index": starting_save_index,
        }

        return {
            "pickups": [
                sm_pickup_details_to_patcher(detail)
                for detail in pickup_list
            ],
            "starting_items": [
                sm_starting_items_to_patcher(item, qty)
                for item, qty in self.patches.starting_items.as_resource_gain()
            ],
            "specific_patches": specific_patches,
            "starting_conditions": starting_location_info
        }
Exemplo n.º 28
0
async def create_player_pool(rng: Random,
                             configuration: BaseConfiguration,
                             player_index: int,
                             num_players: int,
                             rng_required: bool = True) -> PlayerPool:
    game = filtered_database.game_description_for_layout(
        configuration).get_mutable()

    game_generator = game.game.generator
    game.resource_database = game_generator.bootstrap.patch_resource_database(
        game.resource_database, configuration)

    base_patches = game_generator.base_patches_factory.create_base_patches(
        configuration,
        rng,
        game,
        num_players > 1,
        player_index=player_index,
        rng_required=rng_required)

    base_patches = dock_weakness_distributor.distribute_pre_fill_weaknesses(
        base_patches)

    base_patches = await game_generator.hint_distributor.assign_pre_filler_hints(
        base_patches,
        PreFillParams(
            rng,
            configuration,
            game,
            num_players > 1,
        ),
        rng_required=rng_required)

    pool_results = pool_creator.calculate_pool_results(
        configuration,
        game.resource_database,
        base_patches,
        rng,
        rng_required=rng_required)
    target_assignment = [(index, PickupTarget(pickup, player_index))
                         for index, pickup in pool_results.assignment.items()]
    patches = base_patches.assign_new_pickups(
        target_assignment).assign_extra_initial_items(
            pool_results.initial_resources.as_resource_gain())

    return PlayerPool(
        game=game,
        game_generator=game_generator,
        configuration=configuration,
        patches=patches,
        pickups=pool_results.pickups,
    )
Exemplo n.º 29
0
def test_create_hints_item_location(echoes_game_patches, blank_pickup, item,
                                    location, owner, is_multiworld,
                                    echoes_game_description, monkeypatch):
    # Setup
    asset_id = 1000
    pickup_index = PickupIndex(50)
    logbook_node, _, world_list = _create_world_list(asset_id, pickup_index)
    monkeypatch.setattr(echoes_game_description, "world_list", world_list)

    players_config = PlayersConfiguration(
        player_index=0,
        player_names={
            i: f"Player {i + 1}"
            for i in range(int(is_multiworld) + 1)
        },
    )
    location_precision, determiner, item_name = item
    if owner and is_multiworld:
        determiner = "&push;&main-color=#d4cc33;Player 1&pop;'s"

    patches = dataclasses.replace(
        echoes_game_patches,
        pickup_assignment={
            pickup_index: PickupTarget(blank_pickup, 0),
        },
        hints={
            world_list.identifier_for_node(logbook_node):
            Hint(
                HintType.LOCATION,
                PrecisionPair(location[0],
                              location_precision,
                              include_owner=owner),
                pickup_index,
            )
        })
    rng = MagicMock()
    namer = EchoesHintNamer({0: patches}, players_config)

    # Run
    result = hints.create_patches_hints({0: patches}, players_config,
                                        world_list, namer, rng)

    # Assert
    message = "{} {} can be found in {}.".format(determiner, item_name,
                                                 location[1])
    # message = "The Flying Ing Cache in {} contains {}.".format(location[1], item[1])
    assert result[0]['strings'][0] == message
    assert result == [{
        'asset_id': asset_id,
        'strings': [message, '', message]
    }]
Exemplo n.º 30
0
def test_add_relative_hint(echoes_game_description, echoes_game_patches,
                           precise_distance, location_precision,
                           echoes_item_database):
    # Setup
    rng = Random(5000)
    target_precision = MagicMock(spec=HintItemPrecision)
    precision = MagicMock(spec=HintItemPrecision)
    patches = echoes_game_patches.assign_new_pickups([
        (PickupIndex(8),
         PickupTarget(
             _make_pickup(echoes_item_database.item_categories["movement"]),
             0)),
    ])
    hint_distributor = EchoesHintDistributor()

    if location_precision == HintLocationPrecision.RELATIVE_TO_AREA:
        max_distance = 8
        data = RelativeDataArea(
            None if precise_distance else 3,
            # Was Industrial Site
            AreaIdentifier("Temple Grounds", "Hive Chamber A"),
            precision,
        )
    else:
        max_distance = 20
        data = RelativeDataItem(
            None if precise_distance else 11,
            PickupIndex(8),
            precision,
        )

    # Run
    result = hint_distributor.add_relative_hint(
        echoes_game_description.world_list,
        patches,
        rng,
        PickupIndex(1),
        target_precision,
        location_precision,
        precise_distance,
        precision,
        max_distance=max_distance,
    )

    # Assert
    pair = PrecisionPair(location_precision,
                         target_precision,
                         include_owner=False,
                         relative=data)
    assert result == Hint(HintType.LOCATION, pair, PickupIndex(1))