Exemplo n.º 1
0
def test_add_elevator_connections_to_patches_random(echoes_game_data):
    # Setup
    game = data_reader.decode_data(echoes_game_data)
    permalink = dataclasses.replace(Permalink.default(),
                                    layout_configuration=dataclasses.replace(
                                        LayoutConfiguration.default(),
                                        elevators=LayoutElevators.RANDOMIZED))
    expected = dataclasses.replace(GamePatches.with_game(game),
                                   elevator_connection={
                                       589851:
                                       AreaLocation(1039999561, 1868895730),
                                       1572998:
                                       AreaLocation(1039999561, 3479543630),
                                       1966093:
                                       AreaLocation(2252328306, 408633584),
                                       2097251:
                                       AreaLocation(1119434212, 3331021649),
                                       136970379:
                                       AreaLocation(2252328306, 2068511343),
                                       3342446:
                                       AreaLocation(1039999561, 3205424168),
                                       3538975:
                                       AreaLocation(1119434212, 2806956034),
                                       152:
                                       AreaLocation(1006255871, 2889020216),
                                       393260:
                                       AreaLocation(464164546, 3145160350),
                                       524321:
                                       AreaLocation(464164546, 900285955),
                                       589949:
                                       AreaLocation(1006255871, 2278776548),
                                       122:
                                       AreaLocation(464164546, 3528156989),
                                       1245307:
                                       AreaLocation(1006255871, 1345979968),
                                       2949235:
                                       AreaLocation(1006255871, 1287880522),
                                       129:
                                       AreaLocation(1006255871, 2918020398),
                                       2162826:
                                       AreaLocation(1006255871, 1660916974),
                                       4522032:
                                       AreaLocation(1006255871, 3455543403),
                                       38:
                                       AreaLocation(1119434212, 1473133138),
                                       1245332:
                                       AreaLocation(2252328306, 2399252740),
                                       1638535:
                                       AreaLocation(2252328306, 2556480432),
                                   })

    # Run
    result = base_patches_factory.add_elevator_connections_to_patches(
        permalink.layout_configuration,
        Random(permalink.seed_number),
        GamePatches.with_game(game),
    )

    # Assert
    assert result == expected
Exemplo n.º 2
0
def test_add_elevator_connections_to_patches_vanilla(echoes_game_data):
    # Setup
    game = data_reader.decode_data(echoes_game_data)
    permalink = Permalink.default()

    # Run
    result = base_patches_factory.add_elevator_connections_to_patches(
        permalink.layout_configuration, Random(permalink.seed_number),
        GamePatches.with_game(game))

    # Assert
    assert result == GamePatches.with_game(game)
Exemplo n.º 3
0
    def __init__(self, layout_configuration: LayoutConfiguration):
        super().__init__()
        self.setupUi(self)
        set_default_window_icon(self)

        self.layout_configuration = layout_configuration
        self.game_description = data_reader.decode_data(
            layout_configuration.game_data, True)

        self.logic, self._initial_state = logic_bootstrap(
            layout_configuration, self.game_description,
            GamePatches.with_game(self.game_description))
        self.resource_filter_check.stateChanged.connect(
            self.update_locations_tree_for_reachable_nodes)
        self.hide_collected_resources_check.stateChanged.connect(
            self.update_locations_tree_for_reachable_nodes)
        self.undo_last_action_button.clicked.connect(self._undo_last_action)

        self.configuration_label.setText(
            "Trick Level: {}; Elevators: Vanilla; Item Loss: {}".format(
                layout_configuration.trick_level.value,
                layout_configuration.starting_resources.configuration.value,
            ))

        self.setup_pickups_box()
        self.setup_possible_locations_tree()

        self._starting_nodes = {
            node
            for node in self.game_description.world_list.all_nodes
            if node.is_resource_node
            and node.resource() in self._initial_state.resources
        }
        self._add_new_action(self._initial_state.node)
