]> git.lizzy.rs Git - dungeon_game.git/blobdiff - plugins/game/game.c
Only use entity color if use_color = true
[dungeon_game.git] / plugins / game / game.c
index bd93419e5b72c1ce2f42aef12ab6c25f9a1e48de..9fcf7ea6c0191237fec9683d19161f2edd6a6cf6 100644 (file)
@@ -1,7 +1,5 @@
 #include <stdio.h>
-#include <stdbool.h>
 #include <stdlib.h>
-#include <stddef.h>
 #include <unistd.h>
 #include <assert.h>
 #include <ctype.h>
 #include <termios.h>
 #include <math.h>
 #include <pthread.h>
+#include <string.h>
 #include "game.h"
-#define MAKEBUF(type) type *buf = malloc(sizeof(type)); *buf = arg;
 
 /* Shared variables */
 
-struct color black = {0, 0, 0};
+struct color black = {0};
 
 struct material wall;
 struct material air;
@@ -23,7 +21,6 @@ struct material outside;
 
 struct node map[MAP_WIDTH][MAP_HEIGHT];
 
-struct entity player;
 struct list *entities = & (struct list) {
        .element = &player,
        .next = NULL,
@@ -119,6 +116,14 @@ int min(int a, int b)
        return a < b ? a : b;
 }
 
+void *make_buffer(void *ptr, size_t size)
+{
+       void *buf = malloc(size);
+       memcpy(buf, ptr, size);
+
+       return buf;
+}
+
 /* Game-related utility functions */
 
 void quit()
@@ -216,24 +221,22 @@ void add_health(struct entity *entity, int health)
 
 /* Register callback functions */
 
-void register_air_function(struct generator_function arg)
+void register_air_function(struct generator_function func)
 {
-       MAKEBUF(struct generator_function);
-       air_functions = add_element(air_functions, buf);
+       air_functions = add_element(air_functions, make_buffer(&func, sizeof(struct generator_function)));
 }
 
-void register_input_handler(unsigned char c, struct input_handler arg)
+void register_input_handler(unsigned char c, struct input_handler handler)
 {
        if (input_handlers[c])
                return;
 
-       MAKEBUF(struct input_handler);
-       input_handlers[c] = buf;
+       input_handlers[c] = make_buffer(&handler, sizeof(struct input_handler));
 }
 
-void register_render_component(void (*arg)(struct winsize ws))
+void register_render_component(void (*callback)(struct winsize ws))
 {
-       render_components = add_element(render_components, arg);
+       render_components = add_element(render_components, callback);
 };
 
 /* Player */
@@ -248,8 +251,70 @@ static void player_damage(struct entity *self, int damage)
        damage_overlay += (double) damage * 0.5;
 }
 
+struct entity player = {
+       .name = "player",
+       .x = MAP_WIDTH / 2,
+       .y = MAP_HEIGHT / 2,
+       .color = {0},
+       .use_color = false,
+       .texture = "🙂",
+       .remove = false,
+       .meta = NULL,
+       .health = 10,
+       .max_health = 10,
+       .collide_with_entities = true,
+
+       .on_step = NULL,
+       .on_collide = NULL,
+       .on_collide_with_entity = NULL,
+       .on_spawn = NULL,
+       .on_remove = NULL,
+       .on_death = &player_death,
+       .on_damage = &player_damage,
+};
+
 /* Mapgen */
 
