From 2d1a574e097f81909b7f0b138efb025e31745e60 Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 29 Oct 2019 17:38:14 +0000 Subject: [PATCH] * Add a death animation for killing the Metal object, in case somebody wants to Lua up a Sonic CD style race finish for the Metal object, or in case of the following... * Add an alternate DEMOMARKER for ending the Metal Recording on death, which kills the Metal object as well. * Add some more relevant exceptions to the "most objects are removed when touching a deathpit" thing, primarily for the sake of ghosts and Metal playback. --- src/d_clisrv.c | 2 +- src/g_game.c | 50 ++++++++++++++++++++++++++++++--------------- src/g_game.h | 2 +- src/info.c | 4 ++-- src/p_inter.c | 8 +++++++- src/p_mobj.c | 49 +++++++++++++++++++++++++++++++++----------- src/sdl/i_system.c | 4 ++-- src/win32/win_sys.c | 4 ++-- 8 files changed, 85 insertions(+), 38 deletions(-) diff --git a/src/d_clisrv.c b/src/d_clisrv.c index 411d847b5..860bde624 100644 --- a/src/d_clisrv.c +++ b/src/d_clisrv.c @@ -2491,7 +2491,7 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason) void CL_Reset(void) { if (metalrecording) - G_StopMetalRecording(); + G_StopMetalRecording(false); if (metalplayback) G_StopMetalDemo(); if (demorecording) diff --git a/src/g_game.c b/src/g_game.c index 52a2d7566..10e841f64 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -3053,7 +3053,7 @@ static void G_DoCompleted(void) if (metalplayback) G_StopMetalDemo(); if (metalrecording) - G_StopMetalRecording(); + G_StopMetalRecording(false); for (i = 0; i < MAXPLAYERS; i++) if (playeringame[i]) @@ -4060,6 +4060,8 @@ char *G_BuildMapTitle(INT32 mapnum) #define ZT_BUTTONS 0x08 #define ZT_AIMING 0x10 #define DEMOMARKER 0x80 // demoend +#define METALDEATH 0x44 +#define METALSNICE 0x69 static ticcmd_t oldcmd; @@ -4901,7 +4903,6 @@ void G_GhostTicker(void) P_RemoveMobj(follow); P_SetTarget(&follow, NULL); } - // Demo ends after ghost data. if (*g->p == DEMOMARKER) { @@ -4934,7 +4935,24 @@ void G_ReadMetalTic(mobj_t *metal) if (!metal_p) return; + + switch (*metal_p) + { + case METALSNICE: + break; + case METALDEATH: + if (metal->tracer) + P_RemoveMobj(metal->tracer); + P_KillMobj(metal, NULL, NULL, 0); + /* FALLTHRU */ + case DEMOMARKER: + default: + // end of demo data stream + G_StopMetalDemo(); + return; + } metal_p++; + ziptic = READUINT8(metal_p); // Read changes from the tic @@ -5117,13 +5135,6 @@ void G_ReadMetalTic(mobj_t *metal) P_SetTarget(&follow, NULL); } #undef follow - - if (*metal_p == DEMOMARKER) - { - // end of demo data stream - G_StopMetalDemo(); - return; - } } void G_WriteMetalTic(mobj_t *metal) @@ -5134,7 +5145,8 @@ void G_WriteMetalTic(mobj_t *metal) if (!demo_p) // demo_p will be NULL until the race start linedef executor is activated! return; - demo_p++; + + WRITEUINT8(demo_p, METALSNICE); ziptic_p = demo_p++; // the ziptic, written at the end of this function #define MAXMOM (0xFFFF<<8) @@ -5300,7 +5312,7 @@ void G_WriteMetalTic(mobj_t *metal) // latest demos with mouse aiming byte in ticcmd if (demo_p >= demoend - 32) { - G_StopMetalRecording(); // no more space + G_StopMetalRecording(false); // no more space return; } } @@ -6282,19 +6294,23 @@ void G_StopMetalDemo(void) } // Stops metal sonic recording. -ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(void) +ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill) { boolean saved = false; if (demo_p) { UINT8 *p = demobuffer+16; // checksum position + if (kill) + WRITEUINT8(demo_p, METALDEATH); // add the metal death marker + else + WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker #ifdef NOMD5 - UINT8 i; - WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker - for (i = 0; i < 16; i++, p++) - *p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. + { + UINT8 i; + for (i = 0; i < 16; i++, p++) + *p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct. + } #else - WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker md5_buffer((char *)p+16, demo_p - (p+16), (void *)p); // make a checksum of everything after the checksum in the file. #endif saved = FIL_WriteFile(va("%sMS.LMP", G_BuildMapName(gamemap)), demobuffer, demo_p - demobuffer); // finally output the file. diff --git a/src/g_game.h b/src/g_game.h index 198cbc396..8c775c238 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -174,7 +174,7 @@ void G_AddGhost(char *defdemoname); void G_DoPlayMetal(void); void G_DoneLevelLoad(void); void G_StopMetalDemo(void); -ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(void); +ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill); void G_StopDemo(void); boolean G_CheckDemoStatus(void); diff --git a/src/info.c b/src/info.c index 99cd12862..a418b1c51 100644 --- a/src/info.c +++ b/src/info.c @@ -6674,7 +6674,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = sfx_None, // painsound S_NULL, // meleestate S_NULL, // missilestate - S_NULL, // deathstate + S_PLAY_DEAD, // deathstate S_NULL, // xdeathstate sfx_None, // deathsound 0, // speed @@ -6684,7 +6684,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = 0, // mass 0, // damage sfx_None, // activesound - MF_SCENERY|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags + MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags S_NULL // raisestate }, diff --git a/src/p_inter.c b/src/p_inter.c index 44215d691..e25fb395a 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2372,7 +2372,7 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget if (target->player && !target->player->spectator) { if (metalrecording) // Ack! Metal Sonic shouldn't die! Cut the tape, end recording! - G_StopMetalRecording(); + G_StopMetalRecording(true); if (gametype == GT_MATCH // note, no team match suicide penalty && ((target == source) || (source == NULL && inflictor == NULL) || (source && !source->player))) { // Suicide penalty @@ -2761,6 +2761,12 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget } } break; + case MT_METALSONIC_RACE: + target->fuse = TICRATE*3; + target->momx = target->momy = target->momz = 0; + P_SetObjectMomZ(target, 14*FRACUNIT, false); + target->flags = (target->flags & ~MF_NOGRAVITY)|(MF_NOCLIP|MF_NOCLIPTHING); + break; default: break; } diff --git a/src/p_mobj.c b/src/p_mobj.c index c87f0bd3c..64c8d61d3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -2570,19 +2570,30 @@ static boolean P_ZMovement(mobj_t *mo) if (!mo->player && P_CheckDeathPitCollide(mo)) { - if (mo->flags & MF_ENEMY || mo->flags & MF_BOSS || mo->type == MT_MINECART) + switch (mo->type) { - // Kill enemies, bosses and minecarts that fall into death pits. - if (mo->health) - { - P_KillMobj(mo, NULL, NULL, 0); - return false; - } - } - else - { - P_RemoveMobj(mo); - return false; + case MT_GHOST: + case MT_METALSONIC_RACE: + case MT_EXPLODE: + case MT_BOSSEXPLODE: + case MT_SONIC3KBOSSEXPLODE: + break; + default: + if (mo->flags & MF_ENEMY || mo->flags & MF_BOSS || mo->type == MT_MINECART) + { + // Kill enemies, bosses and minecarts that fall into death pits. + if (mo->health) + { + P_KillMobj(mo, NULL, NULL, 0); + } + return false; + } + else + { + P_RemoveMobj(mo); + return false; + } + break; } } @@ -8271,6 +8282,20 @@ void P_MobjThinker(mobj_t *mobj) P_SetObjectMomZ(mobj, -2 * FRACUNIT / 3, true); } break; + case MT_METALSONIC_RACE: + { + if (!(mobj->fuse % 8)) + { + fixed_t r = mobj->radius >> FRACBITS; + mobj_t *explosion = P_SpawnMobj( + mobj->x + (P_RandomRange(r, -r) << FRACBITS), + mobj->y + (P_RandomRange(r, -r) << FRACBITS), + mobj->z + (P_RandomKey(mobj->height >> FRACBITS) << FRACBITS), + MT_SONIC3KBOSSEXPLODE); + S_StartSound(explosion, sfx_s3kb4); + } + P_SetObjectMomZ(mobj, -2 * FRACUNIT / 3, true); + } default: break; } diff --git a/src/sdl/i_system.c b/src/sdl/i_system.c index d7926e5b2..e7f8f2e4f 100644 --- a/src/sdl/i_system.c +++ b/src/sdl/i_system.c @@ -2181,7 +2181,7 @@ void I_Quit(void) if (demorecording) G_CheckDemoStatus(); if (metalrecording) - G_StopMetalRecording(); + G_StopMetalRecording(false); D_QuitNetGame(); I_ShutdownMusic(); @@ -2299,7 +2299,7 @@ void I_Error(const char *error, ...) if (demorecording) G_CheckDemoStatus(); if (metalrecording) - G_StopMetalRecording(); + G_StopMetalRecording(false); D_QuitNetGame(); I_ShutdownMusic(); diff --git a/src/win32/win_sys.c b/src/win32/win_sys.c index 93b3ff523..c9fdb1c97 100644 --- a/src/win32/win_sys.c +++ b/src/win32/win_sys.c @@ -647,7 +647,7 @@ void I_Error(const char *error, ...) if (demorecording) G_CheckDemoStatus(); if (metalrecording) - G_StopMetalRecording(); + G_StopMetalRecording(false); D_QuitNetGame(); @@ -733,7 +733,7 @@ void I_Quit(void) if (demorecording) G_CheckDemoStatus(); if (metalrecording) - G_StopMetalRecording(); + G_StopMetalRecording(false); M_SaveConfig(NULL); // save game config, cvars.. #ifndef NONET