]> git.lizzy.rs Git - nothing.git/blob - src/goals.c
Remove the wave state (#90)
[nothing.git] / src / goals.c
1 #include <assert.h>
2 #include <math.h>
3
4 #include <SDL2/SDL.h>
5
6 #include "./lt.h"
7 #include "./goals.h"
8 #include "./error.h"
9 #include "./pi.h"
10 #include "./triangle.h"
11
12 #define GOAL_RADIUS 10.0f
13
14 struct goals_t {
15     lt_t *lt;
16     point_t *points;
17     rect_t *regions;
18     size_t goals_count;
19     rect_t player_hitbox;
20     float angle;
21 };
22
23 goals_t *create_goals_from_stream(FILE *stream)
24 {
25     assert(stream);
26
27     lt_t *const lt = create_lt();
28     if (lt == NULL) {
29         return NULL;
30     }
31
32     goals_t *const goals = PUSH_LT(lt, malloc(sizeof(goals_t)), free);
33     if (goals == NULL) {
34         throw_error(ERROR_TYPE_LIBC);
35         RETURN_LT(lt, NULL);
36     }
37
38     goals->goals_count = 0;
39     if (fscanf(stream, "%lu", &goals->goals_count) == EOF) {
40         throw_error(ERROR_TYPE_LIBC);
41         RETURN_LT(lt, NULL);
42     }
43
44     goals->points = PUSH_LT(lt, malloc(sizeof(point_t) * goals->goals_count), free);
45     if (goals->points == NULL) {
46         throw_error(ERROR_TYPE_LIBC);
47         RETURN_LT(lt, NULL);
48     }
49
50     goals->regions = PUSH_LT(lt, malloc(sizeof(rect_t) * goals->goals_count), free);
51     if (goals->regions == NULL) {
52         throw_error(ERROR_TYPE_LIBC);
53         RETURN_LT(lt, NULL);
54     }
55
56     for (size_t i = 0; i < goals->goals_count; ++i) {
57         if (fscanf(stream, "%f%f",
58                    &goals->points[i].x,
59                    &goals->points[i].y) < 0) {
60             throw_error(ERROR_TYPE_LIBC);
61             RETURN_LT(lt, NULL);
62         }
63
64         if (fscanf(stream, "%f%f%f%f\n",
65                    &goals->regions[i].x,
66                    &goals->regions[i].y,
67                    &goals->regions[i].w,
68                    &goals->regions[i].h) < 0) {
69             throw_error(ERROR_TYPE_LIBC);
70             RETURN_LT(lt, NULL);
71         }
72     }
73
74     goals->lt = lt;
75     goals->angle = 0.0f;
76
77     return goals;
78 }
79
80 void destroy_goals(goals_t *goals)
81 {
82     assert(goals);
83     RETURN_LT0(goals->lt);
84 }
85
86 static int goals_render_core(const goals_t *goals,
87                              size_t goal_index,
88                              SDL_Renderer *renderer,
89                              const camera_t *camera)
90 {
91     if (SDL_SetRenderDrawColor(renderer, 255, 255, 50, 255) < 0) {
92         throw_error(ERROR_TYPE_SDL2);
93         return -1;
94     }
95
96
97     const point_t position =
98         vec_sum(
99             goals->points[goal_index],
100             vec(0.0f, sinf(goals->angle) * 10.0f));
101
102     const triangle_t core = equilateral_triangle(position, GOAL_RADIUS, PI * -0.5f + goals->angle);
103
104     if (camera_fill_triangle(
105             camera,
106             renderer,
107             core.p1,
108             core.p2,
109             core.p3) < 0) {
110         return -1;
111     }
112
113     return 0;
114 }
115
116 int goals_render(const goals_t *goals,
117                  SDL_Renderer *renderer,
118                  const camera_t *camera)
119
120 {
121     assert(goals);
122     assert(renderer);
123     assert(camera);
124
125     for (size_t i = 0; i < goals->goals_count; ++i) {
126         if (!rects_overlap(goals->regions[i], goals->player_hitbox)) {
127             if (goals_render_core(goals, i, renderer, camera) < 0) {
128                 return -1;
129             }
130         }
131     }
132
133     return 0;
134 }
135
136 void goals_update(goals_t *goals,
137                   Uint32 delta_time)
138 {
139     assert(goals);
140     assert(delta_time > 0);
141
142     float d = (float) delta_time / 1000.0f;
143
144     goals->angle = fmodf(goals->angle + 2.0f * d, 2.0f * PI);
145 }
146
147 void goals_hide(goals_t *goals,
148                 rect_t player_hitbox)
149 {
150     goals->player_hitbox = player_hitbox;
151
152 }