+static void mapgen_set_air(int x, int y)
+{
+       if (is_outside(x, y))
+               return;
+
+       if (map[x][y].material == &air)
+               return;
+
+       map[x][y] = (struct node) {&air};
+
+       for (struct list *ptr = air_functions; ptr != NULL; ptr = ptr->next) {
+               struct generator_function *func = ptr->element;
+
+               if (rand() % func->chance == 0)
+                       func->callback(x, y);
+       }
+}
+
+static void generate_room(int origin_x, int origin_y)
+{
+       int left = 5 + rand() % 10;
+       int right = 5 + rand() % 10;
+
+       int up = 0;
+       int down = 0;
+
+       for (int x = -left; x <= right; x++) {
+               if (x < 0) {
+                       up += rand() % 2;
+                       down += rand() % 2;
+               } else {
+                       up -= rand() % 2;
+                       down -= rand() % 2;
+               }
+
+               for (int y = -up; y <= down; y++)
+                       mapgen_set_air(origin_x + x, origin_y + y);
+       }
+}
+
 static bool check_direction(int x, int y, enum direction dir)
 {
        if (dir % 2 == 0)
@@ -263,16 +328,13 @@ static void generate_corridor(int lx, int ly, enum direction ldir)
        if (is_outside(lx, ly))
                return;
 
-       map[lx][ly] = (struct node) {&air};
-
-       for (struct list *ptr = air_functions; ptr != NULL; ptr = ptr->next) {
-               struct generator_function *func = ptr->element;
-
-               if (! func->chance || rand() % func->chance == 0) {
-                       func->callback(lx, ly);
-               }
+       if (rand() % 200 == 0) {
+               generate_room(lx, ly);
+               return;
        }
 
+       mapgen_set_air(lx, ly);
+
        int x, y;
 
        enum direction dir;
@@ -309,12 +371,12 @@ static void generate_corridor_random(int x, int y)
 
 /* Rendering */
 
-static bool render_color(struct color color, double light, bool bg)
+static bool render_color(struct color color, double light, bool bg, bool use_color)
 {
        if (light <= 0.0) {
                set_color(black, bg);
                return false;
-       } else {
+       } else if (use_color) {
                if (damage_overlay > 0.0)
                        mix_color(&color, damage_overlay_color, damage_overlay * 2.0);
 
@@ -322,6 +384,8 @@ static bool render_color(struct color color, double light, bool bg)
 
                set_color(color, bg);
                return true;
+       } else {
+               return true;
        }
 }
 
@@ -352,12 +416,12 @@ static void render_map(struct winsize ws)
                        double dist = sqrt(x * x + y * y);
                        double light = 1.0 - (double) dist / (double) LIGHT;
 
-                       render_color(node.material->color, light, true);
+                       render_color(node.material->color, light, true, true);
 
                        struct entity *entity = render_entities[x + LIGHT][y + LIGHT];
                        render_entities[x + LIGHT][y + LIGHT] = NULL;
 
-                       if (entity && render_color(entity->color, light, false))
+                       if (entity && render_color(entity->color, light, false, entity->use_color))
                                printf("%s", entity->texture);
                        else
                                printf("  ");
@@ -369,7 +433,7 @@ static void render_map(struct winsize ws)
                        printf(" ");
        }
 
-       for (int i = 0; i < rows_left + 1; i++)
+       for (int i = 0; i < rows_left; i++)
                for (int i = 0; i < ws.ws_col; i++)
                        printf(" ");
 }
@@ -422,8 +486,6 @@ static void *input_thread(void *unused)
 
 void game()
 {
-       srand(time(0));
-
        struct sigaction sa;
        sa.sa_handler = &handle_interrupt;
        sigaction(SIGINT, &sa, NULL);
@@ -519,6 +581,8 @@ void game()
 
 __attribute__ ((constructor)) static void init()
 {
+       srand(time(0));
+
        wall = (struct material) {
                .solid = true,
                .color = get_color("#5B2F00"),
@@ -534,27 +598,6 @@ __attribute__ ((constructor)) static void init()
                .color = black,
        };
 
-       player = (struct entity) {
-               .name = "player",
-               .x = MAP_WIDTH / 2,
-               .y = MAP_HEIGHT / 2,
-               .color = get_color("#00FFFF"),
-               .texture = "🙂",
-               .remove = false,
-               .meta = NULL,
-               .health = 10,
-               .max_health = 10,
-               .collide_with_entities = true,
-
-               .on_step = NULL,
-               .on_collide = NULL,
-               .on_collide_with_entity = NULL,
-               .on_spawn = NULL,
-               .on_remove = NULL,
-               .on_death = &player_death,
-               .on_damage = &player_damage,
-       };
-
        entity_collision_map[player.x][player.y] = &player;
 
        for (int x = 0; x < MAP_WIDTH; x++)