Exemplo n.º 4
0
def _create_test_layout_description(
        configuration: LayoutConfiguration,
        pickup_mapping: Iterable[int],
) -> LayoutDescription:
    """
    Creates a LayoutDescription for the given configuration, with the patches being for the given pickup_mapping
    :param configuration:
    :param pickup_mapping:
    :return:
    """
    game = data_reader.decode_data(configuration.game_data)
    pickup_database = game.pickup_database

    return LayoutDescription(
        version=VERSION,
        permalink=Permalink(
            seed_number=0,
            spoiler=True,
            patcher_configuration=PatcherConfiguration.default(),
            layout_configuration=configuration,
        ),
        patches=GamePatches.with_game(game).assign_new_pickups([
            (PickupIndex(i), pickup_database.original_pickup_mapping[PickupIndex(new_index)])
            for i, new_index in enumerate(pickup_mapping)
        ]),
        solver_path=())
Exemplo n.º 5
0
def test_run_filler(mock_retcon_playthrough_filler: MagicMock,
                    echoes_game_description,
                    pickup
                    ):
    # Setup
    configuration = LayoutConfiguration.default()
    rng = Random(5000)
    status_update = MagicMock()
    item_pool = [pickup]
    patches = GamePatches.with_game(echoes_game_description)

    logbook_nodes = [node for node in echoes_game_description.world_list.all_nodes if isinstance(node, LogbookNode)]

    mock_retcon_playthrough_filler.return_value = patches.assign_hint(
        logbook_nodes[0].resource(), Hint(HintType.LOCATION, None, PickupIndex(0))
    ).assign_pickup_assignment({PickupIndex(1): pickup})

    # Run
    result_patches, remaining_items = runner.run_filler(configuration, echoes_game_description,
                                                        item_pool, patches,
                                                        rng, status_update)

    # Assert
    assert len(result_patches.hints) == len(logbook_nodes)
    assert [hint for hint in patches.hints.values()
            if hint.item_precision is None or hint.location_precision is None] == []
    assert remaining_items == [pickup]
def create_base_patches(
    configuration: LayoutConfiguration,
    rng: Random,
    game: GameDescription,
) -> GamePatches:
    """

    :param configuration:
    :param rng:
    :param game:
    :return:
    """

    # TODO: we shouldn't need the seed_number!

    patches = GamePatches.with_game(game)
    patches = add_elevator_connections_to_patches(configuration, rng, patches)

    # Gates
    patches = patches.assign_gate_assignment(
        gate_assignment_for_configuration(configuration,
                                          game.resource_database, rng))

    # Starting Location
    patches = patches.assign_starting_location(
        starting_location_for_configuration(configuration, game, rng))

    # Hints
    if rng is not None:
        patches = add_default_hints_to_patches(rng, patches, game.world_list)

    return patches
def test_basic_search_with_translator_gate(has_translator: bool,
                                           echoes_resource_database):
    # Setup
    scan_visor = echoes_resource_database.get_by_type_and_index(
        ResourceType.ITEM, 10)

    node_a = GenericNode("Node A", True, 0)
    node_b = GenericNode("Node B", True, 1)
    node_c = GenericNode("Node C", True, 2)
    translator_node = TranslatorGateNode("Translator Gate", True, 3,
                                         TranslatorGate(1), scan_visor)

    world_list = WorldList([
        World("Test World", 1, [
            Area(
                "Test Area A", False, 10, 0,
                [node_a, node_b, node_c, translator_node], {
                    node_a: {
                        node_b: RequirementSet.trivial(),
                        translator_node: RequirementSet.trivial(),
                    },
                    node_b: {
                        node_a: RequirementSet.trivial(),
                    },
                    node_c: {
                        translator_node: RequirementSet.trivial(),
                    },
                    translator_node: {
                        node_a: RequirementSet.trivial(),
                        node_c: RequirementSet.trivial(),
                    },
                })
        ])
    ])
    game = GameDescription(0, "",
                           DockWeaknessDatabase([], [], [],
                                                []), echoes_resource_database,
                           RequirementSet.impossible(), None, {}, world_list)

    patches = GamePatches.with_game(game)
    patches = patches.assign_gate_assignment({TranslatorGate(1): scan_visor})
    initial_state = State({scan_visor: 1 if has_translator else 0}, (), 99,
                          node_a, patches, None, echoes_resource_database)

    # Run
    reach = reach_with_all_safe_resources(game, initial_state)

    # Assert
    if has_translator:
        assert set(
            reach.safe_nodes) == {node_a, node_b, translator_node, node_c}
    else:
        assert set(reach.safe_nodes) == {node_a, node_b}
