Esempio n. 1
0
def test_connections_from_dock_blast_shield(empty_patches):
    # Setup
    trivial = Requirement.trivial()
    req_1 = ResourceRequirement.simple(
        SimpleResourceInfo(0, "Ev1", "Ev1", ResourceType.EVENT))
    req_2 = ResourceRequirement.simple(
        SimpleResourceInfo(1, "Ev2", "Ev2", ResourceType.EVENT))
    dock_type = DockType("Type", "Type", frozendict())
    weak_1 = DockWeakness(0, "Weak 1", frozendict(), req_1, None)
    weak_2 = DockWeakness(1, "Weak 2", frozendict(), trivial,
                          DockLock(DockLockType.FRONT_BLAST_BACK_BLAST, req_2))

    node_1_identifier = NodeIdentifier.create("W", "Area 1", "Node 1")
    node_2_identifier = NodeIdentifier.create("W", "Area 2", "Node 2")

    node_1 = DockNode(node_1_identifier, 0, False, None, "", ("default", ), {},
                      dock_type, node_2_identifier, weak_1, None, None)
    node_1_lock = DockLockNode.create_from_dock(node_1, 1)
    node_2 = DockNode(node_2_identifier, 2, False, None, "", ("default", ), {},
                      dock_type, node_1_identifier, weak_2, None, None)
    node_2_lock = DockLockNode.create_from_dock(node_2, 3)

    area_1 = Area("Area 1", None, True, [node_1, node_1_lock], {}, {})
    area_2 = Area("Area 2", None, True, [node_2, node_2_lock], {}, {})

    world = World("W", [area_1, area_2], {})
    world_list = WorldList([world])
    world_list.ensure_has_node_cache()

    game_mock = MagicMock()
    game_mock.world_list = world_list
    patches = dataclasses.replace(empty_patches, game=game_mock)

    context = NodeContext(
        patches=patches,
        current_resources=ResourceCollection(),
        database=patches.game.resource_database,
        node_provider=world_list,
    )

    # Run
    result_1 = list(node_1.connections_from(context))
    result_2 = list(node_2.connections_from(context))

    # Assert
    simple = ResourceRequirement.simple

    assert result_1 == [
        (node_2,
         RequirementAnd(
             [req_1,
              simple(NodeResourceInfo.from_node(node_2, context))])),
        (node_1_lock, RequirementAnd([trivial, req_2])),
    ]
    assert result_2 == [
        (node_1, simple(NodeResourceInfo.from_node(node_2, context))),
        (node_2_lock, req_2),
    ]
Esempio n. 2
0
def test_connections_from_dock_blast_shield(empty_patches):
    # Setup
    trivial = Requirement.trivial()
    req_1 = ResourceRequirement(
        SimpleResourceInfo("Ev1", "Ev1", ResourceType.EVENT), 1, False)
    req_2 = ResourceRequirement(
        SimpleResourceInfo("Ev2", "Ev2", ResourceType.EVENT), 1, False)
    dock_type = DockType("Type", "Type", frozendict())
    weak_1 = DockWeakness("Weak 1", frozendict(), req_1, None)
    weak_2 = DockWeakness("Weak 2", frozendict(), trivial,
                          DockLock(DockLockType.FRONT_BLAST_BACK_BLAST, req_2))

    node_1_identifier = NodeIdentifier.create("W", "Area 1", "Node 1")
    node_2_identifier = NodeIdentifier.create("W", "Area 2", "Node 2")

    node_1 = DockNode(node_1_identifier, False, None, "", ("default", ), {},
                      dock_type, node_2_identifier, weak_1, None, None)
    node_1_lock = DockLockNode.create_from_dock(node_1)
    node_2 = DockNode(node_2_identifier, False, None, "", ("default", ), {},
                      dock_type, node_1_identifier, weak_2, None, None)
    node_2_lock = DockLockNode.create_from_dock(node_2)

    area_1 = Area("Area 1", None, True, [node_1, node_1_lock], {}, {})
    area_2 = Area("Area 2", None, True, [node_2, node_2_lock], {}, {})

    world = World("W", [area_1, area_2], {})
    world_list = WorldList([world])

    context = NodeContext(
        patches=empty_patches,
        current_resources={},
        database=None,
        node_provider=world_list,
    )

    # Run
    result_1 = list(node_1.connections_from(context))
    result_2 = list(node_2.connections_from(context))

    # Assert
    assert result_1 == [
        (node_2,
         RequirementAnd([req_1,
                         ResourceRequirement.simple(node_2_identifier)])),
        (node_1_lock, RequirementAnd([trivial, req_2])),
    ]
    assert result_2 == [
        (node_1, ResourceRequirement.simple(node_2_identifier)),
        (node_2_lock, req_2),
    ]
