mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 17:22:12 +00:00
* 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.
This commit is contained in:
parent
d7ea986d7b
commit
2d1a574e09
8 changed files with 85 additions and 38 deletions
|
@ -2491,7 +2491,7 @@ static void CL_RemovePlayer(INT32 playernum, INT32 reason)
|
||||||
void CL_Reset(void)
|
void CL_Reset(void)
|
||||||
{
|
{
|
||||||
if (metalrecording)
|
if (metalrecording)
|
||||||
G_StopMetalRecording();
|
G_StopMetalRecording(false);
|
||||||
if (metalplayback)
|
if (metalplayback)
|
||||||
G_StopMetalDemo();
|
G_StopMetalDemo();
|
||||||
if (demorecording)
|
if (demorecording)
|
||||||
|
|
46
src/g_game.c
46
src/g_game.c
|
@ -3053,7 +3053,7 @@ static void G_DoCompleted(void)
|
||||||
if (metalplayback)
|
if (metalplayback)
|
||||||
G_StopMetalDemo();
|
G_StopMetalDemo();
|
||||||
if (metalrecording)
|
if (metalrecording)
|
||||||
G_StopMetalRecording();
|
G_StopMetalRecording(false);
|
||||||
|
|
||||||
for (i = 0; i < MAXPLAYERS; i++)
|
for (i = 0; i < MAXPLAYERS; i++)
|
||||||
if (playeringame[i])
|
if (playeringame[i])
|
||||||
|
@ -4060,6 +4060,8 @@ char *G_BuildMapTitle(INT32 mapnum)
|
||||||
#define ZT_BUTTONS 0x08
|
#define ZT_BUTTONS 0x08
|
||||||
#define ZT_AIMING 0x10
|
#define ZT_AIMING 0x10
|
||||||
#define DEMOMARKER 0x80 // demoend
|
#define DEMOMARKER 0x80 // demoend
|
||||||
|
#define METALDEATH 0x44
|
||||||
|
#define METALSNICE 0x69
|
||||||
|
|
||||||
static ticcmd_t oldcmd;
|
static ticcmd_t oldcmd;
|
||||||
|
|
||||||
|
@ -4901,7 +4903,6 @@ void G_GhostTicker(void)
|
||||||
P_RemoveMobj(follow);
|
P_RemoveMobj(follow);
|
||||||
P_SetTarget(&follow, NULL);
|
P_SetTarget(&follow, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Demo ends after ghost data.
|
// Demo ends after ghost data.
|
||||||
if (*g->p == DEMOMARKER)
|
if (*g->p == DEMOMARKER)
|
||||||
{
|
{
|
||||||
|
@ -4934,7 +4935,24 @@ void G_ReadMetalTic(mobj_t *metal)
|
||||||
|
|
||||||
if (!metal_p)
|
if (!metal_p)
|
||||||
return;
|
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++;
|
metal_p++;
|
||||||
|
|
||||||
ziptic = READUINT8(metal_p);
|
ziptic = READUINT8(metal_p);
|
||||||
|
|
||||||
// Read changes from the tic
|
// Read changes from the tic
|
||||||
|
@ -5117,13 +5135,6 @@ void G_ReadMetalTic(mobj_t *metal)
|
||||||
P_SetTarget(&follow, NULL);
|
P_SetTarget(&follow, NULL);
|
||||||
}
|
}
|
||||||
#undef follow
|
#undef follow
|
||||||
|
|
||||||
if (*metal_p == DEMOMARKER)
|
|
||||||
{
|
|
||||||
// end of demo data stream
|
|
||||||
G_StopMetalDemo();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void G_WriteMetalTic(mobj_t *metal)
|
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!
|
if (!demo_p) // demo_p will be NULL until the race start linedef executor is activated!
|
||||||
return;
|
return;
|
||||||
demo_p++;
|
|
||||||
|
WRITEUINT8(demo_p, METALSNICE);
|
||||||
ziptic_p = demo_p++; // the ziptic, written at the end of this function
|
ziptic_p = demo_p++; // the ziptic, written at the end of this function
|
||||||
|
|
||||||
#define MAXMOM (0xFFFF<<8)
|
#define MAXMOM (0xFFFF<<8)
|
||||||
|
@ -5300,7 +5312,7 @@ void G_WriteMetalTic(mobj_t *metal)
|
||||||
// latest demos with mouse aiming byte in ticcmd
|
// latest demos with mouse aiming byte in ticcmd
|
||||||
if (demo_p >= demoend - 32)
|
if (demo_p >= demoend - 32)
|
||||||
{
|
{
|
||||||
G_StopMetalRecording(); // no more space
|
G_StopMetalRecording(false); // no more space
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6282,19 +6294,23 @@ void G_StopMetalDemo(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stops metal sonic recording.
|
// Stops metal sonic recording.
|
||||||
ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(void)
|
ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill)
|
||||||
{
|
{
|
||||||
boolean saved = false;
|
boolean saved = false;
|
||||||
if (demo_p)
|
if (demo_p)
|
||||||
{
|
{
|
||||||
UINT8 *p = demobuffer+16; // checksum position
|
UINT8 *p = demobuffer+16; // checksum position
|
||||||
#ifdef NOMD5
|
if (kill)
|
||||||
UINT8 i;
|
WRITEUINT8(demo_p, METALDEATH); // add the metal death marker
|
||||||
|
else
|
||||||
WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker
|
WRITEUINT8(demo_p, DEMOMARKER); // add the demo end marker
|
||||||
|
#ifdef NOMD5
|
||||||
|
{
|
||||||
|
UINT8 i;
|
||||||
for (i = 0; i < 16; i++, p++)
|
for (i = 0; i < 16; i++, p++)
|
||||||
*p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct.
|
*p = P_RandomByte(); // This MD5 was chosen by fair dice roll and most likely < 50% correct.
|
||||||
|
}
|
||||||
#else
|
#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.
|
md5_buffer((char *)p+16, demo_p - (p+16), (void *)p); // make a checksum of everything after the checksum in the file.
|
||||||
#endif
|
#endif
|
||||||
saved = FIL_WriteFile(va("%sMS.LMP", G_BuildMapName(gamemap)), demobuffer, demo_p - demobuffer); // finally output the file.
|
saved = FIL_WriteFile(va("%sMS.LMP", G_BuildMapName(gamemap)), demobuffer, demo_p - demobuffer); // finally output the file.
|
||||||
|
|
|
@ -174,7 +174,7 @@ void G_AddGhost(char *defdemoname);
|
||||||
void G_DoPlayMetal(void);
|
void G_DoPlayMetal(void);
|
||||||
void G_DoneLevelLoad(void);
|
void G_DoneLevelLoad(void);
|
||||||
void G_StopMetalDemo(void);
|
void G_StopMetalDemo(void);
|
||||||
ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(void);
|
ATTRNORETURN void FUNCNORETURN G_StopMetalRecording(boolean kill);
|
||||||
void G_StopDemo(void);
|
void G_StopDemo(void);
|
||||||
boolean G_CheckDemoStatus(void);
|
boolean G_CheckDemoStatus(void);
|
||||||
|
|
||||||
|
|
|
@ -6674,7 +6674,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
sfx_None, // painsound
|
sfx_None, // painsound
|
||||||
S_NULL, // meleestate
|
S_NULL, // meleestate
|
||||||
S_NULL, // missilestate
|
S_NULL, // missilestate
|
||||||
S_NULL, // deathstate
|
S_PLAY_DEAD, // deathstate
|
||||||
S_NULL, // xdeathstate
|
S_NULL, // xdeathstate
|
||||||
sfx_None, // deathsound
|
sfx_None, // deathsound
|
||||||
0, // speed
|
0, // speed
|
||||||
|
@ -6684,7 +6684,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
||||||
0, // mass
|
0, // mass
|
||||||
0, // damage
|
0, // damage
|
||||||
sfx_None, // activesound
|
sfx_None, // activesound
|
||||||
MF_SCENERY|MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
|
MF_NOGRAVITY|MF_NOCLIPHEIGHT, // flags
|
||||||
S_NULL // raisestate
|
S_NULL // raisestate
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -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 (target->player && !target->player->spectator)
|
||||||
{
|
{
|
||||||
if (metalrecording) // Ack! Metal Sonic shouldn't die! Cut the tape, end recording!
|
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
|
if (gametype == GT_MATCH // note, no team match suicide penalty
|
||||||
&& ((target == source) || (source == NULL && inflictor == NULL) || (source && !source->player)))
|
&& ((target == source) || (source == NULL && inflictor == NULL) || (source && !source->player)))
|
||||||
{ // Suicide penalty
|
{ // Suicide penalty
|
||||||
|
@ -2761,6 +2761,12 @@ void P_KillMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, UINT8 damaget
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
27
src/p_mobj.c
27
src/p_mobj.c
|
@ -2570,20 +2570,31 @@ static boolean P_ZMovement(mobj_t *mo)
|
||||||
|
|
||||||
if (!mo->player && P_CheckDeathPitCollide(mo))
|
if (!mo->player && P_CheckDeathPitCollide(mo))
|
||||||
{
|
{
|
||||||
|
switch (mo->type)
|
||||||
|
{
|
||||||
|
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)
|
if (mo->flags & MF_ENEMY || mo->flags & MF_BOSS || mo->type == MT_MINECART)
|
||||||
{
|
{
|
||||||
// Kill enemies, bosses and minecarts that fall into death pits.
|
// Kill enemies, bosses and minecarts that fall into death pits.
|
||||||
if (mo->health)
|
if (mo->health)
|
||||||
{
|
{
|
||||||
P_KillMobj(mo, NULL, NULL, 0);
|
P_KillMobj(mo, NULL, NULL, 0);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
P_RemoveMobj(mo);
|
P_RemoveMobj(mo);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (P_MobjFlip(mo)*mo->momz < 0
|
if (P_MobjFlip(mo)*mo->momz < 0
|
||||||
|
@ -8271,6 +8282,20 @@ void P_MobjThinker(mobj_t *mobj)
|
||||||
P_SetObjectMomZ(mobj, -2 * FRACUNIT / 3, true);
|
P_SetObjectMomZ(mobj, -2 * FRACUNIT / 3, true);
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2181,7 +2181,7 @@ void I_Quit(void)
|
||||||
if (demorecording)
|
if (demorecording)
|
||||||
G_CheckDemoStatus();
|
G_CheckDemoStatus();
|
||||||
if (metalrecording)
|
if (metalrecording)
|
||||||
G_StopMetalRecording();
|
G_StopMetalRecording(false);
|
||||||
|
|
||||||
D_QuitNetGame();
|
D_QuitNetGame();
|
||||||
I_ShutdownMusic();
|
I_ShutdownMusic();
|
||||||
|
@ -2299,7 +2299,7 @@ void I_Error(const char *error, ...)
|
||||||
if (demorecording)
|
if (demorecording)
|
||||||
G_CheckDemoStatus();
|
G_CheckDemoStatus();
|
||||||
if (metalrecording)
|
if (metalrecording)
|
||||||
G_StopMetalRecording();
|
G_StopMetalRecording(false);
|
||||||
|
|
||||||
D_QuitNetGame();
|
D_QuitNetGame();
|
||||||
I_ShutdownMusic();
|
I_ShutdownMusic();
|
||||||
|
|
|
@ -647,7 +647,7 @@ void I_Error(const char *error, ...)
|
||||||
if (demorecording)
|
if (demorecording)
|
||||||
G_CheckDemoStatus();
|
G_CheckDemoStatus();
|
||||||
if (metalrecording)
|
if (metalrecording)
|
||||||
G_StopMetalRecording();
|
G_StopMetalRecording(false);
|
||||||
|
|
||||||
D_QuitNetGame();
|
D_QuitNetGame();
|
||||||
|
|
||||||
|
@ -733,7 +733,7 @@ void I_Quit(void)
|
||||||
if (demorecording)
|
if (demorecording)
|
||||||
G_CheckDemoStatus();
|
G_CheckDemoStatus();
|
||||||
if (metalrecording)
|
if (metalrecording)
|
||||||
G_StopMetalRecording();
|
G_StopMetalRecording(false);
|
||||||
|
|
||||||
M_SaveConfig(NULL); // save game config, cvars..
|
M_SaveConfig(NULL); // save game config, cvars..
|
||||||
#ifndef NONET
|
#ifndef NONET
|
||||||
|
|
Loading…
Reference in a new issue