* Add thok auras to Metal playback.

* Add height changes to demos and Metal playback (to properly place thok aura relative to object).
* Fix followmobj recordings in reverse gravity (done via more strenuous flag setting + info height serialisation).
* Make RA ghosts fade in from start tic, and go colorized on their final one.
* Fix thok auras potentially doing bad things if they're set to MT_NULL.
* Add sprite change support to Metal playback.
* Re-enable some stuff I previously disabled for Metal recording/playback.
* Make ALL objects spawned with skins properly acknowledge that their spawnstate's frame is a sprite2, rather than just specific objects.
* Fix placement of Metal Sonic fume in reverse gravity.
* Since not backwards compatible with the previous test build, increment DEMOVERSION again. (Don't worry, we've got like 65524 more versions allowed before we run out of possible DEMOVERSIONs...)
This commit is contained in:
toaster 2019-10-29 15:32:22 +00:00
parent 1906709cf2
commit f0f8b544de
3 changed files with 270 additions and 117 deletions

View file

@ -289,7 +289,7 @@ static struct {
// There is no conflict here.
typedef struct demoghost {
UINT8 checksum[16];
UINT8 *buffer, *p, color;
UINT8 *buffer, *p, color, fadein;
UINT16 version;
mobj_t oldmo, *mo;
struct demoghost *next;
@ -4044,7 +4044,7 @@ char *G_BuildMapTitle(INT32 mapnum)
// DEMO RECORDING
//
#define DEMOVERSION 0x000b
#define DEMOVERSION 0x000c
#define DEMOHEADER "\xF0" "SRB2Replay" "\x0F"
#define DF_GHOST 0x01 // This demo contains ghost data too!
@ -4083,7 +4083,7 @@ static ticcmd_t oldcmd;
#define EZT_SCALE 0x10 // Changed size
#define EZT_HIT 0x20 // Damaged a mobj
#define EZT_SPRITE 0x40 // Changed sprite set completely out of PLAY (NiGHTS, SOCs, whatever)
// spare EZT slot 0x80
#define EZT_HEIGHT 0x80 // Changed height
// GZT_FOLLOW flags
#define FZT_SPAWNED 0x01 // just been spawned
@ -4217,28 +4217,28 @@ void G_WriteDemoTiccmd(ticcmd_t *cmd, INT32 playernum)
void G_GhostAddThok(void)
{
if (!demorecording || !(demoflags & DF_GHOST))
if (!metalrecording && (!demorecording || !(demoflags & DF_GHOST)))
return;
ghostext.flags = (ghostext.flags & ~EZT_THOKMASK) | EZT_THOK;
}
void G_GhostAddSpin(void)
{
if (!demorecording || !(demoflags & DF_GHOST))
if (!metalrecording && (!demorecording || !(demoflags & DF_GHOST)))
return;
ghostext.flags = (ghostext.flags & ~EZT_THOKMASK) | EZT_SPIN;
}
void G_GhostAddRev(void)
{
if (!demorecording || !(demoflags & DF_GHOST))
if (!metalrecording && (!demorecording || !(demoflags & DF_GHOST)))
return;
ghostext.flags = (ghostext.flags & ~EZT_THOKMASK) | EZT_REV;
}
void G_GhostAddFlip(void)
{
if (!demorecording || !(demoflags & DF_GHOST))
if (!metalrecording && (!demorecording || !(demoflags & DF_GHOST)))
return;
ghostext.flags |= EZT_FLIP;
}
@ -4258,7 +4258,7 @@ void G_GhostAddColor(ghostcolor_t color)
void G_GhostAddScale(fixed_t scale)
{
if (!demorecording || !(demoflags & DF_GHOST))
if (!metalrecording && (!demorecording || !(demoflags & DF_GHOST)))
return;
if (ghostext.lastscale == scale)
{
@ -4284,6 +4284,7 @@ void G_WriteGhostTic(mobj_t *ghost)
char ziptic = 0;
UINT8 *ziptic_p;
UINT32 i;
fixed_t height;
if (!demo_p)
return;
@ -4373,6 +4374,12 @@ void G_WriteGhostTic(mobj_t *ghost)
ghostext.flags |= EZT_SPRITE;
}
if ((height = FixedDiv(ghost->height, ghost->scale)) != oldghost.height)
{
oldghost.height = height;
ghostext.flags |= EZT_HEIGHT;
}
if (ghostext.flags)
{
ziptic |= GZT_EXTRA;
@ -4413,10 +4420,15 @@ void G_WriteGhostTic(mobj_t *ghost)
}
if (ghostext.flags & EZT_SPRITE)
WRITEUINT16(demo_p,oldghost.sprite);
if (ghostext.flags & EZT_HEIGHT)
{
height >>= FRACBITS;
WRITEINT16(demo_p, height);
}
ghostext.flags = 0;
}
if (ghost->player && ghost->player->followmobj) // bloats tails runs but what can ya do
if (ghost->player && ghost->player->followmobj && !(ghost->player->followmobj->sprite == SPR_NULL || (ghost->player->followmobj->flags2 & MF2_DONTDRAW))) // bloats tails runs but what can ya do
{
INT16 temp;
UINT8 *followtic_p = demo_p++;
@ -4430,6 +4442,7 @@ void G_WriteGhostTic(mobj_t *ghost)
if (!(oldghost.flags2 & MF2_AMBUSH))
{
followtic |= FZT_SPAWNED;
WRITEINT16(demo_p,ghost->player->followmobj->info->height>>FRACBITS);
if (ghost->player->followmobj->flags2 & MF2_LINKDRAW)
followtic |= FZT_LINKDRAW;
if (ghost->player->followmobj->colorized)
@ -4564,13 +4577,21 @@ void G_ConsGhostTic(void)
}
if (xziptic & EZT_SPRITE)
demo_p += sizeof(UINT16);
if (xziptic & EZT_HEIGHT)
demo_p += sizeof(INT16);
}
if (ziptic & GZT_FOLLOW)
{ // Even more...
UINT8 followtic = READUINT8(demo_p);
if ((followtic & (FZT_SPAWNED|FZT_SKIN)) == (FZT_SPAWNED|FZT_SKIN))
demo_p++;
if (followtic & FZT_SPAWNED)
{
demo_p += sizeof(INT16);
if (followtic & FZT_SKIN)
demo_p++;
}
if (followtic & FZT_SCALE)
demo_p += sizeof(fixed_t);
demo_p += sizeof(INT16);
demo_p += sizeof(INT16);
demo_p += sizeof(INT16);
@ -4579,8 +4600,6 @@ void G_ConsGhostTic(void)
demo_p += sizeof(UINT16);
demo_p++;
demo_p++;
if (followtic & FZT_SCALE)
demo_p += sizeof(fixed_t);
}
// Re-synchronise
@ -4666,6 +4685,11 @@ void G_GhostTicker(void)
g->mo->z = g->oldmo.z;
P_SetThingPosition(g->mo);
g->mo->frame = g->oldmo.frame | tr_trans30<<FF_TRANSSHIFT;
if (g->fadein)
{
g->mo->frame += (((--g->fadein)/6)<<FF_TRANSSHIFT); // this calc never exceeds 9 unless g->fadein is bad, and it's only set once, so...
g->mo->flags2 &= ~MF2_DONTDRAW;
}
g->mo->sprite2 = g->oldmo.sprite2;
if (ziptic & GZT_EXTRA)
@ -4723,33 +4747,38 @@ void G_GhostTicker(void)
break;
}
}
if (type == MT_GHOST)
if (type != MT_NULL)
{
mobj = P_SpawnGhostMobj(g->mo); // does a large portion of the work for us
mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|tr_trans60<<FF_TRANSSHIFT; // P_SpawnGhostMobj sets trans50, we want trans60
}
else
{
mobj = P_SpawnMobj(g->mo->x, g->mo->y, g->mo->z - FixedDiv(FixedMul(g->mo->info->height, g->mo->scale) - g->mo->height,3*FRACUNIT), MT_THOK);
mobj->sprite = states[mobjinfo[type].spawnstate].sprite;
mobj->frame = (states[mobjinfo[type].spawnstate].frame & FF_FRAMEMASK) | tr_trans60<<FF_TRANSSHIFT;
mobj->tics = -1; // nope.
mobj->color = g->mo->color;
if (g->mo->eflags & MFE_VERTICALFLIP)
if (type == MT_GHOST)
{
mobj->flags2 |= MF2_OBJECTFLIP;
mobj->eflags |= MFE_VERTICALFLIP;
mobj = P_SpawnGhostMobj(g->mo); // does a large portion of the work for us
mobj->frame = (mobj->frame & ~FF_FRAMEMASK)|tr_trans60<<FF_TRANSSHIFT; // P_SpawnGhostMobj sets trans50, we want trans60
}
P_SetScale(mobj, g->mo->scale);
mobj->destscale = g->mo->scale;
else
{
mobj = P_SpawnMobjFromMobj(g->mo, 0, 0, -FixedDiv(FixedMul(g->mo->info->height, g->mo->scale) - g->mo->height,3*FRACUNIT), MT_THOK);
mobj->sprite = states[mobjinfo[type].spawnstate].sprite;
mobj->frame = (states[mobjinfo[type].spawnstate].frame & FF_FRAMEMASK) | tr_trans60<<FF_TRANSSHIFT;
mobj->color = g->mo->color;
mobj->skin = g->mo->skin;
P_SetScale(mobj, (mobj->destscale = g->mo->scale));
if (type == MT_THOK) // spintrail-specific modification for MT_THOK
{
mobj->frame = FF_TRANS80;
mobj->fuse = mobj->tics;
}
mobj->tics = -1; // nope.
}
mobj->floorz = mobj->z;
mobj->ceilingz = mobj->z+mobj->height;
P_UnsetThingPosition(mobj);
mobj->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up...
P_SetThingPosition(mobj);
if (!mobj->fuse)
mobj->fuse = 8;
P_SetTarget(&mobj->target, g->mo);
}
mobj->floorz = mobj->z;
mobj->ceilingz = mobj->z+mobj->height;
P_UnsetThingPosition(mobj);
mobj->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up...
P_SetThingPosition(mobj);
mobj->fuse = 8;
P_SetTarget(&mobj->target, g->mo);
}
if (xziptic & EZT_HIT)
{ // Spawn hit poofs for killing things!
@ -4780,6 +4809,11 @@ void G_GhostTicker(void)
}
if (xziptic & EZT_SPRITE)
g->mo->sprite = READUINT16(g->p);
if (xziptic & EZT_HEIGHT)
{
fixed_t temp = READINT16(g->p)<<FRACBITS;
g->mo->height = FixedMul(temp, g->mo->scale);
}
}
// Tick ghost colors (Super and Mario Invincibility flashing)
@ -4806,13 +4840,16 @@ void G_GhostTicker(void)
if (ziptic & GZT_FOLLOW)
{ // Even more...
UINT8 followtic = READUINT8(g->p);
fixed_t temp;
if (followtic & FZT_SPAWNED)
{
if (follow)
P_RemoveMobj(follow);
P_SetTarget(&follow, P_SpawnMobj(g->mo->x, g->mo->y, g->mo->z, MT_GHOST));
P_SetTarget(&follow, P_SpawnMobjFromMobj(g->mo, 0, 0, 0, MT_GHOST));
P_SetTarget(&follow->tracer, g->mo);
follow->tics = -1;
temp = READINT16(g->p)<<FRACBITS;
follow->height = FixedMul(follow->scale, temp);
if (followtic & FZT_LINKDRAW)
follow->flags2 |= MF2_LINKDRAW;
@ -4822,34 +4859,41 @@ void G_GhostTicker(void)
if (followtic & FZT_SKIN)
follow->skin = &skins[READUINT8(g->p)];
follow->eflags = (follow->eflags & ~MFE_VERTICALFLIP)|(g->mo->eflags & MFE_VERTICALFLIP);
}
if (follow)
{
if (!(followtic & FZT_SPAWNED))
{
if (xziptic & EZT_FLIP)
follow->eflags ^= MFE_VERTICALFLIP;
}
if (followtic & FZT_SCALE)
follow->destscale = READFIXED(g->p);
else
follow->destscale = g->mo->destscale;
if (follow->destscale != follow->scale)
P_SetScale(follow, follow->destscale);
P_UnsetThingPosition(follow);
follow->x = g->mo->x + (READINT16(g->p)<<8);
follow->y = g->mo->y + (READINT16(g->p)<<8);
follow->z = g->mo->z + (READINT16(g->p)<<8);
temp = READINT16(g->p)<<8;
follow->x = g->mo->x + temp;
temp = READINT16(g->p)<<8;
follow->y = g->mo->y + temp;
temp = READINT16(g->p)<<8;
follow->z = g->mo->z + temp;
P_SetThingPosition(follow);
if (followtic & FZT_SKIN)
follow->sprite2 = READUINT8(g->p);
else
follow->sprite2 = 0;
follow->sprite = READUINT16(g->p);
follow->frame = (READUINT8(g->p)) | tr_trans30<<FF_TRANSSHIFT;
follow->frame = (READUINT8(g->p)) | (g->mo->frame & FF_TRANSMASK);
follow->angle = g->mo->angle;
follow->color = READUINT8(g->p);
if (followtic & FZT_SCALE)
P_SetScale(follow, (follow->destscale = READFIXED(g->p)));
else
P_SetScale(follow, (follow->destscale = g->mo->destscale));
if (!(followtic & FZT_SPAWNED))
{
if (xziptic & EZT_FLIP)
{
follow->flags2 ^= MF2_OBJECTFLIP;
follow->eflags ^= MFE_VERTICALFLIP;
}
}
}
}
else if (follow)
@ -4857,12 +4901,20 @@ void G_GhostTicker(void)
P_RemoveMobj(follow);
P_SetTarget(&follow, NULL);
}
#undef follow
// Demo ends after ghost data.
if (*g->p == DEMOMARKER)
{
g->mo->momx = g->mo->momy = g->mo->momz = 0;
#if 1 // freeze frame (maybe more useful for time attackers)
g->mo->colorized = true;
if (follow)
follow->colorized = true;
#else // dissapearing act
g->mo->fuse = TICRATE;
if (follow)
follow->fuse = TICRATE;
#endif
if (p)
p->next = g->next;
else
@ -4871,6 +4923,7 @@ void G_GhostTicker(void)
continue;
}
p = g;
#undef follow
}
}
@ -4936,46 +4989,126 @@ void G_ReadMetalTic(mobj_t *metal)
if (metal->destscale != metal->scale)
P_SetScale(metal, metal->destscale);
}
if (xziptic & EZT_THOKMASK)
{ // Let's only spawn ONE of these per frame, thanks.
mobj_t *mobj;
INT32 type = -1;
if (metal->skin)
{
skin_t *skin = (skin_t *)metal->skin;
switch (xziptic & EZT_THOKMASK)
{
case EZT_THOK:
type = skin->thokitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].painchance : (UINT32)skin->thokitem;
break;
case EZT_SPIN:
type = skin->spinitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].damage : (UINT32)skin->spinitem;
break;
case EZT_REV:
type = skin->revitem < 0 ? (UINT32)mobjinfo[MT_PLAYER].raisestate : (UINT32)skin->revitem;
break;
}
}
if (type != MT_NULL)
{
if (type == MT_GHOST)
{
mobj = P_SpawnGhostMobj(metal); // does a large portion of the work for us
}
else
{
mobj = P_SpawnMobjFromMobj(metal, 0, 0, -FixedDiv(FixedMul(metal->info->height, metal->scale) - metal->height,3*FRACUNIT), MT_THOK);
mobj->sprite = states[mobjinfo[type].spawnstate].sprite;
mobj->frame = states[mobjinfo[type].spawnstate].frame;
mobj->angle = metal->angle;
mobj->color = metal->color;
mobj->skin = metal->skin;
P_SetScale(mobj, (mobj->destscale = metal->scale));
if (type == MT_THOK) // spintrail-specific modification for MT_THOK
{
mobj->frame = FF_TRANS70;
mobj->fuse = mobj->tics;
}
mobj->tics = -1; // nope.
}
mobj->floorz = mobj->z;
mobj->ceilingz = mobj->z+mobj->height;
P_UnsetThingPosition(mobj);
mobj->flags = MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY; // make an ATTEMPT to curb crazy SOCs fucking stuff up...
P_SetThingPosition(mobj);
if (!mobj->fuse)
mobj->fuse = 8;
P_SetTarget(&mobj->target, metal);
}
}
if (xziptic & EZT_SPRITE)
metal->sprite = READUINT16(metal_p);
if (xziptic & EZT_HEIGHT)
{
fixed_t temp = READINT16(metal_p)<<FRACBITS;
metal->height = FixedMul(temp, metal->scale);
}
}
#define follow metal->tracer
if (ziptic & GZT_FOLLOW)
{ // Even more...
UINT8 followtic = READUINT8(metal_p);
fixed_t temp;
if (followtic & FZT_SPAWNED)
{
if (follow)
P_RemoveMobj(follow);
P_SetTarget(&follow, P_SpawnMobj(metal->x, metal->y, metal->z, MT_GHOST));
P_SetTarget(&follow, P_SpawnMobjFromMobj(metal, 0, 0, 0, MT_GHOST));
P_SetTarget(&follow->tracer, metal);
follow->tics = -1;
temp = READINT16(metal_p)<<FRACBITS;
follow->height = FixedMul(follow->scale, temp);
if (followtic & FZT_LINKDRAW)
follow->flags2 |= MF2_LINKDRAW;
if (followtic & FZT_COLORIZED)
follow->colorized = true;
follow->eflags = (follow->eflags & ~MFE_VERTICALFLIP)|(metal->eflags & MFE_VERTICALFLIP);
if (followtic & FZT_SKIN)
follow->skin = &skins[READUINT8(metal_p)];
}
if (follow)
{
if (!(followtic & FZT_SPAWNED))
{
if (xziptic & EZT_FLIP)
follow->eflags ^= MFE_VERTICALFLIP;
}
if (followtic & FZT_SCALE)
follow->destscale = READFIXED(metal_p);
else
follow->destscale = metal->destscale;
if (follow->destscale != follow->scale)
P_SetScale(follow, follow->destscale);
P_UnsetThingPosition(follow);
follow->x = metal->x + (READINT16(metal_p)<<8);
follow->y = metal->y + (READINT16(metal_p)<<8);
follow->z = metal->z + (READINT16(metal_p)<<8);
temp = READINT16(metal_p)<<8;
follow->x = metal->x + temp;
temp = READINT16(metal_p)<<8;
follow->y = metal->y + temp;
temp = READINT16(metal_p)<<8;
follow->z = metal->z + temp;
P_SetThingPosition(follow);
if (followtic & FZT_SKIN)
follow->sprite2 = READUINT8(metal_p);
else
follow->sprite2 = 0;
follow->sprite = READUINT16(metal_p);
follow->frame = READUINT32(metal_p); // NOT & FF_FRAMEMASK here, so 32 bits
follow->angle = metal->angle;
follow->color = READUINT8(metal_p);
if (followtic & FZT_SCALE)
P_SetScale(follow, (follow->destscale = READFIXED(metal_p)));
else
P_SetScale(follow, (follow->destscale = metal->destscale));
if (!(followtic & FZT_SPAWNED))
{
if (xziptic & EZT_FLIP)
{
follow->flags2 ^= MF2_OBJECTFLIP;
follow->eflags ^= MFE_VERTICALFLIP;
}
}
}
}
else if (follow)
@ -4997,8 +5130,9 @@ void G_WriteMetalTic(mobj_t *metal)
{
UINT8 ziptic = 0;
UINT8 *ziptic_p;
fixed_t height;
if (!demo_p) // demo_p will be NULL until the race start linedef executor is triggered!
if (!demo_p) // demo_p will be NULL until the race start linedef executor is activated!
return;
demo_p++;
ziptic_p = demo_p++; // the ziptic, written at the end of this function
@ -5077,32 +5211,43 @@ void G_WriteMetalTic(mobj_t *metal)
WRITEUINT8(demo_p,oldmetal.sprite2);
}
// Check for sprite set changes
if (metal->sprite != oldmetal.sprite)
{
UINT8 *exttic_p = NULL;
UINT8 exttic = 0;
if ((metal->eflags & MFE_VERTICALFLIP) != (oldmetal.eflags & MFE_VERTICALFLIP))
{
if (!exttic_p)
exttic_p = demo_p++;
exttic |= EZT_FLIP;
oldmetal.eflags ^= MFE_VERTICALFLIP;
}
if (metal->scale != oldmetal.scale)
{
if (!exttic_p)
exttic_p = demo_p++;
exttic |= EZT_SCALE;
WRITEFIXED(demo_p,metal->scale);
oldmetal.scale = metal->scale;
}
if (exttic_p)
{
*exttic_p = exttic;
ziptic |= GZT_EXTRA;
}
oldmetal.sprite = metal->sprite;
ghostext.flags |= EZT_SPRITE;
}
if (metal->player && metal->player->followmobj)
if ((height = FixedDiv(metal->height, metal->scale)) != oldmetal.height)
{
oldmetal.height = height;
ghostext.flags |= EZT_HEIGHT;
}
if (ghostext.flags & ~(EZT_COLOR|EZT_HIT)) // these two aren't handled by metal ever
{
ziptic |= GZT_EXTRA;
if (ghostext.scale == ghostext.lastscale)
ghostext.flags &= ~EZT_SCALE;
WRITEUINT8(demo_p,ghostext.flags);
if (ghostext.flags & EZT_SCALE)
{
WRITEFIXED(demo_p,ghostext.scale);
ghostext.lastscale = ghostext.scale;
}
if (ghostext.flags & EZT_SPRITE)
WRITEUINT16(demo_p,oldmetal.sprite);
if (ghostext.flags & EZT_HEIGHT)
{
height >>= FRACBITS;
WRITEINT16(demo_p, height);
}
ghostext.flags = 0;
}
if (metal->player && metal->player->followmobj && !(metal->player->followmobj->sprite == SPR_NULL || (metal->player->followmobj->flags2 & MF2_DONTDRAW)))
{
INT16 temp;
UINT8 *followtic_p = demo_p++;
@ -5110,34 +5255,39 @@ void G_WriteMetalTic(mobj_t *metal)
ziptic |= GZT_FOLLOW;
if (metal->player->followmobj->skin)
followtic |= FZT_SKIN;
if (!(oldmetal.flags2 & MF2_AMBUSH))
{
followtic |= FZT_SPAWNED;
/*if (metal->player->followmobj->flags2 & MF2_LINKDRAW)
followtic |= FZT_LINKDRAW;*/
WRITEINT16(demo_p,metal->player->followmobj->info->height>>FRACBITS);
if (metal->player->followmobj->flags2 & MF2_LINKDRAW)
followtic |= FZT_LINKDRAW;
if (metal->player->followmobj->colorized)
followtic |= FZT_COLORIZED;
/*if (followtic & FZT_SKIN)
WRITEUINT8(demo_p,(UINT8)(((skin_t *)(metal->player->followmobj->skin))-skins));*/
if (followtic & FZT_SKIN)
WRITEUINT8(demo_p,(UINT8)(((skin_t *)(metal->player->followmobj->skin))-skins));
oldmetal.flags2 |= MF2_AMBUSH;
}
if (metal->player->followmobj->scale != metal->scale)
{
followtic |= FZT_SCALE;
WRITEFIXED(demo_p,metal->player->followmobj->scale);
}
temp = (INT16)((metal->player->followmobj->x-metal->x)>>8);
WRITEINT16(demo_p,temp);
temp = (INT16)((metal->player->followmobj->y-metal->y)>>8);
WRITEINT16(demo_p,temp);
temp = (INT16)((metal->player->followmobj->z-metal->z)>>8);
WRITEINT16(demo_p,temp);
/*if (followtic & FZT_SKIN)
WRITEUINT8(demo_p,metal->player->followmobj->sprite2);*/
if (followtic & FZT_SKIN)
WRITEUINT8(demo_p,metal->player->followmobj->sprite2);
WRITEUINT16(demo_p,metal->player->followmobj->sprite);
WRITEUINT32(demo_p,metal->player->followmobj->frame); // NOT & FF_FRAMEMASK here, so 32 bits
WRITEUINT8(demo_p,metal->player->followmobj->color);
if (metal->player->followmobj->scale != metal->scale)
{
followtic |= FZT_SCALE;
WRITEFIXED(demo_p,metal->player->followmobj->scale);
}
*followtic_p = followtic;
}
@ -5344,6 +5494,9 @@ void G_BeginMetal(void)
M_Memcpy(demo_p, "METL", 4); demo_p += 4;
memset(&ghostext,0,sizeof(ghostext));
ghostext.lastscale = ghostext.scale = FRACUNIT;
// Set up our memory.
memset(&oldmetal,0,sizeof(oldmetal));
oldmetal.x = mo->x;
@ -5992,7 +6145,9 @@ void G_AddGhost(char *defdemoname)
gh->mo->state = states+S_PLAY_STND;
gh->mo->sprite = gh->mo->state->sprite;
gh->mo->sprite2 = (gh->mo->state->frame & FF_FRAMEMASK);
gh->mo->frame = tr_trans20<<FF_TRANSSHIFT;
//gh->mo->frame = tr_trans30<<FF_TRANSSHIFT;
gh->mo->flags2 |= MF2_DONTDRAW;
gh->fadein = (9-3)*6; // fade from invisible to trans30 over as close to 35 tics as possible
gh->mo->tics = -1;
CONS_Printf(M_GetText("Added ghost %s from %s\n"), name, pdemoname);