Exemplo n.º 8
0
def pretty_print_area(area: Area):
    world_list = _gd.world_list

    print(area.name)
    print("Asset id: {}".format(area.area_asset_id))
    for node in area.nodes:
        print(">", node.name, type(node))
        for target_node, requirements in world_list.potential_nodes_from(node, GamePatches.with_game(_gd)):
            if target_node is None:
                print("  > None?")
            else:
                print("  >", n(target_node))
                requirements.pretty_print("      ")
        print()
Exemplo n.º 9
0
def _create_base_patches(
    rng: Random,
    game: GameDescription,
    permalink: Permalink,
    available_pickups: List[PickupEntry],
) -> GamePatches:

    patches = GamePatches.with_game(game)
    patches = _add_elevator_connections_to_patches(permalink, patches)
    patches = patches.assign_starting_location(
        _starting_location_for_configuration(permalink.layout_configuration,
                                             game, rng))
    patches = _sky_temple_key_distribution_logic(permalink, patches,
                                                 available_pickups)

    return patches
Exemplo n.º 10
0
def test_create_patches(mock_random: MagicMock,
                        mock_calculate_item_pool: MagicMock,
                        mock_sky_temple_key_distribution_logic: MagicMock,
                        mock_retcon_playthrough_filler: MagicMock,
                        mock_indices_for_unassigned_pickups: MagicMock,
                        empty_patches
                        ):
    # Setup
    seed_number: int = 91319
    game = default_prime2_game_description()
    status_update: Union[MagicMock, Callable[[str], None]] = MagicMock()
    configuration = LayoutConfiguration.from_params(trick_level=LayoutTrickLevel.NO_TRICKS,
                                                    sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
                                                    elevators=LayoutRandomizedFlag.VANILLA,
                                                    pickup_quantities={},
                                                    starting_location=StartingLocation.default(),
                                                    starting_resources=StartingResources.from_item_loss(False),
                                                    )
    permalink = Permalink(
        seed_number=seed_number,
        spoiler=True,
        patcher_configuration=PatcherConfiguration.default(),
        layout_configuration=configuration,
    )
    mock_calculate_item_pool.return_value = list(sorted(game.pickup_database.original_pickup_mapping.values()))
    mock_sky_temple_key_distribution_logic.return_value.starting_location = game.starting_location
    mock_sky_temple_key_distribution_logic.return_value.custom_initial_items = None

    filler_patches = mock_retcon_playthrough_filler.return_value

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

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

    mock_sky_temple_key_distribution_logic.assert_called_once_with(permalink, GamePatches.with_game(game), ANY)

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

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

    assert result == filler_patches.assign_new_pickups.return_value
Exemplo n.º 11
0
def _test_data():
    data = default_data.decode_default_prime2()
    game = data_reader.decode_data(data)
    configuration = LayoutConfiguration.from_params()
    permalink = Permalink(
        seed_number=15000,
        spoiler=True,
        patcher_configuration=PatcherConfiguration.default(),
        layout_configuration=configuration,
    )
    patches = GamePatches.with_game(game)
    patches = patches.assign_gate_assignment(
        base_patches_factory.gate_assignment_for_configuration(
            configuration, game.resource_database, Random(15000)))
    game, state = logic_bootstrap(configuration, game, patches)

    return game, state, permalink