Esempio n. 3
0
    def move_node_from_area_to_area(self, old_area: Area, new_area: Area, node: Node):
        assert node in old_area.nodes

        if new_area.node_with_name(node.name) is not None:
            raise ValueError(f"New area {new_area.name} already contains a node named {node.name}")

        old_world = self.game.world_list.world_with_area(old_area)
        new_world = self.game.world_list.world_with_area(new_area)

        self.remove_node(old_area, node)
        self.add_node(new_area, node)
        self.replace_references_to_node_identifier(
            NodeIdentifier.create(old_world.name, old_area.name, node.name),
            NodeIdentifier.create(new_world.name, new_area.name, node.name),
        )
Esempio n. 4
0
def test_add_elevator_connections_to_patches_vanilla(echoes_game_description,
                                                     skip_final_bosses: bool,
                                                     default_echoes_configuration,
                                                     echoes_game_patches):
    # Setup
    patches_factory = echoes_game_description.game.generator.base_patches_factory
    expected = dataclasses.replace(echoes_game_patches,
                                   elevator_connection=echoes_game_description.get_default_elevator_connection())
    if skip_final_bosses:
        node_ident = NodeIdentifier.create("Temple Grounds", "Sky Temple Gateway",
                                           "Teleport to Great Temple - Sky Temple Energy Controller")
        expected.elevator_connection[node_ident] = AreaIdentifier("Temple Grounds", "Credits")

    config = default_echoes_configuration
    config = dataclasses.replace(config,
                                 elevators=dataclasses.replace(config.elevators,
                                                               skip_final_bosses=skip_final_bosses))

    # Run
    result = patches_factory.add_elevator_connections_to_patches(
        config,
        Random(0),
        echoes_game_patches)

    # Assert
    assert result == expected
Esempio n. 5
0
    def static_teleporters(self) -> Dict[NodeIdentifier, AreaIdentifier]:
        static = {}
        if self.skip_final_bosses:
            if self.game == RandovaniaGame.METROID_PRIME:
                crater = NodeIdentifier.create(
                    "Tallon Overworld", "Artifact Temple",
                    "Teleport to Impact Crater - Crater Impact Point")
                static[crater] = AreaIdentifier("End of Game", "Credits")
            elif self.game == RandovaniaGame.METROID_PRIME_ECHOES:
                gateway = NodeIdentifier.create(
                    "Temple Grounds", "Sky Temple Gateway",
                    "Teleport to Great Temple - Sky Temple Energy Controller")
                static[gateway] = AreaIdentifier("Temple Grounds", "Credits")
            else:
                raise ValueError(
                    f"Unsupported skip_final_bosses and {self.game}")

        return static
Esempio n. 6
0
def _logbook_node(request, blank_game_description):
    has_translator = request.param
    translator = blank_game_description.resource_database.get_item("BlueKey")

    node = blank_game_description.world_list.node_by_identifier(NodeIdentifier.create(
        "Intro", "Hint Room", "Hint with Translator" if has_translator else "Hint no Translator",
    ))
    assert isinstance(node, LogbookNode)

    return has_translator, translator, node
