diff --git a/src/dehacked.c b/src/dehacked.c index 5f83b1074..c224d6967 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -1266,6 +1266,13 @@ static void readlevelheader(MYFILE *f, INT32 num) else mapheaderinfo[num-1]->levelflags &= ~LF_SAVEGAME; } + else if (fastcmp(word, "MIXNIGHTSCOUNTDOWN")) + { + if (i || word2[0] == 'T' || word2[0] == 'Y') + mapheaderinfo[num-1]->levelflags |= LF_MIXNIGHTSCOUNTDOWN; + else + mapheaderinfo[num-1]->levelflags &= ~LF_MIXNIGHTSCOUNTDOWN; + } // Individual triggers for menu flags else if (fastcmp(word, "HIDDEN")) @@ -7886,6 +7893,7 @@ struct { {"LF_NORELOAD",LF_NORELOAD}, {"LF_NOZONE",LF_NOZONE}, {"LF_SAVEGAME",LF_SAVEGAME}, + {"LF_MIXNIGHTSCOUNTDOWN",LF_MIXNIGHTSCOUNTDOWN}, // And map flags {"LF2_HIDEINMENU",LF2_HIDEINMENU}, {"LF2_HIDEINSTATS",LF2_HIDEINSTATS}, diff --git a/src/doomstat.h b/src/doomstat.h index 1fcdbfc2f..266216f73 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -309,7 +309,7 @@ typedef struct SINT8 bonustype; ///< What type of bonus does this level have? (-1 for null.) SINT8 maxbonuslives; ///< How many bonus lives to award at Intermission? (-1 for unlimited.) - UINT8 levelflags; ///< LF_flags: merged eight booleans into one UINT8 for space, see below + UINT8 levelflags; ///< LF_flags: merged booleans into one UINT8 for space, see below UINT8 menuflags; ///< LF2_flags: options that affect record attack / nights mode menus char selectheading[22]; ///< Level select heading. Allows for controllable grouping. @@ -335,6 +335,7 @@ typedef struct #define LF_NORELOAD 8 ///< Don't reload level on death #define LF_NOZONE 16 ///< Don't include "ZONE" on level title #define LF_SAVEGAME 32 ///< Save the game upon loading this level +#define LF_MIXNIGHTSCOUNTDOWN 64 ///< Play sfx_timeup instead of music change for NiGHTS countdown #define LF2_HIDEINMENU 1 ///< Hide in the multiplayer menu #define LF2_HIDEINSTATS 2 ///< Hide in the statistics screen diff --git a/src/p_inter.c b/src/p_inter.c index c46ef407d..2471ce8c7 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2756,8 +2756,18 @@ static inline void P_NiGHTSDamage(mobj_t *target, mobj_t *source) if (oldnightstime > 10*TICRATE && player->nightstime < 10*TICRATE) { - //S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH - S_ChangeMusicInternal((((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? "_ntime" : "_drown"), false); + if ((mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN) +#ifdef _WIN32 + // win32 MIDI volume hack means we cannot fade down the music + && S_MusicType() != MU_MID +#endif + ) + { + S_FadeMusic(0, 10*MUSICRATE); + S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. + } + else + S_ChangeMusicInternal((((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? "_ntime" : "_drown"), false); } } } @@ -3137,8 +3147,13 @@ void P_SpecialStageDamage(player_t *player, mobj_t *inflictor, mobj_t *source) if (oldnightstime > 10*TICRATE && player->nightstime < 10*TICRATE) { - //S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH - S_ChangeMusicInternal((((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? "_ntime" : "_drown"), false); + if (mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN) + { + S_FadeMusic(0, 10*MUSICRATE); + S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. + } + else + S_ChangeMusicInternal((((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? "_ntime" : "_drown"), false); } } diff --git a/src/p_user.c b/src/p_user.c index 04b72c970..1e6bf00a4 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -629,6 +629,14 @@ static void P_DeNightserizePlayer(player_t *player) player->marescore = player->spheres =\ player->rings = 0; P_DamageMobj(player->mo, NULL, NULL, 1, DMG_INSTAKILL); + + // Reset music to beginning if MIXNIGHTSCOUNTDOWN + if ((mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN) +#ifdef _WIN32 + && S_MusicType() != MU_MID +#endif + ) + S_SetMusicPosition(0); } break; @@ -639,7 +647,24 @@ static void P_DeNightserizePlayer(player_t *player) player->oldscale = 0; // Restore from drowning music - P_RestoreMusic(player); + if ((mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN) +#ifdef _WIN32 + && S_MusicType() != MU_MID +#endif + ) + { + S_StopSoundByNum(sfx_timeup); + S_StopFadingMusic(); + S_SetInternalMusicVolume(100); + + // Reset the music if you did not destroy all the capsules, because you failed. + // Why make the all-capsules exception: because it's your reward for nearly finishing the level! + // (unless the player auto-loses upon denightserizing; for death case, see above.) + if (P_FindLowestMare() != UINT8_MAX || G_IsSpecialStage(gamemap)) + S_SetMusicPosition(0); + } + else + P_RestoreMusic(player); P_RunDeNightserizeExecutors(player->mo); } @@ -687,7 +712,16 @@ void P_NightserizePlayer(player_t *player, INT32 nighttime) player->nightstime = player->startedtime = player->lapstartedtime = nighttime*TICRATE; player->bonustime = false; - P_RestoreMusic(player); + // Restore from drowning music + if (mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN) + { + S_StopSoundByNum(sfx_timeup); + S_StopFadingMusic(); + S_SetInternalMusicVolume(100); + } + else + P_RestoreMusic(player); + P_SetPlayerMobjState(player->mo, S_PLAY_NIGHTS_TRANS1); if (gametype == GT_RACE || gametype == GT_COMPETITION) @@ -6344,14 +6378,28 @@ static void P_NiGHTSMovement(player_t *player) { P_DeNightserizePlayer(player); S_StartScreamSound(player->mo, sfx_s3k66); -// S_StopSoundByNum(sfx_timeup); // Kill the "out of time" music, if it's playing. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH - P_RestoreMusic(player); // I have my doubts that this is the right place for this... + + if (mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN) + { + S_StopSoundByNum(sfx_timeup); // Kill the "out of time" music, if it's playing. + S_StopFadingMusic(); + S_SetInternalMusicVolume(100); + } + else + P_RestoreMusic(player); // I have my doubts that this is the right place for this... return; } else if (P_IsLocalPlayer(player) && player->nightstime == 10*TICRATE) -// S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. Dummied out, as some on the dev team thought it wasn't Sonic-y enough (Mystic, notably). Uncomment to restore. -SH - S_ChangeMusicInternal((((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? "_ntime" : "_drown"), false); + { + if (mapheaderinfo[gamemap-1]->levelflags & LF_MIXNIGHTSCOUNTDOWN) + { + S_FadeMusic(0, 10*MUSICRATE); + S_StartSound(NULL, sfx_timeup); // that creepy "out of time" music from NiGHTS. + } + else + S_ChangeMusicInternal((((maptol & TOL_NIGHTS) && !G_IsSpecialStage(gamemap)) ? "_ntime" : "_drown"), false); + } if (player->mo->z < player->mo->floorz) player->mo->z = player->mo->floorz; diff --git a/src/sounds.c b/src/sounds.c index 7408dec42..66d498838 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -229,6 +229,7 @@ sfxinfo_t S_sfx[NUMSFX] = {"hoop3", false, 192, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Hoop++"}, {"hidden", false, 204, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Discovery"}, {"prloop", false, 104, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Gust of wind"}, + {"timeup", true, 256, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Ominous Countdown"}, {"ngjump", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Jump"}, {"peww", false, 96, 0, -1, NULL, 0, -1, -1, LUMPERROR, "Pew"}, diff --git a/src/sounds.h b/src/sounds.h index f4847b226..fd1142aba 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -295,6 +295,7 @@ typedef enum sfx_hoop3, sfx_hidden, sfx_prloop, + sfx_timeup, sfx_ngjump, sfx_peww,