]> git.lizzy.rs Git - nothing.git/blobdiff - src/game/level/boxes.c
create_dynarray_from_memory -> create_dynarray
[nothing.git] / src / game / level / boxes.c
index 71112ece42862e56562a04d198351872fe5359d9..5635f6d57edf563b1247e10eb69ea995205794b5 100644 (file)
@@ -1,78 +1,91 @@
-#include <assert.h>
+#include "system/stacktrace.h"
 
+#include "dynarray.h"
 #include "game/level/boxes.h"
-#include "game/level/physical_world.h"
+#include "game/level/level_editor/rect_layer.h"
 #include "game/level/player.h"
-#include "game/level/player/rigid_rect.h"
-#include "system/error.h"
+#include "game/level/rigid_bodies.h"
+#include "math/rand.h"
+#include "system/log.h"
 #include "system/lt.h"
-#include "system/line_stream.h"
+#include "system/nth_alloc.h"
+#include "system/str.h"
+#include "config.h"
 
 struct Boxes
 {
     Lt *lt;
-    size_t count;
-    Rigid_rect **bodies;
+    RigidBodies *rigid_bodies;
+    Dynarray boxes_ids;
+    Dynarray body_ids;
+    Dynarray body_colors;
 };
 
-Boxes *create_boxes_from_line_stream(LineStream *line_stream)
+Boxes *create_boxes_from_rect_layer(const RectLayer *layer, RigidBodies *rigid_bodies)
 {
-    assert(line_stream);
+    trace_assert(layer);
+    trace_assert(rigid_bodies);
 
     Lt *lt = create_lt();
 
-    if (lt == NULL) {
-        return NULL;
-    }
-
-    Boxes *boxes = PUSH_LT(lt, malloc(sizeof(Boxes)), free);
+    Boxes *boxes = PUSH_LT(lt, nth_calloc(1, sizeof(Boxes)), free);
     if (boxes == NULL) {
-        throw_error(ERROR_TYPE_LIBC);
         RETURN_LT(lt, NULL);
     }
+    boxes->lt = lt;
 
-    if (sscanf(
-            line_stream_next(line_stream),
-            "%lu",
-            &boxes->count) == EOF) {
-        throw_error(ERROR_TYPE_LIBC);
-        RETURN_LT(lt, NULL);
-    }
+    boxes->boxes_ids = create_dynarray_malloc(ENTITY_MAX_ID_SIZE);
+    boxes->body_ids = create_dynarray_malloc(sizeof(RigidBodyId));
+    boxes->body_colors = create_dynarray_malloc(sizeof(Color));
 
-    boxes->bodies = PUSH_LT(lt, malloc(sizeof(Rigid_rect*) * boxes->count), free);
-    if (boxes->bodies == NULL) {
-        throw_error(ERROR_TYPE_LIBC);
-        RETURN_LT(lt, NULL);
-    }
+    boxes->rigid_bodies = rigid_bodies;
 
-    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);
-        }
-    }
+    const size_t count = rect_layer_count(layer);
+    Rect const *rects = rect_layer_rects(layer);
+    Color const *colors = rect_layer_colors(layer);
+    const char *ids = rect_layer_ids(layer);
 
-    boxes->lt = lt;
+    for (size_t i = 0; i < count; ++i) {
+        RigidBodyId body_id = rigid_bodies_add(rigid_bodies, rects[i]);
+        dynarray_push(&boxes->body_ids, &body_id);
+        dynarray_push(&boxes->body_colors, &colors[i]);
+        dynarray_push(&boxes->boxes_ids, ids + i * ENTITY_MAX_ID_SIZE);
+    }
 
     return boxes;
 }
 
 void destroy_boxes(Boxes *boxes)
 {
-    assert(boxes);
+    trace_assert(boxes);
+
+    RigidBodyId *body_ids = (RigidBodyId *)boxes->body_ids.data;
+    for (size_t i = 0; i < boxes->body_ids.count; ++i) {
+        rigid_bodies_remove(boxes->rigid_bodies, body_ids[i]);
+    }
+
+    free(boxes->boxes_ids.data);
+    free(boxes->body_ids.data);
+    free(boxes->body_colors.data);
+
     RETURN_LT0(boxes->lt);
 }
 