Exemplo n.º 12
0
def test_retcon_filler_integration():
    layout_configuration = LayoutConfiguration.default()

    rng = Random("fixed-seed!")
    status_update = MagicMock()

    game = data_reader.decode_data(layout_configuration.game_data)
    patches = GamePatches.with_game(game)
    available_pickups = game.pickup_database.all_useful_pickups

    logic, state = logic_bootstrap(layout_configuration, game, patches)
    logic.game.simplify_connections(state.resources)

    filler_patches = retcon.retcon_playthrough_filler(logic, state,
                                                      tuple(available_pickups),
                                                      rng, status_update)
    assert filler_patches == patches
Exemplo n.º 13
0
def validate_command_logic(args):
    debug._DEBUG_LEVEL = args.debug
    data = prime_database.decode_data_file(args)
    game = data_reader.decode_data(data)

    if args.layout_file is not None:
        description = LayoutDescription.from_file(Path(args.layout_file))
        configuration = description.permalink.layout_configuration
        patches = description.patches
    else:
        configuration = LayoutConfiguration.default()
        patches = GamePatches.with_game(game).assign_pickup_assignment(
            game.pickup_database.original_pickup_mapping)

    final_state_by_resolve = resolver.resolve(configuration=configuration,
                                              game=game,
                                              patches=patches)
    print(final_state_by_resolve)
Exemplo n.º 14
0
def test_reach_size_from_start(echoes_game_description):
    # Setup
    configuration = LayoutConfiguration.from_params(
        trick_level_configuration=TrickLevelConfiguration(
            LayoutTrickLevel.HYPERMODE), )
    patches = GamePatches.with_game(echoes_game_description)
    patches = patches.assign_gate_assignment(
        base_patches_factory.gate_assignment_for_configuration(
            configuration, echoes_game_description.resource_database,
            Random(15000)))

    game, state = logic_bootstrap(configuration, echoes_game_description,
                                  patches)

    # Run
    reach = GeneratorReach.reach_from_state(game, state)

    # Assert
    assert len(list(reach.nodes)) == 26
    assert len(list(reach.safe_nodes)) == 4
Exemplo n.º 15
0
def _test_data():
    data = default_data.decode_default_prime2()
    game = data_reader.decode_data(data, False)
    configuration = LayoutConfiguration.from_params(
        trick_level=LayoutTrickLevel.NO_TRICKS,
        sky_temple_keys=LayoutSkyTempleKeyMode.FULLY_RANDOM,
        elevators=LayoutRandomizedFlag.VANILLA,
        pickup_quantities={},
        starting_location=StartingLocation.default(),
        starting_resources=StartingResources.default(),
    )
    permalink = Permalink(
        seed_number=15000,
        spoiler=True,
        patcher_configuration=PatcherConfiguration.default(),
        layout_configuration=configuration,
    )
    logic, state = logic_bootstrap(configuration, game,
                                   GamePatches.with_game(game))

    return logic, state, permalink
Exemplo n.º 16
0
def _create_patches(
    permalink: Permalink,
    game: GameDescription,
    status_update: Callable[[str], None],
) -> GamePatches:
    rng = Random(permalink.as_str)
    configuration = permalink.layout_configuration

    categories = {
        "translator", "major", "energy_tank", "sky_temple_key", "temple_key"
    }
    item_pool = tuple(sorted(calculate_item_pool(permalink, game)))
    available_pickups = list(
        shuffle(rng, calculate_available_pickups(item_pool, categories, None)))

    if configuration.starting_location.configuration != StartingLocationConfiguration.SHIP:
        raise GenerationFailure("The only supported StartingLocation is SHIP",
                                permalink)

    if configuration.starting_resources.configuration == StartingResourcesConfiguration.CUSTOM:
        raise GenerationFailure("Custom StartingResources is unsupported",
                                permalink)

    patches = GamePatches.with_game(game)
    patches = _add_elevator_connections_to_patches(permalink, patches)
    patches = _sky_temple_key_distribution_logic(permalink, patches,
                                                 available_pickups)

    logic, state = logic_bootstrap(configuration, game, patches)
    logic.game.simplify_connections(state.resources)

    filler_patches = retcon_playthrough_filler(logic, state,
                                               tuple(available_pickups), rng,
                                               status_update)

    return filler_patches.assign_new_pickups(
        _indices_for_unassigned_pickups(rng, game,
                                        filler_patches.pickup_assignment,
                                        item_pool))
