Ejemplo n.º 1
0
def test_create_hints_guardians(empty_patches, pickup_index_and_guardian,
                                pickup, item):
    # 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: pickup,
        },
        hints={
            logbook_node.resource():
            Hint(HintType.GUARDIAN,
                 PrecisionPair(PrecisionPair.detailed(), item[0]),
                 pickup_index)
        })
    rng = MagicMock()

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

    # Assert
    message = f"{guardian} is guarding {item[1]}."
    assert result == [{
        'asset_id': asset_id,
        'strings': [message, '', message]
    }]
Ejemplo n.º 2
0
def test_add_hints_precision(empty_patches):
    failed_relative_provider = MagicMock(return_value=None)
    relative_hint_provider = MagicMock()
    player_state = MagicMock()
    rng = MagicMock()
    hints = [
        Hint(
            HintType.LOCATION,
            PrecisionPair(HintLocationPrecision.DETAILED,
                          HintItemPrecision.DETAILED,
                          include_owner=False), PickupIndex(1)),
        Hint(HintType.LOCATION, None, PickupIndex(2)),
        Hint(HintType.LOCATION, None, PickupIndex(3)),
    ]
    nc = NodeIdentifier.create

    initial_patches = empty_patches
    for i, hint in enumerate(hints):
        initial_patches = initial_patches.assign_hint(nc("w", "a", f"{i}"),
                                                      hint)

    hint_distributor = EchoesHintDistributor()
    hint_distributor._get_relative_hint_providers = MagicMock(
        return_value=[failed_relative_provider, relative_hint_provider])

    # Run
    result = hint_distributor.add_hints_precision(player_state,
                                                  initial_patches, rng)

    # Assert
    failed_relative_provider.assert_called_once_with(player_state,
                                                     initial_patches, rng,
                                                     PickupIndex(2))
    relative_hint_provider.assert_called_once_with(player_state,
                                                   initial_patches, rng,
                                                   PickupIndex(3))
    assert result.hints == {
        nc("w", "a", "0"):
        Hint(
            HintType.LOCATION,
            PrecisionPair(HintLocationPrecision.DETAILED,
                          HintItemPrecision.DETAILED,
                          include_owner=False), PickupIndex(1)),
        nc("w", "a", "1"):
        Hint(
            HintType.LOCATION,
            PrecisionPair(HintLocationPrecision.WORLD_ONLY,
                          HintItemPrecision.PRECISE_CATEGORY,
                          include_owner=True), PickupIndex(2)),
        nc("w", "a", "2"):
        relative_hint_provider.return_value,
    }
def add_default_hints_to_patches(
    rng: Random,
    patches: GamePatches,
    world_list: WorldList,
) -> GamePatches:
    """
    Adds hints for the locations
    :param rng:
    :param patches:
    :param world_list:
    :return:
    """

    for node in world_list.all_nodes:
        if isinstance(
                node,
                LogbookNode) and node.lore_type == LoreType.LUMINOTH_WARRIOR:
            patches = patches.assign_hint(
                node.resource(),
                Hint(
                    HintType.KEYBEARER,
                    PrecisionPair(HintLocationPrecision.DETAILED,
                                  HintItemPrecision.PRECISE_CATEGORY),
                    PickupIndex(node.hint_index)))

    # TODO: this should be a flag in PickupNode
    indices_with_hint = [
        (PickupIndex(24), HintType.LIGHT_SUIT_LOCATION),  # Light Suit
        (PickupIndex(43), HintType.GUARDIAN),  # Dark Suit (Amorbis)
        (PickupIndex(79), HintType.GUARDIAN),  # Dark Visor (Chykka)
        (PickupIndex(115), HintType.GUARDIAN),  # Annihilator Beam (Quadraxis)
    ]
    all_logbook_assets = [
        node.resource() for node in world_list.all_nodes
        if isinstance(node, LogbookNode) and node.resource() not in
        patches.hints and node.lore_type.holds_generic_hint
    ]

    rng.shuffle(indices_with_hint)
    rng.shuffle(all_logbook_assets)

    for index, hint_type in indices_with_hint:
        if not all_logbook_assets:
            break

        logbook_asset = all_logbook_assets.pop()
        patches = patches.assign_hint(
            logbook_asset, Hint(hint_type, PrecisionPair.detailed(), index))

    return patches
