#include "game/level/physical_world.h"
#include "game/level/platforms.h"
#include "game/level/player.h"
-#include "system/error.h"
+#include "game/level/regions.h"
+#include "system/line_stream.h"
#include "system/lt.h"
#include "system/lt/lt_adapters.h"
+#include "system/nth_alloc.h"
+
+#define LEVEL_LINE_MAX_LENGTH 512
struct Level
{
Background *background;
Boxes *boxes;
Labels *labels;
+ Regions *regions;
};
Level *create_level_from_file(const char *file_name)
return NULL;
}
- Level *const level = PUSH_LT(lt, malloc(sizeof(Level)), free);
+ Level *const level = PUSH_LT(lt, nth_alloc(sizeof(Level)), free);
if (level == NULL) {
- throw_error(ERROR_TYPE_LIBC);
RETURN_LT(lt, NULL);
}
- FILE *level_file = PUSH_LT(lt, fopen(file_name, "r"), fclose_lt);
- if (level_file == NULL) {
- throw_error(ERROR_TYPE_LIBC);
+ 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->background = PUSH_LT(
lt,
- create_background_from_stream(level_file),
+ create_background_from_line_stream(level_stream),
destroy_background);
if (level->background == NULL) {
RETURN_LT(lt, NULL);
}
- level->player = PUSH_LT(lt, create_player_from_stream(level_file), destroy_player);
+ level->player = PUSH_LT(
+ lt,
+ create_player_from_line_stream(level_stream),
+ destroy_player);
if (level->player == NULL) {
RETURN_LT(lt, NULL);
}
- level->platforms = PUSH_LT(lt, create_platforms_from_stream(level_file), destroy_platforms);
+ level->platforms = PUSH_LT(
+ lt,
+ create_platforms_from_line_stream(level_stream),
+ destroy_platforms);
if (level->platforms == NULL) {
RETURN_LT(lt, NULL);
}
- level->goals = PUSH_LT(lt, create_goals_from_stream(level_file), destroy_goals);
+ level->goals = PUSH_LT(
+ lt,
+ create_goals_from_line_stream(level_stream),
+ destroy_goals);
if (level->goals == NULL) {
RETURN_LT(lt, NULL);
}
- level->lava = PUSH_LT(lt, create_lava_from_stream(level_file), destroy_lava);
+ level->lava = PUSH_LT(
+ lt,
+ create_lava_from_line_stream(level_stream),
+ destroy_lava);
if (level->lava == NULL) {
RETURN_LT(lt, NULL);
}
- level->back_platforms = PUSH_LT(lt, create_platforms_from_stream(level_file), destroy_platforms);
+ level->back_platforms = PUSH_LT(
+ lt,
+ create_platforms_from_line_stream(level_stream),
+ destroy_platforms);
if (level->back_platforms == NULL) {
RETURN_LT(lt, NULL);
}
- level->boxes = PUSH_LT(lt, create_boxes_from_stream(level_file), destroy_boxes);
+ level->boxes = PUSH_LT(
+ lt,
+ create_boxes_from_line_stream(level_stream),
+ destroy_boxes);
if (level->boxes == NULL) {
RETURN_LT(lt, NULL);
}
- level->labels = PUSH_LT(lt, create_labels_from_stream(level_file), destroy_labels);
+ level->labels = PUSH_LT(
+ lt,
+ create_labels_from_line_stream(level_stream),
+ destroy_labels);
if (level->labels == NULL) {
RETURN_LT(lt, NULL);
}
+ level->regions = PUSH_LT(
+ lt,
+ create_regions_from_line_stream(level_stream, level),
+ destroy_regions);
+ if (level->regions == NULL) {
+ RETURN_LT(lt, NULL);
+ }
+
level->physical_world = PUSH_LT(lt, create_physical_world(), destroy_physical_world);
if (level->physical_world == NULL) {
RETURN_LT(lt, NULL);
level->lt = lt;
- fclose(RELEASE_LT(lt, level_file));
+ destroy_line_stream(RELEASE_LT(lt, level_stream));
return level;
}
return -1;
}
+ if (regions_render(level->regions, 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);
goals_update(level->goals, delta_time);
lava_update(level->lava, delta_time);
/* TODO(#104): duplicate code in create_level_from_file and level_reload_preserve_player */
- FILE * const level_file = PUSH_LT(lt, fopen(file_name, "r"), fclose_lt);
- if (level_file == NULL) {
- throw_error(ERROR_TYPE_LIBC);
+ LineStream * const 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, -1);
}
- Background * const background = create_background_from_stream(level_file);
+ 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_stream(level_file);
+ Player * const skipped_player = create_player_from_line_stream(level_stream);
if (skipped_player == NULL) {
RETURN_LT(lt, -1);
}
destroy_player(skipped_player);
- Platforms * const platforms = create_platforms_from_stream(level_file);
+ 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_stream(level_file);
+ 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_stream(level_file);
+ 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_stream(level_file);
+ 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_stream(level_file);
+ Boxes * const boxes = create_boxes_from_line_stream(level_stream);
if (boxes == NULL) {
RETURN_LT(lt, -1);
}
level->boxes = RESET_LT(level->lt, level->boxes, boxes);
- Labels * const labels = create_labels_from_stream(level_file);
+ 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, level);
+ if (regions == NULL) {
+ RETURN_LT(lt, -1);
+ }
+ level->regions = RESET_LT(level->lt, level->regions, regions);
+
physical_world_clean(level->physical_world);
if (physical_world_add_solid(
level->physical_world,
return NULL;
}
+
+void level_hide_goal(Level *level, const char *goal_id)
+{
+ goals_hide(level->goals, goal_id);
+}
+
+void level_show_goal(Level *level, const char *goal_id)
+{
+ goals_show(level->goals, goal_id);
+}
+
+long int level_player_jump_count(Level *level)
+{
+ assert(level);
+ return player_jump_count(level->player);
+}
+
+void level_hide_label(Level *level, const char *label_id)
+{
+ assert(level);
+ assert(label_id);
+
+ /* TODO: level_hide_label is not implemented */
+}