def _patches_with_data(request, echoes_game_data, echoes_item_database):
    game = data_reader.decode_data(echoes_game_data)

    data = {
        "starting_location": "Temple Grounds/Landing Site",
        "starting_items": {},
        "elevators": {
            "Temple Grounds/Temple Transport C":
            "Great Temple/Temple Transport C",
            "Temple Grounds/Transport to Agon Wastes":
            "Agon Wastes/Transport to Temple Grounds",
            "Temple Grounds/Transport to Torvus Bog":
            "Torvus Bog/Transport to Temple Grounds",
            "Temple Grounds/Temple Transport B":
            "Great Temple/Temple Transport B",
            "Temple Grounds/Sky Temple Gateway":
            "Great Temple/Sky Temple Energy Controller",
            "Temple Grounds/Transport to Sanctuary Fortress":
            "Sanctuary Fortress/Transport to Temple Grounds",
            "Temple Grounds/Temple Transport A":
            "Great Temple/Temple Transport A",
            "Great Temple/Temple Transport A":
            "Temple Grounds/Temple Transport A",
            "Great Temple/Temple Transport C":
            "Temple Grounds/Temple Transport C",
            "Great Temple/Temple Transport B":
            "Temple Grounds/Temple Transport B",
            "Great Temple/Sky Temple Energy Controller":
            "Temple Grounds/Sky Temple Gateway",
            "Agon Wastes/Transport to Temple Grounds":
            "Temple Grounds/Transport to Agon Wastes",
            "Agon Wastes/Transport to Torvus Bog":
            "Torvus Bog/Transport to Agon Wastes",
            "Agon Wastes/Transport to Sanctuary Fortress":
            "Sanctuary Fortress/Transport to Agon Wastes",
            "Torvus Bog/Transport to Temple Grounds":
            "Temple Grounds/Transport to Torvus Bog",
            "Torvus Bog/Transport to Agon Wastes":
            "Agon Wastes/Transport to Torvus Bog",
            "Torvus Bog/Transport to Sanctuary Fortress":
            "Sanctuary Fortress/Transport to Torvus Bog",
            "Sanctuary Fortress/Transport to Temple Grounds":
            "Temple Grounds/Transport to Sanctuary Fortress",
            "Sanctuary Fortress/Transport to Agon Wastes":
            "Agon Wastes/Transport to Sanctuary Fortress",
            "Sanctuary Fortress/Transport to Torvus Bog":
            "Torvus Bog/Transport to Sanctuary Fortress"
        },
        "translators": {},
        "locations": {
            world.name: {
                game.world_list.node_name(node): "Nothing"
                for node in world.all_nodes
                if node.is_resource_node and isinstance(node, PickupNode)
            }
            for world in sorted(game.world_list.worlds, key=lambda w: w.name)
        },
        "hints": {},
        "_locations_internal": "",
    }
    patches = GamePatches.with_game(game)

    if request.param.get("starting_item"):
        item_name = request.param.get("starting_item")
        patches = patches.assign_extra_initial_items({
            find_resource_info_with_long_name(game.resource_database.item, item_name):
            1,
        })
        data["starting_items"][item_name] = 1

    if request.param.get("elevator"):
        elevator_id, elevator_source = request.param.get("elevator")
        elevator_connection = copy.copy(patches.elevator_connection)
        elevator_connection[elevator_id] = game.starting_location

        patches = dataclasses.replace(patches,
                                      elevator_connection=elevator_connection)
        data["elevators"][elevator_source] = "Temple Grounds/Landing Site"

    if request.param.get("translator"):
        gates = {}
        for index, gate_name, translator in request.param.get("translator"):
            gates[TranslatorGate(index)] = find_resource_info_with_long_name(
                game.resource_database.item, translator)
            data["translators"][gate_name] = translator

        patches = patches.assign_gate_assignment(gates)

    if request.param.get("pickup"):
        data["_locations_internal"], pickup_name = request.param.get("pickup")
        pickup = pickup_creator.create_major_item(
            echoes_item_database.major_items[pickup_name], MajorItemState(),
            True, game.resource_database, None, False)

        patches = patches.assign_new_pickups([(PickupIndex(5), pickup)])
        data["locations"]["Temple Grounds"][
            'Transport to Agon Wastes/Pickup (Missile)'] = pickup_name

    if request.param.get("hint"):
        asset, hint = request.param.get("hint")
        patches = patches.assign_hint(LogbookAsset(asset),
                                      Hint.from_json(hint))
        data["hints"][str(asset)] = hint

    return data, patches