Esempio n. 7
0
def _pickup_node():
    return PickupNode(
        pickup_index=PickupIndex(1),
        major_location=True,
        identifier=NodeIdentifier.create("W", "A", "Pickup (Ultra Beam)"),
        heal=False,
        location=None,
        layers=("default", ),
        description="",
        extra={},
    )
Esempio n. 8
0
def test_one_way_elevator_connections(echoes_game_description, replacement,
                                      expected):
    # Setup
    rng = random.Random(5000)
    target_locations = [AreaIdentifier(f"w{i}", f"a{i}") for i in range(6)]
    elevators = [
        ElevatorHelper(NodeIdentifier.create(f"w{i}", f"a{i}", f"n{i}"),
                       AreaIdentifier(f"w{i}", f"a{i}")) for i in range(6)
    ]
    database = tuple(elevators)

    # Run
    result = elevator_distributor.one_way_elevator_connections(
        rng, database, target_locations, replacement)

    # Assert
    assert result == expected
Esempio n. 9
0
def test_sort_resource_requirement():
    resources = [
        NodeIdentifier.create("World", "Area", "Node"),
        PickupIndex(10),
        _make_resource("Resource"),
        TrickResourceInfo("Trick", "Trick", "Long Description"),
        ItemResourceInfo("Item", "Item", 1),
    ]

    # Assert resources has an entry for every type of ResourceInfo
    assert {type(it) for it in resources} == set(ResourceInfo.__args__)
    assert len(resources) == len(ResourceInfo.__args__)

    requirements = [ResourceRequirement.simple(it) for it in resources]

    result = sorted(requirements)
    assert result == list(reversed(requirements))
Esempio n. 10
0
def test_two_way_elevator_connections_unchecked():
    # Setup
    rng = random.Random(5000)
    elevators = [
        ElevatorHelper(NodeIdentifier.create(f"w{i}", f"a{i}", f"n{i}"),
                       AreaIdentifier(f"w{i}", f"a{i}")) for i in range(6)
    ]
    database = tuple(elevators)

    # Run
    result = elevator_distributor.two_way_elevator_connections(
        rng, database, False)

    # Assert
    assert result == {
        NodeIdentifier.create("w0", "a0", "n0"): AreaIdentifier("w4", "a4"),
        NodeIdentifier.create("w1", "a1", "n1"): AreaIdentifier("w2", "a2"),
        NodeIdentifier.create("w2", "a2", "n2"): AreaIdentifier("w1", "a1"),
        NodeIdentifier.create("w3", "a3", "n3"): AreaIdentifier("w5", "a5"),
        NodeIdentifier.create("w4", "a4", "n4"): AreaIdentifier("w0", "a0"),
        NodeIdentifier.create("w5", "a5", "n5"): AreaIdentifier("w3", "a3"),
    }
Esempio n. 11
0
 def add(world: str, area: str, node: str, target_world: str, target_area: str):
     elevator_connection[NodeIdentifier.create(world, area, node)] = AreaIdentifier(target_world, target_area)
Esempio n. 12
0
 def ni(w: str, a: str, n: str, tw: str, ta: str):
     elevator_connection[NodeIdentifier.create(w, a, n)] = AreaIdentifier(tw, ta)