View file

@ -10402,8 +10402,6 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
case MT_METALSONIC_RACE:
mobj->skin = &skins[5];
mobj->color = skins[5].prefcolor;
mobj->sprite2 = P_GetSkinSprite2(mobj->skin, mobj->frame & FF_FRAMEMASK, NULL);
mobj->frame &= ~FF_FRAMEMASK;
/* FALLTHRU */
case MT_METALSONIC_BATTLE:
sc = 5;
@ -10471,6 +10469,12 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type)
if (!(mobj->flags & MF_NOTHINK))
P_AddThinker(THINK_MOBJ, &mobj->thinker);
if (mobj->skin) // correct inadequecies above.
{
mobj->sprite2 = P_GetSkinSprite2(mobj->skin, (mobj->frame & FF_FRAMEMASK), NULL);
mobj->frame &= ~FF_FRAMEMASK;
}
// Call action functions when the state is set
if (st->action.acp1 && (mobj->flags & MF_RUNSPAWNFUNC))
{

View file

@ -2048,8 +2048,7 @@ void P_SpawnThokMobj(player_t *player)
mobj->eflags |= (player->mo->eflags & MFE_VERTICALFLIP);
// scale
P_SetScale(mobj, player->mo->scale);
mobj->destscale = player->mo->scale;
P_SetScale(mobj, (mobj->destscale = player->mo->scale));
if (type == MT_THOK) // spintrail-specific modification for MT_THOK
{
@ -2059,8 +2058,7 @@ void P_SpawnThokMobj(player_t *player)
}
P_SetTarget(&mobj->target, player->mo); // the one thing P_SpawnGhostMobj doesn't do
if (demorecording)
G_GhostAddThok();
G_GhostAddThok();
}
//
@ -4574,8 +4572,7 @@ static void P_DoSpinAbility(player_t *player, ticcmd_t *cmd)
if (player->revitem && !(leveltime % 5)) // Now spawn the color thok circle.
{
P_SpawnSpinMobj(player, player->revitem);
if (demorecording)
G_GhostAddRev();
G_GhostAddRev();
}
}
@ -8325,8 +8322,7 @@ static void P_MovePlayer(player_t *player)
if (player->pflags & PF_SPINNING && P_AproxDistance(player->speed, player->mo->momz) > FixedMul(15<<FRACBITS, player->mo->scale) && !(player->pflags & PF_JUMPED))
{
P_SpawnSpinMobj(player, player->spinitem);
if (demorecording)
G_GhostAddSpin();
G_GhostAddSpin();
}
@ -11052,6 +11048,7 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume)
}
fume->movecount = dashmode; // keeps track of previous dashmode value so we know whether Metal is entering or leaving it
fume->eflags = (fume->flags2 & ~MF2_OBJECTFLIP) | (mo->flags2 & MF2_OBJECTFLIP); // Make sure to flip in reverse gravity!
fume->eflags = (fume->eflags & ~MFE_VERTICALFLIP) | (mo->eflags & MFE_VERTICALFLIP); // Make sure to flip in reverse gravity!
// Finally, set its position
@ -11060,10 +11057,7 @@ static void P_DoMetalJetFume(player_t *player, mobj_t *fume)
P_UnsetThingPosition(fume);
fume->x = mo->x + P_ReturnThrustX(fume, angle, dist);
fume->y = mo->y + P_ReturnThrustY(fume, angle, dist);
if (fume->eflags & MFE_VERTICALFLIP)
fume->z = mo->z + ((mo->height + fume->height) >> 1);
else
fume->z = mo->z + ((mo->height - fume->height) >> 1);
fume->z = mo->z + ((mo->height - fume->height) >> 1);
P_SetThingPosition(fume);
}