1 #include "system/stacktrace.h"
4 #include "ebisp/interpreter.h"
5 #include "ebisp/parser.h"
6 #include "ebisp/scope.h"
10 #include "system/str.h"
11 #include "system/line_stream.h"
12 #include "system/log.h"
13 #include "system/lt.h"
14 #include "system/nth_alloc.h"
28 enum RegionState *states;
31 Regions *create_regions_from_line_stream(LineStream *line_stream, Broadcast *broadcast)
33 trace_assert(line_stream);
40 Regions *regions = PUSH_LT(
42 nth_calloc(1, sizeof(Regions)),
44 if (regions == NULL) {
50 line_stream_next(line_stream),
52 ®ions->count) < 0) {
53 log_fail("Could not read amount of script regions\n");
57 regions->rects = PUSH_LT(
59 nth_calloc(1, sizeof(Rect) * regions->count),
61 if (regions->rects == NULL) {
65 regions->colors = PUSH_LT(
67 nth_calloc(1, sizeof(Color) * regions->count),
69 if (regions->colors == NULL) {
73 regions->scripts = PUSH_LT(
75 nth_calloc(1, sizeof(Script*) * regions->count),
77 if (regions->scripts == NULL) {
81 regions->states = PUSH_LT(
83 nth_calloc(1, sizeof(enum RegionState) * regions->count),
85 if (regions->states == NULL) {
89 log_info("Amount of regions: %lu\n", regions->count);
93 for (size_t i = 0; i < regions->count; ++i) {
95 line_stream_next(line_stream),
100 ®ions->rects[i].h,
102 log_fail("Could not read size and color of %dth region\n");
106 regions->colors[i] = hexstr(color);
108 regions->scripts[i] = PUSH_LT(
110 create_script_from_line_stream(line_stream, broadcast),
112 if (regions->scripts[i] == NULL) {
116 /* TODO(#472): Script doesn't provide its id on missing callback error */
117 if (!script_has_scope_value(regions->scripts[i], "on-enter")) {
118 log_fail("Script does not provide on-enter callback\n");
122 if (!script_has_scope_value(regions->scripts[i], "on-leave")) {
123 log_fail("Script does not provide on-leave callback\n");
127 regions->states[i] = RS_PLAYER_OUTSIDE;
134 void destroy_regions(Regions *regions)
136 trace_assert(regions);
137 RETURN_LT0(regions->lt);
140 void regions_player_enter(Regions *regions, Player *player)
142 trace_assert(regions);
143 trace_assert(player);
145 for (size_t i = 0; i < regions->count; ++i) {
146 if (regions->states[i] == RS_PLAYER_OUTSIDE &&
147 player_overlaps_rect(player, regions->rects[i])) {
148 regions->states[i] = RS_PLAYER_INSIDE;
149 script_eval(regions->scripts[i], "(on-enter)");
154 void regions_player_leave(Regions *regions, Player *player)
156 trace_assert(regions);
157 trace_assert(player);
159 for (size_t i = 0; i < regions->count; ++i) {
160 if (regions->states[i] == RS_PLAYER_INSIDE &&
161 !player_overlaps_rect(player, regions->rects[i])) {
162 regions->states[i] = RS_PLAYER_OUTSIDE;
163 script_eval(regions->scripts[i], "(on-leave)");
168 int regions_render(Regions *regions, Camera *camera)
170 trace_assert(regions);
171 trace_assert(camera);
173 for (size_t i = 0; i < regions->count; ++i) {
174 if (camera_render_debug_rect(
177 regions->colors[i]) < 0) {