def test_create_pickup_list_random_data_source(has_memo_data: bool, empty_patches, generic_item_category):
    # Setup
    rng = Random(5000)
    resource_b = ItemResourceInfo(0, "B", "B", 10)

    model_1 = MagicMock(spec=PickupModel)
    model_2 = MagicMock(spec=PickupModel)
    useless_model = PickupModel(game=RandovaniaGame.METROID_PRIME_CORRUPTION, name="Useless")

    pickup_a = PickupEntry("A", model_1, generic_item_category, generic_item_category,
                           progression=tuple())
    pickup_b = PickupEntry("B", model_2, generic_item_category, generic_item_category,
                           progression=((resource_b, 1), (resource_b, 1)))
    pickup_c = PickupEntry("C", model_2, generic_item_category, generic_item_category,
                           progression=tuple())
    useless_pickup = PickupEntry("Useless", useless_model, USELESS_ITEM_CATEGORY, USELESS_ITEM_CATEGORY,
                                 progression=tuple())

    patches = empty_patches.assign_new_pickups([
        (PickupIndex(0), PickupTarget(pickup_a, 0)),
        (PickupIndex(2), PickupTarget(pickup_b, 0)),
        (PickupIndex(3), PickupTarget(pickup_a, 0)),
        (PickupIndex(4), PickupTarget(pickup_c, 0)),
    ])

    if has_memo_data:
        memo_data = {
            "A": "This is an awesome item A",
            "B": "This is B. It is good.",
            "C": "What a nice day to have a C",
            "Useless": "Try again next time",
        }
    else:
        memo_data = {
            name: "{} acquired!".format(name)
            for name in ("A", "B", "C", "Useless")
        }

    creator = pickup_exporter.PickupExporterSolo(memo_data)

    world_list = MagicMock()
    world_list.iterate_nodes.return_value = [
        PickupNode(NodeIdentifier.create("W", "A", f"Name {i}"),
                   i, False, None, "", ("default",), {}, PickupIndex(i), False)
        for i in range(5)
    ]

    # Run
    result = pickup_exporter.export_all_indices(
        patches,
        PickupTarget(useless_pickup, 0),
        world_list,
        rng,
        PickupModelStyle.HIDE_ALL,
        PickupModelDataSource.RANDOM,
        creator,
        pickup_creator.create_visual_etm(),
    )

    # Assert
    assert len(result) == 5
    assert result[0] == pickup_exporter.ExportedPickupDetails(
        index=PickupIndex(0),
        scan_text="A",
        hud_text=[memo_data["A"]],
        conditional_resources=[ConditionalResources("A", None, ())],
        conversion=[],
        model=model_1,
        other_player=False,
        original_pickup=pickup_a,
    )
    assert result[1] == pickup_exporter.ExportedPickupDetails(
        index=PickupIndex(1),
        scan_text="A",
        hud_text=[memo_data["A"]],
        conditional_resources=[ConditionalResources("Useless", None, ())],
        conversion=[],
        model=model_1,
        other_player=False,
        original_pickup=useless_pickup,
    )
    assert result[2] == pickup_exporter.ExportedPickupDetails(
        index=PickupIndex(2),
        scan_text="C",
        hud_text=[memo_data["C"], memo_data["C"]],
        conditional_resources=[
            ConditionalResources("B", None, ((resource_b, 1),)),
            ConditionalResources("B", resource_b, ((resource_b, 1),)),
        ],
        conversion=[],
        model=model_2,
        other_player=False,
        original_pickup=pickup_b,
    )
    assert result[3] == pickup_exporter.ExportedPickupDetails(
        index=PickupIndex(3),
        scan_text="B",
        hud_text=[memo_data["B"]],
        conditional_resources=[ConditionalResources("A", None, ())],
        conversion=[],
        model=model_2,
        other_player=False,
        original_pickup=pickup_a,
    )
    assert result[4] == pickup_exporter.ExportedPickupDetails(
        index=PickupIndex(4),
        scan_text="A",
        hud_text=[memo_data["A"]],
        conditional_resources=[ConditionalResources("C", None, ())],
        conversion=[],
        model=model_1,
        other_player=False,
        original_pickup=pickup_c,
    )
