Skip to content

Minimap Service

This page documents the Minimap service and related DTOs.

DTOs

icecap.services.navigation.minimap.dto

Classes:

  • Minimap

    Data class representing the minimap.

Minimap dataclass

Minimap(maps: dict[int, Map])

Data class representing the minimap.

render

render(map_id: int, position: Position, extent_pixels: int = 0) -> Image

Render a minimap centered at the given position with the specified radius in pixels.

Parameters:

  • map_id
    (int) –

    The ID of the map

  • position
    (Position) –

    The center position (entity position)

  • extent_pixels
    (int, default: 0 ) –

    The extent in pixels (0 for a single tile)

Returns:

  • Image

    A PIL Image of the minimap centered on the position

Source code in icecap/services/navigation/minimap/dto.py
def render(self, map_id: int, position: Position, extent_pixels: int = 0) -> PILImage:
    """
    Render a minimap centered at the given position with the specified radius in pixels.

    Args:
        map_id: The ID of the map
        position: The center position (entity position)
        extent_pixels: The extent in pixels (0 for a single tile)

    Returns:
        A PIL Image of the minimap centered on the position
    """
    map_obj = self.maps.get(map_id)
    if map_obj is None:
        return Image.new(
            "RGBA",
            (2 * extent_pixels, 2 * extent_pixels)
            if extent_pixels > 0
            else (MINIMAP_TILE_SIZE, MINIMAP_TILE_SIZE),
            (0, 0, 0, 0),
        )

    # Convert position to MapPosition
    map_position = MapPosition.from_entity_position(position)

    # Calculate the exact position within the tile
    exact_x = (MAX_MAP_COORDINATE - position.x) / WORLD_TILE_SIZE
    exact_y = (MAX_MAP_COORDINATE - position.y) / WORLD_TILE_SIZE

    # Calculate the pixel offset within the tile
    pixel_offset_x = (exact_x - int(exact_x)) * MINIMAP_TILE_SIZE
    pixel_offset_y = (exact_y - int(exact_y)) * MINIMAP_TILE_SIZE

    if extent_pixels == 0:
        tile = map_obj.tiles.get(map_position)
        if tile is None:
            return Image.new("RGBA", (MINIMAP_TILE_SIZE, MINIMAP_TILE_SIZE), (0, 0, 0, 0))

        return tile.image

    # Calculate how many tiles we need in each direction
    tiles_needed_x = (extent_pixels + pixel_offset_x) // MINIMAP_TILE_SIZE
    tiles_needed_y = (extent_pixels + pixel_offset_y) // MINIMAP_TILE_SIZE
    tiles_needed = int(max(tiles_needed_x, tiles_needed_y))

    # Calculate the size of the temporary image before cropping
    matrix_size = 2 * tiles_needed + 1
    temp_size = int(matrix_size * MINIMAP_TILE_SIZE)
    temp_image = Image.new("RGBA", (temp_size, temp_size), (0, 0, 0, 0))

    for y_offset in range(-tiles_needed, tiles_needed + 1):
        for x_offset in range(-tiles_needed, tiles_needed + 1):
            current_pos = MapPosition(map_position.x + x_offset, map_position.y + y_offset)

            tile = map_obj.tiles.get(current_pos)

            matrix_x = x_offset + tiles_needed
            matrix_y = y_offset + tiles_needed

            pos_x = matrix_x * MINIMAP_TILE_SIZE
            pos_y = matrix_y * MINIMAP_TILE_SIZE

            if tile is not None:
                tile_image = tile.image
                temp_image.paste(tile_image, (pos_x, pos_y), tile_image)

    center_x = tiles_needed * MINIMAP_TILE_SIZE + pixel_offset_x
    center_y = tiles_needed * MINIMAP_TILE_SIZE + pixel_offset_y

    # Calculate the crop box
    left = int(center_x - extent_pixels)
    top = int(center_y - extent_pixels)
    right = int(center_x + extent_pixels)
    bottom = int(center_y + extent_pixels)

    return temp_image.crop((left, top, right, bottom))

Service

icecap.services.navigation.minimap.service

Classes:

  • MinimapService

    Provides tooling to manage and interact with the minimap system in the application.

MinimapService

MinimapService(mpq_reader: MPQFileReader)

Provides tooling to manage and interact with the minimap system in the application.

This class is designed to interact with map-related files to load, parse, and manage minimap data using data from the game's MPQ archive files.

Source code in icecap/services/navigation/minimap/service.py
def __init__(self, mpq_reader: MPQFileReader):
    self.mpq_reader = mpq_reader

    self._md5_translate = self.load_md5_translate()
    self._map_database = self.load_map_database()

get_minimap

get_minimap() -> Minimap

Constructs and returns a minimap containing map tiles for various map records.

Returns:

  • Minimap ( Minimap ) –

    An object containing a collection of maps with their respective tiles.

Source code in icecap/services/navigation/minimap/service.py
def get_minimap(self) -> Minimap:
    """
    Constructs and returns a minimap containing map tiles for various map records.

    Returns:
        Minimap: An object containing a collection of maps with their respective tiles.
    """
    maps: dict[int, Map] = {}
    for record in self._map_database.get_records():
        map_id = getattr(record, "map_id")
        directory = getattr(record, "directory")
        maps[map_id] = Map(map_id=map_id, tiles={})

        for i in range(64):
            for j in range(64):
                texture_path = self.build_minimap_texture_path(directory, i, j)

                if not texture_path:
                    continue

                map_position = MapPosition(x=i, y=j)
                maps[map_id].tiles[map_position] = MapTile(
                    position=map_position, texture_path=texture_path, mpq_reader=self.mpq_reader
                )

    return Minimap(maps=maps)