diff --git a/src/d_netcmd.c b/src/d_netcmd.c index b14f92b33..5c8c327c8 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -1206,9 +1206,9 @@ static void SendNameAndColor(void) players[consoleplayer].mo->color = players[consoleplayer].skincolor; if (metalrecording) - { // Metal Sonic is Sonic, obviously. - SetPlayerSkinByNum(consoleplayer, 0); - CV_StealthSet(&cv_skin, skins[0].name); + { // Starring Metal Sonic as themselves, obviously. + SetPlayerSkinByNum(consoleplayer, 5); + CV_StealthSet(&cv_skin, skins[5].name); } else if ((foundskin = R_SkinAvailable(cv_skin.string)) != -1 && R_SkinUsable(consoleplayer, foundskin)) { diff --git a/src/dehacked.c b/src/dehacked.c index 34ee1f170..6369d5d7f 100644 --- a/src/dehacked.c +++ b/src/dehacked.c @@ -5260,25 +5260,7 @@ static const char *const STATE_LIST[] = { // array length left dynamic for sanit "S_CYBRAKDEMONVILEEXPLOSION3", // Metal Sonic (Race) - // S_PLAY_STND - "S_METALSONIC_STAND", - // S_PLAY_TAP1 - "S_METALSONIC_WAIT1", - "S_METALSONIC_WAIT2", - // S_PLAY_WALK - "S_METALSONIC_WALK1", - "S_METALSONIC_WALK2", - "S_METALSONIC_WALK3", - "S_METALSONIC_WALK4", - "S_METALSONIC_WALK5", - "S_METALSONIC_WALK6", - "S_METALSONIC_WALK7", - "S_METALSONIC_WALK8", - // S_PLAY_SPD1 - "S_METALSONIC_RUN1", - "S_METALSONIC_RUN2", - "S_METALSONIC_RUN3", - "S_METALSONIC_RUN4", + "S_METALSONIC_RACE", // Metal Sonic (Battle) "S_METALSONIC_FLOAT", "S_METALSONIC_VECTOR", diff --git a/src/g_game.c b/src/g_game.c index e2f43e4f2..27cece73d 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -4044,7 +4044,7 @@ char *G_BuildMapTitle(INT32 mapnum) // DEMO RECORDING // -#define DEMOVERSION 0x000a +#define DEMOVERSION 0x000b #define DEMOHEADER "\xF0" "SRB2Replay" "\x0F" #define DF_GHOST 0x01 // This demo contains ghost data too! @@ -4068,7 +4068,6 @@ static ticcmd_t oldcmd; #define GZT_MOMXY 0x02 #define GZT_MOMZ 0x04 #define GZT_ANGLE 0x08 -// Not used for Metal Sonic #define GZT_FRAME 0x10 // Animation frame #define GZT_SPR2 0x20 // Player animations #define GZT_EXTRA 0x40 @@ -4086,6 +4085,14 @@ static ticcmd_t oldcmd; #define EZT_SPRITE 0x40 // Changed sprite set completely out of PLAY (NiGHTS, SOCs, whatever) // spare EZT slot 0x80 +// GZT_FOLLOW flags +#define FZT_SPAWNED 0x01 // just been spawned +#define FZT_SKIN 0x02 // has skin +#define FZT_LINKDRAW 0x04 // has linkdraw (combine with spawned only) +#define FZT_COLORIZED 0x08 // colorized (ditto) +#define FZT_SCALE 0x10 // different scale to object +// spare FZT slots 0x20 to 0x80 + static mobj_t oldmetal, oldghost; void G_SaveMetal(UINT8 **buffer) @@ -4405,26 +4412,54 @@ void G_WriteGhostTic(mobj_t *ghost) ghostext.hitlist = NULL; } if (ghostext.flags & EZT_SPRITE) - WRITEUINT8(demo_p,oldghost.sprite); + WRITEUINT16(demo_p,oldghost.sprite); ghostext.flags = 0; } if (ghost->player && ghost->player->followmobj) // bloats tails runs but what can ya do { INT16 temp; + UINT8 *followtic_p = demo_p++; + UINT8 followtic = 0; ziptic |= GZT_FOLLOW; + if (ghost->player->followmobj->skin) + followtic |= FZT_SKIN; + + if (!(oldghost.flags2 & MF2_AMBUSH)) + { + followtic |= FZT_SPAWNED; + if (ghost->player->followmobj->flags2 & MF2_LINKDRAW) + followtic |= FZT_LINKDRAW; + if (ghost->player->followmobj->colorized) + followtic |= FZT_COLORIZED; + if (followtic & FZT_SKIN) + WRITEUINT8(demo_p,(UINT8)(((skin_t *)(ghost->player->followmobj->skin))-skins)); + oldghost.flags2 |= MF2_AMBUSH; + } + temp = (INT16)((ghost->player->followmobj->x-ghost->x)>>8); WRITEINT16(demo_p,temp); temp = (INT16)((ghost->player->followmobj->y-ghost->y)>>8); WRITEINT16(demo_p,temp); temp = (INT16)((ghost->player->followmobj->z-ghost->z)>>8); WRITEINT16(demo_p,temp); - WRITEUINT8(demo_p,ghost->player->followmobj->sprite); - WRITEUINT8(demo_p,ghost->player->followmobj->sprite2); + if (followtic & FZT_SKIN) + WRITEUINT8(demo_p,ghost->player->followmobj->sprite2); + WRITEUINT16(demo_p,ghost->player->followmobj->sprite); WRITEUINT8(demo_p,(ghost->player->followmobj->frame & FF_FRAMEMASK)); + WRITEUINT8(demo_p,ghost->player->followmobj->color); + if (ghost->player->followmobj->scale != ghost->scale) + { + followtic |= FZT_SCALE; + WRITEFIXED(demo_p,ghost->player->followmobj->scale); + } + + *followtic_p = followtic; } + else + oldghost.flags2 &= ~MF2_AMBUSH; *ziptic_p = ziptic; @@ -4528,17 +4563,24 @@ void G_ConsGhostTic(void) } } if (xziptic & EZT_SPRITE) - demo_p++; + demo_p += sizeof(UINT16); } if (ziptic & GZT_FOLLOW) { // Even more... + UINT8 followtic = READUINT8(demo_p); + if ((followtic & (FZT_SPAWNED|FZT_SKIN)) == (FZT_SPAWNED|FZT_SKIN)) + demo_p++; demo_p += sizeof(INT16); demo_p += sizeof(INT16); demo_p += sizeof(INT16); + if (followtic & FZT_SKIN) + demo_p++; + demo_p += sizeof(UINT16); demo_p++; demo_p++; - demo_p++; + if (followtic & FZT_SCALE) + demo_p += sizeof(fixed_t); } // Re-synchronise @@ -4737,7 +4779,7 @@ void G_GhostTicker(void) } } if (xziptic & EZT_SPRITE) - g->mo->sprite = READUINT8(g->p); + g->mo->sprite = READUINT16(g->p); } // Tick ghost colors (Super and Mario Invincibility flashing) @@ -4763,43 +4805,52 @@ void G_GhostTicker(void) #define follow g->mo->tracer if (ziptic & GZT_FOLLOW) { // Even more... - if (!follow) + UINT8 followtic = READUINT8(g->p); + if (followtic & FZT_SPAWNED) { - mobj_t *newmo = P_SpawnMobj(g->mo->x, g->mo->y, g->mo->z, MT_GHOST); - P_SetTarget(&g->mo->tracer, newmo); - P_SetTarget(&newmo->tracer, g->mo); - newmo->skin = g->mo->skin; - newmo->tics = -1; - newmo->flags2 |= MF2_LINKDRAW; + if (follow) + P_RemoveMobj(follow); + P_SetTarget(&follow, P_SpawnMobj(g->mo->x, g->mo->y, g->mo->z, MT_GHOST)); + P_SetTarget(&follow->tracer, g->mo); + follow->tics = -1; + + if (followtic & FZT_LINKDRAW) + follow->flags2 |= MF2_LINKDRAW; + + if (followtic & FZT_COLORIZED) + follow->colorized = true; + + if (followtic & FZT_SKIN) + follow->skin = &skins[READUINT8(g->p)]; follow->eflags = (follow->eflags & ~MFE_VERTICALFLIP)|(g->mo->eflags & MFE_VERTICALFLIP); - follow->destscale = g->mo->destscale; - if (follow->destscale != follow->scale) - P_SetScale(follow, follow->destscale); } - else + if (follow) { - if (xziptic & EZT_FLIP) - g->mo->eflags ^= MFE_VERTICALFLIP; - if (xziptic & EZT_SCALE) + if (!(followtic & FZT_SPAWNED)) { - follow->destscale = g->mo->destscale; - if (follow->destscale != follow->scale) - P_SetScale(follow, follow->destscale); + if (xziptic & EZT_FLIP) + follow->eflags ^= MFE_VERTICALFLIP; } + + 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); + 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<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)); } - - 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); - P_SetThingPosition(follow); - follow->sprite = READUINT8(g->p); - follow->sprite2 = READUINT8(g->p); - follow->frame = (READUINT8(g->p)) | tr_trans30<angle = g->mo->angle; - follow->color = g->mo->color; } else if (follow) { @@ -4826,11 +4877,11 @@ void G_GhostTicker(void) void G_ReadMetalTic(mobj_t *metal) { UINT8 ziptic; - UINT16 speed; - UINT8 statetype; + UINT8 xziptic = 0; if (!metal_p) return; + metal_p++; ziptic = READUINT8(metal_p); // Read changes from the tic @@ -4857,9 +4908,9 @@ void G_ReadMetalTic(mobj_t *metal) if (ziptic & GZT_ANGLE) metal->angle = READUINT8(metal_p)<<24; if (ziptic & GZT_FRAME) - metal_p++; // Currently unused. (Metal Sonic figures out what he's doing his own damn self.) + oldmetal.frame = READUINT32(metal_p); if (ziptic & GZT_SPR2) - metal_p++; + oldmetal.sprite2 = READUINT8(metal_p); // Set movement, position, and angle // oldmetal contains where you're supposed to be. @@ -4871,13 +4922,15 @@ void G_ReadMetalTic(mobj_t *metal) metal->y = oldmetal.y; metal->z = oldmetal.z; P_SetThingPosition(metal); + metal->frame = oldmetal.frame; + metal->sprite2 = oldmetal.sprite2; if (ziptic & GZT_EXTRA) { // But wait, there's more! - ziptic = READUINT8(metal_p); - if (ziptic & EZT_FLIP) + xziptic = READUINT8(metal_p); + if (xziptic & EZT_FLIP) metal->eflags ^= MFE_VERTICALFLIP; - if (ziptic & EZT_SCALE) + if (xziptic & EZT_SCALE) { metal->destscale = READFIXED(metal_p); if (metal->destscale != metal->scale) @@ -4885,36 +4938,52 @@ void G_ReadMetalTic(mobj_t *metal) } } - // Calculates player's speed based on distance-of-a-line formula - speed = FixedDiv(P_AproxDistance(oldmetal.momx, oldmetal.momy), metal->scale)>>FRACBITS; +#define follow metal->tracer + if (ziptic & GZT_FOLLOW) + { // Even more... + UINT8 followtic = READUINT8(metal_p); + 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->tracer, metal); + follow->tics = -1; - // Use speed to decide an appropriate state - if (speed > 28) // default skin runspeed - statetype = 2; - else if (speed > 1) // stopspeed - statetype = 1; - else - statetype = 0; + if (followtic & FZT_COLORIZED) + follow->colorized = true; - // Set state - if (statetype != metal->threshold) - { - switch (statetype) - { - case 2: // run - P_SetMobjState(metal,metal->info->meleestate); - break; - case 1: // walk - P_SetMobjState(metal,metal->info->seestate); - break; - default: // stand - P_SetMobjState(metal,metal->info->spawnstate); - break; + follow->eflags = (follow->eflags & ~MFE_VERTICALFLIP)|(metal->eflags & MFE_VERTICALFLIP); + } + if (follow) + { + if (!(followtic & FZT_SPAWNED)) + { + if (xziptic & EZT_FLIP) + follow->eflags ^= MFE_VERTICALFLIP; + } + + 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); + P_SetThingPosition(follow); + 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)); + } } - metal->threshold = statetype; - } - - // TODO: Modify state durations based on movement speed, similar to players? + else if (follow) + { + P_RemoveMobj(follow); + P_SetTarget(&follow, NULL); + } +#undef follow if (*metal_p == DEMOMARKER) { @@ -4931,7 +5000,7 @@ void G_WriteMetalTic(mobj_t *metal) if (!demo_p) // demo_p will be NULL until the race start linedef executor is triggered! return; - + demo_p++; ziptic_p = demo_p++; // the ziptic, written at the end of this function #define MAXMOM (0xFFFF<<8) @@ -4944,10 +5013,10 @@ void G_WriteMetalTic(mobj_t *metal) oldmetal.x = metal->x; oldmetal.y = metal->y; oldmetal.z = metal->z; + ziptic |= GZT_XYZ; WRITEFIXED(demo_p,oldmetal.x); WRITEFIXED(demo_p,oldmetal.y); WRITEFIXED(demo_p,oldmetal.z); - ziptic |= GZT_XYZ; } else { @@ -4960,16 +5029,16 @@ void G_WriteMetalTic(mobj_t *metal) { oldmetal.momx = momx; oldmetal.momy = momy; + ziptic |= GZT_MOMXY; WRITEINT16(demo_p,momx); WRITEINT16(demo_p,momy); - ziptic |= GZT_MOMXY; } momx = (INT16)((metal->z-oldmetal.z)>>8); if (momx != oldmetal.momz) { oldmetal.momz = momx; - WRITEINT16(demo_p,momx); ziptic |= GZT_MOMZ; + WRITEINT16(demo_p,momx); } // This SHOULD set oldmetal.x/y/z to match metal->x/y/z @@ -4992,8 +5061,21 @@ void G_WriteMetalTic(mobj_t *metal) WRITEUINT8(demo_p,oldmetal.angle); } - // Metal Sonic does not need our state changes. - // ... currently. + // Store the sprite frame. + if ((metal->frame & FF_FRAMEMASK) != oldmetal.frame) + { + oldmetal.frame = metal->frame; // NOT & FF_FRAMEMASK here, so 32 bits + ziptic |= GZT_FRAME; + WRITEUINT32(demo_p,oldmetal.frame); + } + + if (metal->sprite == SPR_PLAY + && metal->sprite2 != oldmetal.sprite2) + { + oldmetal.sprite2 = metal->sprite2; + ziptic |= GZT_SPR2; + WRITEUINT8(demo_p,oldmetal.sprite2); + } { UINT8 *exttic_p = NULL; @@ -5020,6 +5102,48 @@ void G_WriteMetalTic(mobj_t *metal) } } + if (metal->player && metal->player->followmobj) + { + INT16 temp; + UINT8 *followtic_p = demo_p++; + UINT8 followtic = 0; + + ziptic |= GZT_FOLLOW; + + if (!(oldmetal.flags2 & MF2_AMBUSH)) + { + followtic |= FZT_SPAWNED; + /*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));*/ + oldmetal.flags2 |= MF2_AMBUSH; + } + + 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);*/ + 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; + } + else + oldmetal.flags2 &= ~MF2_AMBUSH; + *ziptic_p = ziptic; // attention here for the ticcmd size! diff --git a/src/info.c b/src/info.c index cfaad552d..99cd12862 100644 --- a/src/info.c +++ b/src/info.c @@ -1800,21 +1800,7 @@ state_t states[NUMSTATES] = {SPR_NULL, 0, 1, {A_BossScream}, 0, 0, S_CYBRAKDEMONVILEEXPLOSION1}, //S_CYBRAKDEMONVILEEXPLOSION3, // Metal Sonic - {SPR_METL, 0, 35, {NULL}, 0, 0, S_METALSONIC_WAIT1}, // S_METALSONIC_STAND - {SPR_METL, 1, 8, {NULL}, 0, 0, S_METALSONIC_WAIT2}, // S_METALSONIC_WAIT1 - {SPR_METL, 2, 8, {NULL}, 0, 0, S_METALSONIC_WAIT1}, // S_METALSONIC_WAIT2 - {SPR_METL, 3, 4, {NULL}, 0, 0, S_METALSONIC_WALK2}, // S_METALSONIC_WALK1 - {SPR_METL, 4, 4, {NULL}, 0, 0, S_METALSONIC_WALK3}, // S_METALSONIC_WALK2 - {SPR_METL, 5, 4, {NULL}, 0, 0, S_METALSONIC_WALK4}, // S_METALSONIC_WALK3 - {SPR_METL, 6, 4, {NULL}, 0, 0, S_METALSONIC_WALK5}, // S_METALSONIC_WALK4 - {SPR_METL, 7, 4, {NULL}, 0, 0, S_METALSONIC_WALK6}, // S_METALSONIC_WALK5 - {SPR_METL, 6, 4, {NULL}, 0, 0, S_METALSONIC_WALK7}, // S_METALSONIC_WALK6 - {SPR_METL, 5, 4, {NULL}, 0, 0, S_METALSONIC_WALK8}, // S_METALSONIC_WALK7 - {SPR_METL, 4, 4, {NULL}, 0, 0, S_METALSONIC_WALK1}, // S_METALSONIC_WALK8 - {SPR_METL, 8, 2, {NULL}, 0, 0, S_METALSONIC_RUN2}, // S_METALSONIC_RUN1 - {SPR_METL, 9, 2, {NULL}, 0, 0, S_METALSONIC_RUN3}, // S_METALSONIC_RUN2 - {SPR_METL, 10, 2, {NULL}, 0, 0, S_METALSONIC_RUN4}, // S_METALSONIC_RUN3 - {SPR_METL, 9, 2, {NULL}, 0, 0, S_METALSONIC_RUN1}, // S_METALSONIC_RUN4 + {SPR_PLAY, SPR2_STND, -1, {NULL}, 0, 0, S_METALSONIC_RACE}, // S_METALSONIC_RACE {SPR_METL, 4, -1, {NULL}, 0, 0, S_NULL}, // S_METALSONIC_FLOAT {SPR_METL, 12|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_METALSONIC_STUN}, // S_METALSONIC_VECTOR @@ -6677,16 +6663,16 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_METALSONIC_RACE 207, // doomednum - S_METALSONIC_STAND, // spawnstate + S_METALSONIC_RACE, // spawnstate 8, // spawnhealth - S_METALSONIC_WALK1, // seestate + S_NULL, // seestate sfx_None, // seesound 0, // reactiontime sfx_None, // attacksound S_NULL, // painstate 0, // painchance sfx_None, // painsound - S_METALSONIC_RUN1, // meleestate + S_NULL, // meleestate S_NULL, // missilestate S_NULL, // deathstate S_NULL, // xdeathstate diff --git a/src/info.h b/src/info.h index e7f41f585..bc3626b92 100644 --- a/src/info.h +++ b/src/info.h @@ -1933,25 +1933,7 @@ typedef enum state S_CYBRAKDEMONVILEEXPLOSION3, // Metal Sonic (Race) - // S_PLAY_STND - S_METALSONIC_STAND, - // S_PLAY_TAP1 - S_METALSONIC_WAIT1, - S_METALSONIC_WAIT2, - // S_PLAY_WALK - S_METALSONIC_WALK1, - S_METALSONIC_WALK2, - S_METALSONIC_WALK3, - S_METALSONIC_WALK4, - S_METALSONIC_WALK5, - S_METALSONIC_WALK6, - S_METALSONIC_WALK7, - S_METALSONIC_WALK8, - // S_PLAY_SPD1 - S_METALSONIC_RUN1, - S_METALSONIC_RUN2, - S_METALSONIC_RUN3, - S_METALSONIC_RUN4, + S_METALSONIC_RACE, // Metal Sonic (Battle) S_METALSONIC_FLOAT, S_METALSONIC_VECTOR, diff --git a/src/p_inter.c b/src/p_inter.c index 9017f795d..44215d691 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -3615,11 +3615,12 @@ boolean P_DamageMobj(mobj_t *target, mobj_t *inflictor, mobj_t *source, INT32 da } else if (inflictor && inflictor->flags & MF_MISSILE) return false; // Metal Sonic walk through flame !! - else + else if (!player->powers[pw_flashing]) { // Oh no! Metal Sonic is hit !! P_ShieldDamage(player, inflictor, source, damage, damagetype); return true; } + return false; } else if (player->powers[pw_invulnerability] || player->powers[pw_flashing] || player->powers[pw_super]) // ignore bouncing & such in invulnerability { diff --git a/src/p_mobj.c b/src/p_mobj.c index 5735dc27b..b74e08e54 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -10399,8 +10399,13 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) if (nummaprings >= 0) nummaprings++; break; - case MT_METALSONIC_BATTLE: 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; break; case MT_FANG: @@ -11248,6 +11253,8 @@ void P_MovePlayerToSpawn(INT32 playernum, mapthing_t *mthing) } if (mthing->options & MTF_AMBUSH) P_SetPlayerMobjState(mobj, S_PLAY_FALL); + else if (metalrecording) + P_SetPlayerMobjState(mobj, S_PLAY_WAIT); } else z = floor; diff --git a/src/p_user.c b/src/p_user.c index f81f6d956..a4e500c7c 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -11455,7 +11455,7 @@ void P_PlayerThink(player_t *player) // deez New User eXperiences. { - angle_t diff = 0; + angle_t oldang = player->drawangle, diff = 0; UINT8 factor; // Directionchar! // Camera angle stuff. @@ -11573,6 +11573,22 @@ void P_PlayerThink(player_t *player) player->drawangle += diff; } + // reset from waiting to standing when turning on the spot + if (player->panim == PA_IDLE) + { + diff = player->drawangle - oldang; + if (diff > ANGLE_180) + diff = InvAngle(diff); + if (diff > ANG10/2) + { + statenum_t stat = player->mo->state-states; + if (stat == S_PLAY_WAIT) + P_SetPlayerMobjState(player->mo, S_PLAY_STND); + else if (stat == S_PLAY_STND) + player->mo->tics++; + } + } + // Autobrake! check ST_drawInput if you modify this { boolean currentlyonground = P_IsObjectOnGround(player->mo); @@ -11812,7 +11828,7 @@ void P_PlayerThink(player_t *player) #define dashmode player->dashmode // Dash mode - thanks be to Iceman404 - if ((player->charflags & SF_DASHMODE) && !(player->gotflag) && !(maptol & TOL_NIGHTS)) // woo, dashmode! no nights tho. + if ((player->charflags & SF_DASHMODE) && !(player->gotflag) && !(maptol & TOL_NIGHTS) && !metalrecording) // woo, dashmode! no nights tho. { boolean totallyradical = player->speed >= FixedMul(player->runspeed, player->mo->scale); boolean floating = (player->secondjump == 1); diff --git a/src/r_things.c b/src/r_things.c index 00eaae1c2..22f9c5d89 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -2692,6 +2692,7 @@ boolean R_SkinUsable(INT32 playernum, INT32 skinnum) || (modeattacking) // If you have someone else's run you might as well take a look || (Playing() && (R_SkinAvailable(mapheaderinfo[gamemap-1]->forcecharacter) == skinnum)) // Force 1. || (netgame && (cv_forceskin.value == skinnum)) // Force 2. + || (metalrecording && skinnum == 5) // Force 3. ); }