]> git.lizzy.rs Git - nothing.git/blob - src/game/level/lava.c
Delete LineStream from the existance
[nothing.git] / src / game / level / lava.c
1 #include <SDL.h>
2 #include "system/stacktrace.h"
3 #include <stdio.h>
4
5 #include "color.h"
6 #include "game/level/lava/wavy_rect.h"
7 #include "lava.h"
8 #include "math/rect.h"
9 #include "system/lt.h"
10 #include "system/nth_alloc.h"
11 #include "system/log.h"
12 #include "game/level/level_editor/rect_layer.h"
13
14 #define LAVA_BOINGNESS 2500.0f
15
16 struct Lava {
17     Lt *lt;
18     size_t rects_count;
19     Wavy_rect **rects;
20 };
21
22 Lava *create_lava_from_rect_layer(const RectLayer *rect_layer)
23 {
24     Lt *lt = create_lt();
25
26     Lava *lava = PUSH_LT(lt, nth_calloc(1, sizeof(Lava)), free);
27     if (lava == NULL) {
28         RETURN_LT(lt, NULL);
29     }
30     lava->lt = lt;
31
32     lava->rects_count = rect_layer_count(rect_layer);
33     lava->rects = PUSH_LT(lt, nth_calloc(lava->rects_count, sizeof(Wavy_rect*)), free);
34     if (lava->rects == NULL) {
35         RETURN_LT(lt, NULL);
36     }
37
38     const Rect *rects = rect_layer_rects(rect_layer);
39     const Color *colors = rect_layer_colors(rect_layer);
40     for (size_t i = 0; i < lava->rects_count; ++i) {
41         lava->rects[i] = PUSH_LT(lt, create_wavy_rect(rects[i], colors[i]), destroy_wavy_rect);
42         if (lava->rects[i] == NULL) {
43             RETURN_LT(lt, NULL);
44         }
45     }
46
47     return lava;
48 }
49
50 void destroy_lava(Lava *lava)
51 {
52     trace_assert(lava);
53     RETURN_LT0(lava->lt);
54 }
55
56 /* TODO(#449): lava does not render its id in debug mode */
57 int lava_render(const Lava *lava,
58                 const Camera *camera)
59 {
60     trace_assert(lava);
61     trace_assert(camera);
62
63     for (size_t i = 0; i < lava->rects_count; ++i) {
64         if (wavy_rect_render(lava->rects[i], camera) < 0) {
65             return -1;
66         }
67     }
68
69     return 0;
70 }
71
72 int lava_update(Lava *lava, float delta_time)
73 {
74     trace_assert(lava);
75
76     for (size_t i = 0; i < lava->rects_count; ++i) {
77         if (wavy_rect_update(lava->rects[i], delta_time) < 0) {
78             return -1;
79         }
80     }
81
82     return 0;
83 }
84
85 bool lava_overlaps_rect(const Lava *lava,
86                         Rect rect)
87 {
88     trace_assert(lava);
89
90     for (size_t i = 0; i < lava->rects_count; ++i) {
91         if (rects_overlap(wavy_rect_hitbox(lava->rects[i]), rect)) {
92             return true;
93         }
94     }
95
96     return 0;
97 }
98
99 void lava_float_rigid_body(Lava *lava, RigidBodies *rigid_bodies, RigidBodyId id)
100 {
101     trace_assert(lava);
102
103     const Rect object_hitbox = rigid_bodies_hitbox(rigid_bodies, id);
104     for (size_t i = 0; i < lava->rects_count; ++i) {
105         const Rect lava_hitbox = wavy_rect_hitbox(lava->rects[i]);
106         if (rects_overlap(object_hitbox, lava_hitbox)) {
107             const Rect overlap_area = rects_overlap_area(object_hitbox, lava_hitbox);
108             const float k = overlap_area.w * overlap_area.h / (object_hitbox.w * object_hitbox.h);
109             rigid_bodies_apply_force(
110                 rigid_bodies,
111                 id,
112                 vec(0.0f, -k * LAVA_BOINGNESS));
113             rigid_bodies_damper(rigid_bodies, id, vec(0.0f, -0.9f));
114         }
115     }
116 }