diff --git a/src/seg005.c b/src/seg005.c index b5e73698..97d7757e 100644 --- a/src/seg005.c +++ b/src/seg005.c @@ -408,7 +408,7 @@ void __pascal far control_standing() { // seg005:0482 void __pascal far up_pressed() { - // If there is a level door nearby, enter it. + // If there is an open level door nearby, enter it. int leveldoor_tilepos = -1; if (get_tile_at_char() == tiles_16_level_door_left) leveldoor_tilepos = curr_tilepos; else if (get_tile_behind_char() == tiles_16_level_door_left) leveldoor_tilepos = curr_tilepos; @@ -421,15 +421,13 @@ void __pascal far up_pressed() { : leveldoor_open ) ){ -#ifdef USE_TELEPORTS - pickup_obj_type = -1; -#endif go_up_leveldoor(); return; } #ifdef USE_TELEPORTS // If there is a teleport nearby, enter it. + // (A teleport is a repurposed left half balcony with a non-zero modifier.) leveldoor_tilepos = -1; // This detection is not perfect... if (get_tile_at_char() == tiles_23_balcony_left) leveldoor_tilepos = curr_tilepos; @@ -442,6 +440,7 @@ void __pascal far up_pressed() { if (pickup_obj_type > 0) { go_up_leveldoor(); + seqtbl_offset_char(seq_teleport); return; } } diff --git a/src/seg006.c b/src/seg006.c index 30162355..095b9ab1 100644 --- a/src/seg006.c +++ b/src/seg006.c @@ -636,15 +636,6 @@ void __pascal far play_seq() { if (recording || replaying) break; // don't do end level music in replays #endif -#ifdef USE_TELEPORTS - // Don't play end level music if the player entered a teleport. - if (pickup_obj_type != -1) { - //play_sound(sound_45_jump_through_mirror); - // Don't wait until the kid walks all the way up the stairs. (optional) - teleport(); - break; - } -#endif if (is_sound_on) { if (current_level == 4) { play_sound(sound_32_shadow_music); // end level with shadow (level 4) @@ -656,13 +647,6 @@ void __pascal far play_seq() { } break; case SEQ_END_LEVEL: // end level -#ifdef USE_TELEPORTS - // If the player entered a teleport, don't go to the next level. - if (pickup_obj_type != -1) { - teleport(); - break; - } -#endif ++next_level; #ifdef USE_REPLAY // Preserve the seed in this frame, to ensure reproducibility of the replay in the next level, @@ -673,9 +657,17 @@ void __pascal far play_seq() { #endif break; case SEQ_GET_ITEM: // get item - if (*(SEQTBL_0 + Char.curr_seq++) == 1) { + { + int item = *(SEQTBL_0 + Char.curr_seq++); + if (item == 1) { proc_get_object(); } +#ifdef USE_TELEPORTS + if (item == 2) { + teleport(); + } +#endif + } break; case SEQ_DIE: // nop break; diff --git a/src/seqtbl.c b/src/seqtbl.c index f441889f..b3160f52 100644 --- a/src/seqtbl.c +++ b/src/seqtbl.c @@ -196,6 +196,11 @@ The authors of this program may be contacted at https://forum.princed.org #define Mleave 4 + Mraise //SEQTBL_BASE + 2285 // 0x225B #define Mclimb 19 + Mleave //SEQTBL_BASE + 2304 // 0x226E #define Mclimb_loop 2 + Mclimb //SEQTBL_BASE + 2306 // 0x2270 +#ifdef USE_TELEPORTS +#define teleport 4 + Mclimb_loop +#define teleport_loop 81 + teleport +#endif +// TODO: What are we going to do if we add yet another sequence, and we want to allow compiling with that sequence but without teleports? const word seqtbl_offsets[] = { 0x0000, startrun, stand, standjump, @@ -226,7 +231,10 @@ const word seqtbl_offsets[] = { Vexit, Mclimb, Vraise, Plie, patchfall, Mscurry, Mstop, Mleave, Pembrace, Pwaiting, Pstroke, Prise, - Pcrouch, Pslump, Mraise + Pcrouch, Pslump, Mraise, +#ifdef USE_TELEPORTS + teleport, +#endif }; // data:196E @@ -1138,8 +1146,31 @@ byte seqtbl[] = { LABEL(Mclimb) // Mouse: climb frame_186_mouse_1, frame_186_mouse_1, /* ":loop" */ LABEL(Mclimb_loop) frame_188_mouse_stand, - jmp(Mclimb_loop) // goto ":loop" + jmp(Mclimb_loop), // goto ":loop" +#ifdef USE_TELEPORTS + // Based on climbstairs. + LABEL(teleport) + act(actions_5_bumped), + dx(-5), dy(-1), snd(SND_FOOTSTEP), frame_217_exit_stairs_1, + frame_218_exit_stairs_2, frame_219_exit_stairs_3, + dx(1), frame_220_exit_stairs_4, + dx(-4), dy(-3), snd(SND_FOOTSTEP), frame_221_exit_stairs_5, + dx(-4), dy(-2), frame_222_exit_stairs_6, + dx(-2), dy(-3), frame_223_exit_stairs_7, + dx(-3), dy(-8), /*snd(SND_LEVEL),*/ snd(SND_FOOTSTEP), frame_224_exit_stairs_8, + dx(-1), dy(-1), frame_225_exit_stairs_9, + dx(-3), dy(-4), frame_226_exit_stairs_10, + dx(-1), dy(-5), snd(SND_FOOTSTEP), frame_227_exit_stairs_11, + dx(-2), dy(-1), frame_228_exit_stairs_12, + frame_0, + snd(SND_FOOTSTEP), frame_0, frame_0, frame_0, + snd(SND_FOOTSTEP), frame_0, frame_0, frame_0, + snd(SND_FOOTSTEP), frame_0, frame_0, frame_0, + snd(SND_FOOTSTEP), /*SEQ_END_LEVEL,*/ SEQ_GET_ITEM, 2, // get_item 2 triggers the teleport effect, like in SNES PoP. + /* ":loop" */ LABEL(teleport_loop) frame_0, + jmp(teleport_loop), // goto ":loop" +#endif }; void apply_seqtbl_patches() { diff --git a/src/types.h b/src/types.h index 69ea9a8f..3fa1d5f0 100644 --- a/src/types.h +++ b/src/types.h @@ -1085,6 +1085,9 @@ enum seqids { seq_111_princess_stand_up_PV2 = 111, seq_112_princess_crouch_down_PV2 = 112, seq_114_mouse_stand = 114, +#ifdef USE_TELEPORTS + seq_teleport = 115, +#endif }; enum seqtbl_instructions {