Ejemplo n.º 4
0
def test_add_hints_precision(empty_patches, mocker):
    failed_relative_provider = MagicMock(return_value=None)
    relative_hint_provider = MagicMock()
    mocker.patch(
        "randovania.generator.filler.runner._get_relative_hint_providers",
        return_value=[failed_relative_provider, relative_hint_provider])

    player_state = MagicMock()
    rng = MagicMock()
    hints = [
        Hint(
            HintType.LOCATION,
            PrecisionPair(HintLocationPrecision.DETAILED,
                          HintItemPrecision.DETAILED,
                          include_owner=False), PickupIndex(1)),
        Hint(HintType.LOCATION, None, PickupIndex(2)),
        Hint(HintType.LOCATION, None, PickupIndex(3)),
    ]

    initial_patches = empty_patches
    for i, hint in enumerate(hints):
        initial_patches = initial_patches.assign_hint(LogbookAsset(i), hint)

    # Run
    result = runner.add_hints_precision(player_state, initial_patches, rng)

    # Assert
    failed_relative_provider.assert_called_once_with(player_state,
                                                     initial_patches, rng,
                                                     PickupIndex(2))
    relative_hint_provider.assert_called_once_with(player_state,
                                                   initial_patches, rng,
                                                   PickupIndex(3))
    assert result.hints == {
        LogbookAsset(0):
        Hint(
            HintType.LOCATION,
            PrecisionPair(HintLocationPrecision.DETAILED,
                          HintItemPrecision.DETAILED,
                          include_owner=False), PickupIndex(1)),
        LogbookAsset(1):
        Hint(
            HintType.LOCATION,
            PrecisionPair(HintLocationPrecision.WORLD_ONLY,
                          HintItemPrecision.PRECISE_CATEGORY,
                          include_owner=False), PickupIndex(2)),
        LogbookAsset(2):
        relative_hint_provider.return_value,
    }
Ejemplo n.º 5
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}.')
Ejemplo n.º 6
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]
    }]
Ejemplo n.º 7
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.')
Ejemplo n.º 8
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: pickup,
                                  },
                                  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;You're not authorized to view this hint.&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]
    }]
Ejemplo n.º 9
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.'
    )
Ejemplo n.º 10
0
 def g(index, loc):
     return (
         PickupIndex(index),
         PrecisionPair(loc,
                       HintItemPrecision.DETAILED,
                       include_owner=False),
     )
Ejemplo n.º 11
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]
    }]
Ejemplo n.º 12
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]
    }]
Ejemplo n.º 13
0
def test_create_hints_nothing(empty_patches, players_config):
    # Setup
    asset_id = 1000
    pickup_index = PickupIndex(50)

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

    patches = dataclasses.replace(empty_patches,
                                  hints={
                                      logbook_node.resource():
                                      Hint(
                                          HintType.LOCATION,
                                          PrecisionPair(
                                              HintLocationPrecision.DETAILED,
                                              HintItemPrecision.DETAILED),
                                          pickup_index)
                                  })
    rng = MagicMock()

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

    # Assert
    message = (
        "The &push;&main-color=#FF6705B3;Energy Transfer Module&pop; can be found in "
        "&push;&main-color=#FF3333;World - Area&pop;.")
    assert result == [{
        'asset_id': asset_id,
        'strings': [message, '', message]
    }]
Ejemplo n.º 14
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]
    }]
Ejemplo n.º 15
0
def add_relative_hint(world_list: WorldList,
                      patches: GamePatches,
                      rng: Random,
                      target: PickupIndex,
                      target_precision: HintItemPrecision,
                      relative_type: HintLocationPrecision,
                      precise_distance: bool,
                      precision: Union[HintItemPrecision, HintRelativeAreaName],
                      max_distance: int,
                      ) -> Optional[Hint]:
    """
    Creates a relative hint.
    :return: Might be None, if no hint could be created.
    """
    target_node = node_search.pickup_index_to_node(world_list, target)
    target_area = world_list.nodes_to_area(target_node)
    distances = node_search.distances_to_node(world_list, target_node, patches=patches, cutoff=max_distance)

    def _major_pickups(area: Area) -> Iterator[PickupIndex]:
        for index in area.pickup_indices:
            t = patches.pickup_assignment.get(index)
            # FIXME: None should be ok, but this must be called after junk has been filled
            if t is not None:
                cat = t.pickup.item_category
                if cat.is_major_category or (cat != ItemCategory.EXPANSION
                                             and target_precision == HintItemPrecision.DETAILED):
                    yield index

    area_choices = {
        area: 1 / max(distance, 2)
        for area, distance in distances.items()
        if (distance > 0 and area.in_dark_aether == target_area.in_dark_aether
            and (relative_type == HintLocationPrecision.RELATIVE_TO_AREA or _not_empty(_major_pickups(area))))
    }
    if not area_choices:
        return None
    area = random_lib.select_element_with_weight(dict(sorted(area_choices.items(),
                                                             key=lambda a: a[0].area_asset_id)), rng)

    distance_offset = 0
    if not precise_distance:
        distance_offset = max_distance - distances[area]

    if relative_type == HintLocationPrecision.RELATIVE_TO_AREA:
        relative = RelativeDataArea(distance_offset, world_list.area_to_area_location(area),
                                    precision)
    elif relative_type == HintLocationPrecision.RELATIVE_TO_INDEX:
        relative = RelativeDataItem(distance_offset, rng.choice(list(_major_pickups(area))), precision)
    else:
        raise ValueError(f"Invalid relative_type: {relative_type}")

    precision_pair = PrecisionPair(relative_type, target_precision, include_owner=False, relative=relative)
    return Hint(HintType.LOCATION, precision_pair, target)