def test_create_pickup_list(model_style: PickupModelStyle, empty_patches, generic_item_category,
                            blank_resource_db):
    # Setup
    has_scan_text = model_style in {PickupModelStyle.ALL_VISIBLE, PickupModelStyle.HIDE_MODEL}
    rng = Random(5000)

    model_0 = MagicMock(spec=PickupModel)
    model_1 = MagicMock(spec=PickupModel)
    model_2 = MagicMock(spec=PickupModel)
    useless_model = PickupModel(
        game=RandovaniaGame.METROID_PRIME_ECHOES,
        name="EnergyTransferModule",
    )

    useless_resource =  ItemResourceInfo(0, "Useless", "Useless", 10)
    resource_a = ItemResourceInfo(1, "A", "A", 10)
    resource_b = ItemResourceInfo(2, "B", "B", 10)
    pickup_a = PickupEntry("P-A", model_1, generic_item_category, generic_item_category,
                           progression=((resource_a, 1),),
                           )
    pickup_b = PickupEntry("P-B", model_2, generic_item_category, generic_item_category,
                           progression=((resource_b, 1),
                                        (resource_a, 5)), )
    pickup_c = PickupEntry("P-C", model_2, AMMO_ITEM_CATEGORY, generic_item_category,
                           progression=tuple(),
                           extra_resources=((resource_b, 2), (resource_a, 1)),
                           unlocks_resource=True,
                           resource_lock=ResourceLock(resource_a, resource_a, useless_resource))

    useless_pickup = PickupEntry("P-Useless", model_0, USELESS_ITEM_CATEGORY, USELESS_ITEM_CATEGORY,
                                 progression=((useless_resource, 1),))
    patches = empty_patches.assign_new_pickups([
        (PickupIndex(0), PickupTarget(pickup_a, 0)),
        (PickupIndex(2), PickupTarget(pickup_b, 0)),
        (PickupIndex(3), PickupTarget(pickup_a, 0)),
        (PickupIndex(4), PickupTarget(pickup_c, 0)),
    ])
    creator = pickup_exporter.PickupExporterSolo(pickup_exporter.GenericAcquiredMemo())

    world_list = MagicMock()
    world_list.iterate_nodes.return_value = [
        PickupNode(NodeIdentifier.create("World", "Area", f"Name {i}"),
                   i, False, None, "", ("default",), {}, PickupIndex(i), False)
        for i in range(5)
    ]

    # Run
    result = pickup_exporter.export_all_indices(
        patches,
        PickupTarget(useless_pickup, 0),
        world_list,
        rng,
        model_style,
        PickupModelDataSource.ETM,
        creator,
        pickup_creator.create_visual_etm(),
    )

    # Assert
    assert len(result) == 5
    assert result[0] == pickup_exporter.ExportedPickupDetails(
        index=PickupIndex(0),
        scan_text="P-A" if has_scan_text else "Unknown item",
        hud_text=["A acquired!"] if model_style != PickupModelStyle.HIDE_ALL else ['Unknown item acquired!'],
        conditional_resources=[ConditionalResources("A", None, ((resource_a, 1),))],
        conversion=[],
        model=model_1 if model_style == PickupModelStyle.ALL_VISIBLE else useless_model,
        other_player=False,
        original_pickup=pickup_a,
    )
    assert result[1] == pickup_exporter.ExportedPickupDetails(
        index=PickupIndex(1),
        scan_text="P-Useless" if has_scan_text else "Unknown item",
        hud_text=["Useless acquired!"] if model_style != PickupModelStyle.HIDE_ALL else ['Unknown item acquired!'],
        conditional_resources=[ConditionalResources("Useless", None, ((useless_resource, 1),))],
        conversion=[],
        model=model_0 if model_style == PickupModelStyle.ALL_VISIBLE else useless_model,
        other_player=False,
        original_pickup=useless_pickup,
    )
    assert result[2] == pickup_exporter.ExportedPickupDetails(
        index=PickupIndex(2),
        scan_text="P-B. Provides the following in order: B, A" if has_scan_text else "Unknown item",
        hud_text=["B acquired!", "A acquired!"] if model_style != PickupModelStyle.HIDE_ALL else [
            'Unknown item acquired!', 'Unknown item acquired!'],
        conditional_resources=[
            ConditionalResources("B", None, ((resource_b, 1),)),
            ConditionalResources("A", resource_b, ((resource_a, 5),)),
        ],
        conversion=[],
        model=model_2 if model_style == PickupModelStyle.ALL_VISIBLE else useless_model,
        other_player=False,
        original_pickup=pickup_b,
    )
    assert result[3] == pickup_exporter.ExportedPickupDetails(
        index=PickupIndex(3),
        scan_text="P-A" if has_scan_text else "Unknown item",
        hud_text=["A acquired!"] if model_style != PickupModelStyle.HIDE_ALL else ['Unknown item acquired!'],
        conditional_resources=[ConditionalResources("A", None, ((resource_a, 1),))],
        conversion=[],
        model=model_1 if model_style == PickupModelStyle.ALL_VISIBLE else useless_model,
        other_player=False,
        original_pickup=pickup_a,
    )
    assert result[4] == pickup_exporter.ExportedPickupDetails(
        index=PickupIndex(4),
        scan_text="P-C. Provides 2 B and 1 A" if has_scan_text else "Unknown item",
        hud_text=["P-C acquired!"] if model_style != PickupModelStyle.HIDE_ALL else ['Unknown item acquired!'],
        conditional_resources=[ConditionalResources("P-C", None, (
            (resource_b, 2), (resource_a, 1),
        ))],
        conversion=[ResourceConversion(source=useless_resource, target=resource_a)],
        model=model_2 if model_style == PickupModelStyle.ALL_VISIBLE else useless_model,
        other_player=False,
        original_pickup=pickup_c,
    )
