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
This commit is contained in:
Anonimus 2025-08-26 22:49:54 -04:00
parent 940ff00849
commit cc9130c2ea
7 changed files with 87 additions and 12 deletions

View file

@ -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)

View file

@ -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);

View file

@ -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

View file

@ -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;

View file

@ -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);

View file

@ -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));
}

View file

@ -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<skincolornum_t>(vis->mobj->color), GTC_CACHE);
{
return R_GetTranslationColormap(R_IsOverlayingInvinciblePlayer(vis->mobj) ? TC_BLINK : TC_RAINBOW,
static_cast<skincolornum_t>(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;