#include "system/stacktrace.h"
-#include "ebisp/gc.h"
-#include "ebisp/interpreter.h"
-#include "ebisp/parser.h"
-#include "ebisp/scope.h"
+#include "config.h"
#include "player.h"
#include "regions.h"
-#include "script.h"
#include "system/str.h"
#include "system/line_stream.h"
#include "system/log.h"
#include "system/lt.h"
#include "system/nth_alloc.h"
+#include "game/level/level_editor/rect_layer.h"
+#include "game/level/labels.h"
+#include "game/level/goals.h"
enum RegionState {
- RS_PLAYER_INSIDE = 0,
- RS_PLAYER_OUTSIDE
+ RS_PLAYER_OUTSIDE = 0,
+ RS_PLAYER_INSIDE
};
-struct Regions
-{
+struct Regions {
Lt *lt;
size_t count;
+ char *ids;
Rect *rects;
Color *colors;
- Script **scripts;
enum RegionState *states;
+ Action *actions;
+
+ Labels *labels;
+ Goals *goals;
};
-Regions *create_regions_from_line_stream(LineStream *line_stream, Broadcast *broadcast)
+Regions *create_regions_from_rect_layer(const RectLayer *rect_layer,
+ Labels *labels,
+ Goals *goals)
{
- trace_assert(line_stream);
+ trace_assert(rect_layer);
+ trace_assert(labels);
Lt *lt = create_lt();
- if (lt == NULL) {
- return NULL;
- }
Regions *regions = PUSH_LT(
lt,
}
regions->lt = lt;
- if(sscanf(
- line_stream_next(line_stream),
- "%lu",
- ®ions->count) < 0) {
- log_fail("Could not read amount of script regions\n");
+ regions->count = rect_layer_count(rect_layer);
+
+ regions->ids = PUSH_LT(
+ lt,
+ nth_calloc(regions->count * ENTITY_MAX_ID_SIZE, sizeof(char)),
+ free);
+ if (regions->ids == NULL) {
RETURN_LT(lt, NULL);
}
+ memcpy(regions->ids,
+ rect_layer_ids(rect_layer),
+ regions->count * ENTITY_MAX_ID_SIZE * sizeof(char));
+
regions->rects = PUSH_LT(
lt,
if (regions->rects == NULL) {
RETURN_LT(lt, NULL);
}
+ memcpy(regions->rects,
+ rect_layer_rects(rect_layer),
+ regions->count * sizeof(Rect));
+
regions->colors = PUSH_LT(
lt,
if (regions->colors == NULL) {
RETURN_LT(lt, NULL);
}
+ memcpy(regions->colors,
+ rect_layer_colors(rect_layer),
+ regions->count * sizeof(Color));
- regions->scripts = PUSH_LT(
+ regions->states = PUSH_LT(
lt,
- nth_calloc(1, sizeof(Script*) * regions->count),
+ nth_calloc(1, sizeof(enum RegionState) * regions->count),
free);
- if (regions->scripts == NULL) {
+ if (regions->states == NULL) {
RETURN_LT(lt, NULL);
}
- regions->states = PUSH_LT(
+ regions->actions = PUSH_LT(
lt,
- nth_calloc(1, sizeof(enum RegionState) * regions->count),
+ nth_calloc(1, sizeof(Action) * regions->count),
free);
- if (regions->states == NULL) {
+ if (regions->actions == NULL) {
RETURN_LT(lt, NULL);
}
+ memcpy(regions->actions,
+ rect_layer_actions(rect_layer),
+ regions->count * sizeof(Action));
- log_info("Amount of regions: %lu\n", regions->count);
+ // TODO(#1108): impossible to change the region action from the Level Editor
- char color[7];
-
- for (size_t i = 0; i < regions->count; ++i) {
- if (sscanf(
- line_stream_next(line_stream),
- "%f%f%f%f%6s",
- ®ions->rects[i].x,
- ®ions->rects[i].y,
- ®ions->rects[i].w,
- ®ions->rects[i].h,
- color) < 0) {
- log_fail("Could not read size and color of %dth region\n");
- RETURN_LT(lt, NULL);
- }
-
- regions->colors[i] = hexstr(color);
-
- regions->scripts[i] = PUSH_LT(
- lt,
- create_script_from_line_stream(line_stream, broadcast),
- destroy_script);
- if (regions->scripts[i] == NULL) {
- RETURN_LT(lt, NULL);
- }
-
- /* TODO(#472): Script doesn't provide its id on missing callback error */
- if (!script_has_scope_value(regions->scripts[i], "on-enter")) {
- log_fail("Script does not provide on-enter callback\n");
- RETURN_LT(lt, NULL);
- }
-
- if (!script_has_scope_value(regions->scripts[i], "on-leave")) {
- log_fail("Script does not provide on-leave callback\n");
- RETURN_LT(lt, NULL);
- }
-
- regions->states[i] = RS_PLAYER_OUTSIDE;
- }
+ regions->labels = labels;
+ regions->goals = goals;
return regions;
}
if (regions->states[i] == RS_PLAYER_OUTSIDE &&
player_overlaps_rect(player, regions->rects[i])) {
regions->states[i] = RS_PLAYER_INSIDE;
- script_eval(regions->scripts[i], "(on-enter)");
+
+ switch (regions->actions[i].type) {
+ case ACTION_HIDE_LABEL: {
+ labels_hide(regions->labels, regions->actions[i].entity_id);
+ } break;
+
+ case ACTION_TOGGLE_GOAL: {
+ goals_hide(regions->goals, regions->actions[i].entity_id);
+ } break;
+
+ default: {}
+ }
}
}
}
if (regions->states[i] == RS_PLAYER_INSIDE &&
!player_overlaps_rect(player, regions->rects[i])) {
regions->states[i] = RS_PLAYER_OUTSIDE;
- script_eval(regions->scripts[i], "(on-leave)");
+
+ switch (regions->actions[i].type) {
+ case ACTION_TOGGLE_GOAL: {
+ goals_show(regions->goals, regions->actions[i].entity_id);
+ } break;
+
+ default: {}
+ }
}
}
}
-int regions_render(Regions *regions, Camera *camera)
+int regions_render(Regions *regions, const Camera *camera)
{
trace_assert(regions);
trace_assert(camera);