""" map_headers[0].tileset == 'OVERWORLD' map_headers[0].name1 = 'PalletTown' map_headers[0].name2 = 'PALLET_TOWN' map_headers[0].blocks() == 'PalletTown_Blocks' map_constants_list['PALLET_TOWN'] == MapConstant(10, 19) maps_blocks_list['PalletTown_Blocks'] == 'maps/PalletTown.blk' tileset_constants_list['OVERWORLD'] == 0 tileset_headers_list[0].name == 'Overworld' tileset_headers_list[0].blockset() == 'Overworld_Block' tileset_headers_list[0].gfx() == 'Overworld_GFX' gfx_tilesets_list['Overworld_Block'] == 'gfx/blocksets/overworld.bst' gfx_tilesets_list['Overworld_GFX'] == 'gfx/tilesets/overworld.2bpp' """ from parse import parse from generate.sort import default_sort from generate.binary import binary_res, start_size_value from generate.generate import renderer from parse.map_header import Connection directions = sorted(['north', 'south', 'east', 'west']) def sorted_map_constants_list(): return sorted(parse.map_constants_list.items(), key=default_sort) def sorted_map_headers(): map_constants_list = sorted_map_constants_list() map_headers_dict = dict((map_header.name2, map_header) for map_header in parse.map_headers) # hack to remove unused/duplicate underground_path_route_7 #map_headers = sorted(parse.map_headers, key=lambda m: m.name2) #return filter(lambda m: m.name1 != "UndergroundPathRoute7Copy", map_headers) return ( map_headers_dict[map_name2] for map_name2, _ in map_constants_list if map_name2 in map_headers_dict # e.g CERULEAN_TRASHED_HOUSE_COPY has no map header ) def includes_header(): yield "#pragma once" yield "" yield '#include "../start_size.hpp"' yield '#include "tilesets.hpp"' yield "" for map_header in sorted_map_headers(): block_path = parse.maps_blocks_list[map_header.blocks()] yield f'#include "../res/{block_path}.h"' yield "" def struct_map_t(): _sorted_map_headers = list(sorted_map_headers()) map_names = ( f"{map_header.name2.lower()}," for map_header in _sorted_map_headers ) return [ "struct map_t {", "enum map {", *map_names, "last_map, // special map name", "unused_map_ed, // special silph co elevator map name", "unconnected, // special unconnected map", "};", "", *struct_connection_t(), "", "start_size_t blocks;", "uint32_t width;", "uint32_t height;", "connection_t connections[4];", "enum tileset_t::tileset tileset;", "enum map id;", "", f"static constexpr int32_t count = {len(_sorted_map_headers)};", "};", ] def struct_connection_t(): return [ "struct connection_t {", "enum map_t::map map;", "int8_t offset;", "", "enum direction {", *(f"{d}," for d in directions), "};", "};", ] def connections(map_header): cs = dict((c.name, c) for c in map_header.connections) assert len(cs) == len(map_header.connections), map_header.connections unconnected = Connection( name = "__invalid", map_name1 = "Unconnected", map_name2 = "unconnected", offset = 0, ) for direction in directions: # already sorted connection = cs.get(direction, unconnected) yield f"[map_t::connection_t::{direction}] = {{" yield f".map = map_t::{connection.map_name2.lower()}," yield f".offset = {connection.offset}," yield "}," def map(map_header): block_path = parse.maps_blocks_list[map_header.blocks()] map_constant = parse.map_constants_list[map_header.name2] return [ f"[map_t::{map_header.name2.lower()}] = {{", ".blocks = {", *start_size_value(block_path), "},", f".width = {map_constant.width},", f".height = {map_constant.height},", ".connections = {", *connections(map_header), "},", f".tileset = tileset_t::{map_header.tileset.lower()},", f".id = map_t::{map_header.name2.lower()},", "},", ] def extern_maps(): yield "extern const map_t maps[];" def maps(): yield "const map_t maps[] = {" for map_header in sorted_map_headers(): yield from map(map_header) yield "};" def generate_header(): render, out = renderer() render(includes_header()) render(struct_map_t()) render(extern_maps()); return out def includes_source(): yield '#include ' yield '' yield '#include "maps.hpp"' yield '' def generate_source(): render, out = renderer() render(includes_source()) render(maps()) return out