#!/usr/bin/python """ Utility script that extracts entities tileset with animations """ import json import sys import os from collections import defaultdict from extract_common import * raw_entities = defaultdict(list) entities = defaultdict(list) content = open("../assets/entities.tsj").read() tiles = json.loads(content)["tiles"] for tile in tiles: if "type" not in tile: continue raw_entities[tile["type"]].append(tile) entity_enum_prefix = "ENTITY_" animation_enum_prefix = "ANIM_" entity_enums = {} animations = set() entity_animations = {} def entity_enum(type): return f"{entity_enum_prefix}{type.upper()}" def animation_enum(value): value = value.split("_")[0] return f"{animation_enum_prefix}{value.upper()}" def simple_entity(entity): type = entity["type"] id = entity["id"] entity_enums[entity_enum(type)] = id def animated_entity(entity): simple_entity(entity[0]) entity_name = entity_enum(entity[0]["type"]) cur_animations = defaultdict(list) for frame in entity: assert entity_name == entity_enum(frame["type"]) for prop in frame["properties"]: if prop["name"] != "animation": continue animation_name = animation_enum(prop["value"]) animations.add(animation_name) cur_animations[animation_name].append(frame["id"]) break entity_animations[entity_name] = cur_animations for k, v in raw_entities.items(): num_frames = len(v) if num_frames == 1: simple_entity(v[0]) else: animated_entity(v) writer = ExtractFileWriter("entity_types") writer.header_guard_start() writer.include("") writer.output_line() # ============================ writer.enum_dict("EntityType", entity_enums) writer.enum_list("AnimationType", animations) # ============================ writer.output("typedef struct AnimationSequence {\n") writer.indent() writer.output("i32 startFrame;\n") writer.output("i32 frameCount;\n") writer.unindent() writer.output("} AnimationSequence;\n") writer.output_line() # ============================ # ============================ writer.output("static bool entityHasAnimation(EntityType entity, AnimationType anim) ") writer.block_start() writer.output("switch (entity) ") writer.block_start() for entity, anims in entity_animations.items(): writer.output(f"case {entity}: ") writer.block_start() writer.output("switch (anim) ") writer.block_start() for anim in anims: writer.output(f"case {anim}:") writer.output_line() writer.indent() writer.output("return true;\n") writer.unindent() writer.block_end() writer.output("break;\n") writer.block_end() writer.block_end() writer.output("return false;\n") writer.block_end() writer.output_line() # ============================ writer.output("static AnimationSequence getEntityAnimation(EntityType entity, AnimationType anim) ") writer.block_start() writer.output("switch (entity) ") writer.block_start() for entity, anims in entity_animations.items(): writer.output(f"case {entity}: ") writer.block_start() writer.output("switch (anim) ") writer.block_start() for anim in anims: ids = sorted(anims[anim]) for id0, id1 in zip(ids, ids[1:]): assert id1 - id0 == 1 writer.output(f"case {anim}: return (AnimationSequence) {{{min(ids)}, {len(ids)}}};") writer.output_line() writer.block_end() writer.block_end() writer.block_end() writer.output("BZ_ASSERT(0);\n") writer.block_end() writer.output_line() # ============================ writer.header_guard_stop()