]> git.lizzy.rs Git - nothing.git/blob - src/game/level/boxes.c
(#189) Fix standing on the boxes
[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 int boxes_render(boxes_t *boxes, camera_t *camera)
65 {
66     assert(boxes);
67     assert(camera);
68
69     for (size_t i = 0; i < boxes->count; ++i) {
70         if (rigid_rect_render(boxes->bodies[i], camera) < 0) {
71             return -1;
72         }
73     }
74
75     return 0;
76 }
77
78 int boxes_update(boxes_t *boxes,
79                  float delta_time)
80 {
81     assert(boxes);
82     assert(delta_time);
83
84     for (size_t i = 0; i < boxes->count; ++i) {
85         if (rigid_rect_update(boxes->bodies[i], delta_time) < 0) {
86             return -1;
87         }
88     }
89
90     for (size_t i = 0; i < boxes->count; ++i) {
91         for (size_t j = 0; j < boxes->count; ++j) {
92             if (i != j) {
93                 rigid_rect_collide_with_rect(
94                     boxes->bodies[i],
95                     rigid_rect_hitbox(boxes->bodies[j]));
96             }
97         }
98     }
99
100     return 0;
101 }
102
103 void boxes_collide_with_platforms(boxes_t *boxes,
104                                   const platforms_t *platforms)
105 {
106     assert(boxes);
107     assert(platforms);
108
109     for (size_t i = 0; i < boxes->count; ++i) {
110         rigid_rect_collide_with_platforms(boxes->bodies[i], platforms);
111     }
112 }
113
114 void boxes_collide_with_player(boxes_t *boxes,
115                                player_t *player)
116 {
117     assert(boxes);
118     assert(player);
119
120     for (size_t i = 0; i < boxes->count; ++i) {
121         player_impact_rigid_rect(player, boxes->bodies[i]);
122     }
123 }
124
125 void boxes_rect_object_collide(const boxes_t *boxes,
126                                rect_t object,
127                                int sides[RECT_SIDE_N])
128 {
129     assert(boxes);
130
131     memset(sides, 0, sizeof(int) * RECT_SIDE_N);
132
133     for (size_t i = 0; i < boxes->count; ++i) {
134         const rect_t hitbox = rigid_rect_hitbox(boxes->bodies[i]);
135         rect_object_impact(&object, &hitbox, sides);
136     }
137 }