-int boxes_render(Boxes *boxes, Camera *camera)
+int boxes_render(Boxes *boxes, const Camera *camera)
 {
-    assert(boxes);
-    assert(camera);
-
-    for (size_t i = 0; i < boxes->count; ++i) {
-        if (rigid_rect_render(boxes->bodies[i], camera) < 0) {
+    trace_assert(boxes);
+    trace_assert(camera);
+
+    const size_t count = boxes->body_ids.count;
+    RigidBodyId *body_ids = (RigidBodyId *)boxes->body_ids.data;
+    Color *body_colors = (Color *)boxes->body_colors.data;
+
+    for (size_t i = 0; i < count; ++i) {
+        if (rigid_bodies_render(
+                boxes->rigid_bodies,
+                body_ids[i],
+                body_colors[i],
+                camera) < 0) {
             return -1;
         }
     }
@@ -83,11 +96,13 @@ int boxes_render(Boxes *boxes, Camera *camera)
 int boxes_update(Boxes *boxes,
                  float delta_time)
 {
-    assert(boxes);
-    assert(delta_time);
+    trace_assert(boxes);
 
-    for (size_t i = 0; i < boxes->count; ++i) {
-        if (rigid_rect_update(boxes->bodies[i], delta_time) < 0) {
+    const size_t count = boxes->body_ids.count;
+    RigidBodyId *body_ids = (RigidBodyId *)boxes->body_ids.data;
+
+    for (size_t i = 0; i < count; ++i) {
+        if (rigid_bodies_update(boxes->rigid_bodies, body_ids[i], delta_time) < 0) {
             return -1;
         }
     }
@@ -95,41 +110,46 @@ int boxes_update(Boxes *boxes,
     return 0;
 }
 
-int boxes_add_to_physical_world(const Boxes *boxes,
-                                Physical_world *physical_world)
+void boxes_float_in_lava(Boxes *boxes, Lava *lava)
 {
-    assert(boxes);
-    assert(physical_world);
+    trace_assert(boxes);
+    trace_assert(lava);
 
-    for (size_t i = 0; i < boxes->count; ++i) {
-        if (physical_world_add_solid(
-                physical_world,
-                rigid_rect_as_solid(boxes->bodies[i])) < 0) {
-            return -1;
-        }
-    }
+    const size_t count = boxes->body_ids.count;
+    RigidBodyId *body_ids = (RigidBodyId*)boxes->body_ids.data;
 
-    return 0;
+    for (size_t i = 0; i < count; ++i) {
+        lava_float_rigid_body(lava, boxes->rigid_bodies, body_ids[i]);
+    }
 }
 
-void boxes_float_in_lava(Boxes *boxes, Lava *lava)
+int boxes_add_box(Boxes *boxes, Rect rect, Color color)
 {
-    assert(boxes);
-    assert(lava);
+    trace_assert(boxes);
 
-    for (size_t i = 0; i < boxes->count; ++i) {
-        lava_float_rigid_rect(lava, boxes->bodies[i]);
-    }
+    RigidBodyId body_id = rigid_bodies_add(boxes->rigid_bodies, rect);
+    dynarray_push(&boxes->body_ids, &body_id);
+    dynarray_push(&boxes->body_colors, &color);
+
+    return 0;
 }
 
-Rigid_rect *boxes_rigid_rect(Boxes *boxes, const char *id)
+int boxes_delete_at(Boxes *boxes, Vec2f position)
 {
-    assert(boxes);
-    assert(id);
-
-    for (size_t i = 0; i < boxes->count; ++i) {
-        if (rigid_rect_has_id(boxes->bodies[i], id)) {
-            return boxes->bodies[i];
+    trace_assert(boxes);
+
+    const size_t count = boxes->body_ids.count;
+    RigidBodyId *body_ids = (RigidBodyId*)boxes->body_ids.data;
+
+    for (size_t i = 0; i < count; ++i) {
+        const Rect hitbox = rigid_bodies_hitbox(
+            boxes->rigid_bodies,
+            body_ids[i]);
+        if (rect_contains_point(hitbox, position)) {
+            rigid_bodies_remove(boxes->rigid_bodies, body_ids[i]);
+            dynarray_delete_at(&boxes->body_ids, i);
+            dynarray_delete_at(&boxes->body_colors, i);
+            return 0;
         }
     }