From f0f8b544deb9b7006a11bcbc629ba591b071688c Mon Sep 17 00:00:00 2001 From: toaster Date: Tue, 29 Oct 2019 15:32:22 +0000 Subject: [PATCH] * 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...) --- src/g_game.c | 361 ++++++++++++++++++++++++++++++++++++--------------- src/p_mobj.c | 8 +- src/p_user.c | 18 +-- 3 files changed, 270 insertions(+), 117 deletions(-) diff --git a/src/g_game.c b/src/g_game.c index 27cece73d..b5e8a9509 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -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<fadein) + { + g->mo->frame += (((--g->fadein)/6)<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<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<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<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<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)<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)<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<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)<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)<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<mo->frame = tr_trans30<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); diff --git a/src/p_mobj.c b/src/p_mobj.c index b74e08e54..c87f0bd3c 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -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)) { diff --git a/src/p_user.c b/src/p_user.c index a4e500c7c..7ac9b34ed 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -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<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); }