Files
PixelDefense/scripts/extract_entities.py
2023-12-05 11:25:56 +01:00

155 lines
3.6 KiB
Python

#!/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("<breeze.h>")
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()