From cc9130c2ea9626c610dc6b0b8dadb5c30dda2de6 Mon Sep 17 00:00:00 2001 From: Anonimus Date: Tue, 26 Aug 2025 22:49:54 -0400 Subject: [PATCH] Alt Invincibility overlay improvements * Separate color table for less garish colors * Directly copies interpoltation and rotations from its source * Uses TC_BLINK for solid color overlaying --- src/k_color.c | 30 ++++++++++++++++++++++++++++++ src/k_color.h | 15 +++++++++++++++ src/k_hud.c | 4 ++-- src/p_mobj.c | 8 ++------ src/r_patch.h | 1 + src/r_patchrotation.c | 23 ++++++++++++++++++++++- src/r_things.cpp | 18 +++++++++++++++--- 7 files changed, 87 insertions(+), 12 deletions(-) diff --git a/src/k_color.c b/src/k_color.c index 8381f5cb3..f22f6cfdd 100644 --- a/src/k_color.c +++ b/src/k_color.c @@ -17,6 +17,25 @@ #include "r_things.h" #include "v_video.h" +UINT16 altinvinccolors[16] = { + SKINCOLOR_BLOODCELL, // 0 + SKINCOLOR_FUCHSIA, // 1 + SKINCOLOR_LANTERN, // 2 + SKINCOLOR_FIERY, // 3 + SKINCOLOR_FLAME, // 4 + SKINCOLOR_APRICOT, // 5 + SKINCOLOR_GARDEN, // 6 + SKINCOLOR_OLIVINE, // 7 + SKINCOLOR_LIME, // 8 + SKINCOLOR_EMERALD, // 9 + SKINCOLOR_NAVY, // 10 + SKINCOLOR_BLUE, // 11 + SKINCOLOR_SAPPHIRE, // 12 + SKINCOLOR_BLUEBERRY, // 13 + SKINCOLOR_PURPLE, // 14 + SKINCOLOR_VIOLET // 15 +}; + /*-------------------------------------------------- UINT8 K_ColorRelativeLuminance(UINT8 r, UINT8 g, UINT8 b) @@ -42,6 +61,17 @@ UINT16 K_RainbowColor(tic_t time) return (UINT16)(FIRSTRAINBOWCOLOR + (time % (FIRSTSUPERCOLOR - FIRSTRAINBOWCOLOR))); } +/*-------------------------------------------------- + UINT16 K_AltInvincibilityColor(tic_t time) + + See header file for description. +--------------------------------------------------*/ + +UINT16 K_AltInvincibilityColor(tic_t time) +{ + return (UINT16)(altinvinccolors[(time) & 15]); +} + /*-------------------------------------------------- void K_RainbowColormap(UINT8 *dest_colormap, skincolornum_t skincolor) diff --git a/src/k_color.h b/src/k_color.h index 6619390d7..e57ec3783 100644 --- a/src/k_color.h +++ b/src/k_color.h @@ -54,6 +54,21 @@ UINT8 K_ColorRelativeLuminance(UINT8 r, UINT8 g, UINT8 b); UINT16 K_RainbowColor(tic_t time); +/*-------------------------------------------------- + UINT16 K_AltInvincibilityColor(tic_t time) + + Gives you a color from the "alt Invincibility" color table, for less + aggressive rainbow coloring. + + Input Arguments:- + time - Time offset, usually is leveltime. + + Return:- + Skincolor value. +--------------------------------------------------*/ + +UINT16 K_AltInvincibilityColor(tic_t time); + /*-------------------------------------------------- void K_RainbowColormap(UINT8 *dest_colormap, skincolornum_t skincolor); diff --git a/src/k_hud.c b/src/k_hud.c index 709df6c8e..9c7bb67f0 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -1944,7 +1944,7 @@ static boolean K_drawKartPositionFaces(void) if ((players[rankplayer[i]].invincibilitytimer) && (K_GetKartInvinType() == KARTINVIN_ALTERN)) { - colormap = R_GetTranslationColormap(TC_RAINBOW, K_RainbowColor(leveltime / 2), GTC_CACHE); + colormap = R_GetTranslationColormap(TC_BLINK, K_AltInvincibilityColor(leveltime / 2), GTC_CACHE); invinchudtrans = K_InvincibilityHUDVisibility(players[rankplayer[i]].invincibilitytimer); V_DrawMappedPatch(FACE_X, Y, invinchudtrans|V_SNAPTOLEFT|V_ADD, faceprefix[players[rankplayer[i]].skin][FACE_RANK], colormap); @@ -3759,7 +3759,7 @@ static void K_drawKartMinimap(void) if ((players[i].invincibilitytimer) && ((K_InvincibilityGradient(players[i].invincibilitytimer) > (FRACUNIT/2)) || (K_GetKartInvinType() == KARTINVIN_LEGACY))) { - usecolor = (K_RainbowColor(leveltime / 2)); + usecolor = ((K_GetKartInvinType() == KARTINVIN_ALTERN) ? K_AltInvincibilityColor(leveltime / 2) : K_RainbowColor(leveltime / 2)); colorizeplayer = true; } else diff --git a/src/p_mobj.c b/src/p_mobj.c index fea8a449a..3b2aeabf9 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -6773,16 +6773,13 @@ static void P_PlayerInvincibilityOverlay(mobj_t *thing) thing->z += thing->target->height - thing->height; } - thing->color = K_RainbowColor(leveltime / 2); + thing->color = K_AltInvincibilityColor(leveltime / 2); thing->colorized = true; thing->dispoffset = min(2, thing->target->dispoffset + 1); thing->angle = (thing->target->player ? thing->target->player->drawangle : thing->target->angle); - thing->roll = thing->target->roll; - thing->pitch = thing->target->pitch; - thing->sloperoll = thing->target->sloperoll; - thing->slopepitch = thing->target->slopepitch; + // Rotation is handled in r_patchrotation thing->sprite = thing->target->sprite; thing->sprite2 = thing->target->sprite2; @@ -6795,7 +6792,6 @@ static void P_PlayerInvincibilityOverlay(mobj_t *thing) thing->sprxoff = thing->target->sprxoff; thing->spryoff = thing->target->spryoff; thing->sprzoff = thing->target->sprzoff; - thing->rollangle = thing->target->rollangle; thing->spritexscale = thing->target->spritexscale; thing->spriteyscale = thing->target->spriteyscale; diff --git a/src/r_patch.h b/src/r_patch.h index 0c57021d1..84718c253 100644 --- a/src/r_patch.h +++ b/src/r_patch.h @@ -46,6 +46,7 @@ patch_t *Patch_GetRotatedSprite( void *info, INT32 rotationangle); INT32 R_GetRollAngle(angle_t rollangle); +boolean R_IsOverlayingInvinciblePlayer(mobj_t* mobj); angle_t R_GetPitchRollAngle(mobj_t *mobj, player_t *viewPlayer, interpmobjstate_t *interp); angle_t R_ModelRotationAngle(mobj_t *mobj, player_t *viewPlayer); angle_t R_SpriteRotationAngle(mobj_t *mobj, player_t *viewPlayer, interpmobjstate_t *interp); diff --git a/src/r_patchrotation.c b/src/r_patchrotation.c index afef26024..b83797537 100644 --- a/src/r_patchrotation.c +++ b/src/r_patchrotation.c @@ -81,6 +81,14 @@ static angle_t R_PlayerSpriteRotation(player_t *player, player_t *viewPlayer) return rollAngle; } +// Hacky boolean to check if we're the rainbow Invincibility overlay +boolean R_IsOverlayingInvinciblePlayer(mobj_t* mobj) +{ + return ((K_GetKartInvinType() == KARTINVIN_ALTERN) && (mobj->type == MT_OVERLAY) && + (mobj->target) && (mobj->extravalue2) && (mobj->target->player) && + (mobj->target->player->invincibilitytimer)); +} + angle_t R_ModelRotationAngle(mobj_t *mobj, player_t *viewPlayer) { angle_t rollAngle = mobj->rollangle; @@ -89,13 +97,26 @@ angle_t R_ModelRotationAngle(mobj_t *mobj, player_t *viewPlayer) { rollAngle += R_PlayerSpriteRotation(mobj->player, viewPlayer); } + else if (R_IsOverlayingInvinciblePlayer(mobj)) + { + rollAngle += R_PlayerSpriteRotation(mobj->target->player, viewPlayer); + } return rollAngle; } angle_t R_SpriteRotationAngle(mobj_t *mobj, player_t *viewPlayer, interpmobjstate_t *interp) { - angle_t rollOrPitch = R_GetPitchRollAngle(mobj, viewPlayer, interp); + angle_t rollOrPitch; + + if (R_IsOverlayingInvinciblePlayer(mobj)) + { + rollOrPitch = R_GetPitchRollAngle(mobj->target, viewPlayer, interp); + } + else + { + rollOrPitch = R_GetPitchRollAngle(mobj, viewPlayer, interp); + } return (rollOrPitch + R_ModelRotationAngle(mobj, viewPlayer)); } diff --git a/src/r_things.cpp b/src/r_things.cpp index 0cf72358f..77ced92f9 100644 --- a/src/r_things.cpp +++ b/src/r_things.cpp @@ -875,8 +875,13 @@ UINT8 *R_GetSpriteTranslation(vissprite_t *vis) if (vis->mobj->color) { // New colormap stuff for skins Tails 06-07-2002 + if (!(vis->cut & SC_PRECIP) && vis->mobj->colorized) - return R_GetTranslationColormap(TC_RAINBOW, static_cast(vis->mobj->color), GTC_CACHE); + { + return R_GetTranslationColormap(R_IsOverlayingInvinciblePlayer(vis->mobj) ? TC_BLINK : TC_RAINBOW, + static_cast(vis->mobj->color), + GTC_CACHE); + } else if (!(vis->cut & SC_PRECIP) && vis->mobj->skin && vis->mobj->sprite == SPR_PLAY) // This thing is a player! { size_t skinnum = (skin_t*)vis->mobj->skin-skins; @@ -1767,15 +1772,22 @@ static void R_ProjectSprite(mobj_t *thing) // uncapped/interpolation interpmobjstate_t interp = {0}; + mobj_t *interptarg = thing; + + if (R_IsOverlayingInvinciblePlayer(thing)) + { + // Kill overlay misalignment + interptarg = thing->target; + } // do interpolation if (R_UsingFrameInterpolation() && !paused) { - R_InterpolateMobjState(oldthing, rendertimefrac, &interp); + R_InterpolateMobjState(interptarg, rendertimefrac, &interp); } else { - R_InterpolateMobjState(oldthing, FRACUNIT, &interp); + R_InterpolateMobjState(interptarg, FRACUNIT, &interp); } this_scale = interp.scale;