]> git.lizzy.rs Git - nothing.git/blob - src/game/level/lava.c
Remove `lt == NULL` checks
[nothing.git] / src / game / level / lava.c
1 #include <SDL2/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/line_stream.h"
11 #include "system/nth_alloc.h"
12 #include "system/log.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_line_stream(LineStream *line_stream)
23 {
24     trace_assert(line_stream);
25
26     Lt lt = {0};
27
28     Lava *lava = PUSH_LT(lt, nth_calloc(1, sizeof(Lava)), free);
29     if (lava == NULL) {
30         RETURN_LT(lt, NULL);
31     }
32
33     if (sscanf(
34             line_stream_next(line_stream),
35             "%lu",
36             &lava->rects_count) < 0) {
37         log_fail("Could not read amount of lavas\n");
38         RETURN_LT(lt, NULL);
39     }
40
41     lava->rects = PUSH_LT(lt, nth_calloc(1, sizeof(Wavy_rect*) * lava->rects_count), free);
42     if (lava->rects == NULL) {
43         RETURN_LT(lt, NULL);
44     }
45
46     for (size_t i = 0; i < lava->rects_count; ++i) {
47         lava->rects[i] = PUSH_LT(lt, create_wavy_rect_from_line_stream(line_stream), destroy_wavy_rect);
48         if (lava->rects[i] == NULL) {
49             RETURN_LT(lt, NULL);
50         }
51     }
52
53     lava->lt = lt;
54
55     return lava;
56 }
57
58 void destroy_lava(Lava *lava)
59 {
60     trace_assert(lava);
61     RETURN_LT0(lava->lt);
62 }
63
64 /* TODO(#449): lava does not render its id in debug mode */
65 int lava_render(const Lava *lava,
66                 Camera *camera)
67 {
68     trace_assert(lava);
69     trace_assert(camera);
70
71     for (size_t i = 0; i < lava->rects_count; ++i) {
72         if (wavy_rect_render(lava->rects[i], camera) < 0) {
73             return -1;
74         }
75     }
76
77     return 0;
78 }
79
80 int lava_update(Lava *lava, float delta_time)
81 {
82     trace_assert(lava);
83
84     for (size_t i = 0; i < lava->rects_count; ++i) {
85         if (wavy_rect_update(lava->rects[i], delta_time) < 0) {
86             return -1;
87         }
88     }
89
90     return 0;
91 }
92
93 bool lava_overlaps_rect(const Lava *lava,
94                         Rect rect)
95 {
96     trace_assert(lava);
97
98     for (size_t i = 0; i < lava->rects_count; ++i) {
99         if (rects_overlap(wavy_rect_hitbox(lava->rects[i]), rect)) {
100             return true;
101         }
102     }
103
104     return 0;
105 }
106
107 void lava_float_rigid_body(Lava *lava, RigidBodies *rigid_bodies, RigidBodyId id)
108 {
109     trace_assert(lava);
110
111     const Rect object_hitbox = rigid_bodies_hitbox(rigid_bodies, id);
112     for (size_t i = 0; i < lava->rects_count; ++i) {
113         const Rect lava_hitbox = wavy_rect_hitbox(lava->rects[i]);
114         if (rects_overlap(object_hitbox, lava_hitbox)) {
115             const Rect overlap_area = rects_overlap_area(object_hitbox, lava_hitbox);
116             const float k = overlap_area.w * overlap_area.h / (object_hitbox.w * object_hitbox.h);
117             rigid_bodies_apply_force(
118                 rigid_bodies,
119                 id,
120                 vec(0.0f, -k * LAVA_BOINGNESS));
121             rigid_bodies_damper(rigid_bodies, id, vec(0.0f, -0.9f));
122         }
123     }
124 }