Exemplo n.º 18
0
def test_create_elevators_field_elevators_for_a_seed(vanilla_gateway: bool,
                                                     echoes_resource_database, empty_patches):
    # Setup
    game = data_reader.decode_data(default_data.decode_default_prime2())
    patches = GamePatches.with_game(game)

    elevator_connection = copy.copy(patches.elevator_connection)
    elevator_connection[589851] = AreaLocation(464164546, 900285955)
    elevator_connection[1572998] = AreaLocation(1039999561, 3479543630)

    if not vanilla_gateway:
        elevator_connection[136970379] = AreaLocation(2252328306, 3619928121)

    patches = dataclasses.replace(patches, elevator_connection=elevator_connection)

    # Run
    result = patcher_file._create_elevators_field(patches, game)

    # Assert
    expected = [
        {"instance_id": 589851,
         "origin_location": {"world_asset_id": 1006255871, "area_asset_id": 2918020398},
         "target_location": {"world_asset_id": 464164546, "area_asset_id": 900285955},
         "room_name": "Transport to Sanctuary Spider side"},

        {"instance_id": 1572998,
         "origin_location": {"world_asset_id": 1006255871, "area_asset_id": 1660916974},
         "target_location": {"world_asset_id": 1039999561, "area_asset_id": 3479543630},
         "room_name": "Transport to Torvus Temple Access"},

        {"instance_id": 1966093,
         "origin_location": {"world_asset_id": 1006255871, "area_asset_id": 2889020216},
         "target_location": {"world_asset_id": 1039999561, "area_asset_id": 1868895730},
         "room_name": "Transport to Torvus Entrance"},

        {"instance_id": 2097251,
         "origin_location": {"world_asset_id": 1006255871, "area_asset_id": 1287880522},
         "target_location": {"world_asset_id": 2252328306, "area_asset_id": 2399252740},
         "room_name": "Transport to Temple Transport Violet"},

        {"instance_id": 136970379,
         "origin_location": {"world_asset_id": 1006255871, "area_asset_id": 2278776548},
         "target_location": {"world_asset_id": 2252328306,
                             "area_asset_id": 2068511343 if vanilla_gateway else 3619928121},
         "room_name": "Sky Temple Gateway" if vanilla_gateway else "Transport to Sanctum"},

        {"instance_id": 3342446,
         "origin_location": {"world_asset_id": 1006255871, "area_asset_id": 3455543403},
         "target_location": {"world_asset_id": 464164546, "area_asset_id": 3528156989},
         "room_name": "Transport to Sanctuary Entrance"},

        {"instance_id": 3538975,
         "origin_location": {"world_asset_id": 1006255871, "area_asset_id": 1345979968},
         "target_location": {"world_asset_id": 2252328306, "area_asset_id": 408633584},
         "room_name": "Transport to Temple Transport Emerald"},

        {"instance_id": 152,
         "origin_location": {"world_asset_id": 2252328306, "area_asset_id": 408633584},
         "target_location": {"world_asset_id": 1006255871, "area_asset_id": 1345979968},
         "room_name": "Transport to Sanctuary Quadrant"},

        {"instance_id": 393260,
         "origin_location": {"world_asset_id": 2252328306, "area_asset_id": 2556480432},
         "target_location": {"world_asset_id": 1006255871, "area_asset_id": 2918020398},
         "room_name": "Transport to Torvus Quadrant"},

        {"instance_id": 524321,
         "origin_location": {"world_asset_id": 2252328306, "area_asset_id": 2399252740},
         "target_location": {"world_asset_id": 1006255871, "area_asset_id": 1287880522},
         "room_name": "Transport to Agon Quadrant"},

        {"instance_id": 589949,
         "origin_location": {"world_asset_id": 2252328306, "area_asset_id": 2068511343},
         "target_location": {"world_asset_id": 1006255871, "area_asset_id": 2278776548},
         "room_name": "Sky Temple Energy Controller"},

        {"instance_id": 122,
         "origin_location": {"world_asset_id": 1119434212, "area_asset_id": 1473133138},
         "target_location": {"world_asset_id": 1006255871, "area_asset_id": 1660916974},
         "room_name": "Transport to Agon Gate"},

        {"instance_id": 1245307,
         "origin_location": {"world_asset_id": 1119434212, "area_asset_id": 2806956034},
         "target_location": {"world_asset_id": 1039999561, "area_asset_id": 3479543630},
         "room_name": "Transport to Torvus Temple Access"},

        {"instance_id": 2949235,
         "origin_location": {"world_asset_id": 1119434212, "area_asset_id": 3331021649},
         "target_location": {"world_asset_id": 464164546, "area_asset_id": 900285955},
         "room_name": "Transport to Sanctuary Spider side"},

        {"instance_id": 129,
         "origin_location": {"world_asset_id": 1039999561, "area_asset_id": 1868895730},
         "target_location": {"world_asset_id": 1006255871, "area_asset_id": 2889020216},
         "room_name": "Transport to Torvus Gate"},

        {"instance_id": 2162826,
         "origin_location": {"world_asset_id": 1039999561, "area_asset_id": 3479543630},
         "target_location": {"world_asset_id": 1119434212, "area_asset_id": 2806956034},
         "room_name": "Transport to Agon Portal Access"},

        {"instance_id": 4522032,
         "origin_location": {"world_asset_id": 1039999561, "area_asset_id": 3205424168},
         "target_location": {"world_asset_id": 464164546, "area_asset_id": 3145160350},
         "room_name": "Transport to Sanctuary Vault side"},

        {"instance_id": 38,
         "origin_location": {"world_asset_id": 464164546, "area_asset_id": 3528156989},
         "target_location": {"world_asset_id": 1006255871, "area_asset_id": 3455543403},
         "room_name": "Transport to Sanctuary Gate"},

        {"instance_id": 1245332,
         "origin_location": {"world_asset_id": 464164546, "area_asset_id": 900285955},
         "target_location": {"world_asset_id": 1119434212, "area_asset_id": 3331021649},
         "room_name": "Transport to Agon Temple Access"},

        {"instance_id": 1638535,
         "origin_location": {"world_asset_id": 464164546, "area_asset_id": 3145160350},
         "target_location": {"world_asset_id": 1039999561, "area_asset_id": 3205424168},
         "room_name": "Transport to Lower Torvus Access"}
    ]
    assert result == expected