Esempio n. 15
0
 def _create_identifier(self, node_name: str):
     return NodeIdentifier.create(self.current_world.name,
                                  self.current_area.name, node_name)
Esempio n. 16
0
def _a(world, area, instance_id=None):
    if instance_id is not None:
        return NodeIdentifier.create(world, area, instance_id).as_json
    return AreaIdentifier(world, area).as_json
Esempio n. 17
0
        rng, database, False)

    # Assert
    assert result == {
        NodeIdentifier.create("w0", "a0", "n0"): AreaIdentifier("w4", "a4"),
        NodeIdentifier.create("w1", "a1", "n1"): AreaIdentifier("w2", "a2"),
        NodeIdentifier.create("w2", "a2", "n2"): AreaIdentifier("w1", "a1"),
        NodeIdentifier.create("w3", "a3", "n3"): AreaIdentifier("w5", "a5"),
        NodeIdentifier.create("w4", "a4", "n4"): AreaIdentifier("w0", "a0"),
        NodeIdentifier.create("w5", "a5", "n5"): AreaIdentifier("w3", "a3"),
    }


@pytest.mark.parametrize(["replacement", "expected"], [
    (False, {
        NodeIdentifier.create("w0", "a0", "n0"): AreaIdentifier("w1", "a1"),
        NodeIdentifier.create("w1", "a1", "n1"): AreaIdentifier("w2", "a2"),
        NodeIdentifier.create("w2", "a2", "n2"): AreaIdentifier("w3", "a3"),
        NodeIdentifier.create("w3", "a3", "n3"): AreaIdentifier("w5", "a5"),
        NodeIdentifier.create("w4", "a4", "n4"): AreaIdentifier("w0", "a0"),
        NodeIdentifier.create("w5", "a5", "n5"): AreaIdentifier("w4", "a4"),
    }),
    (True, {
        NodeIdentifier.create("w0", "a0", "n0"): AreaIdentifier("w2", "a2"),
        NodeIdentifier.create("w1", "a1", "n1"): AreaIdentifier("w3", "a3"),
        NodeIdentifier.create("w2", "a2", "n2"): AreaIdentifier("w4", "a4"),
        NodeIdentifier.create("w3", "a3", "n3"): AreaIdentifier("w2", "a2"),
        NodeIdentifier.create("w4", "a4", "n4"): AreaIdentifier("w5", "a5"),
        NodeIdentifier.create("w5", "a5", "n5"): AreaIdentifier("w3", "a3"),
    }),
])
Esempio n. 18
0
def decode_single(player_index: int, all_pools: Dict[int, PoolResults],
                  game: GameDescription, game_modifications: dict,
                  configuration: BaseConfiguration) -> GamePatches:
    """
    Decodes a dict created by `serialize` back into a GamePatches.
    :param player_index:
    :param all_pools:
    :param game:
    :param game_modifications:
    :param configuration:
    :return:
    """
    world_list = game.world_list
    weakness_db = game.dock_weakness_database

    if game_modifications["game"] != game.game.value:
        raise ValueError(
            f"Expected '{game.game.value}', got '{game_modifications['game']}'"
        )

    initial_pickup_assignment = all_pools[player_index].assignment

    # Starting Location
    starting_location = AreaIdentifier.from_string(
        game_modifications["starting_location"])

    # Initial items
    starting_items = {
        find_resource_info_with_long_name(game.resource_database.item,
                                          resource_name): quantity
        for resource_name, quantity in
        game_modifications["starting_items"].items()
    }

    # Elevators
    elevator_connection: ElevatorConnection = {
        NodeIdentifier.from_string(source_name):
        AreaIdentifier.from_string(target_name)
        for source_name, target_name in
        game_modifications["teleporters"].items()
    }

    # Dock Weakness
    dock_weakness: dict[NodeIdentifier, DockWeakness] = {
        NodeIdentifier.from_string(source_name): weakness_db.get_by_weakness(
            weakness_data["type"],
            weakness_data["name"],
        )
        for source_name, weakness_data in
        game_modifications["dock_weakness"].items()
    }

    # Configurable Nodes
    configurable_nodes = {
        NodeIdentifier.from_string(identifier):
        data_reader.read_requirement(requirement, game.resource_database)
        for identifier, requirement in
        game_modifications["configurable_nodes"].items()
    }

    # Pickups
    target_name_re = re.compile(r"(.*) for Player (\d+)")

    pickup_assignment: PickupAssignment = {}
    for world_name, world_data in game_modifications["locations"].items():
        for area_node_name, target_name in typing.cast(dict[str, str],
                                                       world_data).items():
            if target_name == _ETM_NAME:
                continue

            pickup_name_match = target_name_re.match(target_name)
            if pickup_name_match is not None:
                pickup_name = pickup_name_match.group(1)
                target_player = int(pickup_name_match.group(2)) - 1
            else:
                pickup_name = target_name
                target_player = 0

            node_identifier = NodeIdentifier.create(
                world_name, *area_node_name.split("/", 1))
            node = world_list.node_by_identifier(node_identifier)
            assert isinstance(node, PickupNode)
            if node.pickup_index in initial_pickup_assignment:
                pickup = initial_pickup_assignment[node.pickup_index]
                if (pickup_name, target_player) != (pickup.name, player_index):
                    raise ValueError(
                        f"{area_node_name} should be vanilla based on configuration"
                    )

            elif pickup_name != _ETM_NAME:
                configuration_item_pool = all_pools[target_player].pickups
                pickup = _find_pickup_with_name(configuration_item_pool,
                                                pickup_name)
                configuration_item_pool.remove(pickup)
            else:
                pickup = None

            if pickup is not None:
                pickup_assignment[node.pickup_index] = PickupTarget(
                    pickup, target_player)

    # Hints
    hints = {}
    for identifier_str, hint in game_modifications["hints"].items():
        hints[NodeIdentifier.from_string(identifier_str)] = Hint.from_json(
            hint)

    return GamePatches(
        player_index=player_index,
        configuration=configuration,
        pickup_assignment=pickup_assignment,  # PickupAssignment
        elevator_connection=elevator_connection,  # ElevatorConnection
        dock_connection={},  # Dict[Tuple[int, int], DockConnection]
        dock_weakness=dock_weakness,
        configurable_nodes=configurable_nodes,
        starting_items=starting_items,  # ResourceGainTuple
        starting_location=starting_location,  # AreaIdentifier
        hints=hints,
    )
 def add(world: str, area: str, node: str, target_world: str,
         target_area: str):
     elevator_connection.append((
         wl.get_teleporter_node(NodeIdentifier.create(world, area, node)),
         AreaIdentifier(target_world, target_area),
     ))
