diff --git a/app_file.c b/app_file.c index a799930..533fd0d 100644 --- a/app_file.c +++ b/app_file.c @@ -156,9 +156,21 @@ static void _app_LevelCommand(App *app, char *cmd) { } } + CMD("CAMERA_FOCUS") { + Box2 box = readbox2(); + + Entity *e = entity_Create(app->entity, cmd); + misc_InstantiateCameraFocus(app, e, box); + entity_Commit(app->entity, e); + } + CMD("CUTOFF") { app->player->cutoff = TOKEN_DOUBLE; } + + else { + WARN("unknown command \"%s\"", cmd); + } } diff --git a/camera.c b/camera.c index 92adb96..4ea47df 100644 --- a/camera.c +++ b/camera.c @@ -38,8 +38,8 @@ void camera_DeleteEntity(System_Camera *sys, uintptr_t id) { void camera_Advance(System_Camera *sys, Duration deltaTime) { Vec2 tocenter; - if (sys->target.size.x > EPS) - tocenter = box2_Center(sys->target); + if (sys->target != NULL) + tocenter = box2_Center(*sys->target); else if (sys->player) tocenter = vec2_Add( sys->player->super->position->position, diff --git a/camera.h b/camera.h index 498da53..079cc74 100644 --- a/camera.h +++ b/camera.h @@ -15,9 +15,9 @@ typedef struct { App *super; Component_Player *player; - Box2 screen; // Screen box, e.g. 1280x720 origin (0,0) - Box2 cam, target; // Current & target camera - double speed; // Fraction of distance between cam & target to be covered in 1 sec + Box2 screen; // Screen box, e.g. 1280x720 origin (0,0) + Box2 cam, *target; // Current & target camera + double speed; // Fraction of distance between cam & target to be covered in 1 sec } System_Camera; System_Camera *camera_NewSystem(App *super); diff --git a/intro.txt b/intro.txt index e81c9ae..c2e51f3 100644 --- a/intro.txt +++ b/intro.txt @@ -15,3 +15,4 @@ HAZARD_RESPAWN 1492 23 297 242 1706 250 LEVEL_TRANSITION 2624 853 371 76 level1.txt TEXTBOX 2577 264 137 132 info_plate_small_2 Jump\sdown\sto\sthe\snext\slevel.\nNow\scomplete\swith\slevel\stransitions! HAZARD_RESPAWN 2315 41 107 368 2372 392 +CAMERA_FOCUS 1050 -70 1400 1000 diff --git a/mapper_misc.c b/mapper_misc.c index 2e69083..89c82b9 100644 --- a/mapper_misc.c +++ b/mapper_misc.c @@ -115,6 +115,28 @@ void misc_thinker_ChangeLevel(App *app, Entity *e, Duration deltaTime) { } +void misc_thinker_CameraFocus(App *app, Entity *e, Duration deltaTime) { + if (!e->misc || !(e->misc->trigger_flags & misc_CameraFocus)) { + WARN("called on an entity without misc or misc.flags&misc_CameraFocus", 0); + e->thinker = NULL; + return; + } + + if (app->player->player == NULL) // No player + return; + Component_Player *p = app->player->player; + + Box2 worldbox = ABSOLUTE_BOX(e, e->misc->trigger); + if (box2_Contains(worldbox, p->super->position->position)) { + app->camera->target = &e->misc->trigger; + } else { + if (app->camera->target == &e->misc->trigger) + // Player just left this box + app->camera->target = NULL; + } +} + + // Utility functions for creating misc entities void misc_InstantiateTextbox(App *app, Entity *e, const char *text, Box2 trigger_box, float offset) { ASSERT(e->misc == NULL && "Instantiate must be called with e.misc not set"); @@ -166,3 +188,11 @@ void misc_InstantiateChangeLevel(App *app, Entity *e, Box2 trigger_box, const ch e->misc->change_level = copy_malloc(next_level); e->thinker = &misc_thinker_ChangeLevel; } + +void misc_InstantiateCameraFocus(App *app, Entity *e, Box2 trigger_box) { + 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->trigger_flags = misc_CameraFocus; + e->thinker = &misc_thinker_CameraFocus; +} diff --git a/mapper_misc.h b/mapper_misc.h index 2f05dca..0932168 100644 --- a/mapper_misc.h +++ b/mapper_misc.h @@ -43,9 +43,13 @@ void misc_thinker_ToLive(App *app, Entity *e, Duration deltaTime); // Thinker for level transition void misc_thinker_ChangeLevel(App *app, Entity *e, Duration deltaTime); +// Thinker for camera focus +void misc_thinker_CameraFocus(App *app, Entity *e, Duration deltaTime); + typedef enum { - misc_Hazard = 1 << 0, // Hazard, harms the player on contact + misc_Hazard = 1 << 0, // Hazard, harms the player on contact + misc_CameraFocus = 1 << 1, // Camera focuses the center of the box when player's pos is in the box } misc_TriggerFlags; @@ -89,6 +93,10 @@ void misc_InstantiateToLive(App *app, Entity *e, Duration duration, TimePoint si // Creates misc & the thinker. void misc_InstantiateChangeLevel(App *app, Entity *e, Box2 trigger_box, const char *next_level); +// Inserts components for camera focus box +// Creates misc & thinker +void misc_InstantiateCameraFocus(App *app, Entity *e, Box2 trigger_box); + static inline Box2 misc_TextboxUpright(double width, double height) { Box2 b = {