Ejemplo n.º 16
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]
    }]
Ejemplo n.º 17
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))
Ejemplo n.º 18
0
def precision_pair_weighted_list() -> List[PrecisionPair]:
    tiers = {
        (HintLocationPrecision.DETAILED, HintItemPrecision.DETAILED): 5,
        (HintLocationPrecision.DETAILED, HintItemPrecision.PRECISE_CATEGORY): 2,
        (HintLocationPrecision.DETAILED, HintItemPrecision.GENERAL_CATEGORY): 1,

        (HintLocationPrecision.WORLD_ONLY, HintItemPrecision.DETAILED): 2,
        (HintLocationPrecision.WORLD_ONLY, HintItemPrecision.PRECISE_CATEGORY): 1,
    }

    hints = []
    for params, quantity in tiers.items():
        hints.extend([PrecisionPair(*params, include_owner=False)] * quantity)

    return hints
Ejemplo n.º 19
0
    def precision_pair_weighted_list(self) -> list[PrecisionPair]:
        tiers = {
            (HintLocationPrecision.DETAILED, HintItemPrecision.DETAILED, True):
            2,
            (HintLocationPrecision.DETAILED, HintItemPrecision.PRECISE_CATEGORY, True):
            1,
            (HintLocationPrecision.WORLD_ONLY, HintItemPrecision.DETAILED, True):
            1,
        }

        hints = []
        for params, quantity in tiers.items():
            hints.extend([PrecisionPair(*params)] * quantity)

        return hints
Ejemplo n.º 20
0
def test_create_hints_item_location(empty_patches, pickup, item, location,
                                    owner, is_multiworld):
    # Setup
    asset_id = 1000
    pickup_index = PickupIndex(50)
    logbook_node, _, world_list = _create_world_list(asset_id, pickup_index)
    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 = "Player 1's"

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

    # Run
    result = item_hints.create_hints({0: patches}, players_config, world_list,
                                     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]
    }]
Ejemplo n.º 21
0
def replace_hints_without_precision_with_jokes(
    patches: GamePatches, ) -> GamePatches:
    """
    Adds WRONG_GAME precision to all hints that are missing one precision.
    :param patches:
    :return:
    """

    hints_to_replace = {
        asset: dataclasses.replace(hint, precision=PrecisionPair.joke())
        for asset, hint in patches.hints.items() if hint.precision
    }

    return dataclasses.replace(patches,
                               hints={
                                   asset: hints_to_replace.get(asset, hint)
                                   for asset, hint in patches.hints.items()
                               })
Ejemplo n.º 22
0
def test_add_relative_hint(echoes_game_description, empty_patches,
                           location_precision):
    # Setup
    rng = Random(5000)
    target_precision = MagicMock()
    precise_distance = MagicMock()
    precision = MagicMock()
    patches = empty_patches.assign_pickup_assignment({
        PickupIndex(8):
        PickupTarget(_make_pickup(ItemCategory.MOVEMENT), 0),
    })

    if location_precision == HintLocationPrecision.RELATIVE_TO_AREA:
        max_distance = 8
        data = RelativeDataArea(
            precise_distance,
            AreaLocation(0x3BFA3EFF, 0x62AC8AC4),
            precision,
        )
    else:
        max_distance = 20
        data = RelativeDataItem(
            precise_distance,
            PickupIndex(8),
            precision,
        )

    # Run
    result = runner.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))
