1 #include "system/stacktrace.h"
4 #include "ebisp/builtins.h"
5 #include "ebisp/interpreter.h"
6 #include "game/level/boxes.h"
7 #include "game/level/player.h"
8 #include "game/level/rigid_bodies.h"
10 #include "system/line_stream.h"
11 #include "system/log.h"
12 #include "system/lt.h"
13 #include "system/nth_alloc.h"
15 #define BOXES_CAPACITY 1000
20 RigidBodies *rigid_bodies;
21 RigidBodyId *body_ids;
25 Boxes *create_boxes_from_line_stream(LineStream *line_stream, RigidBodies *rigid_bodies)
27 trace_assert(line_stream);
35 Boxes *boxes = PUSH_LT(lt, nth_alloc(sizeof(Boxes)), free);
41 boxes->rigid_bodies = rigid_bodies;
44 line_stream_next(line_stream),
46 &boxes->count) == EOF) {
47 log_fail("Could not read amount of boxes\n");
50 log_info("Boxes count: %d\n", boxes->count);
52 trace_assert(boxes->count < BOXES_CAPACITY);
54 boxes->body_ids = PUSH_LT(lt, nth_alloc(sizeof(RigidBodyId) * BOXES_CAPACITY), free);
55 if (boxes->body_ids == NULL) {
59 for (size_t i = 0; i < boxes->count; ++i) {
60 boxes->body_ids[i] = rigid_bodies_add_from_line_stream(boxes->rigid_bodies, line_stream);
66 void destroy_boxes(Boxes *boxes)
70 for (size_t i = 0; i < boxes->count; ++i) {
71 rigid_bodies_remove(boxes->rigid_bodies, boxes->body_ids[i]);
74 RETURN_LT0(boxes->lt);
77 int boxes_render(Boxes *boxes, Camera *camera)
82 for (size_t i = 0; i < boxes->count; ++i) {
83 if (rigid_bodies_render(boxes->rigid_bodies, boxes->body_ids[i], camera) < 0) {
91 int boxes_update(Boxes *boxes,
95 trace_assert(delta_time);
97 for (size_t i = 0; i < boxes->count; ++i) {
98 if (rigid_bodies_update(boxes->rigid_bodies, boxes->body_ids[i], delta_time) < 0) {
106 void boxes_float_in_lava(Boxes *boxes, Lava *lava)
111 for (size_t i = 0; i < boxes->count; ++i) {
112 lava_float_rigid_body(lava, boxes->rigid_bodies, boxes->body_ids[i]);
116 int boxes_add_box(Boxes *boxes, Rect rect, Color color)
119 trace_assert(boxes->count < BOXES_CAPACITY);
121 boxes->body_ids[boxes->count++] = rigid_bodies_add(boxes->rigid_bodies, rect, color);
127 boxes_send(Boxes *boxes, Gc *gc, struct Scope *scope, struct Expr path)
133 struct Expr target = void_expr();
134 struct Expr rest = void_expr();
135 struct EvalResult res = match_list(gc, "e*", path, &target, &rest);
140 if (symbol_p(target)) {
141 const char *action = target.atom->str;
143 if (strcmp(action, "new") == 0) {
144 struct Expr optional_args = void_expr();
146 res = match_list(gc, "dddd*", rest, &x, &y, &w, &h, &optional_args);
151 Color color = rgba(rand_float(1.0f), rand_float(1.0f), rand_float(1.0f), 1.0f);
152 if (!nil_p(optional_args)) {
153 const char *color_hex = NULL;
154 res = match_list(gc, "s*", optional_args, &color_hex, NULL);
155 color = hexstr(color_hex);
158 boxes_add_box(boxes, rect((float) x, (float) y, (float) w, (float) h), color);
160 return eval_success(NIL(gc));
163 return unknown_target(gc, "box", action);
166 return wrong_argument_type(gc, "string-or-symbol-p", target);
170 int boxes_delete_at(Boxes *boxes, Vec position)
174 for (size_t i = 0; i < boxes->count; ++i) {
175 const Rect hitbox = rigid_bodies_hitbox(
178 if (rect_contains_point(hitbox, position)) {
179 rigid_bodies_remove(boxes->rigid_bodies, boxes->body_ids[i]);
180 for (size_t j = i; j < boxes->count - 1; ++j) {
181 boxes->body_ids[j] = boxes->body_ids[j + 1];