diff --git a/src/deh_tables.c b/src/deh_tables.c index bd17b2afb..a8fd4612c 100644 --- a/src/deh_tables.c +++ b/src/deh_tables.c @@ -4674,6 +4674,8 @@ const char *const STATE_LIST[] = { // array length left dynamic for sanity testi "S_DOWNLINE4", "S_DOWNLINE5", + "S_HOLDBUBBLE", + // Finish line beam "S_FINISHBEAM1", "S_FINISHBEAM2", @@ -5795,6 +5797,7 @@ const char *const MOBJTYPE_LIST[] = { // array length left dynamic for sanity t "MT_SPINDASHWIND", "MT_SOFTLANDING", "MT_DOWNLINE", + "MT_HOLDBUBBLE", "MT_PAPERITEMSPOT", diff --git a/src/info.c b/src/info.c index 5ded215d5..672c0401d 100644 --- a/src/info.c +++ b/src/info.c @@ -754,6 +754,7 @@ char sprnames[NUMSPRITES + 1][5] = "SDWN", // Spindash wind "EBRK", // Soft Landing / Ebrake aura stuff. "HMTR", // Down Lines + "HBUB", // HOLD! Bubble "TRCK", @@ -5256,11 +5257,14 @@ state_t states[NUMSTATES] = {SPR_EBRK, 4|FF_ADD|FF_FLOORSPRITE, 4, {NULL}, 0, 0, S_NULL}, // S_SOFTLANDING5 // Downwards Lines - {SPR_HMTR, 0, 2, {NULL}, 0, 0, S_DOWNLINE2}, // S_DOWNLINE1 - {SPR_HMTR, 1, 2, {NULL}, 0, 0, S_DOWNLINE3}, // S_DOWNLINE2 - {SPR_HMTR, 2, 2, {NULL}, 0, 0, S_DOWNLINE4}, // S_DOWNLINE3 - {SPR_HMTR, 3, 2, {NULL}, 0, 0, S_DOWNLINE5}, // S_DOWNLINE4 - {SPR_HMTR, 4, 2, {NULL}, 0, 0, S_NULL}, // S_DOWNLINE5 + {SPR_HMTR, 0|FF_ADD, 1, {NULL}, 0, 0, S_DOWNLINE2}, // S_DOWNLINE1 + {SPR_HMTR, 1|FF_ADD, 1, {NULL}, 0, 0, S_DOWNLINE3}, // S_DOWNLINE2 + {SPR_HMTR, 2|FF_ADD, 1, {NULL}, 0, 0, S_DOWNLINE4}, // S_DOWNLINE3 + {SPR_HMTR, 3|FF_ADD, 1, {NULL}, 0, 0, S_DOWNLINE5}, // S_DOWNLINE4 + {SPR_HMTR, 4|FF_ADD, 1, {NULL}, 0, 0, S_NULL}, // S_DOWNLINE5 + + // HOLD Bubble + {SPR_HBUB, 0|FF_FULLBRIGHT, -1, {NULL}, 0, 0, S_HOLDBUBBLE}, // S_HOLDBUBBLE // Finish line beam {SPR_FLBM, FF_FULLBRIGHT, 1, {NULL}, 0, 0, S_NULL}, // S_FINISHBEAM1 @@ -29242,7 +29246,34 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] = { // MT_DOWNLINE -1, // doomednum - S_DOWNLINE1, // spawnstate + S_DOWNLINE1, // spawnstate + 1000, // spawnhealth + S_NULL, // seestate + sfx_None, // seesound + 8, // reactiontime + sfx_None, // attacksound + S_NULL, // painstate + 0, // painchance + sfx_None, // painsound + S_NULL, // meleestate + S_NULL, // missilestate + S_NULL, // deathstate + S_NULL, // xdeathstate + sfx_None, // deathsound + 0, // speed + 12*FRACUNIT, // radius + 24*FRACUNIT, // height + 0, // display offset + 100, // mass + 0, // damage + sfx_None, // activesound + MF_NOBLOCKMAP|MF_NOCLIP|MF_NOCLIPHEIGHT|MF_NOGRAVITY|MF_SCENERY|MF_DONTENCOREMAP, // flags + S_NULL // raisestate + }, + + { // MT_HOLDBUBBLE + -1, // doomednum + S_HOLDBUBBLE, // spawnstate 1000, // spawnhealth S_NULL, // seestate sfx_None, // seesound diff --git a/src/info.h b/src/info.h index 3494d057b..e64dae3de 100644 --- a/src/info.h +++ b/src/info.h @@ -1302,6 +1302,7 @@ typedef enum sprite SPR_SDWN, // Spindash wind SPR_EBRK, // Soft Landing / Ebrake aura stuff. SPR_HMTR, // downwards line + SPR_HBUB, // HOLD! Bubble SPR_TRCK, @@ -5676,6 +5677,8 @@ typedef enum state S_DOWNLINE4, S_DOWNLINE5, + S_HOLDBUBBLE, + S_FINISHBEAM1, S_FINISHBEAM2, S_FINISHBEAM3, @@ -6814,6 +6817,7 @@ typedef enum mobj_type MT_SPINDASHWIND, MT_SOFTLANDING, MT_DOWNLINE, + MT_HOLDBUBBLE, MT_PAPERITEMSPOT, diff --git a/src/k_kart.c b/src/k_kart.c index 5a85341a9..752e4e225 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -8588,6 +8588,8 @@ INT32 K_StairJankFlip(INT32 value) } // Ebraking visuals for mo +// we use mo->hprev for the hold bubble. If another hprev exists for some reason, remove it. + void K_KartEbrakeVisuals(player_t *p) { mobj_t *wave; @@ -8601,9 +8603,35 @@ void K_KartEbrakeVisuals(player_t *p) { wave = P_SpawnMobj(p->mo->x, p->mo->y, p->mo->z, MT_SOFTLANDING); P_SetScale(wave, p->mo->scale); + wave->momx = p->mo->momx; + wave->momy = p->mo->momy; + wave->momz = p->mo->momz; wave->standingslope = p->mo->standingslope; } + // HOLD! bubble. + if (!p->ebrakefor) + { + if (p->mo->hprev && !P_MobjWasRemoved(p->mo->hprev)) + { + // for some reason, there's already an hprev. Remove it. + P_RemoveMobj(p->mo->hprev); + } + + p->mo->hprev = P_SpawnMobj(p->mo->x, p->mo->y, p->mo->z, MT_HOLDBUBBLE); + p->mo->hprev->renderflags |= (RF_DONTDRAW & ~K_GetPlayerDontDrawFlag(p)); + } + + // Update HOLD bubble. + if (p->mo->hprev && !P_MobjWasRemoved(p->mo->hprev)) + { + P_MoveOrigin(p->mo->hprev, p->mo->x, p->mo->y, p->mo->z); + p->mo->hprev->angle = p->mo->angle; + p->mo->hprev->fuse = TICRATE/2; // When we leave spindash for any reason, make sure this bubble goes away soon after. + K_FlipFromObject(p->mo->hprev, p->mo); + } + + if (!p->spindash) { // Spawn downwards fastline @@ -8622,14 +8650,45 @@ void K_KartEbrakeVisuals(player_t *p) } else { + const UINT16 MAXCHARGETIME = K_GetSpindashChargeTime(p); + const fixed_t MAXSHAKE = FRACUNIT; + + // update HOLD bubble with numbers based on charge. + if (p->mo->hprev && !P_MobjWasRemoved(p->mo->hprev)) + { + UINT8 frame = min(1 + ((p->spindash*3) / MAXCHARGETIME), 4); + + // ?! limit. + if (p->spindash >= MAXCHARGETIME +TICRATE) + frame = 5; + + p->mo->hprev->frame = frame|FF_FULLBRIGHT; + } + + // shake the player as they charge their spindash! + + // "gentle" shaking as we start... + if (p->spindash < MAXCHARGETIME) + { + fixed_t shake = FixedMul(((p->spindash)*FRACUNIT/MAXCHARGETIME), MAXSHAKE); + SINT8 mult = leveltime & 1 ? 1 : -1; + + p->mo->spritexoffset = shake*mult; + } + else // get VIOLENT on overcharge :) + { + fixed_t shake = MAXSHAKE + FixedMul(((p->spindash-MAXCHARGETIME)*FRACUNIT/TICRATE), MAXSHAKE)*3; + SINT8 mult = leveltime & 1 ? 1 : -1; + + p->mo->spritexoffset = shake*mult; + } + // sqish them a little MORE.... p->mo->spritexscale = FRACUNIT*12/10; p->mo->spriteyscale = FRACUNIT*8/10; } - - p->ebrakefor++; } else if (p->ebrakefor) // cancel effects @@ -8638,6 +8697,16 @@ void K_KartEbrakeVisuals(player_t *p) p->mo->spritexscale = FRACUNIT; p->mo->spriteyscale = FRACUNIT; + // reset shake + p->mo->spritexoffset = 0; + + // remove the bubble instantly unless it's in the !? state + if (p->mo->hprev && !P_MobjWasRemoved(p->mo->hprev) && (p->mo->hprev->frame & FF_FRAMEMASK) != 5) + { + P_RemoveMobj(p->mo->hprev); + p->mo->hprev = NULL; + } + p->ebrakefor = 0; } }