]> git.lizzy.rs Git - nothing.git/blob - src/game/level/boxes.c
fa6827df341471080e4d169eb4b85e4776c38f84
[nothing.git] / src / game / level / boxes.c
1 #include "system/stacktrace.h"
2
3 #include "dynarray.h"
4 #include "game/level/boxes.h"
5 #include "game/level/level_editor/rect_layer.h"
6 #include "game/level/player.h"
7 #include "game/level/rigid_bodies.h"
8 #include "math/rand.h"
9 #include "system/log.h"
10 #include "system/lt.h"
11 #include "system/nth_alloc.h"
12 #include "system/str.h"
13 #include "config.h"
14
15 struct Boxes
16 {
17     Lt *lt;
18     RigidBodies *rigid_bodies;
19     Dynarray boxes_ids;
20     Dynarray body_ids;
21     Dynarray body_colors;
22 };
23
24 Boxes *create_boxes_from_rect_layer(const RectLayer *layer, RigidBodies *rigid_bodies)
25 {
26     trace_assert(layer);
27     trace_assert(rigid_bodies);
28
29     Lt *lt = create_lt();
30
31     Boxes *boxes = PUSH_LT(lt, nth_calloc(1, sizeof(Boxes)), free);
32     if (boxes == NULL) {
33         RETURN_LT(lt, NULL);
34     }
35     boxes->lt = lt;
36
37     boxes->boxes_ids = create_dynarray(ENTITY_MAX_ID_SIZE);
38     boxes->body_ids = create_dynarray(sizeof(RigidBodyId));
39     boxes->body_colors = create_dynarray(sizeof(Color));
40
41     boxes->rigid_bodies = rigid_bodies;
42
43     const size_t count = rect_layer_count(layer);
44     Rect const *rects = rect_layer_rects(layer);
45     Color const *colors = rect_layer_colors(layer);
46     const char *ids = rect_layer_ids(layer);
47
48     for (size_t i = 0; i < count; ++i) {
49         RigidBodyId body_id = rigid_bodies_add(rigid_bodies, rects[i]);
50         dynarray_push(&boxes->body_ids, &body_id);
51         dynarray_push(&boxes->body_colors, &colors[i]);
52         dynarray_push(&boxes->boxes_ids, ids + i * ENTITY_MAX_ID_SIZE);
53     }
54
55     return boxes;
56 }
57
58 void destroy_boxes(Boxes *boxes)
59 {
60     trace_assert(boxes);
61
62     RigidBodyId *body_ids = (RigidBodyId *)boxes->body_ids.data;
63     for (size_t i = 0; i < boxes->body_ids.count; ++i) {
64         rigid_bodies_remove(boxes->rigid_bodies, body_ids[i]);
65     }
66
67     free(boxes->boxes_ids.data);
68     free(boxes->body_ids.data);
69     free(boxes->body_colors.data);
70
71     RETURN_LT0(boxes->lt);
72 }
73
74 int boxes_render(Boxes *boxes, const Camera *camera)
75 {
76     trace_assert(boxes);
77     trace_assert(camera);
78
79     const size_t count = boxes->body_ids.count;
80     RigidBodyId *body_ids = (RigidBodyId *)boxes->body_ids.data;
81     Color *body_colors = (Color *)boxes->body_colors.data;
82
83     for (size_t i = 0; i < count; ++i) {
84         if (rigid_bodies_render(
85                 boxes->rigid_bodies,
86                 body_ids[i],
87                 body_colors[i],
88                 camera) < 0) {
89             return -1;
90         }
91     }
92
93     return 0;
94 }
95
96 int boxes_update(Boxes *boxes,
97                  float delta_time)
98 {
99     trace_assert(boxes);
100
101     const size_t count = boxes->body_ids.count;
102     RigidBodyId *body_ids = (RigidBodyId *)boxes->body_ids.data;
103
104     for (size_t i = 0; i < count; ++i) {
105         if (rigid_bodies_update(boxes->rigid_bodies, body_ids[i], delta_time) < 0) {
106             return -1;
107         }
108     }
109
110     return 0;
111 }
112
113 void boxes_float_in_lava(Boxes *boxes, Lava *lava)
114 {
115     trace_assert(boxes);
116     trace_assert(lava);
117
118     const size_t count = boxes->body_ids.count;
119     RigidBodyId *body_ids = (RigidBodyId*)boxes->body_ids.data;
120
121     for (size_t i = 0; i < count; ++i) {
122         lava_float_rigid_body(lava, boxes->rigid_bodies, body_ids[i]);
123     }
124 }
125
126 int boxes_add_box(Boxes *boxes, Rect rect, Color color)
127 {
128     trace_assert(boxes);
129
130     RigidBodyId body_id = rigid_bodies_add(boxes->rigid_bodies, rect);
131     dynarray_push(&boxes->body_ids, &body_id);
132     dynarray_push(&boxes->body_colors, &color);
133
134     return 0;
135 }
136
137 int boxes_delete_at(Boxes *boxes, Vec2f position)
138 {
139     trace_assert(boxes);
140
141     const size_t count = boxes->body_ids.count;
142     RigidBodyId *body_ids = (RigidBodyId*)boxes->body_ids.data;
143
144     for (size_t i = 0; i < count; ++i) {
145         const Rect hitbox = rigid_bodies_hitbox(
146             boxes->rigid_bodies,
147             body_ids[i]);
148         if (rect_contains_point(hitbox, position)) {
149             rigid_bodies_remove(boxes->rigid_bodies, body_ids[i]);
150             dynarray_delete_at(&boxes->body_ids, i);
151             dynarray_delete_at(&boxes->body_colors, i);
152             return 0;
153         }
154     }
155
156     return 0;
157 }