]> git.lizzy.rs Git - dungeon_game.git/commitdiff
Add fireballs
authorElias Fleckenstein <eliasfleckenstein@web.de>
Wed, 9 Jun 2021 17:41:18 +0000 (19:41 +0200)
committerElias Fleckenstein <eliasfleckenstein@web.de>
Wed, 9 Jun 2021 17:41:18 +0000 (19:41 +0200)
plugins/apple/apple.c
plugins/fireball/Makefile [new file with mode: 0644]
plugins/fireball/fireball.c [new file with mode: 0644]
plugins/game/game.c
plugins/game/game.h
plugins/monster/monster.c

index d8e7375a7e9f81672825eecddfc0d676e86120a2..d100e45bd0381303f1e8442faba0566a6d1d5b53 100644 (file)
@@ -15,7 +15,7 @@ static void apple_step(struct entity *self, struct entity_step_data stepdata)
 
 static void spawn_apple(int x, int y)
 {
-       spawn(apple, x, y);
+       spawn(apple, x, y, NULL);
 }
 
 __attribute__((constructor)) static void init()
diff --git a/plugins/fireball/Makefile b/plugins/fireball/Makefile
new file mode 100644 (file)
index 0000000..bc0a277
--- /dev/null
@@ -0,0 +1,4 @@
+plugins/fireball/fireball.so: plugins/fireball/fireball.c plugins/game/game.h
+       cc -g -shared -fpic -o plugins/fireball/fireball.so plugins/fireball/fireball.c
+
+PLUGINS := ${PLUGINS} plugins/fireball/fireball.so
diff --git a/plugins/fireball/fireball.c b/plugins/fireball/fireball.c
new file mode 100644 (file)
index 0000000..1c3eeb6
--- /dev/null
@@ -0,0 +1,101 @@
+#include <stdlib.h>
+#include <stddef.h>
+#include "../game/game.h"
+
+static struct entity fireball;
+
+struct fireball_data
+{
+       double timer;
+       int vx;
+       int vy;
+};
+
+static void fireball_spawn(struct entity *self, void *data)
+{
+       self->meta = malloc(sizeof(struct fireball_data));
+       *((struct fireball_data *) self->meta) = *((struct fireball_data *) data);
+}
+
+static void fireball_step(struct entity *self, struct entity_step_data stepdata)
+{
+       struct fireball_data *data = self->meta;
+
+       if (stepdata.visible && (data->timer -= stepdata.dtime) <= 0.0) {
+               data->timer = 0.1;
+               move(self, data->vx, data->vy);
+       }
+}
+
+static void fireball_collide(struct entity *self, int x, int y)
+{
+       (void) x, y;
+
+       self->remove = true;
+}
+
+static void fireball_collide_with_entity(struct entity *self, struct entity *other)
+{
+       add_health(other, -(1 + rand() % 3));
+       self->remove = true;
+}
+
+static bool try_shoot(int x, int y, int vx, int vy)
+{
+       x += vx;
+       y += vy;
+
+       return spawn(fireball, x, y, & (struct fireball_data) {
+               .timer = 0.1,
+               .vx = vx,
+               .vy = vy,
+       });
+}
+
+static void shoot_fireball()
+{
+       int x, y;
+
+       x = player.x;
+       y = player.y;
+
+       for (int tries = 10; tries > 0; tries--) {
+               int vx, vy;
+
+               vx = vy = 0;
+
+               dir_to_xy(rand() % 4, &vx, &vy);
+
+               if (try_shoot(x, y, vx, vy))
+                       return;
+       }
+}
+
+__attribute__((constructor)) static void init()
+{
+       fireball = (struct entity) {
+               .name = "fireball",
+               .x = 0,
+               .y = 0,
+               .color = get_color("#FF6611"),
+               .texture = "⬤ ",
+               .remove = false,
+               .meta = NULL,
+               .health = 1,
+               .max_health = 1,
+               .collide_with_entities = true,
+
+               .on_step = &fireball_step,
+               .on_collide = &fireball_collide,
+               .on_collide_with_entity = &fireball_collide_with_entity,
+               .on_spawn = &fireball_spawn,
+               .on_remove = NULL,
+               .on_death = NULL,
+               .on_damage = NULL,
+       };
+
+       register_input_handler(' ', (struct input_handler) {
+               .run_if_dead = false,
+               .callback = &shoot_fireball,
+       });
+}
index bb434ca159653ac2f10c5b5e91fbad16578a3114..3b2ad4b8f3333bb7f3e11933fd745a738da32234 100644 (file)
@@ -89,13 +89,13 @@ bool move(struct entity *entity, int xoff, int yoff)
        }
 }
 
