#!/usr/bin/python """ Utility script that extracts tiles with the same class and outputs C enum and functions for them (so there is no string checking). """ import json import sys import os from collections import defaultdict types = defaultdict(list) path = sys.argv[1] content = open(path).read() tiles = json.loads(content)["tiles"] for tile in tiles: if "type" not in tile: continue id = tile["id"] type = tile["type"] types[type].append(id) enum_type = os.path.basename(path).split(".")[0].capitalize() enum_name = enum_type.upper() if sys.argv[2]: enum_type = sys.argv[2] indent_level = 0 indent_offset = 4 def indent(): return ' ' * indent_level def enum_string(name): return f"{enum_name}_{name.upper()}" # ============================ header_guard = f"{enum_type.capitalize()}_H" print(f"#ifndef {header_guard}") print(f"#define {header_guard}") script_name = os.path.basename(__file__) print(f"// This file was generated by: {script_name}") print() print("#include ") print("#include ") print() print() # ============================ enum_none = enum_string("none") enum_count = enum_string("count") print(f"{indent()}typedef enum {enum_type} {{") indent_level += indent_offset print(f"{indent()}{enum_none},") for enum in types: print(f"{indent()}{enum_string(enum)},") print(f"{indent()}{enum_count}") indent_level -= indent_offset print(f"{indent()}}} {enum_type};") print() print() # ============================ print(f"{indent()}static {enum_type} getTileBuilding(BzTile tile) {{") indent_level += indent_offset print(f"{indent()}switch (tile) {{") for enum, ids in types.items(): indent_level += indent_offset for id in ids: print(f"{indent()}case {id}:") indent_level += indent_offset print(f"{indent()} return {enum_string(enum)};") indent_level -= indent_offset indent_level -= indent_offset indent_level += indent_offset print(f"{indent()}default:") indent_level += indent_offset print(f"{indent()}return {enum_string('none')};") indent_level -= indent_offset indent_level -= indent_offset print(f"{indent()}}}") indent_level -= indent_offset print(f"{indent()}}}") print() # ============================ print(f"{indent()}static BzTile getBuildingTile({enum_type} type) {{") indent_level += indent_offset print(f"{indent()}switch (type) {{") indent_level += indent_offset for type, ids in types.items(): min_id = min(ids) print(f"{indent()}case {enum_string(type)}: return {min_id};") print(f"{indent()}default: return -1;") indent_level -= indent_offset print(f"{indent()}}}") indent_level -= indent_offset print(f"{indent()}}}") print() # ============================ print(f"{indent()}static {enum_type} getBuildingFromStr(const char *str) {{") indent_level += indent_offset # trie would be much better for type in types: print(f"{indent()}if (strncmp(\"{type}\", str, {len(type)}) == 0) return {enum_string(type)};") print(f"{indent()}else return {enum_string('none')};") indent_level -= indent_offset print(f"{indent()}}}") # ============================ print(f"{indent()}static const char *getBuildingStr({enum_type} type) {{") indent_level += indent_offset print(f"{indent()}switch (type) {{") indent_level += indent_offset print(f"{indent()}case {enum_string('none')}: return \"none\";") for type in types: print(f"{indent()}case {enum_string(type)}: return \"{type}\";") print(f"{indent()}default: return NULL;") indent_level -= indent_offset print(f"{indent()}}}") indent_level -= indent_offset print(f"{indent()}}}") print() # ============================ print(f"{indent()}static void getBuildingSize({enum_type} type, BzTile *outWidth, BzTile *outHeight) {{") indent_level += indent_offset print(f"{indent()} switch (type) {{") indent_level += indent_offset for enum, ids in types.items(): print(f"{indent()}case {enum_string(enum)}:") indent_level += indent_offset w = 1 h = 1 for curr, next in zip(ids, ids[1:]): if next > curr + 1: h += 1 elif h == 1: w += 1 print(f"{indent()}if (outWidth) *outWidth = {w};") print(f"{indent()}if (outHeight) *outHeight = {h};") print(f"{indent()}break;") indent_level -= indent_offset print(f"{indent()}default:") indent_level += indent_offset print(f"{indent()}if (outWidth) *outWidth = 0;") print(f"{indent()}if (outHeight) *outHeight = 0;") print(f"{indent()}break;") indent_level -= indent_offset indent_level -= indent_offset print(f"{indent()}}}") indent_level -= indent_offset indent_level -= indent_offset indent_level -= indent_offset print(f"{indent()}}}") print() # ============================ print(f"#endif //{header_guard}")