diff --git a/app_file.c b/app_file.c index 358b6ea..3182e29 100644 --- a/app_file.c +++ b/app_file.c @@ -68,7 +68,7 @@ static void _app_LevelCommand(App *app, char *cmd) { c = TOKEN_DOUBLE; d = TOKEN_DOUBLE; - Entity *e = entity_Create(app->entity, NULL); + Entity *e = entity_Create(app->entity, cmd); ADD_COMPONENT(e, hitbox); e->hitbox->box = box2(a, b, c, d); e->hitbox->fixed = true; @@ -80,7 +80,7 @@ static void _app_LevelCommand(App *app, char *cmd) { a = TOKEN_DOUBLE; b = TOKEN_DOUBLE; - Entity *e = entity_Create(app->entity, NULL); + Entity *e = entity_Create(app->entity, cmd); ADD_COMPONENT(e, player); e->player->hazardRespawn = vec2(a, b); ADD_COMPONENT(e, position); @@ -101,7 +101,7 @@ static void _app_LevelCommand(App *app, char *cmd) { e = TOKEN_DOUBLE; f = TOKEN_DOUBLE; - Entity *en = entity_Create(app->entity, NULL); + Entity *en = entity_Create(app->entity, cmd); misc_InstantiateHazardRespawn(app, en, box2(a, b, c, d), vec2(e, f)); entity_Commit(app->entity, en); } @@ -113,7 +113,7 @@ static void _app_LevelCommand(App *app, char *cmd) { c = TOKEN_DOUBLE; d = TOKEN_DOUBLE; - Entity *e = entity_Create(app->entity, NULL); + Entity *e = entity_Create(app->entity, cmd); misc_InstantiateHazard(app, e, box2(a, b, c, d)); entity_Commit(app->entity, e); } @@ -125,7 +125,7 @@ static void _app_LevelCommand(App *app, char *cmd) { c = TOKEN_DOUBLE; d = TOKEN_DOUBLE; - Entity *e = entity_Create(app->entity, NULL); + Entity *e = entity_Create(app->entity, cmd); char *bundle = TOKEN; if (bundle != NULL) e->render = render_NewComponent(app, bundle); @@ -147,9 +147,17 @@ static void _app_LevelCommand(App *app, char *cmd) { } CMD("LEVEL_TRANSITION") { - // TODO - // Entity *e = entity_Create(app->entity, NULL); - // entity_Commit(app->entity, e); + double a, b, c, d; + a = TOKEN_DOUBLE; + b = TOKEN_DOUBLE; + c = TOKEN_DOUBLE; + d = TOKEN_DOUBLE; + char *next_level = TOKEN; + if (next_level) { + Entity *e = entity_Create(app->entity, cmd); + misc_InstantiateChangeLevel(app, e, box2(a, b, c, d), next_level); + entity_Commit(app->entity, e); + } } CMD("CUTOFF") { @@ -166,6 +174,7 @@ void _app_SwitchLevel(App *app) { WARN("called when switch_level is NULL", 0); return; } + INFO("Switching level to %s", app->switch_level); FILE *f = fopen(app->switch_level, "r"); if (!f) { diff --git a/app_render.cpp b/app_render.cpp index 047f98f..e0f41fe 100644 --- a/app_render.cpp +++ b/app_render.cpp @@ -56,6 +56,8 @@ void app_Render(App *app) { } if (e->misc->trigger_flags & misc_Hazard) setlinecolor(RGB(255, 0, 0)); + if (e->misc->change_level) + setlinecolor(RGB(255, 255, 0)); Box2 box; if (e->position) box = camera_TransformBox2(app->camera, box2_Offset(e->misc->trigger, e->position->position)); diff --git a/entity.c b/entity.c index 1f8a509..c679dea 100644 --- a/entity.c +++ b/entity.c @@ -4,6 +4,7 @@ #include "camera.h" #include "mapper_misc.h" #include "physics.h" +#include "render_component.h" #include "util/assert.h" #include "util/tree.h" #include "util/vector.h" @@ -98,6 +99,7 @@ static inline void _entity_Delete(System_Entity *sys, uintptr_t id) { player_DeleteEntity(sys->super->player, e->id); camera_DeleteEntity(sys->super->camera, e->id); + _entity_FreeMembers(e); tree_Delete(sys->entities, node); diff --git a/level1.txt b/level1.txt new file mode 100644 index 0000000..d07471b --- /dev/null +++ b/level1.txt @@ -0,0 +1,4 @@ +CUTOFF 600 +HITBOX 60 350 1134 65 +TEXTBOX 541 191 178 166 info_plate_small_1 Work\sin\sProgress!! +PLAYER 565 350 diff --git a/mapper_misc.c b/mapper_misc.c index 37f3253..2e69083 100644 --- a/mapper_misc.c +++ b/mapper_misc.c @@ -18,6 +18,8 @@ void misc_DeleteComponent(Component_Misc *misc) { } if (misc->respawn_pos) free(misc->respawn_pos); + if (misc->change_level) + free(misc->change_level); free(misc); } } @@ -96,6 +98,22 @@ void misc_thinker_ToLive(App *app, Entity *e, Duration deltaTime) { } } +void misc_thinker_ChangeLevel(App *app, Entity *e, Duration deltaTime) { + if (!e->misc || !e->misc->change_level) { + WARN("called on an entity without misc or misc.change_level", 0); + e->thinker = NULL; + return; + } + if (app->player->player == NULL) // No player + return; + Component_Player *p = app->player->player; + Box2 playerbox = physics_HitboxAbsolute(p->super->hitbox); + + Box2 worldbox = ABSOLUTE_BOX(e, e->misc->trigger); + if (box2_Intersects(worldbox, playerbox, NULL)) + app_QueueLoadLevel(app, e->misc->change_level); +} + // Utility functions for creating misc entities void misc_InstantiateTextbox(App *app, Entity *e, const char *text, Box2 trigger_box, float offset) { @@ -140,3 +158,11 @@ void misc_InstantiateToLive(App *app, Entity *e, Duration duration, TimePoint si e->thinker = &misc_thinker_ToLive; } + +void misc_InstantiateChangeLevel(App *app, Entity *e, Box2 trigger_box, const char *next_level) { + ASSERT(e->misc == NULL && "Instantiate must be called with e.misc not set"); + e->misc = zero_malloc(sizeof(Component_Misc)); + e->misc->trigger = trigger_box; + e->misc->change_level = copy_malloc(next_level); + e->thinker = &misc_thinker_ChangeLevel; +} diff --git a/mapper_misc.h b/mapper_misc.h index 5aeda96..2f05dca 100644 --- a/mapper_misc.h +++ b/mapper_misc.h @@ -40,6 +40,10 @@ void misc_thinker_Hazard(App *app, Entity *e, Duration deltaTime); // Kills itself after some time void misc_thinker_ToLive(App *app, Entity *e, Duration deltaTime); +// Thinker for level transition +void misc_thinker_ChangeLevel(App *app, Entity *e, Duration deltaTime); + + typedef enum { misc_Hazard = 1 << 0, // Hazard, harms the player on contact } misc_TriggerFlags; @@ -51,7 +55,8 @@ typedef struct { Box2 trigger; // Relative to Position if exists; absolute otherwise misc_TriggerFlags trigger_flags; misc_Textbox *textbox; - Vec2 *respawn_pos; // Set hazard respawn trigger + Vec2 *respawn_pos; // Set hazard respawn trigger + char *change_level; // Change level TimePoint tolive; // Deletes itself after this time if it is not 0 } Component_Misc; @@ -80,6 +85,11 @@ void misc_InstantiateHazard(App *app, Entity *e, Box2 trigger_box); void misc_InstantiateToLive(App *app, Entity *e, Duration duration, TimePoint since); +// Inserts components for change level +// Creates misc & the thinker. +void misc_InstantiateChangeLevel(App *app, Entity *e, Box2 trigger_box, const char *next_level); + + static inline Box2 misc_TextboxUpright(double width, double height) { Box2 b = { .lefttop = { diff --git a/types.h b/types.h index c040baa..32cdec3 100644 --- a/types.h +++ b/types.h @@ -14,7 +14,8 @@ extern "C" { #define SCREEN_WIDTH 1600 #define SCREEN_HEIGHT 900 -#define WARN(fmt, ...) fprintf(stderr, "[WARN][%s] " fmt "\n", __func__, __VA_ARGS__) +#define WARN(fmt, ...) fprintf(stderr, "[WARN][%s] " fmt "\n", __func__, ##__VA_ARGS__) +#define INFO(fmt, ...) fprintf(stderr, "[%s] " fmt "\n", __func__, ##__VA_ARGS__) static inline void *zero_malloc(size_t size) {