-#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;
}
}
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;
}
}
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;
}
}