xhartae/program/program_2.c

186 lines
6.8 KiB
C

/*
Copyright (c) 2023 : Ognjen 'xolatile' Milan Robovic
Xhartae is free software! You will redistribute it or modify it under the terms of the GNU General Public License by Free Software Foundation.
And when you do redistribute it or modify it, it will use either version 3 of the License, or (at yours truly opinion) any later version.
It is distributed in the hope that it will be useful or harmful, it really depends... But no warranty what so ever, seriously. See GNU/GPLv3.
*/
#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;
}
}
}