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
Esempio n. 2
0
    async def assign_joke_hints(self, patches: GamePatches, identifiers: list[NodeIdentifier],
                                prefill: PreFillParams) -> GamePatches:

        all_hint_identifiers = [identifier for identifier in identifiers if identifier not in patches.hints]
        prefill.rng.shuffle(all_hint_identifiers)

        num_joke = self.num_joke_hints

        while num_joke > 0 and all_hint_identifiers:
            identifier = all_hint_identifiers.pop()
            patches = patches.assign_hint(identifier, Hint(HintType.JOKE, None))
            num_joke -= 1
            identifiers.remove(identifier)

        return patches
Esempio n. 3
0
    async def assign_guaranteed_indices_hints(self, patches: GamePatches, identifiers: list[NodeIdentifier],
                                              prefill: PreFillParams) -> GamePatches:
        # Specific Pickup/any LogbookNode Hints
        indices_with_hint = await self.get_guranteed_hints(patches, prefill)
        prefill.rng.shuffle(indices_with_hint)

        all_hint_identifiers = [identifier for identifier in identifiers if identifier not in patches.hints]
        prefill.rng.shuffle(all_hint_identifiers)

        for index, precision in indices_with_hint:
            if not all_hint_identifiers:
                break

            identifier = all_hint_identifiers.pop()
            patches = patches.assign_hint(identifier, Hint(HintType.LOCATION, precision, index))
            identifiers.remove(identifier)

        return patches
Esempio n. 4
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
Esempio n. 5
0
    async def assign_other_hints(self, patches: GamePatches,
                                 identifiers: list[NodeIdentifier],
                                 prefill: PreFillParams) -> GamePatches:
        all_hint_identifiers = [
            identifier for identifier in identifiers
            if identifier not in patches.hints
        ]
        prefill.rng.shuffle(all_hint_identifiers)

        # Dark Temple hints
        temple_hints = list(enum_lib.iterate_enum(HintDarkTemple))
        while all_hint_identifiers and temple_hints:
            identifier = all_hint_identifiers.pop()
            patches = patches.assign_hint(
                identifier,
                Hint(HintType.RED_TEMPLE_KEY_SET,
                     None,
                     dark_temple=temple_hints.pop(0)))
            identifiers.remove(identifier)

        return patches
Esempio n. 6
0
def add_echoes_default_hints_to_patches(
    rng: Random,
    patches: GamePatches,
    world_list: WorldList,
    num_joke: int,
    is_multiworld: bool,
) -> GamePatches:
    """
    Adds hints that are present on all games.
    :param rng:
    :param patches:
    :param world_list:
    :param num_joke
    :param is_multiworld
    :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.LOCATION,
                    PrecisionPair(HintLocationPrecision.KEYBEARER,
                                  HintItemPrecision.BROAD_CATEGORY,
                                  include_owner=True),
                    PickupIndex(node.hint_index)))

    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(all_logbook_assets)

    # The 4 guaranteed hints
    indices_with_hint = [
        (PickupIndex(24),
         HintLocationPrecision.LIGHT_SUIT_LOCATION),  # Light Suit
        (PickupIndex(43),
         HintLocationPrecision.GUARDIAN),  # Dark Suit (Amorbis)
        (PickupIndex(79),
         HintLocationPrecision.GUARDIAN),  # Dark Visor (Chykka)
        (PickupIndex(115),
         HintLocationPrecision.GUARDIAN),  # Annihilator Beam (Quadraxis)
    ]
    rng.shuffle(indices_with_hint)
    for index, location_type in indices_with_hint:
        if not all_logbook_assets:
            break

        logbook_asset = all_logbook_assets.pop()
        patches = patches.assign_hint(
            logbook_asset,
            Hint(
                HintType.LOCATION,
                PrecisionPair(location_type,
                              HintItemPrecision.DETAILED,
                              include_owner=False), index))

    # Dark Temple hints
    temple_hints = list(iterate_enum(HintDarkTemple))
    while all_logbook_assets and temple_hints:
        logbook_asset = all_logbook_assets.pop()
        patches = patches.assign_hint(
            logbook_asset,
            Hint(HintType.RED_TEMPLE_KEY_SET,
                 None,
                 dark_temple=temple_hints.pop(0)))

    # Jokes
    while num_joke > 0 and all_logbook_assets:
        logbook_asset = all_logbook_assets.pop()
        patches = patches.assign_hint(logbook_asset, Hint(HintType.JOKE, None))
        num_joke -= 1

    return patches