1 #include "system/stacktrace.h"
5 #include "ebisp/builtins.h"
6 #include "ebisp/interpreter.h"
7 #include "game/level/boxes.h"
8 #include "game/level/level_editor/rect_layer.h"
9 #include "game/level/player.h"
10 #include "game/level/rigid_bodies.h"
11 #include "math/rand.h"
12 #include "system/line_stream.h"
13 #include "system/log.h"
14 #include "system/lt.h"
15 #include "system/nth_alloc.h"
16 #include "system/str.h"
21 RigidBodies *rigid_bodies;
24 Dynarray *body_colors;
27 Boxes *create_boxes_from_rect_layer(const RectLayer *layer, RigidBodies *rigid_bodies)
30 trace_assert(rigid_bodies);
34 Boxes *boxes = PUSH_LT(lt, nth_calloc(1, sizeof(Boxes)), free);
40 boxes->rigid_bodies = rigid_bodies;
42 boxes->boxes_ids = PUSH_LT(
44 create_dynarray(RECT_LAYER_ID_MAX_SIZE),
46 if (boxes->boxes_ids == NULL) {
50 boxes->body_ids = PUSH_LT(lt, create_dynarray(sizeof(RigidBodyId)), destroy_dynarray);
51 if (boxes->body_ids == NULL) {
55 boxes->body_colors = PUSH_LT(lt, create_dynarray(sizeof(Color)), destroy_dynarray);
56 if (boxes->body_colors == NULL) {
60 const size_t count = rect_layer_count(layer);
61 Rect const *rects = rect_layer_rects(layer);
62 Color const *colors = rect_layer_colors(layer);
63 const char *ids = rect_layer_ids(layer);
65 for (size_t i = 0; i < count; ++i) {
66 RigidBodyId body_id = rigid_bodies_add(rigid_bodies, rects[i]);
67 dynarray_push(boxes->body_ids, &body_id);
68 dynarray_push(boxes->body_colors, &colors[i]);
69 dynarray_push(boxes->boxes_ids, ids + i * RECT_LAYER_ID_MAX_SIZE);
75 void destroy_boxes(Boxes *boxes)
79 const size_t count = dynarray_count(boxes->body_ids);
80 RigidBodyId *body_ids = dynarray_data(boxes->body_ids);
82 for (size_t i = 0; i < count; ++i) {
83 rigid_bodies_remove(boxes->rigid_bodies, body_ids[i]);
86 RETURN_LT0(boxes->lt);
89 int boxes_render(Boxes *boxes, Camera *camera)
94 const size_t count = dynarray_count(boxes->body_ids);
95 RigidBodyId *body_ids = dynarray_data(boxes->body_ids);
96 Color *body_colors = dynarray_data(boxes->body_colors);
98 for (size_t i = 0; i < count; ++i) {
99 if (rigid_bodies_render(
111 int boxes_update(Boxes *boxes,
116 const size_t count = dynarray_count(boxes->body_ids);
117 RigidBodyId *body_ids = dynarray_data(boxes->body_ids);
119 for (size_t i = 0; i < count; ++i) {
120 if (rigid_bodies_update(boxes->rigid_bodies, body_ids[i], delta_time) < 0) {
128 void boxes_float_in_lava(Boxes *boxes, Lava *lava)
133 const size_t count = dynarray_count(boxes->body_ids);
134 RigidBodyId *body_ids = dynarray_data(boxes->body_ids);
136 for (size_t i = 0; i < count; ++i) {
137 lava_float_rigid_body(lava, boxes->rigid_bodies, body_ids[i]);
141 int boxes_add_box(Boxes *boxes, Rect rect, Color color)
145 RigidBodyId body_id = rigid_bodies_add(boxes->rigid_bodies, rect);
146 dynarray_push(boxes->body_ids, &body_id);
147 dynarray_push(boxes->body_colors, &color);
153 boxes_send(Boxes *boxes, Gc *gc, struct Scope *scope, struct Expr path)
159 struct Expr target = void_expr();
160 struct Expr rest = void_expr();
161 struct EvalResult res = match_list(gc, "e*", path, &target, &rest);
166 if (symbol_p(target)) {
167 const char *action = target.atom->str;
169 if (strcmp(action, "new") == 0) {
170 struct Expr optional_args = void_expr();
172 res = match_list(gc, "dddd*", rest, &x, &y, &w, &h, &optional_args);
177 Color color = rgba(rand_float(1.0f), rand_float(1.0f), rand_float(1.0f), 1.0f);
178 if (!nil_p(optional_args)) {
179 const char *color_hex = NULL;
180 res = match_list(gc, "s*", optional_args, &color_hex, NULL);
181 color = hexstr(color_hex);
184 boxes_add_box(boxes, rect((float) x, (float) y, (float) w, (float) h), color);
186 return eval_success(NIL(gc));
187 } else if (strcmp(action, "coord") == 0) {
188 const char *box_id = NULL;
189 res = match_list(gc, "s", rest, &box_id);
194 size_t n = dynarray_count(boxes->boxes_ids);
195 RigidBodyId *body_ids = dynarray_data(boxes->body_ids);
196 for (size_t i = 0; i < n; ++i) {
197 if (strcmp(dynarray_pointer_at(boxes->boxes_ids, i), box_id) == 0) {
198 Rect hitbox = rigid_bodies_hitbox(boxes->rigid_bodies, body_ids[i]);
201 NUMBER(gc, (long int)hitbox.x),
202 NUMBER(gc, (long int)hitbox.y)));
206 return eval_failure(SYMBOL(gc, "box-not-found"));
209 return unknown_target(gc, "box", action);
212 return wrong_argument_type(gc, "string-or-symbol-p", target);
216 int boxes_delete_at(Boxes *boxes, Vec position)
220 const size_t count = dynarray_count(boxes->body_ids);
221 RigidBodyId *body_ids = dynarray_data(boxes->body_ids);
223 for (size_t i = 0; i < count; ++i) {
224 const Rect hitbox = rigid_bodies_hitbox(
227 if (rect_contains_point(hitbox, position)) {
228 rigid_bodies_remove(boxes->rigid_bodies, body_ids[i]);
229 dynarray_delete_at(boxes->body_ids, i);
230 dynarray_delete_at(boxes->body_colors, i);