Anim pointer -> enum, so can be serialized

main
parent 029ef591a6
commit 631c7d4aa7

@ -62,9 +62,9 @@
{ {
filepath: "hurt_vignette.png", filepath: "hurt_vignette.png",
} }
@image dialog_circle: @image hovering_circle:
{ {
filepath: "dialog_circle.png", filepath: "hovering_circle.png",
} }
@image white_square: @image white_square:
{ {

Before

Width:  |  Height:  |  Size: 11 KiB

After

Width:  |  Height:  |  Size: 11 KiB

@ -3,6 +3,9 @@
#define ARRLEN(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x]))))) #define ARRLEN(x) ((sizeof(x)/sizeof(0[x])) / ((size_t)(!(sizeof(x) % sizeof(0[x])))))
#define ARR_ITER(type, arr) for(type *it = &arr[0]; it < &arr[ARRLEN(arr)]; it++) #define ARR_ITER(type, arr) for(type *it = &arr[0]; it < &arr[ARRLEN(arr)]; it++)
#define ARR_ITER_I(type, arr, i_var) ARR_ITER(type, arr) for(int i_var = (int)(it - &arr[0]); i_var != -1; i_var = -1) #define ARR_ITER_I(type, arr, i_var) ARR_ITER(type, arr) for(int i_var = (int)(it - &arr[0]); i_var != -1; i_var = -1)
#define GET_TABLE(table, index) (assert(index < ARRLEN(table) && index >= 0), table[index])
// you can't do &(some func, variable) to get the variable's address in C. Sad!
#define GET_TABLE_PTR(table, index) (assert(index < ARRLEN(table) && index >= 0), &table[index])
// null terminator always built into buffers so can read properly from data // null terminator always built into buffers so can read properly from data
#define BUFF_VALID(buff_ptr) assert((buff_ptr)->cur_index <= ARRLEN((buff_ptr)->data)) #define BUFF_VALID(buff_ptr) assert((buff_ptr)->cur_index <= ARRLEN((buff_ptr)->data))
@ -15,3 +18,5 @@
#define BUFF_PUSH_FRONT(buff_ptr, value) { (buff_ptr)->cur_index++; BUFF_VALID(buff_ptr); for(int i = (buff_ptr)->cur_index - 1; i > 0; i--) { (buff_ptr)->data[i] = (buff_ptr)->data[i - 1]; }; (buff_ptr)->data[0] = value; } #define BUFF_PUSH_FRONT(buff_ptr, value) { (buff_ptr)->cur_index++; BUFF_VALID(buff_ptr); for(int i = (buff_ptr)->cur_index - 1; i > 0; i--) { (buff_ptr)->data[i] = (buff_ptr)->data[i - 1]; }; (buff_ptr)->data[0] = value; }
#define BUFF_REMOVE_FRONT(buff_ptr) {if((buff_ptr)->cur_index > 0) {for(int i = 0; i < (buff_ptr)->cur_index - 1; i++) { (buff_ptr)->data[i] = (buff_ptr)->data[i+1]; }; (buff_ptr)->cur_index--;}} #define BUFF_REMOVE_FRONT(buff_ptr) {if((buff_ptr)->cur_index > 0) {for(int i = 0; i < (buff_ptr)->cur_index - 1; i++) { (buff_ptr)->data[i] = (buff_ptr)->data[i+1]; }; (buff_ptr)->cur_index--;}}
#define BUFF_CLEAR(buff_ptr) {memset((buff_ptr), 0, sizeof(*(buff_ptr))); ((buff_ptr)->cur_index = 0);} #define BUFF_CLEAR(buff_ptr) {memset((buff_ptr), 0, sizeof(*(buff_ptr))); ((buff_ptr)->cur_index = 0);}

@ -1,5 +1,7 @@
#pragma once #pragma once
#include "HandmadeMath.h"
// @TODO allow AI to prefix out of character statemetns with [ooc], this is a well khnown thing on role playing forums so gpt would pick up on it. // @TODO allow AI to prefix out of character statemetns with [ooc], this is a well khnown thing on role playing forums so gpt would pick up on it.
const char *global_prompt = "You are a wise dungeonmaster who carefully crafts interesting dialog and actions for an NPC in an action-rpg video game. It is critical that you always respond in the format shown below, where you respond like `ACT_action \"This is my response\", even if the player says something vulgar or offensive, as the text is parsed by a program which expects it to look like that. Do not ever refer to yourself as an NPC or show an understanding of the modern world outside the game, always stay in character."; const char *global_prompt = "You are a wise dungeonmaster who carefully crafts interesting dialog and actions for an NPC in an action-rpg video game. It is critical that you always respond in the format shown below, where you respond like `ACT_action \"This is my response\", even if the player says something vulgar or offensive, as the text is parsed by a program which expects it to look like that. Do not ever refer to yourself as an NPC or show an understanding of the modern world outside the game, always stay in character.";
@ -137,3 +139,130 @@ CharacterGen characters[] = {
"The NPC you will be acting as is named Death. He is leading a crusade against the town of Worchen, wreaking havock among the villagers. He believes that all things, even villages, must die, to be replaced by the new, and avoid becoming stagnant.", "The NPC you will be acting as is named Death. He is leading a crusade against the town of Worchen, wreaking havock among the villagers. He believes that all things, even villages, must die, to be replaced by the new, and avoid becoming stagnant.",
}, },
}; };
typedef struct
{
const char *img_var_name;
const char *enum_name;
double time_per_frame;
int num_frames;
Vec2 start;
Vec2 offset;
float horizontal_diff_btwn_frames;
Vec2 region_size;
bool no_wrap; // does not wrap when playing
} AnimatedSprite;
AnimatedSprite sprites[] = {
{.enum_name = "invalid", .img_var_name = "image_white_square"},
{
.enum_name = "knight_idle",
.img_var_name = "image_new_knight_idle",
.time_per_frame = 0.4,
.num_frames = 6,
.start = {0.0f, 0.0f},
.horizontal_diff_btwn_frames = 64.0,
.region_size = {64.0f, 64.0f},
},
{
.enum_name = "knight_running",
.img_var_name = "image_new_knight_run",
.time_per_frame = 0.1,
.num_frames = 7,
.start = {64.0f*10, 0.0f},
.horizontal_diff_btwn_frames = 64.0,
.region_size = {64.0f, 64.0f},
},
{
.enum_name = "knight_rolling",
.img_var_name = "image_knight_roll",
.time_per_frame = 0.04,
.num_frames = 12,
.start = {19.0f, 0.0f},
.horizontal_diff_btwn_frames = 120.0,
.region_size = {80.0f, 80.0f},
.no_wrap = true,
},
{
.enum_name = "knight_attack",
.img_var_name = "image_new_knight_attack",
.time_per_frame = 0.06,
.num_frames = 7,
.start = {0.0f, 0.0f},
.horizontal_diff_btwn_frames = 64.0,
.region_size = {64.0f, 64.0f},
.no_wrap = true,
},
{
.enum_name = "old_man_idle",
.img_var_name = "image_old_man",
.time_per_frame = 0.4,
.num_frames = 4,
.start = {0.0, 0.0},
.horizontal_diff_btwn_frames = 16.0f,
.region_size = {16.0f, 16.0f},
},
{
.enum_name = "death_idle",
.img_var_name = "image_death",
.time_per_frame = 0.15,
.num_frames = 10,
.start = {0.0, 0.0},
.horizontal_diff_btwn_frames = 100.0f,
.region_size = {100.0f, 100.0f},
},
{
.enum_name = "skeleton_idle",
.img_var_name = "image_skeleton",
.time_per_frame = 0.15,
.num_frames = 6,
.start = {0.0f, 0.0f},
.horizontal_diff_btwn_frames = 80.0,
.offset = {0.0f, 20.0f},
.region_size = {80.0f, 80.0f},
},
{
.enum_name = "skeleton_swing_sword",
.img_var_name = "image_skeleton",
.time_per_frame = 0.10,
.num_frames = 6,
.start = {0.0f, 240.0f},
.horizontal_diff_btwn_frames = 80.0,
.offset = {0.0f, 20.0f},
.region_size = {80.0f, 80.0f},
.no_wrap = true,
},
{
.enum_name = "skeleton_run",
.img_var_name = "image_skeleton",
.time_per_frame = 0.07,
.num_frames = 8,
.start = {0.0f, 160.0f},
.horizontal_diff_btwn_frames = 80.0,
.offset = {0.0f, 20.0f},
.region_size = {80.0f, 80.0f},
},
{
.enum_name = "skeleton_die",
.img_var_name = "image_skeleton",
.time_per_frame = 0.10,
.num_frames = 13,
.start = {0.0f, 400.0f},
.horizontal_diff_btwn_frames = 80.0,
.offset = {0.0f, 20.0f},
.region_size = {80.0f, 80.0f},
.no_wrap = true,
},
{
.enum_name = "merchant_idle",
.img_var_name = "image_merchant",
.time_per_frame = 0.15,
.num_frames = 8,
.start = {0.0, 0.0},
.horizontal_diff_btwn_frames = 110.0f,
.region_size = {110.0f, 110.0f},
.offset = {0.0f, -20.0f},
},
};

