]> git.lizzy.rs Git - nothing.git/blobdiff - src/game/level/boxes.c
(#802) TODO
[nothing.git] / src / game / level / boxes.c
index c2b0a0c8c306a5bc37dec4c7185f23c8606f959c..462475e9fb169996797fd6ec30107bddeac63eab 100644 (file)
@@ -1,24 +1,28 @@
 #include "system/stacktrace.h"
 
+#include "broadcast.h"
+#include "ebisp/builtins.h"
+#include "ebisp/interpreter.h"
 #include "game/level/boxes.h"
-#include "game/level/physical_world.h"
 #include "game/level/player.h"
-#include "game/level/player/rigid_rect.h"
+#include "game/level/rigid_bodies.h"
+#include "math/rand.h"
 #include "system/line_stream.h"
+#include "system/log.h"
 #include "system/lt.h"
 #include "system/nth_alloc.h"
-#include "system/log.h"
-#include "ebisp/interpreter.h"
-#include "broadcast.h"
+
+#define BOXES_CAPACITY 1000
 
 struct Boxes
 {
     Lt *lt;
+    RigidBodies *rigid_bodies;
+    RigidBodyId *body_ids;
     size_t count;
-    Rigid_rect **bodies;
 };
 
-Boxes *create_boxes_from_line_stream(LineStream *line_stream)
+Boxes *create_boxes_from_line_stream(LineStream *line_stream, RigidBodies *rigid_bodies)
 {
     trace_assert(line_stream);
 
@@ -32,6 +36,9 @@ Boxes *create_boxes_from_line_stream(LineStream *line_stream)
     if (boxes == NULL) {
         RETURN_LT(lt, NULL);
     }
+    boxes->lt = lt;
+
+    boxes->rigid_bodies = rigid_bodies;
 
     if (sscanf(
             line_stream_next(line_stream),
@@ -40,30 +47,30 @@ Boxes *create_boxes_from_line_stream(LineStream *line_stream)
         log_fail("Could not read amount of boxes\n");
         RETURN_LT(lt, NULL);
     }
+    log_info("Boxes count: %d\n", boxes->count);
 
-    boxes->bodies = PUSH_LT(lt, nth_alloc(sizeof(Rigid_rect*) * boxes->count), free);
-    if (boxes->bodies == NULL) {
+    trace_assert(boxes->count < BOXES_CAPACITY);
+
+    boxes->body_ids = PUSH_LT(lt, nth_alloc(sizeof(RigidBodyId) * BOXES_CAPACITY), free);
+    if (boxes->body_ids == NULL) {
         RETURN_LT(lt, NULL);
     }
 
     for (size_t i = 0; i < boxes->count; ++i) {
-        boxes->bodies[i] = PUSH_LT(
-            lt,
-            create_rigid_rect_from_line_stream(line_stream),
-            destroy_rigid_rect);
-        if (boxes->bodies[i] == NULL) {
-            RETURN_LT(lt, NULL);
-        }
+        boxes->body_ids[i] = rigid_bodies_add_from_line_stream(boxes->rigid_bodies, line_stream);
     }
 
-    boxes->lt = lt;
-
     return boxes;
 }
 
 void destroy_boxes(Boxes *boxes)
 {
     trace_assert(boxes);
+
+    for (size_t i = 0; i < boxes->count; ++i) {
+        rigid_bodies_remove(boxes->rigid_bodies, boxes->body_ids[i]);
+    }
+
     RETURN_LT0(boxes->lt);
 }
 
@@ -73,7 +80,7 @@ int boxes_render(Boxes *boxes, Camera *camera)
     trace_assert(camera);
 
     for (size_t i = 0; i < boxes->count; ++i) {
-        if (rigid_rect_render(boxes->bodies[i], camera) < 0) {
+        if (rigid_bodies_render(boxes->rigid_bodies, boxes->body_ids[i], camera) < 0) {
             return -1;
         }
     }
@@ -88,24 +95,7 @@ int boxes_update(Boxes *boxes,
     trace_assert(delta_time);
 
     for (size_t i = 0; i < boxes->count; ++i) {
-        if (rigid_rect_update(boxes->bodies[i], delta_time) < 0) {
-            return -1;
-        }
-    }
-
-    return 0;
-}
-
-int boxes_add_to_physical_world(const Boxes *boxes,
-                                Physical_world *physical_world)
-{
-    trace_assert(boxes);
-    trace_assert(physical_world);
-
-    for (size_t i = 0; i < boxes->count; ++i) {
-        if (physical_world_add_solid(
-                physical_world,
-                rigid_rect_as_solid(boxes->bodies[i])) < 0) {
+        if (rigid_bodies_update(boxes->rigid_bodies, boxes->body_ids[i], delta_time) < 0) {
             return -1;
         }
     }
@@ -119,20 +109,16 @@ void boxes_float_in_lava(Boxes *boxes, Lava *lava)
     trace_assert(lava);
 
     for (size_t i = 0; i < boxes->count; ++i) {
-        lava_float_rigid_rect(lava, boxes->bodies[i]);
+        lava_float_rigid_body(lava, boxes->rigid_bodies, boxes->body_ids[i]);
     }
 }
 
-Rigid_rect *boxes_rigid_rect(Boxes *boxes, const char *id)
+int boxes_add_box(Boxes *boxes, Rect rect, Color color)
 {
     trace_assert(boxes);
-    trace_assert(id);
+    trace_assert(boxes->count < BOXES_CAPACITY);
 
-    for (size_t i = 0; i < boxes->count; ++i) {
-        if (rigid_rect_has_id(boxes->bodies[i], id)) {
-            return boxes->bodies[i];
-        }
-    }
+    boxes->body_ids[boxes->count++] = rigid_bodies_add(boxes->rigid_bodies, rect, color);
 
     return 0;
 }
@@ -144,18 +130,60 @@ boxes_send(Boxes *boxes, Gc *gc, struct Scope *scope, struct Expr path)
     trace_assert(gc);
     trace_assert(scope);
 
-    const char *target = NULL;
+    struct Expr target = void_expr();
     struct Expr rest = void_expr();
-    struct EvalResult res = match_list(gc, "s*", path, &target, &rest);
+    struct EvalResult res = match_list(gc, "e*", path, &target, &rest);
     if (res.is_error) {
         return res;
     }
 
+    if (symbol_p(target)) {
+        const char *action = target.atom->str;
+
+        if (strcmp(action, "new") == 0) {
+            struct Expr optional_args = void_expr();
+            long int x, y, w, h;
+            res = match_list(gc, "dddd*", rest, &x, &y, &w, &h, &optional_args);
+            if (res.is_error) {
+                return res;
+            }
+
+            Color color = rgba(rand_float(1.0f), rand_float(1.0f), rand_float(1.0f), 1.0f);
+            if (!nil_p(optional_args)) {
+                const char *color_hex = NULL;
+                res = match_list(gc, "s*", optional_args, &color_hex, NULL);
+                color = hexstr(color_hex);
+            }
+
+            boxes_add_box(boxes, rect((float) x, (float) y, (float) w, (float) h), color);
+
+            return eval_success(NIL(gc));
+        }
+
+        return unknown_target(gc, "box", action);
+    }
+
+    return wrong_argument_type(gc, "string-or-symbol-p", target);
+}
+
+
+int boxes_delete_at(Boxes *boxes, Vec position)
+{
+    trace_assert(boxes);
+
     for (size_t i = 0; i < boxes->count; ++i) {
-        if (rigid_rect_has_id(boxes->bodies[i], target)) {
-            return rigid_rect_send(boxes->bodies[i], gc, scope, rest);
+        const Rect hitbox = rigid_bodies_hitbox(
+            boxes->rigid_bodies,
+            boxes->body_ids[i]);
+        if (rect_contains_point(hitbox, position)) {
+            rigid_bodies_remove(boxes->rigid_bodies, boxes->body_ids[i]);
+            for (size_t j = i; j < boxes->count - 1; ++j) {
+                boxes->body_ids[j] = boxes->body_ids[j + 1];
+            }
+            boxes->count--;
+            return 0;
         }
     }
 
-    return unknown_target(gc, "box", target);
+    return 0;
 }