Esempio n. 20
0
    def read_node(self, name: str, data: Dict) -> Node:
        try:
            location = None
            if data["coordinates"] is not None:
                location = location_from_json(data["coordinates"])

            generic_args = {
                "identifier":
                NodeIdentifier.create(self.current_world_name,
                                      self.current_area_name, name),
                "heal":
                data["heal"],
                "location":
                location,
                "description":
                data["description"],
                "layers":
                tuple(data["layers"]),
                "extra":
                frozen_lib.wrap(data["extra"]),
            }
            node_type: int = data["node_type"]

            if node_type == "generic":
                return GenericNode(**generic_args)

            elif node_type == "dock":
                return DockNode(
                    **generic_args,
                    dock_type=self.dock_weakness_database.find_type(
                        data["dock_type"]),
                    default_connection=NodeIdentifier.from_json(
                        data["default_connection"]),
                    default_dock_weakness=self.dock_weakness_database.
                    get_by_weakness(
                        data["dock_type"],
                        data["default_dock_weakness"],
                    ),
                    override_default_open_requirement=read_optional_requirement(
                        data["override_default_open_requirement"],
                        self.resource_database),
                    override_default_lock_requirement=read_optional_requirement(
                        data["override_default_lock_requirement"],
                        self.resource_database),
                )

            elif node_type == "pickup":
                return PickupNode(
                    **generic_args,
                    pickup_index=PickupIndex(data["pickup_index"]),
                    major_location=data["major_location"],
                )

            elif node_type == "teleporter":
                return TeleporterNode(
                    **generic_args,
                    default_connection=AreaIdentifier.from_json(
                        data["destination"]),
                    keep_name_when_vanilla=data["keep_name_when_vanilla"],
                    editable=data["editable"],
                )

            elif node_type == "event":
                return EventNode(
                    **generic_args,
                    event=self.resource_database.get_by_type_and_index(
                        ResourceType.EVENT, data["event_name"]))

            elif node_type == "configurable_node":
                return ConfigurableNode(**generic_args, )

            elif node_type == "logbook":
                lore_type = LoreType(data["lore_type"])

                if lore_type == LoreType.REQUIRES_ITEM:
                    required_translator = self.resource_database.get_item(
                        data["extra"]["translator"])
                else:
                    required_translator = None

                if lore_type in {
                        LoreType.SPECIFIC_PICKUP, LoreType.SKY_TEMPLE_KEY_HINT
                }:
                    hint_index = data["extra"]["hint_index"]
                else:
                    hint_index = None

                return LogbookNode(
                    **generic_args,
                    string_asset_id=data["string_asset_id"],
                    scan_visor=self._get_scan_visor(),
                    lore_type=lore_type,
                    required_translator=required_translator,
                    hint_index=hint_index,
                )

            elif node_type == "player_ship":
                return PlayerShipNode(
                    **generic_args,
                    is_unlocked=read_requirement(data["is_unlocked"],
                                                 self.resource_database),
                    item_to_summon=self._get_command_visor(),
                )

            else:
                raise Exception(f"Unknown type: {node_type}")

        except Exception as e:
            raise Exception(f"In node {name}, got error: {e}")
Esempio n. 21
0
from randovania.layout import game_patches_serializer
from randovania.layout.base.major_item_state import MajorItemState
from randovania.layout.base.trick_level_configuration import TrickLevelConfiguration
from randovania.layout.generator_parameters import GeneratorParameters
from randovania.network_common.pickup_serializer import BitPackPickupEntry


@pytest.fixture(params=[
    {},
    {
        "starting_item": "Morph Ball"
    },
    {
        "elevator":
        NodeIdentifier.create(
            "Temple Grounds", "Transport to Agon Wastes",
            "Elevator to Agon Wastes - Transport to Temple Grounds")
    },
    {
        "configurable_nodes":
        [("Agon Wastes/Mining Plaza/Translator Gate", "Cobalt"),
         ("Torvus Bog/Great Bridge/Translator Gate", "Emerald")]
    },
    {
        "pickup": "Morph Ball Bomb"
    },
    {
        "hint": [
            'Torvus Bog/Catacombs/Lore Scan', {
                "hint_type": "location",
                "dark_temple": None,