Add named animations
This commit is contained in:
@@ -251,7 +251,7 @@ static AnimationFrame terrainGetAnimationFrame(BzTileID tile, i32 frameIdx) {
|
|||||||
case 4868: return ((AnimationFrame []) {{4868, 100}, {4869, 100}, {4870, 100}, {4871, 100}}) [frameIdx];
|
case 4868: return ((AnimationFrame []) {{4868, 100}, {4869, 100}, {4870, 100}, {4871, 100}}) [frameIdx];
|
||||||
default:
|
default:
|
||||||
BZ_ASSERT(0);
|
BZ_ASSERT(0);
|
||||||
return (AnimationFrame) {0, 0};
|
return (AnimationFrame) {-1, -1.0f};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -312,4 +312,68 @@ static BuildingType getBuildingSize(BuildingType type, BzTileID *outWidth, BzTil
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
typedef enum EntityType {
|
||||||
|
ENTITY_WORKER,
|
||||||
|
ENTITY_COUNT,
|
||||||
|
ENTITY_NONE,
|
||||||
|
} EntityType;
|
||||||
|
|
||||||
|
typedef enum AnimType {
|
||||||
|
ANIM_IDLE,
|
||||||
|
ANIM_WALK,
|
||||||
|
ANIM_HURT,
|
||||||
|
ANIM_DIE,
|
||||||
|
ANIM_COUNT,
|
||||||
|
ANIM_NONE,
|
||||||
|
} AnimType;
|
||||||
|
|
||||||
|
static bool entityHasAnimation(EntityType entity, AnimType type) {
|
||||||
|
switch (entity) {
|
||||||
|
case ENTITY_WORKER:
|
||||||
|
switch (type) {
|
||||||
|
case ANIM_IDLE:
|
||||||
|
case ANIM_WALK:
|
||||||
|
case ANIM_HURT:
|
||||||
|
case ANIM_DIE:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static AnimationSequence entityGetAnimationSequence(EntityType entity, AnimType type) {
|
||||||
|
switch (entity) {
|
||||||
|
case ENTITY_WORKER:
|
||||||
|
switch (type) {
|
||||||
|
case ANIM_IDLE: return (AnimationSequence) {.startFrame = 27, .frameCount = 2};
|
||||||
|
case ANIM_WALK: return (AnimationSequence) {.startFrame = 29, .frameCount = 4};
|
||||||
|
case ANIM_HURT: return (AnimationSequence) {.startFrame = 32, .frameCount = 3};
|
||||||
|
case ANIM_DIE: return (AnimationSequence) {.startFrame = 32, .frameCount = 6};
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
BZ_ASSERT(0);
|
||||||
|
return (AnimationSequence) {0, 0};
|
||||||
|
}
|
||||||
|
|
||||||
|
static AnimationFrame entityGetAnimationFrame(EntityType entity, AnimType type, i32 frameIdx) {
|
||||||
|
switch (entity) {
|
||||||
|
case ENTITY_WORKER:
|
||||||
|
switch (type) {
|
||||||
|
case ANIM_IDLE: return ((AnimationFrame []) {{27, 200}, {28, 200}}) [frameIdx];
|
||||||
|
case ANIM_WALK: return ((AnimationFrame []) {{29, 180}, {30, 180}, {31, 180}, {30, 180}}) [frameIdx];
|
||||||
|
case ANIM_HURT: return ((AnimationFrame []) {{32, 140}, {33, 140}, {34, 140}}) [frameIdx];
|
||||||
|
case ANIM_DIE: return ((AnimationFrame []) {{32, 140}, {33, 140}, {34, 140}, {36, 150}, {35, 130}, {36, 1400}}) [frameIdx];
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
BZ_ASSERT(0);
|
||||||
|
return (AnimationFrame) {-1, -1.0f};
|
||||||
|
}
|
||||||
|
|
||||||
#endif // GAME_TILESET_H
|
#endif // GAME_TILESET_H
|
||||||
|
|||||||
@@ -237,7 +237,8 @@
|
|||||||
"name":"entity",
|
"name":"entity",
|
||||||
"type":"string",
|
"type":"string",
|
||||||
"value":""
|
"value":""
|
||||||
}]
|
}],
|
||||||
|
"type":"worker"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id":28,
|
"id":28,
|
||||||
@@ -246,7 +247,8 @@
|
|||||||
"name":"entity",
|
"name":"entity",
|
||||||
"type":"string",
|
"type":"string",
|
||||||
"value":""
|
"value":""
|
||||||
}]
|
}],
|
||||||
|
"type":"worker"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"animation":[
|
"animation":[
|
||||||
@@ -277,7 +279,8 @@
|
|||||||
"name":"entity",
|
"name":"entity",
|
||||||
"type":"string",
|
"type":"string",
|
||||||
"value":""
|
"value":""
|
||||||
}]
|
}],
|
||||||
|
"type":"worker"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id":30,
|
"id":30,
|
||||||
@@ -286,7 +289,116 @@
|
|||||||
"name":"entity",
|
"name":"entity",
|
||||||
"type":"string",
|
"type":"string",
|
||||||
"value":""
|
"value":""
|
||||||
}]
|
}],
|
||||||
|
"type":"worker"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":31,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"entity",
|
||||||
|
"type":"string",
|
||||||
|
"value":""
|
||||||
|
}],
|
||||||
|
"type":"worker"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"animation":[
|
||||||
|
{
|
||||||
|
"duration":140,
|
||||||
|
"tileid":32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"duration":140,
|
||||||
|
"tileid":33
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"duration":140,
|
||||||
|
"tileid":34
|
||||||
|
}],
|
||||||
|
"id":32,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"animation",
|
||||||
|
"type":"string",
|
||||||
|
"value":"hurt"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"entity",
|
||||||
|
"type":"string",
|
||||||
|
"value":""
|
||||||
|
}],
|
||||||
|
"type":"worker"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":33,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"entity",
|
||||||
|
"type":"string",
|
||||||
|
"value":""
|
||||||
|
}],
|
||||||
|
"type":"worker"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":34,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"entity",
|
||||||
|
"type":"string",
|
||||||
|
"value":""
|
||||||
|
}],
|
||||||
|
"type":"worker"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"animation":[
|
||||||
|
{
|
||||||
|
"duration":140,
|
||||||
|
"tileid":32
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"duration":140,
|
||||||
|
"tileid":33
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"duration":140,
|
||||||
|
"tileid":34
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"duration":150,
|
||||||
|
"tileid":36
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"duration":130,
|
||||||
|
"tileid":35
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"duration":1400,
|
||||||
|
"tileid":36
|
||||||
|
}],
|
||||||
|
"id":35,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"animation",
|
||||||
|
"type":"string",
|
||||||
|
"value":"die"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name":"entity",
|
||||||
|
"type":"string",
|
||||||
|
"value":""
|
||||||
|
}],
|
||||||
|
"type":"worker"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id":36,
|
||||||
|
"properties":[
|
||||||
|
{
|
||||||
|
"name":"entity",
|
||||||
|
"type":"string",
|
||||||
|
"value":""
|
||||||
|
}],
|
||||||
|
"type":"worker"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id":256,
|
"id":256,
|
||||||
|
|||||||
@@ -119,7 +119,7 @@
|
|||||||
<property name="terrain" value=""/>
|
<property name="terrain" value=""/>
|
||||||
</properties>
|
</properties>
|
||||||
</tile>
|
</tile>
|
||||||
<tile id="27">
|
<tile id="27" type="worker">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="animation" value="idle"/>
|
<property name="animation" value="idle"/>
|
||||||
<property name="entity" value=""/>
|
<property name="entity" value=""/>
|
||||||
@@ -129,12 +129,12 @@
|
|||||||
<frame tileid="28" duration="200"/>
|
<frame tileid="28" duration="200"/>
|
||||||
</animation>
|
</animation>
|
||||||
</tile>
|
</tile>
|
||||||
<tile id="28">
|
<tile id="28" type="worker">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="entity" value=""/>
|
<property name="entity" value=""/>
|
||||||
</properties>
|
</properties>
|
||||||
</tile>
|
</tile>
|
||||||
<tile id="29">
|
<tile id="29" type="worker">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="animation" value="walk"/>
|
<property name="animation" value="walk"/>
|
||||||
<property name="entity" value=""/>
|
<property name="entity" value=""/>
|
||||||
@@ -146,14 +146,20 @@
|
|||||||
<frame tileid="30" duration="180"/>
|
<frame tileid="30" duration="180"/>
|
||||||
</animation>
|
</animation>
|
||||||
</tile>
|
</tile>
|
||||||
<tile id="30">
|
<tile id="30" type="worker">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="entity" value=""/>
|
<property name="entity" value=""/>
|
||||||
</properties>
|
</properties>
|
||||||
</tile>
|
</tile>
|
||||||
<tile id="32">
|
<tile id="31" type="worker">
|
||||||
|
<properties>
|
||||||
|
<property name="entity" value=""/>
|
||||||
|
</properties>
|
||||||
|
</tile>
|
||||||
|
<tile id="32" type="worker">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="animation" value="hurt"/>
|
<property name="animation" value="hurt"/>
|
||||||
|
<property name="entity" value=""/>
|
||||||
</properties>
|
</properties>
|
||||||
<animation>
|
<animation>
|
||||||
<frame tileid="32" duration="140"/>
|
<frame tileid="32" duration="140"/>
|
||||||
@@ -161,7 +167,21 @@
|
|||||||
<frame tileid="34" duration="140"/>
|
<frame tileid="34" duration="140"/>
|
||||||
</animation>
|
</animation>
|
||||||
</tile>
|
</tile>
|
||||||
<tile id="35">
|
<tile id="33" type="worker">
|
||||||
|
<properties>
|
||||||
|
<property name="entity" value=""/>
|
||||||
|
</properties>
|
||||||
|
</tile>
|
||||||
|
<tile id="34" type="worker">
|
||||||
|
<properties>
|
||||||
|
<property name="entity" value=""/>
|
||||||
|
</properties>
|
||||||
|
</tile>
|
||||||
|
<tile id="35" type="worker">
|
||||||
|
<properties>
|
||||||
|
<property name="animation" value="die"/>
|
||||||
|
<property name="entity" value=""/>
|
||||||
|
</properties>
|
||||||
<animation>
|
<animation>
|
||||||
<frame tileid="32" duration="140"/>
|
<frame tileid="32" duration="140"/>
|
||||||
<frame tileid="33" duration="140"/>
|
<frame tileid="33" duration="140"/>
|
||||||
@@ -171,6 +191,11 @@
|
|||||||
<frame tileid="36" duration="1400"/>
|
<frame tileid="36" duration="1400"/>
|
||||||
</animation>
|
</animation>
|
||||||
</tile>
|
</tile>
|
||||||
|
<tile id="36" type="worker">
|
||||||
|
<properties>
|
||||||
|
<property name="entity" value=""/>
|
||||||
|
</properties>
|
||||||
|
</tile>
|
||||||
<tile id="256">
|
<tile id="256">
|
||||||
<properties>
|
<properties>
|
||||||
<property name="terrain" value=""/>
|
<property name="terrain" value=""/>
|
||||||
|
|||||||
@@ -115,9 +115,6 @@ class EnumWriter:
|
|||||||
def to_enum(self, name):
|
def to_enum(self, name):
|
||||||
return f"{self.prefix.upper()}_{name.upper()}"
|
return f"{self.prefix.upper()}_{name.upper()}"
|
||||||
|
|
||||||
def to_anim_enum(self, name):
|
|
||||||
return f"ANIM_{name.upper()}"
|
|
||||||
|
|
||||||
def output_enum(self):
|
def output_enum(self):
|
||||||
self.writer.enum_list(self.enum_type, self.enums)
|
self.writer.enum_list(self.enum_type, self.enums)
|
||||||
|
|
||||||
@@ -288,8 +285,146 @@ class EnumWriter:
|
|||||||
writer.output("default:\n")
|
writer.output("default:\n")
|
||||||
writer.indent()
|
writer.indent()
|
||||||
writer.output("BZ_ASSERT(0);\n")
|
writer.output("BZ_ASSERT(0);\n")
|
||||||
writer.output("return (AnimationFrame) {0, 0};\n")
|
writer.output("return (AnimationFrame) {-1, -1.0f};\n")
|
||||||
writer.unindent()
|
writer.unindent()
|
||||||
writer.block_end()
|
writer.block_end()
|
||||||
writer.block_end()
|
writer.block_end()
|
||||||
writer.empty_line()
|
writer.empty_line()
|
||||||
|
|
||||||
|
|
||||||
|
class AnimationWriter(EnumWriter):
|
||||||
|
def __init__(self, writer: ExtractFileWriter, class_prefix, anim_prefix, tiles):
|
||||||
|
super().__init__(writer, class_prefix, tiles)
|
||||||
|
self.writer = writer
|
||||||
|
self.anim_prefix = anim_prefix
|
||||||
|
self.anim_type = f"{anim_prefix.capitalize()}Type"
|
||||||
|
self.anim_map = defaultdict(lambda: defaultdict(list))
|
||||||
|
self.animations = []
|
||||||
|
self.all_tiles = tiles
|
||||||
|
|
||||||
|
animations = []
|
||||||
|
|
||||||
|
for tile in self.all_tiles:
|
||||||
|
if 'animation' not in tile:
|
||||||
|
continue
|
||||||
|
if 'properties' not in tile:
|
||||||
|
continue
|
||||||
|
if 'type' not in tile:
|
||||||
|
continue
|
||||||
|
|
||||||
|
enum = self.to_enum(tile['type'])
|
||||||
|
props = tile['properties']
|
||||||
|
anim_type = [prop['value'] for prop in props if prop['name'] == 'animation'][0]
|
||||||
|
anim_type = self.to_anim_enum(anim_type)
|
||||||
|
animations.append(anim_type)
|
||||||
|
|
||||||
|
self.anim_map[enum][anim_type] = tile['animation']
|
||||||
|
|
||||||
|
animations.append(self.to_anim_enum("count"))
|
||||||
|
animations.append(self.to_anim_enum("none"))
|
||||||
|
anim_seen = set()
|
||||||
|
anim_add = anim_seen.add
|
||||||
|
self.animations = [x for x in animations if not (x in anim_seen or anim_add(x))]
|
||||||
|
|
||||||
|
def to_anim_enum(self, name):
|
||||||
|
return f"{self.anim_prefix.upper()}_{name.upper()}"
|
||||||
|
|
||||||
|
def output_anim_enum(self):
|
||||||
|
writer = self.writer
|
||||||
|
writer.enum_list(self.anim_type, self.animations)
|
||||||
|
pass
|
||||||
|
|
||||||
|
def output_has_anim(self, func_name):
|
||||||
|
writer = self.writer
|
||||||
|
writer.output(f"static bool {func_name}({self.enum_type} entity, {self.anim_type} type) ")
|
||||||
|
writer.block_start()
|
||||||
|
|
||||||
|
writer.output("switch (entity) ")
|
||||||
|
writer.block_start()
|
||||||
|
for entity, anims in self.anim_map.items():
|
||||||
|
writer.output(f"case {entity}:\n")
|
||||||
|
writer.indent()
|
||||||
|
writer.output("switch (type) ")
|
||||||
|
writer.block_start()
|
||||||
|
|
||||||
|
for anim in anims:
|
||||||
|
writer.output(f"case {anim}:\n")
|
||||||
|
writer.indent()
|
||||||
|
writer.output("return true;\n")
|
||||||
|
writer.unindent()
|
||||||
|
writer.output("default:\n")
|
||||||
|
writer.indent()
|
||||||
|
writer.output("return false;\n")
|
||||||
|
writer.unindent()
|
||||||
|
|
||||||
|
writer.block_end()
|
||||||
|
writer.unindent()
|
||||||
|
writer.output("default:\n")
|
||||||
|
writer.indent()
|
||||||
|
writer.output("return false;\n")
|
||||||
|
writer.unindent()
|
||||||
|
|
||||||
|
writer.block_end()
|
||||||
|
writer.block_end()
|
||||||
|
writer.empty_line()
|
||||||
|
|
||||||
|
def output_anim_sequence(self, func_name):
|
||||||
|
writer = self.writer
|
||||||
|
writer.output(f"static AnimationSequence {func_name}({self.enum_type} entity, {self.anim_type} type) ")
|
||||||
|
writer.block_start()
|
||||||
|
|
||||||
|
writer.output("switch (entity) ")
|
||||||
|
writer.block_start()
|
||||||
|
for entity, animation_types in self.anim_map.items():
|
||||||
|
writer.output(f"case {entity}:\n")
|
||||||
|
writer.indent()
|
||||||
|
writer.output("switch (type) ")
|
||||||
|
writer.block_start()
|
||||||
|
for anim_type in animation_types:
|
||||||
|
anim = self.anim_map[entity][anim_type]
|
||||||
|
num_frames = len(anim)
|
||||||
|
anim_id = anim[0]['tileid']
|
||||||
|
ret = f"(AnimationSequence) {{.startFrame = {anim_id}, .frameCount = {num_frames}}}"
|
||||||
|
writer.output(f"case {anim_type}: return {ret};\n")
|
||||||
|
writer.output("default: break;\n")
|
||||||
|
writer.block_end()
|
||||||
|
writer.unindent()
|
||||||
|
writer.output("default: break;\n")
|
||||||
|
writer.block_end()
|
||||||
|
|
||||||
|
writer.output("BZ_ASSERT(0);\n")
|
||||||
|
writer.output("return (AnimationSequence) {0, 0};\n")
|
||||||
|
writer.block_end()
|
||||||
|
writer.empty_line()
|
||||||
|
|
||||||
|
def output_anim_frame(self, func_name):
|
||||||
|
writer = self.writer
|
||||||
|
writer.output(
|
||||||
|
f"static AnimationFrame {func_name}({self.enum_type} entity, {self.anim_type} type, i32 frameIdx) ")
|
||||||
|
writer.block_start()
|
||||||
|
|
||||||
|
writer.output("switch (entity) ")
|
||||||
|
writer.block_start()
|
||||||
|
for entity, animation_types in self.anim_map.items():
|
||||||
|
writer.output(f"case {entity}:\n")
|
||||||
|
writer.indent()
|
||||||
|
writer.output("switch (type) ")
|
||||||
|
writer.block_start()
|
||||||
|
for anim_type in animation_types:
|
||||||
|
anim = self.anim_map[entity][anim_type]
|
||||||
|
frames = [str(x['tileid']) for x in anim]
|
||||||
|
durations = [str(x['duration']) for x in anim]
|
||||||
|
|
||||||
|
anim_frames = [f"{{{frame}, {duration}}}" for frame, duration in zip(frames, durations)]
|
||||||
|
ret = f"((AnimationFrame []) {{{', '.join(anim_frames)}}}) [frameIdx]"
|
||||||
|
writer.output(f"case {anim_type}: return {ret};\n")
|
||||||
|
writer.output("default: break;\n")
|
||||||
|
writer.block_end()
|
||||||
|
writer.unindent()
|
||||||
|
writer.output("default: break;\n")
|
||||||
|
writer.block_end()
|
||||||
|
|
||||||
|
writer.output("BZ_ASSERT(0);\n")
|
||||||
|
writer.output("return (AnimationFrame) {-1, -1.0f};\n")
|
||||||
|
writer.block_end()
|
||||||
|
writer.empty_line()
|
||||||
|
|||||||
@@ -52,6 +52,14 @@ building_writer.output_enum_to_str("getBuildingStr")
|
|||||||
building_writer.output_enum_tile_size("getBuildingSize")
|
building_writer.output_enum_tile_size("getBuildingSize")
|
||||||
writer.empty_line()
|
writer.empty_line()
|
||||||
|
|
||||||
|
anim_writer = AnimationWriter(writer, "entity", "anim", entity_tiles)
|
||||||
|
|
||||||
|
anim_writer.output_enum()
|
||||||
|
anim_writer.output_anim_enum()
|
||||||
|
anim_writer.output_has_anim("entityHasAnimation")
|
||||||
|
anim_writer.output_anim_sequence("entityGetAnimationSequence")
|
||||||
|
anim_writer.output_anim_frame("entityGetAnimationFrame")
|
||||||
|
|
||||||
writer.header_guard_stop()
|
writer.header_guard_stop()
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user