@ -130,8 +130,9 @@ int main(int argc, char **argv)
#define GEN_ENUM(arr_elem_type, arr, enum_type_name, enum_name_access, fmt_str) { fprintf(char_header, "typedef enum\n{\n"); ARR_ITER(arr_elem_type, arr) fprintf(char_header, fmt_str, enum_name_access); fprintf(char_header, "} %s;\n", enum_type_name); GEN_TABLE(arr_elem_type, enum_type_name "_names", arr, enum_name_access); } #define GEN_ENUM(arr_elem_type, arr, enum_type_name, enum_name_access, fmt_str) { fprintf(char_header, "typedef enum\n{\n"); ARR_ITER(arr_elem_type, arr) fprintf(char_header, fmt_str, enum_name_access); fprintf(char_header, "} %s;\n", enum_type_name); GEN_TABLE(arr_elem_type, enum_type_name "_names", arr, enum_name_access); }
GEN_ENUM(char *, actions, "Action", *it, "ACT_%s,\n"); GEN_ENUM(char *, actions, "Action", *it, "ACT_%s,\n");
GEN_ENUM(ItemInfo, items, "ItemKind", it->enum_name, "ITEM_%s,\n"); GEN_ENUM(ItemInfo, items, "ItemKind", it->enum_name, "ITEM_%s,\n");
GEN_ENUM(AnimatedSprite, sprites, "AnimKind", it->enum_name, "ANIM_%s,\n");
// escape multiline strings in C
fprintf(char_header, "typedef enum\n{\n"); fprintf(char_header, "typedef enum\n{\n");
ARR_ITER(CharacterGen, characters) ARR_ITER(CharacterGen, characters)
{ {
@ -320,6 +321,13 @@ int main(int argc, char **argv)
fprintf(output, "TileSet tilesets[] = { %.*s\n };\n", MD_S8VArg(MD_S8ListJoin(cg_arena, tileset_decls, &join))); fprintf(output, "TileSet tilesets[] = { %.*s\n };\n", MD_S8VArg(MD_S8ListJoin(cg_arena, tileset_decls, &join)));
fprintf(output, "sg_image * anim_img_table[] = {\n");
ARR_ITER(AnimatedSprite, sprites)
{
fprintf(output, "&%s,\n", it->img_var_name);
}
fprintf(output, "}; // anim_img_table \n");
fclose(output); fclose(output);
return 0; return 0;

180
main.c

@ -128,18 +128,6 @@ typedef struct TileSet
AnimatedTile animated[128]; AnimatedTile animated[128];
} TileSet; } TileSet;
typedef struct AnimatedSprite
{
sg_image *img;
double time_per_frame;
int num_frames;
Vec2 start;
Vec2 offset;
float horizontal_diff_btwn_frames;
Vec2 region_size;
bool no_wrap; // does not wrap when playing
} AnimatedSprite;
#ifdef DEVTOOLS #ifdef DEVTOOLS
#define SERVER_URL "http://localhost:8090" #define SERVER_URL "http://localhost:8090"
#else #else
@ -551,8 +539,8 @@ sg_image load_image(const char *path)
return to_return; return to_return;
} }
#include "quad-sapp.glsl.h"
#include "assets.gen.c" #include "assets.gen.c"
#include "quad-sapp.glsl.h"
AABB level_aabb = { .upper_left = {0.0f, 0.0f}, .lower_right = {TILE_SIZE * LEVEL_TILES, -(TILE_SIZE * LEVEL_TILES)} }; AABB level_aabb = { .upper_left = {0.0f, 0.0f}, .lower_right = {TILE_SIZE * LEVEL_TILES, -(TILE_SIZE * LEVEL_TILES)} };
typedef struct GameState { typedef struct GameState {
@ -709,120 +697,6 @@ void end_text_input(char *what_player_said)
process_perception(talking, (Perception){.type = PlayerDialog, .player_dialog = what_player_said_sentence,}); process_perception(talking, (Perception){.type = PlayerDialog, .player_dialog = what_player_said_sentence,});
} }
} }
AnimatedSprite knight_idle =
{
.img = &image_new_knight_idle,
.time_per_frame = 0.4,
.num_frames = 6,
.start = {0.0f, 0.0f},
.horizontal_diff_btwn_frames = 64.0,
.region_size = {64.0f, 64.0f},
};
AnimatedSprite knight_running =
{
.img = &image_new_knight_run,
.time_per_frame = 0.1,
.num_frames = 7,
.start = {64.0f*10, 0.0f},
.horizontal_diff_btwn_frames = 64.0,
.region_size = {64.0f, 64.0f},
};
AnimatedSprite knight_rolling =
{
.img = &image_knight_roll,
.time_per_frame = 0.04,
.num_frames = 12,
.start = {19.0f, 0.0f},
.horizontal_diff_btwn_frames = 120.0,
.region_size = {80.0f, 80.0f},
.no_wrap = true,
};
AnimatedSprite knight_attack =
{
.img = &image_new_knight_attack,
.time_per_frame = 0.06,
.num_frames = 7,
.start = {0.0f, 0.0f},
.horizontal_diff_btwn_frames = 64.0,
.region_size = {64.0f, 64.0f},
.no_wrap = true,
};
AnimatedSprite old_man_idle =
{
.img = &image_old_man,
.time_per_frame = 0.4,
.num_frames = 4,
.start = {0.0, 0.0},
.horizontal_diff_btwn_frames = 16.0f,
.region_size = {16.0f, 16.0f},
};
AnimatedSprite death_idle =
{
.img = &image_death,
.time_per_frame = 0.15,
.num_frames = 10,
.start = {0.0, 0.0},
.horizontal_diff_btwn_frames = 100.0f,
.region_size = {100.0f, 100.0f},
};
AnimatedSprite skeleton_idle =
{
.img = &image_skeleton,
.time_per_frame = 0.15,
.num_frames = 6,
.start = {0.0f, 0.0f},
.horizontal_diff_btwn_frames = 80.0,
.offset = {0.0f, 20.0f},
.region_size = {80.0f, 80.0f},
};
AnimatedSprite skeleton_swing_sword =
{
.img = &image_skeleton,
.time_per_frame = 0.10,
.num_frames = 6,
.start = {0.0f, 240.0f},
.horizontal_diff_btwn_frames = 80.0,
.offset = {0.0f, 20.0f},
.region_size = {80.0f, 80.0f},
.no_wrap = true,
};
AnimatedSprite skeleton_run =
{
.img = &image_skeleton,
.time_per_frame = 0.07,
.num_frames = 8,
.start = {0.0f, 160.0f},
.horizontal_diff_btwn_frames = 80.0,
.offset = {0.0f, 20.0f},
.region_size = {80.0f, 80.0f},
};
AnimatedSprite skeleton_die =
{
.img = &image_skeleton,
.time_per_frame = 0.10,
.num_frames = 13,
.start = {0.0f, 400.0f},
.horizontal_diff_btwn_frames = 80.0,
.offset = {0.0f, 20.0f},
.region_size = {80.0f, 80.0f},
.no_wrap = true,
};
AnimatedSprite merchant_idle =
{
.img = &image_merchant,
.time_per_frame = 0.15,
.num_frames = 8,
.start = {0.0, 0.0},
.horizontal_diff_btwn_frames = 110.0f,
.region_size = {110.0f, 110.0f},
.offset = {0.0f, -20.0f},
};
/* /*
AnimatedSprite moose_idle = AnimatedSprite moose_idle =
{ {
@ -1564,14 +1438,12 @@ void swap(Vec2 *p1, Vec2 *p2)
*p2 = tmp; *p2 = tmp;
} }
double anim_sprite_duration(AnimatedSprite *s) double anim_sprite_duration(AnimKind anim)
{ {
AnimatedSprite *s = GET_TABLE_PTR(sprites, anim);
return s->num_frames * s->time_per_frame; return s->num_frames * s->time_per_frame;
} }
Vec2 tile_id_to_coord(sg_image tileset_image, Vec2 tile_size, uint16_t tile_id) Vec2 tile_id_to_coord(sg_image tileset_image, Vec2 tile_size, uint16_t tile_id)
{ {
int tiles_per_row = (int)(img_size(tileset_image).X / tile_size.X); int tiles_per_row = (int)(img_size(tileset_image).X / tile_size.X);
@ -1850,15 +1722,14 @@ void draw_shadow_for(DrawParams d)
draw_quad(d); draw_quad(d);
} }
//void draw_animated_sprite(AnimatedSprite *s, double elapsed_time, bool flipped, Vec2 pos, Color tint) //void draw_animated_sprite(AnimatedSprite *s, double elapsed_time, bool flipped, Vec2 pos, Color tint)
void draw_animated_sprite(DrawnAnimatedSprite d) void draw_animated_sprite(DrawnAnimatedSprite d)
{ {
AnimatedSprite *s = d.anim; AnimatedSprite *s = GET_TABLE_PTR(sprites, d.anim);
sg_image spritesheet_img = *GET_TABLE(anim_img_table, d.anim);
float y_sort_pos = y_coord_sorting_at(d.pos); float y_sort_pos = y_coord_sorting_at(d.pos);
d.pos = AddV2(d.pos, s->offset); d.pos = AddV2(d.pos, s->offset);
sg_image spritesheet_img = *s->img;
int index = (int)floor(d.elapsed_time/s->time_per_frame) % s->num_frames; int index = (int)floor(d.elapsed_time/s->time_per_frame) % s->num_frames;
if(s->no_wrap) if(s->no_wrap)
{ {
@ -2454,7 +2325,9 @@ void frame(void)
assert(player != NULL); assert(player != NULL);
// gameplay processing loop, do multiple if lagging // gameplay processing loop, do multiple if lagging
// these are static so that, on frames where no gameplay processing is necessary and just rendering, the rendering uses values from last frame
static Entity *interacting_with = 0; // used by rendering to figure out who to draw dialog box on static Entity *interacting_with = 0; // used by rendering to figure out who to draw dialog box on
static bool player_in_combat = false;
const float dialog_interact_size = 2.5f * TILE_SIZE; const float dialog_interact_size = 2.5f * TILE_SIZE;
int num_timestep_loops = 0; int num_timestep_loops = 0;
{ {
@ -2467,6 +2340,7 @@ void frame(void)
float dt = timestep; float dt = timestep;
// process gs.entities // process gs.entities
player_in_combat = false; // in combat set by various enemies when they fight the player
PROFILE_SCOPE("entity processing") PROFILE_SCOPE("entity processing")
{ {
ENTITIES_ITER(gs.entities) ENTITIES_ITER(gs.entities)
@ -2671,8 +2545,9 @@ void frame(void)
Overlapping overlapping_weapon = get_overlapping(cur_level, weapon_aabb); Overlapping overlapping_weapon = get_overlapping(cur_level, weapon_aabb);
if(it->swing_timer > 0.0) if(it->swing_timer > 0.0)
{ {
player_in_combat = true;
it->swing_timer += dt; it->swing_timer += dt;
if(it->swing_timer >= anim_sprite_duration(&skeleton_swing_sword)) if(it->swing_timer >= anim_sprite_duration(ANIM_skeleton_swing_sword))
{ {
it->swing_timer = 0.0; it->swing_timer = 0.0;
} }
@ -2692,6 +2567,7 @@ void frame(void)
it->walking = LenV2(SubV2(player->pos, it->pos)) < 250.0f; it->walking = LenV2(SubV2(player->pos, it->pos)) < 250.0f;
if(it->walking) if(it->walking)
{ {
player_in_combat = true;
Entity *skele = it; Entity *skele = it;
BUFF_ITER(Overlap, &overlapping_weapon) BUFF_ITER(Overlap, &overlapping_weapon)
{ {
@ -2999,7 +2875,7 @@ void frame(void)
player->after_image_timer += dt; player->after_image_timer += dt;
player->time_not_rolling = 0.0f; player->time_not_rolling = 0.0f;
player->roll_progress += dt; player->roll_progress += dt;
if(player->roll_progress > anim_sprite_duration(&knight_rolling)) if(player->roll_progress > anim_sprite_duration(ANIM_knight_rolling))
{ {
player->is_rolling = false; player->is_rolling = false;
} }
@ -3043,7 +2919,7 @@ void frame(void)
request_do_damage(*it, player, DAMAGE_SWORD); request_do_damage(*it, player, DAMAGE_SWORD);
} }
player->swing_progress += dt; player->swing_progress += dt;
if(player->swing_progress > anim_sprite_duration(&knight_attack)) if(player->swing_progress > anim_sprite_duration(ANIM_knight_attack))
{ {
player->state = CHARACTER_IDLE; player->state = CHARACTER_IDLE;
} }
@ -3090,38 +2966,38 @@ void frame(void)
} }
// interaction circle // interaction circle
draw_quad((DrawParams){true, quad_centered(interacting_with->pos, V2(TILE_SIZE, TILE_SIZE)), image_dialog_circle, full_region(image_dialog_circle), WHITE}); draw_quad((DrawParams){true, quad_centered(interacting_with->pos, V2(TILE_SIZE, TILE_SIZE)), image_hovering_circle, full_region(image_hovering_circle), WHITE});
} }
if(player->state == CHARACTER_WALKING) if(player->state == CHARACTER_WALKING)
{ {
if(player->is_rolling) if(player->is_rolling)
{ {
to_draw = (DrawnAnimatedSprite){&knight_running, player->roll_progress, player->facing_left, character_sprite_pos, WHITE}; to_draw = (DrawnAnimatedSprite){ANIM_knight_running, player->roll_progress, player->facing_left, character_sprite_pos, WHITE};
} }
else else
{ {
to_draw = (DrawnAnimatedSprite){&knight_running, elapsed_time, player->facing_left, character_sprite_pos, WHITE}; to_draw = (DrawnAnimatedSprite){ANIM_knight_running, elapsed_time, player->facing_left, character_sprite_pos, WHITE};
} }
} }
else if(player->state == CHARACTER_IDLE) else if(player->state == CHARACTER_IDLE)
{ {
if(player->is_rolling) if(player->is_rolling)
{ {
to_draw = (DrawnAnimatedSprite){&knight_running, player->roll_progress, player->facing_left, character_sprite_pos, WHITE}; to_draw = (DrawnAnimatedSprite){ANIM_knight_running, player->roll_progress, player->facing_left, character_sprite_pos, WHITE};
} }
else else
{ {
to_draw = (DrawnAnimatedSprite){&knight_idle, elapsed_time, player->facing_left, character_sprite_pos, WHITE}; to_draw = (DrawnAnimatedSprite){ANIM_knight_idle, elapsed_time, player->facing_left, character_sprite_pos, WHITE};
} }
} }
else if(player->state == CHARACTER_ATTACK) else if(player->state == CHARACTER_ATTACK)
{ {
to_draw = (DrawnAnimatedSprite){&knight_attack, player->swing_progress, player->facing_left, character_sprite_pos, WHITE}; to_draw = (DrawnAnimatedSprite){ANIM_knight_attack, player->swing_progress, player->facing_left, character_sprite_pos, WHITE};
} }
else if(player->state == CHARACTER_TALKING) else if(player->state == CHARACTER_TALKING)
{ {
to_draw = (DrawnAnimatedSprite){&knight_idle, elapsed_time, player->facing_left, character_sprite_pos, WHITE}; to_draw = (DrawnAnimatedSprite){ANIM_knight_idle, elapsed_time, player->facing_left, character_sprite_pos, WHITE};
} }
else else
{ {
@ -3186,7 +3062,7 @@ void frame(void)
{ {
//if(it->npc_kind != DEATH) //if(it->npc_kind != DEATH)
{ {
float shadow_size = knight_rolling.region_size.x * 0.5f; float shadow_size = GET_TABLE(sprites, ANIM_knight_rolling).region_size.x * 0.5f;
Vec2 shadow_offset = V2(0.0f, -20.0f); Vec2 shadow_offset = V2(0.0f, -20.0f);
if(npc_is_knight_sprite(it)) if(npc_is_knight_sprite(it))
{ {
@ -3228,38 +3104,38 @@ void frame(void)
if(it->npc_kind == NPC_OldMan) if(it->npc_kind == NPC_OldMan)
{ {
bool face_left =SubV2(player->pos, it->pos).x < 0.0f; bool face_left =SubV2(player->pos, it->pos).x < 0.0f;
draw_animated_sprite((DrawnAnimatedSprite){&old_man_idle, elapsed_time, face_left, it->pos, col}); draw_animated_sprite((DrawnAnimatedSprite){ANIM_old_man_idle, elapsed_time, face_left, it->pos, col});
} }
else if(it->npc_kind == NPC_Skeleton) else if(it->npc_kind == NPC_Skeleton)
{ {
Color col = WHITE; Color col = WHITE;
if(it->dead) if(it->dead)
{ {
draw_animated_sprite((DrawnAnimatedSprite){&skeleton_die, it->dead_time, it->facing_left, it->pos, col}); draw_animated_sprite((DrawnAnimatedSprite){ANIM_skeleton_die, it->dead_time, it->facing_left, it->pos, col});
} }
else else
{ {
if(it->swing_timer > 0.0) if(it->swing_timer > 0.0)
{ {
// swinging sword // swinging sword
draw_animated_sprite((DrawnAnimatedSprite){&skeleton_swing_sword, it->swing_timer, it->facing_left, it->pos, col}); draw_animated_sprite((DrawnAnimatedSprite){ANIM_skeleton_swing_sword, it->swing_timer, it->facing_left, it->pos, col});
} }
else else
{ {
if(it->walking) if(it->walking)
{ {
draw_animated_sprite((DrawnAnimatedSprite){&skeleton_run, elapsed_time, it->facing_left, it->pos, col}); draw_animated_sprite((DrawnAnimatedSprite){ANIM_skeleton_run, elapsed_time, it->facing_left, it->pos, col});
} }
else else
{ {
draw_animated_sprite((DrawnAnimatedSprite){&skeleton_idle, elapsed_time, it->facing_left, it->pos, col}); draw_animated_sprite((DrawnAnimatedSprite){ANIM_skeleton_idle, elapsed_time, it->facing_left, it->pos, col});
} }
} }
} }
} }
else if(it->npc_kind == NPC_Death) else if(it->npc_kind == NPC_Death)
{ {
draw_animated_sprite((DrawnAnimatedSprite){&death_idle, elapsed_time, true, AddV2(it->pos, V2(0, 30.0f)), col}); draw_animated_sprite((DrawnAnimatedSprite){ANIM_death_idle, elapsed_time, true, AddV2(it->pos, V2(0, 30.0f)), col});
} }
else if(it->npc_kind == NPC_GodRock) else if(it->npc_kind == NPC_GodRock)
{ {
@ -3283,7 +3159,7 @@ void frame(void)
{ {
assert(false); assert(false);
} }
draw_animated_sprite((DrawnAnimatedSprite){&knight_idle, elapsed_time, true, AddV2(it->pos, V2(0, 30.0f)), tint}); draw_animated_sprite((DrawnAnimatedSprite){ANIM_knight_idle, elapsed_time, true, AddV2(it->pos, V2(0, 30.0f)), tint});
} }
else if(it->npc_kind == NPC_MOOSE) else if(it->npc_kind == NPC_MOOSE)
{ {

@ -134,10 +134,9 @@ typedef enum
typedef Vec4 Color; typedef Vec4 Color;
#error "to make this serializable, need to make 'animated sprite enum', not pointer to global variable. Do this in codegen?"
typedef struct typedef struct
{ {
void *anim; // is an AnimatedSprite but can't get the decl here AnimKind anim;
double elapsed_time; double elapsed_time;
bool flipped; bool flipped;
Vec2 pos; Vec2 pos;

Loading…
Cancel
Save