-void spawn(struct entity def, int x, int y)
+bool spawn(struct entity def, int x, int y, void *data)
 {
-       if (is_outside(x, y))
-               return;
+       if (is_solid(x, y))
+               return false;
 
        if (def.collide_with_entities && entity_collision_map[x][y])
-               return;
+               return false;
 
        def.x = x;
        def.y = y;
@@ -109,7 +109,9 @@ void spawn(struct entity def, int x, int y)
                entity_collision_map[x][y] = entity;
 
        if (entity->on_spawn)
-               entity->on_spawn(entity);
+               entity->on_spawn(entity, data);
+
+       return true;
 }
 
 void add_health(struct entity *entity, int health)
@@ -170,6 +172,24 @@ void register_input_handler(unsigned char c, struct input_handler handler)
        input_handlers[c] = buf;
 }
 
+void dir_to_xy(int dir, int *x, int *y)
+{
+       switch (dir) {
+               case 0:
+                       (*x)++;
+                       break;
+               case 1:
+                       (*y)++;
+                       break;
+               case 2:
+                       (*x)--;
+                       break;
+               case 3:
+                       (*y)--;
+                       break;
+       }
+}
+
 /* Player */
 
 static void player_death(struct entity *self)
@@ -225,21 +245,7 @@ static void generate_corridor(int lx, int ly, int ldir, bool off)
                else
                        dir = rand() % 4;
 
-               switch (dir) {
-                       case 0:
-                               x++;
-                               break;
-                       case 1:
-                               y++;
-                               break;
-                       case 2:
-                               x--;
-                               break;
-                       case 3:
-                               y--;
-                               break;
-               }
-
+               dir_to_xy(dir, &x, &y);
        } while (dir == ret || (! check_direction(x, y, dir) && --limit));
 
        if (limit)
@@ -520,6 +526,9 @@ void game()
                                if (entity->meta)
                                        free(entity->meta);
 
+                               if (entity->collide_with_entities)
+                                       entity_collision_map[entity->x][entity->y] = NULL;
+
                                free(entity);
                                free(*ptr);
 
index 212eeae05321d7e9aab42e687f27add0df045824..28a7c2cfff13ef46db5860906f6d8b7e860ec292 100644 (file)
@@ -47,7 +47,7 @@ struct entity
        void (*on_step)(struct entity *self, struct entity_step_data stepdata);
        void (*on_collide)(struct entity *self, int x, int y);
        void (*on_collide_with_entity)(struct entity *self, struct entity *other);
-       void (*on_spawn)(struct entity *self);
+       void (*on_spawn)(struct entity *self, void *data);
        void (*on_remove)(struct entity *self);
        void (*on_death)(struct entity *self);
        void (*on_damage)(struct entity *self, int damage);
@@ -98,7 +98,7 @@ bool is_outside(int x, int y);
 struct node get_node(int x, int y);
 bool is_solid(int x, int y);
 bool move(struct entity *entity, int xoff, int yoff);
-void spawn(struct entity def, int x, int y);
+bool spawn(struct entity def, int x, int y, void *data);
 void add_health(struct entity *entity, int health);
 void add_score(int s);
 bool player_dead();
@@ -107,6 +107,7 @@ void light_color(struct color *color, double light);
 void mix_color(struct color *color, struct color other, double ratio);
 void register_air_function(struct generator_function func);
 void register_input_handler(unsigned char c, struct input_handler handler);
+void dir_to_xy(int dir, int *x, int *y);
 struct list *add_element(struct list *list, void *element);
 
 #endif
index 7124c76fe3c6768157a168bfa436b72147e3b2b9..59fa3806244b9b6220c9f0508ea043ce940c3535 100644 (file)
@@ -9,8 +9,10 @@ struct monster_data
        double timer;
 };
 
-static void monster_spawn(struct entity *self)
+static void monster_spawn(struct entity *self, void *data)
 {
+       (void) data;
+
        self->meta = malloc(sizeof(struct monster_data));
        ((struct monster_data *) self->meta)->timer = 0.5;
 }
@@ -26,7 +28,7 @@ static void monster_step(struct entity *self, struct entity_step_data stepdata)
        }
 }
 
-static void monster_on_collide_with_entity(struct entity *self, struct entity *other)
+static void monster_collide_with_entity(struct entity *self, struct entity *other)
 {
        if (other == &player)
                add_health(other, -1);
@@ -40,7 +42,7 @@ static void monster_death(struct entity *self)
 
 static void spawn_monster(int x, int y)
 {
-       spawn(monster, x, y);
+       spawn(monster, x, y, NULL);
 }
 
 __attribute__((constructor)) static void init()
@@ -59,7 +61,7 @@ __attribute__((constructor)) static void init()
 
                .on_step = &monster_step,
                .on_collide = NULL,
-               .on_collide_with_entity = &monster_on_collide_with_entity,
+               .on_collide_with_entity = &monster_collide_with_entity,
                .on_spawn = &monster_spawn,
                .on_remove = NULL,
                .on_death = &monster_death,