diff --git a/src/d_player.h b/src/d_player.h index 098ed8bd1..4630224dc 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -987,11 +987,13 @@ struct player_t INT16 incontrol; // -1 to -175 when spinning out or tumbling, 1 to 175 when not. Use to check for combo hits or emergency inputs. UINT16 progressivethrust; // When getting beat up in GTR_BUMPERS, speed up the longer you've been out of control. + UINT8 ringvisualwarning; // Check with > 1, not >= 1! Set when put in debt, counts down and holds at 1 when still in debt. boolean analoginput; // Has an input been recorded that requires analog usage? For input display. boolean markedfordeath; boolean dotrickfx; + boolean stingfx; UINT8 bumperinflate; UINT8 ringboxdelay; // Delay until Ring Box auto-activates diff --git a/src/k_hud.cpp b/src/k_hud.cpp index 5cdef51e4..05be55eb7 100644 --- a/src/k_hud.cpp +++ b/src/k_hud.cpp @@ -2958,7 +2958,19 @@ static void K_drawRingCounter(boolean gametypeinfoshown) rn[0] = ((abs(stplyr->hudrings) / 10) % 10); rn[1] = (abs(stplyr->hudrings) % 10); - if (stplyr->hudrings <= 0 && (leveltime/5 & 1)) // In debt + if (stplyr->hudrings <= 0 && stplyr->ringvisualwarning > 1) + { + colorring = true; + if ((leveltime/2 & 1)) + { + ringmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_CRIMSON, GTC_CACHE); + } + else + { + ringmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_WHITE, GTC_CACHE); + } + } + else if (stplyr->hudrings <= 0 && (leveltime/5 & 1)) // In debt { ringmap = R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_CRIMSON, GTC_CACHE); colorring = true; @@ -3069,16 +3081,24 @@ static void K_drawRingCounter(boolean gametypeinfoshown) V_DrawMappedPatch(LAPS_X+ringx+7, fy-5, V_HUDTRANS|V_SLIDEIN|splitflags|ringflip, kp_ring[ringanim_realframe], (colorring ? ringmap : NULL)); + // "Why fy-4? Why LAPS_X+29+1?" + // "use magic numbers" - jartha 2024-03-05 if (stplyr->hudrings < 0) // Draw the minus for ring debt { - V_DrawMappedPatch(LAPS_X+23, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_ringdebtminus, ringmap); - V_DrawMappedPatch(LAPS_X+29, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[rn[0]], ringmap); - V_DrawMappedPatch(LAPS_X+35, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[rn[1]], ringmap); + V_DrawMappedPatch(LAPS_X+23-1, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_ringdebtminus, ringmap); + using srb2::Draw; + Draw row = Draw(LAPS_X+29+0, fy-4).flags(V_HUDTRANS|V_SLIDEIN|splitflags).font(Draw::Font::kThinTimer).colormap(ringmap); + row.text("{:02}", abs(stplyr->hudrings)); + // V_DrawMappedPatch(LAPS_X+29, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[TALLNUM_FONT].font[rn[0]], ringmap); + // V_DrawMappedPatch(LAPS_X+35, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[TALLNUM_FONT].font[rn[1]], ringmap); } else { - V_DrawMappedPatch(LAPS_X+23, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[rn[0]], ringmap); - V_DrawMappedPatch(LAPS_X+29, fy, V_HUDTRANS|V_SLIDEIN|splitflags, kp_facenum[rn[1]], ringmap); + using srb2::Draw; + Draw row = Draw(LAPS_X+23+3, fy-4).flags(V_HUDTRANS|V_SLIDEIN|splitflags).font(Draw::Font::kThinTimer).colormap(ringmap); + row.text("{:02}", abs(stplyr->hudrings)); + // V_DrawMappedPatch(LAPS_X+23, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[TALLNUM_FONT].font[rn[0]], ringmap); + // V_DrawMappedPatch(LAPS_X+29, fy, V_HUDTRANS|V_SLIDEIN|splitflags, fontv[TALLNUM_FONT].font[rn[1]], ringmap); } // SPB ring lock diff --git a/src/k_kart.c b/src/k_kart.c index 084b0c244..a68293cf4 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -4819,6 +4819,12 @@ void K_DebtStingPlayer(player_t *player, mobj_t *source) player->spinouttimer = length; player->wipeoutslow = min(length-1, wipeoutslowtime+1); + player->ringvisualwarning = TICRATE*2; + player->stingfx = true; + + if (P_IsDisplayPlayer(player)) + S_StartSoundAtVolume(NULL, sfx_sting0, 200); + P_SetPlayerMobjState(player->mo, S_KART_SPINOUT); } @@ -8423,20 +8429,38 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) // Battle: spawn zero-bumpers indicator if ((gametyperules & GTR_SPHERES) ? player->mo->health <= 1 : player->rings <= 0) { - mobj_t *debtflag = P_SpawnMobj(player->mo->x + player->mo->momx, player->mo->y + player->mo->momy, - player->mo->z + P_GetMobjZMovement(player->mo) + player->mo->height + (24*player->mo->scale), MT_THOK); + UINT8 doubler; - P_SetMobjState(debtflag, S_RINGDEBT); - P_SetScale(debtflag, (debtflag->destscale = player->mo->scale)); + // GROSS. In order to have a transparent version of this for a splitscreen local player, we actually need to spawn two! + for (doubler = 0; doubler < 2; doubler++) + { + mobj_t *debtflag = P_SpawnMobj(player->mo->x + player->mo->momx, player->mo->y + player->mo->momy, + player->mo->z + P_GetMobjZMovement(player->mo) + player->mo->height + (24*player->mo->scale), MT_THOK); - K_MatchGenericExtraFlags(debtflag, player->mo); - debtflag->frame += (leveltime % 4); + P_SetMobjState(debtflag, S_RINGDEBT); + P_SetScale(debtflag, (debtflag->destscale = player->mo->scale)); - if ((leveltime/12) & 1) - debtflag->frame += 4; + K_MatchGenericExtraFlags(debtflag, player->mo); + debtflag->frame += (leveltime % 4); - debtflag->color = player->skincolor; - debtflag->fuse = 2; + if ((leveltime/12) & 1) + debtflag->frame += 4; + + debtflag->color = player->skincolor; + debtflag->fuse = 2; + + if (doubler == 0) // Real copy. Draw for everyone but us. + { + debtflag->renderflags |= K_GetPlayerDontDrawFlag(player); + } + else if (doubler == 1) // Fake copy. Draw for only us, and go transparent after a bit. + { + debtflag->renderflags |= (RF_DONTDRAW & ~K_GetPlayerDontDrawFlag(player)); + if (player->ringvisualwarning <= 1 || gametyperules & GTR_SPHERES) + debtflag->renderflags |= RF_TRANS50; + } + } + } if (player->springstars && (leveltime & 1)) @@ -8960,6 +8984,12 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->dotrickfx = false; } + if (player->stingfx && !player->mo->hitlag) + { + S_StartSound(player->mo, sfx_s226l); + player->stingfx = false; + } + // Don't screw up chain ring pickup/usage with instawhip charge. // If the button stays held, delay charge a bit. if (player->instaWhipChargeLockout) @@ -9024,6 +9054,21 @@ void K_KartPlayerThink(player_t *player, ticcmd_t *cmd) player->incontrol++; } + if (player->rings <= 0) + { + if (player->ringvisualwarning > 1) + player->ringvisualwarning--; + } + else + { + player->ringvisualwarning = 0; + } + + if (player->ringvisualwarning == 0 && player->rings <= 0) + { + player->ringvisualwarning = 6*TICRATE/2; + } + player->incontrol = min(player->incontrol, 5*TICRATE); player->incontrol = max(player->incontrol, -5*TICRATE); diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index e2cbffd0a..81031d7b9 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -263,8 +263,12 @@ static int player_get(lua_State *L) lua_pushboolean(L, plr->incontrol); else if (fastcmp(field,"progressivethrust")) lua_pushboolean(L, plr->progressivethrust); + else if (fastcmp(field,"ringvisualwarning")) + lua_pushboolean(L, plr->ringvisualwarning); else if (fastcmp(field,"dotrickfx")) lua_pushboolean(L, plr->dotrickfx); + else if (fastcmp(field,"stingfx")) + lua_pushboolean(L, plr->stingfx); else if (fastcmp(field,"bumperinflate")) lua_pushboolean(L, plr->bumperinflate); else if (fastcmp(field,"ringboxdelay")) @@ -801,12 +805,16 @@ static int player_set(lua_State *L) plr->incontrol = luaL_checkinteger(L, 3); else if (fastcmp(field,"progressivethrust")) plr->progressivethrust = luaL_checkboolean(L, 3); + else if (fastcmp(field,"ringvisualwarning")) + plr->ringvisualwarning = luaL_checkboolean(L, 3); else if (fastcmp(field,"analoginput")) plr->markedfordeath = luaL_checkboolean(L, 3); else if (fastcmp(field,"markedfordeath")) plr->markedfordeath = luaL_checkboolean(L, 3); else if (fastcmp(field,"dotrickfx")) plr->dotrickfx = luaL_checkboolean(L, 3); + else if (fastcmp(field,"stingfx")) + plr->stingfx = luaL_checkboolean(L, 3); else if (fastcmp(field,"bumperinflate")) plr->bumperinflate = luaL_checkboolean(L, 3); else if (fastcmp(field,"ringboxdelay")) diff --git a/src/p_enemy.c b/src/p_enemy.c index 645ff3013..9052ef63d 100644 --- a/src/p_enemy.c +++ b/src/p_enemy.c @@ -3522,6 +3522,16 @@ void A_AttractChase(mobj_t *actor) S_ReducedVFXSoundAtVolume(actor->target, sfx_s1b5, actor->target->player->ringvolume, NULL); + if (actor->target->player->rings <= 10 && P_IsDisplayPlayer(actor->target->player)) + { + S_ReducedVFXSoundAtVolume(actor->target, sfx_gshab, + 210 - 10*actor->target->player->rings + , NULL); + + if (actor->target->player->rings == 0) + S_ReducedVFXSoundAtVolume(actor->target, sfx_gshad, 127, NULL); + } + actor->target->player->ringvolume -= RINGVOLUMEUSEPENALTY; sparkle = P_SpawnMobj(actor->target->x, actor->target->y, actor->target->z, MT_RINGSPARKS); diff --git a/src/p_saveg.c b/src/p_saveg.c index b6efe3530..c975682bc 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -598,11 +598,13 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEINT16(save->p, players[i].incontrol); WRITEUINT16(save->p, players[i].progressivethrust); + WRITEUINT8(save->p, players[i].ringvisualwarning); WRITEUINT8(save->p, players[i].analoginput); WRITEUINT8(save->p, players[i].markedfordeath); WRITEUINT8(save->p, players[i].dotrickfx); + WRITEUINT8(save->p, players[i].stingfx); WRITEUINT8(save->p, players[i].bumperinflate); WRITEUINT8(save->p, players[i].ringboxdelay); @@ -1184,11 +1186,13 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].incontrol = READINT16(save->p); players[i].progressivethrust = READUINT16(save->p); + players[i].ringvisualwarning = READUINT8(save->p); players[i].analoginput = READUINT8(save->p); players[i].markedfordeath = READUINT8(save->p); players[i].dotrickfx = READUINT8(save->p); + players[i].stingfx = READUINT8(save->p); players[i].bumperinflate = READUINT8(save->p); players[i].ringboxdelay = READUINT8(save->p); diff --git a/src/sounds.c b/src/sounds.c index e9c3eff9c..566e14660 100644 --- a/src/sounds.c +++ b/src/sounds.c @@ -1520,6 +1520,12 @@ sfxinfo_t S_sfx[NUMSFX] = {"tmxbdn", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Button down {"tmxbup", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Button up + // SMS + {"sting0", false, 64, 2, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // Ring loss + + // Patching up base sounds + {"s226l", false, 64, 0, -1, NULL, 0, -1, -1, LUMPERROR, ""}, // s2 spikes LOUD + // SRB2kart - Skin sounds {"kwin", false, 64, 96, -1, NULL, 0, SKSKWIN, -1, LUMPERROR, ""}, {"klose", false, 64, 96, -1, NULL, 0, SKSKLOSE, -1, LUMPERROR, ""}, diff --git a/src/sounds.h b/src/sounds.h index 532c844be..e48b39f88 100644 --- a/src/sounds.h +++ b/src/sounds.h @@ -1596,6 +1596,12 @@ typedef enum sfx_tmxbdn, sfx_tmxbup, + // SMS + sfx_sting0, + + // Patch-up + sfx_s226l, + // And LASTLY, Kart's skin sounds. sfx_kwin, sfx_klose,