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