Ejemplo n.º 23
0
    async def assign_specific_location_hints(self, patches: GamePatches, prefill: PreFillParams) -> GamePatches:
        specific_location_precisions = await self.get_specific_pickup_precision_pair_overrides(patches, prefill)

        # TODO: this is an Echoes default. Should not have a default and all nodes have one in the DB.
        default_precision = PrecisionPair(HintLocationPrecision.KEYBEARER, HintItemPrecision.BROAD_CATEGORY,
                                          include_owner=True)

        wl = prefill.game.world_list
        for node in wl.iterate_nodes():
            if isinstance(node, LogbookNode) and node.lore_type == LoreType.SPECIFIC_PICKUP:
                identifier = wl.identifier_for_node(node)
                patches = patches.assign_hint(
                    identifier,
                    Hint(HintType.LOCATION,
                         specific_location_precisions.get(identifier, default_precision),
                         PickupIndex(node.hint_index))
                )

        return patches
Ejemplo n.º 24
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}.'
    )
Ejemplo n.º 25
0
def test_create_hints_light_suit_location(echoes_game_patches, players_config,
                                          blank_pickup, item,
                                          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)

    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(HintLocationPrecision.LIGHT_SUIT_LOCATION,
                              item[0],
                              include_owner=False),
                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 = f"U-Mos's reward for returning the Sanctuary energy is {item[1]}."
    assert result == [{
        'asset_id': asset_id,
        'strings': [message, '', message]
    }]
Ejemplo n.º 26
0
def test_create_hints_guardians(echoes_game_patches, pickup_index_and_guardian,
                                blank_pickup, item, players_config,
                                echoes_game_description, monkeypatch):
    # Setup
    asset_id = 1000
    pickup_index, guardian = pickup_index_and_guardian

    logbook_node, _, world_list = _create_world_list(asset_id, pickup_index)
    monkeypatch.setattr(echoes_game_description, "world_list", world_list)

    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(HintLocationPrecision.GUARDIAN,
                              item[0],
                              include_owner=False),
                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 = f"{guardian} is guarding {item[1]}."
    assert result == [{
        'asset_id': asset_id,
        'strings': [message, '', message]
    }]
Ejemplo n.º 27
0
def test_create_hints_item_detailed(hint_type, 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: pickup,
                                  },
                                  hints={
                                      logbook_node.resource():
                                      Hint(hint_type,
                                           PrecisionPair(location[0], item[0]),
                                           pickup_index)
                                  })
    rng = MagicMock()

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

    # Assert
    if location[0] == HintLocationPrecision.WRONG_GAME and item[
            0] == HintItemPrecision.WRONG_GAME:
        message = "&push;&main-color=#45F731;Warning! Dark Aether's atmosphere is dangerous!" \
                  " Energized Safe Zones don't last forever!&pop;"
    elif hint_type == HintType.LOCATION:
        message = "{} can be found in {}.".format(
            item[1][0].upper() + item[1][1:], location[1])
    elif hint_type == HintType.KEYBEARER:
        message = "The Flying Ing Cache in {} contains {}.".format(
            location[1], item[1])
    assert result == [{
        'asset_id': asset_id,
        'strings': [message, '', message]
    }]
Ejemplo n.º 28
0
def test_create_hints_nothing(echoes_game_patches, players_config, monkeypatch,
                              echoes_game_description):
    # Setup
    asset_id = 1000
    pickup_index = PickupIndex(0)

    logbook_node, _, world_list = _create_world_list(asset_id, pickup_index)
    monkeypatch.setattr(echoes_game_description, "world_list", world_list)

    patches = dataclasses.replace(
        echoes_game_patches,
        hints={
            world_list.identifier_for_node(logbook_node):
            Hint(
                HintType.LOCATION,
                PrecisionPair(HintLocationPrecision.DETAILED,
                              HintItemPrecision.DETAILED,
                              include_owner=False),
                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 = (
        "The &push;&main-color=#FF6705B3;Energy Transfer Module&pop; can be found in "
        "&push;&main-color=#FF3333;World - Area&pop;.")
    assert result == [{
        'asset_id': asset_id,
        'strings': [message, '', message]
    }]
 def _keybearer_hint(number: int):
     return Hint(
         HintType.LOCATION,
         PrecisionPair(HintLocationPrecision.KEYBEARER,
                       HintItemPrecision.BROAD_CATEGORY,
                       include_owner=True), PickupIndex(number))
 def _guardian_hint(number: int):
     return Hint(
         HintType.LOCATION,
         PrecisionPair(HintLocationPrecision.GUARDIAN,
                       HintItemPrecision.DETAILED,
                       include_owner=False), PickupIndex(number))