/* 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. */ #ifndef CHAPTER_5_SOURCE #define CHAPTER_5_SOURCE #include "chapter_x.h" /* So, what are actually getters and setters, and why you should never use them? Lets explain. */ #define MEMORY_LIMIT (1024 * 1024) static number_t game_memory_length = 0; static memory_t * game_memory = NULL; static procedure_t game_free_memory (memory_t memory) { ++game_memory_length; game_memory = reallocate (game_memory, game_memory_length * (number_t) sizeof (* game_memory)); game_memory [game_memory_length - 1] = memory; } procedure_t game_clean_up (procedure_t) { for (number_t pointer = 0; pointer < game_memory_length; ++pointer) { game_memory [pointer] = deallocate (game_memory [pointer]); } game_memory = deallocate (game_memory); } bundle_t * game_bundle (number_t minimum, number_t maximum, number_t current) { bundle_t * bundle = allocate ((number_t) sizeof (* bundle)); bundle->minimum = minimum; bundle->maximum = maximum; bundle->current = current; game_free_memory (bundle); return (bundle); } symbol_t * game_symbol (number_t character, number_t colour, number_t effect) { symbol_t * symbol = allocate ((number_t) sizeof (* symbol)); symbol->character = character; symbol->colour = colour; symbol->effect = effect; game_free_memory (symbol); return (symbol); } sprite_t * game_sprite (number_t width, number_t height, memory_t data) { sprite_t * sprite = allocate ((number_t) sizeof (* sprite)); sprite->width = width; sprite->height = height; sprite->data = data; game_free_memory (sprite); return (sprite); } generator_t * game_generator (generate_t function) { generator_t * generator = allocate ((number_t) sizeof (* generator)); generator->generate = function; game_free_memory (generator); return (generator); } attribute_t * game_attribute (string_t name, bundle_t * points, ...) { va_list list; attribute_t * attribute = allocate ((number_t) sizeof (* attribute)); string_copy ((attribute->name = allocate (string_length (name) + 1)), name); memory_copy ((attribute->points = allocate ((number_t) sizeof (* attribute->points))), points, (number_t) sizeof (* points)); va_start (list, points); for (;;) { number_t action = (number_t) va_arg (list, int); if (action > 0) { attribute->positive_count += 1; attribute->positive = reallocate (attribute->positive, attribute->positive_count * (number_t) sizeof (action)); attribute->positive [attribute->positive_count - 1] = (action_t) action; } else if (action < 0) { attribute->negative_count += 1; attribute->negative = reallocate (attribute->negative, attribute->negative_count * (number_t) sizeof (action)); attribute->negative [attribute->negative_count - 1] = (action_t) -action; } else break; } va_end (list); game_free_memory (attribute->name); game_free_memory (attribute->points); game_free_memory (attribute->positive); game_free_memory (attribute->negative); game_free_memory (attribute); return (attribute); } skill_t * game_skill (string_t name, bundle_t * points, ...) { va_list list; skill_t * skill = allocate ((number_t) sizeof (* skill)); string_copy ((skill->name = allocate (string_length (name) + 1)), name); memory_copy ((skill->points = allocate ((number_t) sizeof (* skill->points))), points, (number_t) sizeof (* points)); va_start (list, points); for (;;) { action_t action = (action_t) va_arg (list, int); if (action > 0) { skill->positive_count += 1; skill->positive = reallocate (skill->positive, skill->positive_count * (number_t) sizeof (action)); skill->positive [skill->positive_count - 1] = action; } else break; } va_end (list); game_free_memory (skill->name); game_free_memory (skill->points); game_free_memory (skill->positive); game_free_memory (skill); return (skill); } bot_t * game_bot (string_t name, symbol_t * symbol, sprite_t * sprite, bundle_t * health, bundle_t * mana, bundle_t * stamina) { bot_t * bot = allocate ((number_t) sizeof (* bot)); string_copy ((bot->name = allocate (string_length (name) + 1)), name); bot->x = 0; bot->y = 0; memory_copy ((bot->symbol = allocate ((number_t) sizeof (* bot->symbol))), symbol, (number_t) sizeof (* symbol)); memory_copy ((bot->sprite = allocate ((number_t) sizeof (* bot->sprite))), sprite, (number_t) sizeof (* sprite)); memory_copy ((bot->health = allocate ((number_t) sizeof (* bot->health))), health, (number_t) sizeof (* health)); memory_copy ((bot->mana = allocate ((number_t) sizeof (* bot->mana))), mana, (number_t) sizeof (* mana)); memory_copy ((bot->stamina = allocate ((number_t) sizeof (* bot->stamina))), stamina, (number_t) sizeof (* stamina)); game_free_memory (bot->name); game_free_memory (bot->symbol); game_free_memory (bot->sprite); game_free_memory (bot->health); game_free_memory (bot->mana); game_free_memory (bot->stamina); game_free_memory (bot); return (bot); } player_t * game_player (string_t name, symbol_t * symbol, sprite_t * sprite, bundle_t * health, bundle_t * mana, bundle_t * stamina, ...) { va_list list; player_t * player = allocate ((number_t) sizeof (* player)); string_copy ((player->name = allocate (string_length (name) + 1)), name); player->x = 3; player->y = 3; memory_copy ((player->symbol = allocate ((number_t) sizeof (* player->symbol))), symbol, (number_t) sizeof (* symbol)); memory_copy ((player->sprite = allocate ((number_t) sizeof (* player->sprite))), sprite, (number_t) sizeof (* sprite)); memory_copy ((player->health = allocate ((number_t) sizeof (* player->health))), health, (number_t) sizeof (* health)); memory_copy ((player->mana = allocate ((number_t) sizeof (* player->mana))), mana, (number_t) sizeof (* mana)); memory_copy ((player->stamina = allocate ((number_t) sizeof (* player->stamina))), stamina, (number_t) sizeof (* stamina)); player->attribute_count = 0; player->skill_count = 0; va_start (list, stamina); for (;;) { attribute_t * attribute = (attribute_t *) va_arg (list, void *); if (attribute != NULL) { player->attribute_count += 1; player->attributes = reallocate (player->attributes, player->attribute_count * (number_t) sizeof (* player->attributes)); player->attributes [player->attribute_count - 1] = attribute; } else break; } for (;;) { skill_t * skill = (skill_t *) va_arg (list, void *); if (skill != NULL) { player->skill_count += 1; player->skills = reallocate (player->skills, player->skill_count * (number_t) sizeof (* player->skills)); player->skills [player->skill_count - 1] = skill; } else break; } va_end (list); game_free_memory (player->name); game_free_memory (player->symbol); game_free_memory (player->sprite); game_free_memory (player->health); game_free_memory (player->mana); game_free_memory (player->stamina); game_free_memory (player->attributes); game_free_memory (player->skills); game_free_memory (player); return (player); } block_t * game_block (string_t name, symbol_t * symbol, sprite_t * sprite, number_t collision, number_t override) { block_t * block = allocate ((number_t) sizeof (* block)); string_copy ((block->name = allocate (string_length (name) + 1)), name); memory_copy ((block->symbol = allocate ((number_t) sizeof (* block->symbol))), symbol, (number_t) sizeof (* symbol)); memory_copy ((block->sprite = allocate ((number_t) sizeof (* block->sprite))), sprite, (number_t) sizeof (* sprite)); block->collision = collision; block->override = override; game_free_memory (block->name); game_free_memory (block->symbol); game_free_memory (block->sprite); game_free_memory (block); return (block); } world_t * game_world (number_t width, number_t height, ...) { va_list list; world_t * world = allocate ((number_t) sizeof (* world)); world->width = width; world->height = height; world->block = allocate (width * height * (number_t) sizeof (* world->block)); va_start (list, height); for (;;) { generator_t * generator = (generator_t *) va_arg (list, void *); if (generator != NULL) { memory_t data = (memory_t) va_arg (list, void *); number_t w = (number_t) va_arg (list, int); number_t h = (number_t) va_arg (list, int); number_t x = (number_t) va_arg (list, int); number_t y = (number_t) va_arg (list, int); generator->generate (world, data, w, h, x, y); } else break; } va_end (list); game_free_memory (world->bots); game_free_memory (world->block); game_free_memory (world); return (world); } procedure_t game_render_attribute (attribute_t * attribute, number_t x, number_t y) { curses_render_string (attribute->name, COLOUR_CYAN, EFFECT_NORMAL, x + 0, y); curses_render_string ("[ ", COLOUR_GREY, EFFECT_BOLD, x + 18, y); curses_render_string (format_to_string (attribute->points->minimum, 0, 10, 4, ' '), COLOUR_RED, EFFECT_NORMAL, x + 20, y); curses_render_string (format_to_string (attribute->points->current, 0, 10, 4, ' '), COLOUR_WHITE, EFFECT_NORMAL, x + 24, y); curses_render_string (format_to_string (attribute->points->maximum, 0, 10, 4, ' '), COLOUR_GREEN, EFFECT_NORMAL, x + 28, y); curses_render_string (" ]", COLOUR_GREY, EFFECT_BOLD, x + 32, y); } procedure_t game_render_skill (skill_t * skill, number_t x, number_t y) { curses_render_string (skill->name, COLOUR_CYAN, EFFECT_NORMAL, x + 0, y); curses_render_string ("[ ", COLOUR_GREY, EFFECT_BOLD, x + 18, y); curses_render_string (format_to_string (skill->points->minimum, 0, 10, 4, ' '), COLOUR_RED, EFFECT_NORMAL, x + 20, y); curses_render_string (format_to_string (skill->points->current, 0, 10, 4, ' '), COLOUR_WHITE, EFFECT_NORMAL, x + 24, y); curses_render_string (format_to_string (skill->points->maximum, 0, 10, 4, ' '), COLOUR_GREEN, EFFECT_NORMAL, x + 28, y); curses_render_string (" ]", COLOUR_GREY, EFFECT_BOLD, x + 32, y); } procedure_t game_render_bot (bot_t * bot) { curses_render_character ((char) bot->symbol->character, bot->symbol->colour, bot->symbol->effect, bot->x, bot->y); } procedure_t game_render_player (player_t * player) { curses_render_character ((char) player->symbol->character, player->symbol->colour, player->symbol->effect, player->x, player->y); } procedure_t game_render_block (block_t * block, number_t x, number_t y) { curses_render_character ((char) block->symbol->character, block->symbol->colour, block->symbol->effect, x, y); } procedure_t game_render_world (world_t * world, number_t x, number_t y, number_t width, number_t height) { for (number_t j = 0; (j < height) && (j < world->height); ++j) { for (number_t i = 0; (i < width) && (i < world->width); ++i) { game_render_block (world->block [j * world->width + i], i + x, j + y); } } for (number_t index = 0; index < world->bot_count; ++index) { game_render_bot (& world->bots [index]); } } #endif