]> git.lizzy.rs Git - dungeon_game.git/blob - plugins/fireball/fireball.c
3da29a47d9e025a8efed27dbdbc27a74be46e147
[dungeon_game.git] / plugins / fireball / fireball.c
1 #include <stdlib.h>
2 #include <stddef.h>
3 #include "../game/game.h"
4
5 static struct entity fireball;
6
7 struct fireball_data
8 {
9         double timer;
10         int vx;
11         int vy;
12 };
13
14 static void fireball_spawn(struct entity *self, void *data)
15 {
16         self->meta = malloc(sizeof(struct fireball_data));
17         *((struct fireball_data *) self->meta) = *((struct fireball_data *) data);
18
19         self->color.r = clamp(self->color.r + rand() % 65 - 32, 0, 255);
20         self->color.g = clamp(self->color.g + rand() % 65 - 32, 0, 255);
21         self->color.b = clamp(self->color.b + rand() % 65 - 32, 0, 255);
22 }
23
24 static void fireball_step(struct entity *self, struct entity_step_data stepdata)
25 {
26         struct fireball_data *data = self->meta;
27
28         if (stepdata.visible && (data->timer -= stepdata.dtime) <= 0.0) {
29                 data->timer = 0.1;
30                 move(self, data->vx, data->vy);
31         }
32 }
33
34 static void fireball_collide(struct entity *self, int x, int y)
35 {
36         (void) x, y;
37
38         self->remove = true;
39 }
40
41 static void fireball_collide_with_entity(struct entity *self, struct entity *other)
42 {
43         add_health(other, -(1 + rand() % 3));
44         self->remove = true;
45 }
46
47 static bool try_shoot(int x, int y, int vx, int vy)
48 {
49         x += vx;
50         y += vy;
51
52         return spawn(fireball, x, y, & (struct fireball_data) {
53                 .timer = 0.1,
54                 .vx = vx,
55                 .vy = vy,
56         });
57 }
58
59 static void shoot_fireball()
60 {
61         int x, y;
62
63         x = player.x;
64         y = player.y;
65
66         for (int tries = 10; tries > 0; tries--) {
67                 int vx, vy;
68
69                 vx = vy = 0;
70
71                 dir_to_xy(rand() % 4, &vx, &vy);
72
73                 if (try_shoot(x, y, vx, vy))
74                         return;
75         }
76 }
77
78 __attribute__((constructor)) static void init()
79 {
80         fireball = (struct entity) {
81                 .name = "fireball",
82                 .x = 0,
83                 .y = 0,
84                 .color = get_color("#FF6611"),
85                 .texture = "⬤ ",
86                 .remove = false,
87                 .meta = NULL,
88                 .health = 1,
89                 .max_health = 1,
90                 .collide_with_entities = true,
91
92                 .on_step = &fireball_step,
93                 .on_collide = &fireball_collide,
94                 .on_collide_with_entity = &fireball_collide_with_entity,
95                 .on_spawn = &fireball_spawn,
96                 .on_remove = NULL,
97                 .on_death = NULL,
98                 .on_damage = NULL,
99         };
100
101         register_input_handler(' ', (struct input_handler) {
102                 .run_if_dead = false,
103                 .callback = &shoot_fireball,
104         });
105 }