]> git.lizzy.rs Git - nothing.git/blob - src/game/level/boxes.c
Get rid of specific rigid_rect methods
[nothing.git] / src / game / level / boxes.c
1 #include <assert.h>
2
3 #include "game/level/boxes.h"
4 #include "game/level/player.h"
5 #include "game/level/player/rigid_rect.h"
6 #include "system/lt.h"
7 #include "system/error.h"
8
9 struct boxes_t
10 {
11     lt_t *lt;
12     size_t count;
13     rigid_rect_t **bodies;
14 };
15
16 boxes_t *create_boxes_from_stream(FILE *stream)
17 {
18     assert(stream);
19
20     lt_t *lt = create_lt();
21
22     if (lt == NULL) {
23         return NULL;
24     }
25
26     boxes_t *boxes = PUSH_LT(lt, malloc(sizeof(boxes_t)), free);
27     if (boxes == NULL) {
28         throw_error(ERROR_TYPE_LIBC);
29         RETURN_LT(lt, NULL);
30     }
31
32     if (fscanf(stream, "%lu", &boxes->count) == EOF) {
33         throw_error(ERROR_TYPE_LIBC);
34         RETURN_LT(lt, NULL);
35     }
36
37     boxes->bodies = PUSH_LT(lt, malloc(sizeof(rigid_rect_t*) * boxes->count), free);
38     if (boxes->bodies == NULL) {
39         throw_error(ERROR_TYPE_LIBC);
40         RETURN_LT(lt, NULL);
41     }
42
43     for (size_t i = 0; i < boxes->count; ++i) {
44         boxes->bodies[i] = PUSH_LT(
45             lt,
46             create_rigid_rect_from_stream(stream),
47             destroy_rigid_rect);
48         if (boxes->bodies[i] == NULL) {
49             RETURN_LT(lt, NULL);
50         }
51     }
52
53     boxes->lt = lt;
54
55     return boxes;
56 }
57
58 void destroy_boxes(boxes_t *boxes)
59 {
60     assert(boxes);
61     RETURN_LT0(boxes->lt);
62 }
63
64 solid_ref_t boxes_as_solid(boxes_t *boxes)
65 {
66     solid_ref_t ref = {
67         .tag = SOLID_BOXES,
68         .solid = (void*) boxes
69     };
70
71     return ref;
72 }
73
74 int boxes_render(boxes_t *boxes, camera_t *camera)
75 {
76     assert(boxes);
77     assert(camera);
78
79     for (size_t i = 0; i < boxes->count; ++i) {
80         if (rigid_rect_render(boxes->bodies[i], camera) < 0) {
81             return -1;
82         }
83     }
84
85     return 0;
86 }
87
88 int boxes_update(boxes_t *boxes,
89                  float delta_time)
90 {
91     assert(boxes);
92     assert(delta_time);
93
94     for (size_t i = 0; i < boxes->count; ++i) {
95         if (rigid_rect_update(boxes->bodies[i], delta_time) < 0) {
96             return -1;
97         }
98     }
99
100     for (size_t i = 0; i < boxes->count; ++i) {
101         for (size_t j = 0; j < boxes->count; ++j) {
102             if (i != j) {
103                 rigid_rect_collide_with_rect(
104                     boxes->bodies[i],
105                     rigid_rect_hitbox(boxes->bodies[j]));
106             }
107         }
108     }
109
110     return 0;
111 }
112
113 void boxes_collide_with_platforms(boxes_t *boxes,
114                                   platforms_t *platforms)
115 {
116     assert(boxes);
117     assert(platforms);
118
119     for (size_t i = 0; i < boxes->count; ++i) {
120         rigid_rect_collide_with_solid(boxes->bodies[i], platforms_as_solid(platforms));
121     }
122 }
123
124 void boxes_collide_with_player(boxes_t *boxes,
125                                player_t *player)
126 {
127     assert(boxes);
128     assert(player);
129
130     for (size_t i = 0; i < boxes->count; ++i) {
131         player_impact_rigid_rect(player, boxes->bodies[i]);
132     }
133 }
134
135 void boxes_rect_object_collide(const boxes_t *boxes,
136                                rect_t object,
137                                int sides[RECT_SIDE_N])
138 {
139     assert(boxes);
140
141     memset(sides, 0, sizeof(int) * RECT_SIDE_N);
142
143     for (size_t i = 0; i < boxes->count; ++i) {
144         const rect_t hitbox = rigid_rect_hitbox(boxes->bodies[i]);
145         rect_object_impact(&object, &hitbox, sides);
146     }
147 }