#include "../chapter/chapter_0.c" #include "../chapter/chapter_1.c" #include "../chapter/chapter_2.c" static int entity_define (char * name, int character, int colour, int effect, int value, int logic, void (* trigger) (void)); static void entity_create (int entity, int amount); static void entity_render (int entity); static void entity_clean_up (void); static void entity_update_logic (void); static int player_x = 0; static int player_y = 0; static int player_coins = 0; static int entity_count = 0; static char * * entity_name = NULL; static char * entity_character = '\0'; static int * entity_colour = 0; static int * entity_effect = 0; static int * entity_value = 0; static int * entity_logic = 0; static void (* * entity_trigger) (void) = NULL; static int entity_usage = 0; static int * entity_index = 0; static int * entity_x = 0; static int * entity_y = 0; static void player_move_up (void) { player_y -= 1; limit (& player_y, 0, curses_screen_height - 1); } static void player_move_down (void) { player_y += 1; limit (& player_y, 0, curses_screen_height - 1); } static void player_move_left (void) { player_x -= 1; limit (& player_x, 0, curses_screen_width - 1); } static void player_move_right (void) { player_x += 1; limit (& player_x, 0, curses_screen_width - 1); } static void player_take_coin (void) { ++player_coins; } static void player_died (void) { curses_active = 0; } int main (void) { terminal_show_cursor (FALSE); curses_configure (); curses_bind (SIGNAL_W, player_move_up); curses_bind (SIGNAL_S, player_move_down); curses_bind (SIGNAL_A, player_move_left); curses_bind (SIGNAL_D, player_move_right); int coin = entity_define ("Coin", '+', COLOUR_YELLOW, EFFECT_BOLD, 1, FALSE, player_take_coin); int goblin = entity_define ("Goblin", 'g', COLOUR_RED, EFFECT_NORMAL, 3, TRUE, player_died); int hob_goblin = entity_define ("Hob Goblin", 'G', COLOUR_RED, EFFECT_BOLD, 7, TRUE, player_died); entity_create (coin, 11); entity_create (goblin, 7); entity_create (hob_goblin, 3); while (curses_active) { curses_render_background ('.', COLOUR_GREY, EFFECT_BOLD); curses_render_rectangle_fill (',', COLOUR_GREEN, EFFECT_NORMAL, 10, 10, 80, 24); curses_render_rectangle_line ('#', COLOUR_WHITE, EFFECT_NORMAL, 10, 10, 80, 24); for (int entity = 0; entity < entity_usage; ++entity) { entity_render (entity); } curses_render_character ('@', COLOUR_CYAN, EFFECT_BOLD, player_x, player_y); curses_render_number (player_coins, COLOUR_YELLOW, EFFECT_BOLD, 0, 0); entity_update_logic (); curses_synchronize (); } entity_clean_up (); terminal_show_cursor (TRUE); return (EXIT_SUCCESS); } static int entity_define (char * name, int character, int colour, int effect, int value, int logic, void (* trigger) (void)) { int entity = entity_count; ++entity_count; entity_name = reallocate (entity_name, entity_count * (int) sizeof (* entity_name)); entity_character = reallocate (entity_character, entity_count * (int) sizeof (* entity_character)); entity_colour = reallocate (entity_colour, entity_count * (int) sizeof (* entity_colour)); entity_effect = reallocate (entity_effect, entity_count * (int) sizeof (* entity_effect)); entity_value = reallocate (entity_value, entity_count * (int) sizeof (* entity_value)); entity_logic = reallocate (entity_logic, entity_count * (int) sizeof (* entity_logic)); entity_trigger = reallocate (entity_trigger, entity_count * (int) sizeof (* entity_trigger)); string_copy ((entity_name [entity] = allocate (string_length (name) + 1)), name); entity_character [entity] = character; entity_colour [entity] = colour; entity_effect [entity] = effect; entity_value [entity] = value; entity_logic [entity] = logic; entity_trigger [entity] = trigger; return (entity); } static void entity_create (int entity, int amount) { int index; for (index = 0; index < amount; ++index) { ++entity_usage; entity_index = reallocate (entity_index, entity_usage * (int) sizeof (* entity_index)); entity_x = reallocate (entity_x, entity_usage * (int) sizeof (* entity_x)); entity_y = reallocate (entity_y, entity_usage * (int) sizeof (* entity_y)); entity_index [entity_usage - 1] = entity; entity_x [entity_usage - 1] = randomize (0, curses_screen_width - 1); entity_y [entity_usage - 1] = randomize (0, curses_screen_height - 1); } } static void entity_render (int entity) { if (entity_index [entity] == -1) { return; } curses_render_character (entity_character [entity_index [entity]], entity_colour [entity_index [entity]], entity_effect [entity_index [entity]], entity_x [entity], entity_y [entity]); } void entity_clean_up (void) { for (int entity = 0; entity < entity_count; ++entity) { entity_name [entity] = deallocate (entity_name [entity]); } entity_name = deallocate (entity_name); entity_character = deallocate (entity_character); entity_colour = deallocate (entity_colour); entity_effect = deallocate (entity_effect); entity_value = deallocate (entity_value); entity_logic = deallocate (entity_logic); entity_trigger = deallocate (entity_trigger); entity_index = deallocate (entity_index); entity_x = deallocate (entity_x); entity_y = deallocate (entity_y); entity_count = 0; entity_usage = 0; } void entity_update_logic (void) { for (int entity = 0; entity < entity_usage; ++entity) { if (entity_index [entity] == -1) { continue; } if (entity_logic [entity_index [entity]] == TRUE) { entity_x [entity] += randomize (0, 1) * ((randomize (0, 1) == 0) ? +1 : -1); entity_y [entity] += randomize (0, 1) * ((randomize (0, 1) == 0) ? +1 : -1); limit (& entity_x [entity], 0, curses_screen_width - 1); limit (& entity_y [entity], 0, curses_screen_height - 1); } if ((player_x == entity_x [entity]) && (player_y == entity_y [entity])) { if (entity_trigger [entity_index [entity]] != NULL) { entity_trigger [entity_index [entity]] (); } entity_index [entity] = -1; } } }