-#include <SDL2/SDL.h>
+#include <SDL.h>
#include "system/stacktrace.h"
#include "broadcast.h"
#include "game/level/regions.h"
#include "game/level/rigid_bodies.h"
#include "game/level_metadata.h"
-#include "game/level/level_editor/proto_rect.h"
+#include "game/level/level_editor/rect_layer.h"
+#include "game/level/level_editor/point_layer.h"
+#include "game/level/level_editor/player_layer.h"
+#include "game/level/level_editor/label_layer.h"
#include "system/line_stream.h"
#include "system/log.h"
#include "system/lt.h"
-#include "system/lt/lt_adapters.h"
#include "system/nth_alloc.h"
#include "system/str.h"
#include "game/level/level_editor.h"
+#include "game/level/script.h"
-#define LEVEL_LINE_MAX_LENGTH 512
#define LEVEL_GRAVITY 1500.0f
struct Level
{
Lt *lt;
- const char *file_name;
LevelMetadata *metadata;
Background *background;
RigidBodies *rigid_bodies;
Boxes *boxes;
Labels *labels;
Regions *regions;
-
- bool edit_mode;
- // TODO: LevelEditor doesn't capture the initial state of the level loaded from a file
- LevelEditor *level_editor;
+ Broadcast *broadcast;
+ Script *supa_script;
};
-Level *create_level_from_file(const char *file_name, Broadcast *broadcast)
+Level *create_level_from_level_editor(const LevelEditor *level_editor,
+ Broadcast *broadcast)
{
- trace_assert(file_name);
+ trace_assert(level_editor);
+ trace_assert(broadcast);
- Lt *const lt = create_lt();
- if (lt == NULL) {
- return NULL;
- }
+ Lt *lt = create_lt();
- Level *const level = PUSH_LT(lt, nth_alloc(sizeof(Level)), free);
+ Level *level = PUSH_LT(
+ lt,
+ nth_calloc(1, sizeof(Level)),
+ free);
if (level == NULL) {
RETURN_LT(lt, NULL);
}
level->lt = lt;
- level->file_name = PUSH_LT(lt, string_duplicate(file_name, NULL), free);
- if (level->file_name == NULL) {
- RETURN_LT(lt, NULL);
- }
-
- LineStream *level_stream = PUSH_LT(
- lt,
- create_line_stream(
- file_name,
- "r",
- LEVEL_LINE_MAX_LENGTH),
- destroy_line_stream);
- if (level_stream == NULL) {
- RETURN_LT(lt, NULL);
- }
-
- level->metadata = PUSH_LT(
- lt,
- create_level_metadata_from_line_stream(level_stream),
- destroy_level_metadata);
- if (level->metadata == NULL) {
- RETURN_LT(lt, NULL);
- }
-
level->background = PUSH_LT(
lt,
- create_background_from_line_stream(level_stream),
+ create_background(color_picker_rgba(&level_editor->background_layer)),
destroy_background);
if (level->background == NULL) {
RETURN_LT(lt, NULL);
level->player = PUSH_LT(
lt,
- create_player_from_line_stream(level_stream, level->rigid_bodies, broadcast),
+ create_player_from_player_layer(
+ &level_editor->player_layer,
+ level->rigid_bodies,
+ broadcast),
destroy_player);
if (level->player == NULL) {
RETURN_LT(lt, NULL);
level->platforms = PUSH_LT(
lt,
- create_platforms_from_line_stream(level_stream),
+ create_platforms_from_rect_layer(level_editor->platforms_layer),
destroy_platforms);
if (level->platforms == NULL) {
RETURN_LT(lt, NULL);
level->goals = PUSH_LT(
lt,
- create_goals_from_line_stream(level_stream),
+ create_goals_from_point_layer(level_editor->goals_layer),
destroy_goals);
if (level->goals == NULL) {
RETURN_LT(lt, NULL);
level->lava = PUSH_LT(
lt,
- create_lava_from_line_stream(level_stream),
+ create_lava_from_rect_layer(level_editor->lava_layer),
destroy_lava);
if (level->lava == NULL) {
RETURN_LT(lt, NULL);
level->back_platforms = PUSH_LT(
lt,
- create_platforms_from_line_stream(level_stream),
+ create_platforms_from_rect_layer(level_editor->back_platforms_layer),
destroy_platforms);
if (level->back_platforms == NULL) {
RETURN_LT(lt, NULL);
level->boxes = PUSH_LT(
lt,
- create_boxes_from_line_stream(level_stream, level->rigid_bodies),
+ create_boxes_from_rect_layer(level_editor->boxes_layer, level->rigid_bodies),
destroy_boxes);
if (level->boxes == NULL) {
RETURN_LT(lt, NULL);
level->labels = PUSH_LT(
lt,
- create_labels_from_line_stream(level_stream),
+ create_labels_from_label_layer(level_editor->label_layer),
destroy_labels);
if (level->labels == NULL) {
RETURN_LT(lt, NULL);
level->regions = PUSH_LT(
lt,
- create_regions_from_line_stream(level_stream, broadcast),
+ create_regions_from_rect_layer(level_editor->regions_layer),
destroy_regions);
if (level->regions == NULL) {
RETURN_LT(lt, NULL);
}
- level->edit_mode = false;
- level->level_editor = PUSH_LT(
+ level->broadcast = broadcast;
+
+ level->supa_script = PUSH_LT(
lt,
- create_level_editor(),
- destroy_level_editor);
- if (level->level_editor == NULL) {
+ create_script_from_string(
+ broadcast,
+ level_editor->supa_script_source),
+ destroy_script);
+ if (level->supa_script == NULL) {
+ log_fail("Could not construct Supa Script for the level\n");
RETURN_LT(lt, NULL);
}
- destroy_line_stream(RELEASE_LT(lt, level_stream));
-
return level;
}
RETURN_LT0(level->lt);
}
+
int level_render(const Level *level, Camera *camera)
{
trace_assert(level);
return -1;
}
- if (level->edit_mode) {
- if (level_editor_render(level->level_editor, camera) < 0) {
- return -1;
- }
- }
-
return 0;
}
player_hide_goals(level->player, level->goals);
player_die_from_lava(level->player, level->lava);
- regions_player_enter(level->regions, level->player);
- regions_player_leave(level->regions, level->player);
+ regions_player_enter(level->regions, level->player, level->supa_script);
+ regions_player_leave(level->regions, level->player, level->supa_script);
goals_update(level->goals, delta_time);
lava_update(level->lava, delta_time);
labels_update(level->labels, delta_time);
- if (level->edit_mode) {
- level_editor_update(level->level_editor, delta_time);
- }
-
return 0;
}
-int level_event(Level *level, const SDL_Event *event, const Camera *camera)
+int level_event(Level *level, const SDL_Event *event)
{
trace_assert(level);
trace_assert(event);
case SDL_KEYDOWN:
switch (event->key.keysym.sym) {
case SDLK_SPACE: {
- player_jump(level->player);
+ player_jump(level->player, level->supa_script);
} break;
-
- case SDLK_TAB: {
- level->edit_mode = !level->edit_mode;
- SDL_SetRelativeMouseMode(level->edit_mode);
- if (!level->edit_mode) {
- level->boxes = RESET_LT(
- level->lt,
- level->boxes,
- create_boxes_from_layer(
- level_editor_boxes(level->level_editor),
- level->rigid_bodies));
- if (level->boxes == NULL) {
- return -1;
- }
- }
- };
}
break;
case SDL_JOYBUTTONDOWN:
if (event->jbutton.button == 1) {
- player_jump(level->player);
+ player_jump(level->player, level->supa_script);
}
break;
}
- if (level->edit_mode) {
- level_editor_event(level->level_editor, event, camera);
- }
-
return 0;
}
return 0;
}
-int level_reload_preserve_player(Level *level, Broadcast *broadcast)
-{
- Lt * const lt = create_lt();
- if (lt == NULL) {
- return -1;
- }
-
- log_info("Soft-reloading the level from '%s'...\n", level->file_name);
-
- /* TODO(#104): duplicate code in create_level_from_file and level_reload_preserve_player */
-
- LineStream * const level_stream = PUSH_LT(
- lt,
- create_line_stream(
- level->file_name,
- "r",
- LEVEL_LINE_MAX_LENGTH),
- destroy_line_stream);
- if (level_stream == NULL) {
- RETURN_LT(lt, -1);
- }
-
- LevelMetadata *const metadata = create_level_metadata_from_line_stream(level_stream);
- if (metadata == NULL) {
- RETURN_LT(lt, -1);
- }
- level->metadata = RESET_LT(level->lt, level->metadata, metadata);
-
- Background * const background = create_background_from_line_stream(level_stream);
- if (background == NULL) {
- RETURN_LT(lt, -1);
- }
- level->background = RESET_LT(level->lt, level->background, background);
-
- Player * const skipped_player = create_player_from_line_stream(level_stream, level->rigid_bodies, broadcast);
- if (skipped_player == NULL) {
- RETURN_LT(lt, -1);
- }
- destroy_player(skipped_player);
-
- Platforms * const platforms = create_platforms_from_line_stream(level_stream);
- if (platforms == NULL) {
- RETURN_LT(lt, -1);
- }
- level->platforms = RESET_LT(level->lt, level->platforms, platforms);
-
- Goals * const goals = create_goals_from_line_stream(level_stream);
- if (goals == NULL) {
- RETURN_LT(lt, -1);
- }
- level->goals = RESET_LT(level->lt, level->goals, goals);
-
- Lava * const lava = create_lava_from_line_stream(level_stream);
- if (lava == NULL) {
- RETURN_LT(lt, -1);
- }
- level->lava = RESET_LT(level->lt, level->lava, lava);
-
- Platforms * const back_platforms = create_platforms_from_line_stream(level_stream);
- if (back_platforms == NULL) {
- RETURN_LT(lt, -1);
- }
- level->back_platforms = RESET_LT(level->lt, level->back_platforms, back_platforms);
-
- Boxes * const boxes = create_boxes_from_line_stream(level_stream, level->rigid_bodies);
- if (boxes == NULL) {
- RETURN_LT(lt, -1);
- }
- level->boxes = RESET_LT(level->lt, level->boxes, boxes);
-
- Labels * const labels = create_labels_from_line_stream(level_stream);
- if (labels == NULL) {
- RETURN_LT(lt, -1);
- }
- level->labels = RESET_LT(level->lt, level->labels, labels);
-
- Regions * const regions = create_regions_from_line_stream(level_stream, broadcast);
- if (regions == NULL) {
- RETURN_LT(lt, -1);
- }
- level->regions = RESET_LT(level->lt, level->regions, regions);
-
- RETURN_LT(lt, 0);
-}
-
int level_sound(Level *level, Sound_samples *sound_samples)
{
if (goals_sound(level->goals, sound_samples) < 0) {
int level_enter_camera_event(Level *level, Camera *camera)
{
- if (!level->edit_mode) {
- player_focus_camera(level->player, camera);
- camera_scale(camera, 1.0f);
- } else {
- level_editor_focus_camera(
- level->level_editor,
- camera);
- }
+ player_focus_camera(level->player, camera);
+ camera_scale(camera, 1.0f);
goals_cue(level->goals, camera);
goals_checkpoint(level->goals, level->player);
return eval_success(NIL(gc));
} else if (strcmp(target, "edit") == 0) {
- level->edit_mode = !level->edit_mode;
- SDL_SetRelativeMouseMode(level->edit_mode);
return eval_success(NIL(gc));
}
return unknown_target(gc, "level", target);
}
-
-bool level_edit_mode(const Level *level)
-{
- trace_assert(level);
- return level->edit_mode;
-}