Spinout rotations

This commit is contained in:
Anonimus 2025-09-14 07:05:12 -04:00
parent 4a79ad337b
commit a4d89f3083
11 changed files with 282 additions and 35 deletions

View file

@ -661,6 +661,9 @@ static CV_PossibleValue_t minimapdot_cons_t[] = {{0, "Off"}, {1, "Dot"}, {2, "He
consvar_t cv_showminimapangle = CVAR_INIT ("showminimapangle", "Dot", CV_SAVE, minimapdot_cons_t, NULL);
consvar_t cv_minihead = CVAR_INIT ("smallminimapplayers", "Off", CV_SAVE, CV_OnOff, NULL);
static CV_PossibleValue_t spinoutroll_cons_t[] = {{0, "Off"}, {1, "Minimap Only"}, {2, "Rankings Only"}, {3, "Minimap+Rankings"}, {0, NULL}};
consvar_t cv_spinoutroll = CVAR_INIT ("spinoutroll", "Minimap+Rankings", CV_SAVE, spinoutroll_cons_t, NULL);
consvar_t cv_showviewpointtext = CVAR_INIT ("showviewpointtext", "On", CV_SAVE, CV_OnOff, NULL);
// Intermission time Tails 04-19-2002
@ -973,6 +976,7 @@ void D_RegisterServerCommands(void)
CV_RegisterVar(&cv_showminimapnames);
CV_RegisterVar(&cv_showminimapangle);
CV_RegisterVar(&cv_minihead);
CV_RegisterVar(&cv_spinoutroll);
CV_RegisterVar(&cv_showlapemblem);
CV_RegisterVar(&cv_racesplits);
CV_RegisterVar(&cv_showviewpointtext);

View file

@ -226,6 +226,7 @@ extern consvar_t cv_pingmeasurement;
extern consvar_t cv_showminimapnames;
extern consvar_t cv_showminimapangle;
extern consvar_t cv_minihead;
extern consvar_t cv_spinoutroll;
extern consvar_t cv_showlapemblem;
extern consvar_t cv_racesplits;

View file

@ -625,6 +625,8 @@ struct player_t
tic_t driftsparkGrowTimer;
tic_t driftelapsed; // Elapsed time spent during a drift.
fixed_t spinoutrot; // When a player spins out, this value increments modulus 360.
SINT8 aizdriftstrat; // (-1 to 1) - Let go of your drift while boosting? Helper for the SICK STRATZ (sliptiding!) you have just unlocked
INT32 aizdrifttilt;
INT32 aizdriftturn;

View file

@ -2725,6 +2725,7 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps)
p->ringvolume = 255;
p->ringtransparency = 255;
p->spinoutrot = 0;
p->spectatorreentry = spectatorreentry;
p->grieftime = grieftime;

View file

@ -366,6 +366,9 @@ void K_LoadKartHUDGraphics(void)
{
buffer[7] = '0'+(i+1);
HU_UpdatePatch(&kp_facehighlight[i], "%s", buffer);
kp_facehighlight[i]->leftoffset = kp_facehighlight[i]->width / 2;
kp_facehighlight[i]->topoffset = kp_facehighlight[i]->height / 2;
}
// Special minimap icons
@ -1856,6 +1859,16 @@ static UINT32 K_InvincibilityHUDVisibility(UINT16 t)
return min(9, 10 - alphalevel)<<V_ALPHASHIFT;
}
static boolean K_RankIconCanSpinout(void)
{
return ((cv_spinoutroll.value) & 2);
}
static boolean K_MinimapIconCanSpinout(void)
{
return ((cv_spinoutroll.value) & 1);
}
static boolean K_drawKartPositionFaces(void)
{
// FACE_X = 15; // 15
@ -1868,6 +1881,14 @@ static boolean K_drawKartPositionFaces(void)
INT32 bumperx, numplayersingame = 0;
UINT8 *colormap;
UINT32 invinchudtrans;
vector2_t offsets;
#ifdef ROTSPRITE
angle_t rollangle = 0;
INT32 rot = 0;
#endif
offsets.x = offsets.y = 0;
ranklines = 0;
memset(completed, 0, sizeof (completed));
@ -1960,14 +1981,33 @@ static boolean K_drawKartPositionFaces(void)
else
colormap = R_GetTranslationColormap(players[rankplayer[i]].skin, players[rankplayer[i]].mo->color, GTC_CACHE);
V_DrawMappedPatch(FACE_X, Y, V_HUDTRANS|V_SNAPTOLEFT, faceprefix[players[rankplayer[i]].skin][FACE_RANK], colormap);
patch_t *facerank = faceprefix[players[rankplayer[i]].skin][FACE_RANK];
offsets.x = facerank->leftoffset;
offsets.y = facerank->topoffset;
#ifdef ROTSPRITE
if ((K_RankIconCanSpinout()) && (players[rankplayer[i]].spinoutrot))
{
// Rotate counterclockwise.
rollangle = FixedAngle(players[rankplayer[i]].spinoutrot * -1);
rot = R_GetRollAngle(rollangle);
if (rot)
{
facerank = Patch_GetRotated(facerank, rot, false);
}
}
#endif
V_DrawMappedPatch(FACE_X + offsets.x, Y + offsets.y, V_HUDTRANS|V_SNAPTOLEFT, facerank, colormap);
if ((players[rankplayer[i]].invincibilitytimer) && (K_GetKartInvinType() == KARTINVIN_ALTERN))
{
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);
V_DrawMappedPatch(FACE_X + offsets.x, Y + offsets.y, invinchudtrans|V_SNAPTOLEFT|V_ADD, facerank, colormap);
}
if (LUA_HudEnabled(hud_battlebumpers))
@ -1985,7 +2025,30 @@ static boolean K_drawKartPositionFaces(void)
}
if (i == strank)
V_DrawScaledPatch(FACE_X, Y, V_HUDTRANS|V_SNAPTOLEFT, kp_facehighlight[(leveltime / 4) % 8]);
{
patch_t *highlight = kp_facehighlight[(leveltime / 4) % 8];
INT32 left, top;
left = highlight->leftoffset;
top = highlight->topoffset;
#ifdef ROTSPRITE
if ((K_RankIconCanSpinout()) && (players[rankplayer[i]].spinoutrot))
{
// Rotate counterclockwise.
rollangle = FixedAngle(players[rankplayer[i]].spinoutrot * -1);
rot = R_GetRollAngle(rollangle);
if (rot)
{
highlight = Patch_GetRotated(highlight, rot, false);
}
}
#endif
V_DrawScaledPatch(FACE_X+left, Y+top, V_HUDTRANS|V_SNAPTOLEFT, highlight);
}
if (gametype == GT_BATTLE && players[rankplayer[i]].bumper <= 0)
V_DrawScaledPatch(FACE_X-4, Y-3, V_HUDTRANS|V_SNAPTOLEFT, kp_ranknobumpers);
@ -2201,7 +2264,17 @@ INT32 K_DrawNeoTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines
V_DrawThinString(x2 + 20, y2, ((tab[i].num == whiteplayer) ? hightlightcolor : 0)|V_ALLOWLOWERCASE|V_6WIDTHSPACE, playername);
V_DrawFixedPatch((x2+11)*FRACUNIT, (y+1)*FRACUNIT, FRACUNIT/2, 0, faceprefix[players[tab[i].num].skin][FACE_RANK], colormap);
patch_t *facerank = faceprefix[players[tab[i].num].skin][FACE_RANK];
fixed_t scale = FRACUNIT/2;
V_DrawFixedPatch(
((x2+11)*FRACUNIT) + ((facerank->leftoffset) * scale),
((y+1)*FRACUNIT) + ((facerank->topoffset) * scale),
scale,
0,
facerank,
colormap
);
/*if (gametype == GT_BATTLE && players[tab[i].num].bumper > 0) -- not enough space for this
{
@ -2214,8 +2287,17 @@ INT32 K_DrawNeoTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines
}
}*/
patch_t *highlight = kp_facehighlight[(leveltime / 4) % 8];
if (tab[i].num == whiteplayer)
V_DrawFixedPatch((x2+11)*FRACUNIT, (y+1)*FRACUNIT, FRACUNIT/2, 0, kp_facehighlight[(leveltime / 4) % 8], NULL);
V_DrawFixedPatch(
((x2+11)*FRACUNIT)+(highlight->leftoffset * scale),
((y+1)*FRACUNIT)+(highlight->topoffset * scale),
scale,
0,
highlight,
NULL
);
if ((gametyperules & GTR_BUMPERS) && players[tab[i].num].bumper <= 0)
V_DrawScaledPatch(x2-4, y-7, 0, kp_ranknobumpers);
@ -2434,7 +2516,9 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN
else
V_DrawString(x + 20, y2, ((tab[i].num == whiteplayer) ? hightlightcolor : 0)|V_ALLOWLOWERCASE, playername);
V_DrawMappedPatch(x, y-4, 0, faceprefix[players[tab[i].num].skin][FACE_RANK], colormap);
patch_t *facerank = faceprefix[players[tab[i].num].skin][FACE_RANK];
V_DrawMappedPatch(x+facerank->leftoffset, y-4+facerank->topoffset, 0, facerank, colormap);
/*if (gametype == GT_BATTLE && players[tab[i].num].bumper > 0) -- not enough space for this
{
@ -2448,7 +2532,10 @@ void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, IN
}*/
if (tab[i].num == whiteplayer)
V_DrawScaledPatch(x, y-4, 0, kp_facehighlight[(leveltime / 4) % 8]);
{
patch_t *highlight = kp_facehighlight[(leveltime / 4) % 8];
V_DrawScaledPatch(x+highlight->leftoffset, y-4+highlight->topoffset, 0, highlight);
}
if (gametype == GT_BATTLE && players[tab[i].num].bumper <= 0)
V_DrawScaledPatch(x-4, y-7, 0, kp_ranknobumpers);
@ -2519,7 +2606,9 @@ static void K_drawKartLaps(void)
if (LUA_HudEnabled(hud_lives) && uselives)
{
UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, K_GetHudColor(), GTC_CACHE);
V_DrawMappedPatch(fr+21, fy-13, V_HUDTRANS|splitflags, faceprefix[stplyr->skin][FACE_MINIMAP], colormap);
patch_t *mmappatch = faceprefix[stplyr->skin][FACE_MINIMAP];
V_DrawMappedPatch(fr+21+mmappatch->leftoffset, fy-13+mmappatch->topoffset, V_HUDTRANS|splitflags, mmappatch, colormap);
if (stplyr->lives >= 0)
V_DrawScaledPatch(fr+34, fy-10, V_HUDTRANS|splitflags, fontv[PINGNUM_FONT].font[(stplyr->lives % 10)]); // make sure this doesn't overflow OR underflow
}
@ -2564,7 +2653,8 @@ static void K_drawKartLaps(void)
}
UINT8 *colormap = R_GetTranslationColormap(stplyr->skin, K_GetHudColor(), GTC_CACHE);
V_DrawMappedPatch(fx+59+offsetx, fy-16+offsety, V_HUDTRANS|splitflags, faceprefix[stplyr->skin][FACE_RANK], colormap);
patch_t *facerank = faceprefix[stplyr->skin][FACE_RANK];
V_DrawMappedPatch(fx+59+offsetx+facerank->leftoffset, fy-16+offsety+facerank->topoffset, V_HUDTRANS|splitflags, facerank, colormap);
if (stplyr->lives >= 0)
V_DrawScaledPatch(fx+77+offsetx, fy-11+offsety, V_HUDTRANS|splitflags, kp_facenum[(stplyr->lives % 10)]); // make sure this doesn't overflow OR underflow
}
@ -3072,7 +3162,8 @@ static void K_drawKartWanted(void)
if (players[battlewanted[i]].skincolor)
{
colormap = R_GetTranslationColormap(TC_RAINBOW, p->skincolor, GTC_CACHE);
V_DrawFixedPatch(x<<FRACBITS, y<<FRACBITS, FRACUNIT, V_HUDTRANS|(r_splitscreen < 3 ? V_SNAPTORIGHT : 0)|V_SNAPTOBOTTOM, (scale == FRACUNIT ? faceprefix[p->skin][FACE_WANTED] : faceprefix[p->skin][FACE_RANK]), colormap);
patch_t *wantedicon = (scale == FRACUNIT ? faceprefix[p->skin][FACE_WANTED] : faceprefix[p->skin][FACE_RANK]);
V_DrawFixedPatch((x+wantedicon->leftoffset)<<FRACBITS, (y+wantedicon->topoffset)<<FRACBITS, FRACUNIT, V_HUDTRANS|(r_splitscreen < 3 ? V_SNAPTORIGHT : 0)|V_SNAPTOBOTTOM, wantedicon, colormap);
/*if (basey2) // again with 4p stuff
V_DrawFixedPatch(x<<FRACBITS, (y - (basey-basey2))<<FRACBITS, FRACUNIT, V_HUDTRANS|V_SNAPTOTOP, (scale == FRACUNIT ? faceprefix[p->skin][FACE_WANTED] : faceprefix[p->skin][FACE_RANK]), colormap);*/
}
@ -3569,7 +3660,7 @@ static void K_drawKartNameTags(void)
V_ClearClipRect();
}
static inline void K_drawKartMinimapIcon(fixed_t objx, fixed_t objy, INT32 hudx, INT32 hudy, INT32 flags, patch_t *icon, UINT8 *colormap)
static inline void K_drawKartMinimapIcon(fixed_t objx, fixed_t objy, INT32 hudx, INT32 hudy, INT32 flags, patch_t *icon, UINT8 *colormap, vector2_t *origin)
{
// amnum xpos & ypos are the icon's speed around the HUD.
// The number being divided by is for how fast it moves.
@ -3582,6 +3673,20 @@ static inline void K_drawKartMinimapIcon(fixed_t objx, fixed_t objy, INT32 hudx,
INT32 amxpos, amypos;
fixed_t scale = FRACUNIT;
INT16 w, h;
if (origin)
{
w = origin->x * 2;
h = origin->y * 2;
}
else
{
w = icon->width;
h = icon->height;
}
if (!cv_showminimapangle.value && (icon == kp_minimapdot))
return;
@ -3594,8 +3699,8 @@ static inline void K_drawKartMinimapIcon(fixed_t objx, fixed_t objy, INT32 hudx,
if (encoremode)
amnumxpos = -amnumxpos;
amxpos = amnumxpos + ((hudx + (minimapinfo.minimap_pic->width-icon->width)/2)<<FRACBITS);
amypos = amnumypos + ((hudy + (minimapinfo.minimap_pic->height-icon->height)/2)<<FRACBITS);
amxpos = amnumxpos + ((hudx + (minimapinfo.minimap_pic->width-w)/2)<<FRACBITS);
amypos = amnumypos + ((hudy + (minimapinfo.minimap_pic->height-h)/2)<<FRACBITS);
if (cv_minihead.value && !(icon == kp_minimapdot))
{
@ -3793,6 +3898,13 @@ static void K_drawKartMinimap(void)
UINT16 usecolor;
boolean colorizeplayer;
#ifdef ROTSPRITE
angle_t rollangle = 0;
INT32 rot = 0;
#endif
vector2_t iconoffsets;
// Draw the HUD only when playing in a level.
// hu_stuff needs this, unlike st_stuff.
if (gamestate != GS_LEVEL)
@ -3808,6 +3920,9 @@ static void K_drawKartMinimap(void)
return; // no pic, just get outta here
}
iconoffsets.x = 0;
iconoffsets.y = 0;
drawinfo_t info;
K_getMinimapDrawinfo(&info);
x = info.x;
@ -3881,7 +3996,11 @@ static void K_drawKartMinimap(void)
interpx = R_InterpolateFixed(g->mo->old_x, g->mo->x);
interpy = R_InterpolateFixed(g->mo->old_y, g->mo->y);
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, faceprefix[skin][FACE_MINIMAP], colormap);
patch_t *ghostPic = faceprefix[skin][FACE_MINIMAP];
iconoffsets.x = ((ghostPic->width) / 2) - ghostPic->leftoffset;
iconoffsets.y = ((ghostPic->height) / 2) - ghostPic->topoffset;
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, ghostPic, colormap, &iconoffsets);
g = g->next;
}
@ -3924,6 +4043,10 @@ static void K_drawKartMinimap(void)
if (players[i].mo->health <= 0 && players[i].pflags & PF_NOCONTEST)
{
workingPic = kp_nocontestminimap;
iconoffsets.x = ((workingPic->width) / 2);
iconoffsets.y = ((workingPic->height) / 2);
colormap = R_GetTranslationColormap(TC_DEFAULT, mobj->color, GTC_CACHE);
}
else
@ -3932,6 +4055,23 @@ static void K_drawKartMinimap(void)
workingPic = faceprefix[skin][FACE_MINIMAP];
iconoffsets.x = ((workingPic->width) / 2) - workingPic->leftoffset;
iconoffsets.y = ((workingPic->height) / 2) - workingPic->topoffset;
#ifdef ROTSPRITE
if ((K_MinimapIconCanSpinout()) && (players[i].spinoutrot))
{
// Rotate counterclockwise.
rollangle = FixedAngle(players[i].spinoutrot * -1);
rot = R_GetRollAngle(rollangle);
if (rot)
{
workingPic = Patch_GetRotated(workingPic, rot, false);
}
}
#endif
colorizeplayer = players[i].mo->colorized;
if ((players[i].invincibilitytimer) && ((K_InvincibilityGradient(players[i].invincibilitytimer) > (FRACUNIT/2)) || (K_GetKartInvinType() == KARTINVIN_LEGACY)))
@ -3966,7 +4106,7 @@ static void K_drawKartMinimap(void)
interpx = R_InterpolateFixed(mobj->old_x, mobj->x);
interpy = R_InterpolateFixed(mobj->old_y, mobj->y);
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, workingPic, colormap);
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, workingPic, colormap, &iconoffsets);
if (mobj->player)
{
@ -3978,7 +4118,7 @@ static void K_drawKartMinimap(void)
if ((gametype == GT_RACE && players[i].position == spbplace)
|| (gametype == GT_BATTLE && K_IsPlayerWanted(&players[i])))
{
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_wantedreticle, NULL);
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_wantedreticle, NULL, NULL);
}
}
}
@ -4029,7 +4169,7 @@ static void K_drawKartMinimap(void)
interpx = R_InterpolateFixed(mobj->old_x, mobj->x);
interpy = R_InterpolateFixed(mobj->old_y, mobj->y);
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, workingPic, colormap);
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, workingPic, colormap, NULL);
}
for (mobj = misccap; mobj; mobj = next)
@ -4064,7 +4204,7 @@ static void K_drawKartMinimap(void)
interpx = R_InterpolateFixed(mobj->old_x, mobj->x);
interpy = R_InterpolateFixed(mobj->old_y, mobj->y);
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, workingPic, colormap);
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, workingPic, colormap, NULL);
}
// draw our local players here, opaque.
@ -4097,7 +4237,7 @@ static void K_drawKartMinimap(void)
interpy = R_InterpolateFixed(bossinfo.weakspots[i].spot->old_y, bossinfo.weakspots[i].spot->y);
// temporary graphic?
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_wantedreticle, colormap);
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_wantedreticle, colormap, NULL);
}
}
@ -4116,6 +4256,10 @@ static void K_drawKartMinimap(void)
if (players[localplayers[i]].mo->health <= 0 && players[localplayers[i]].pflags & PF_NOCONTEST)
{
workingPic = kp_nocontestminimap;
iconoffsets.x = ((workingPic->width) / 2);
iconoffsets.y = ((workingPic->height) / 2);
colormap = R_GetTranslationColormap(TC_DEFAULT, mobj->color, GTC_CACHE);
nocontest = true;
@ -4126,6 +4270,23 @@ static void K_drawKartMinimap(void)
workingPic = faceprefix[skin][FACE_MINIMAP];
iconoffsets.x = ((workingPic->width) / 2) - workingPic->leftoffset;
iconoffsets.y = ((workingPic->height) / 2) - workingPic->topoffset;
#ifdef ROTSPRITE
if ((K_MinimapIconCanSpinout()) && (players[localplayers[i]].spinoutrot))
{
// Rotate counterclockwise.
rollangle = FixedAngle(players[localplayers[i]].spinoutrot * -1);
rot = R_GetRollAngle(rollangle);
if (rot)
{
workingPic = Patch_GetRotated(workingPic, rot, false);
}
}
#endif
colorizeplayer = players[localplayers[i]].mo->colorized;
if ((players[localplayers[i]].invincibilitytimer) &&
@ -4178,7 +4339,8 @@ static void K_drawKartMinimap(void)
y - FixedMul(FSIN(ang), ICON_DOT_RADIUS),
splitflags,
kp_minimapdot,
colormap
colormap,
NULL
);
}
else if (cv_showminimapangle.value == 2)
@ -4196,13 +4358,13 @@ static void K_drawKartMinimap(void)
}
}
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, workingPic, colormap);
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, workingPic, colormap, &iconoffsets);
// Target reticule
if ((gametype == GT_RACE && players[localplayers[i]].position == spbplace)
|| (gametype == GT_BATTLE && K_IsPlayerWanted(&players[localplayers[i]])))
{
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_wantedreticle, NULL);
K_drawKartMinimapIcon(interpx, interpy, x, y, splitflags, kp_wantedreticle, NULL, NULL);
}
K_drawKartMinimapNametag(interpx, interpy, x, y, splitflags, mobj->player);
@ -4977,7 +5139,9 @@ static void K_drawLapSplitComparison(void)
INT32 stwidth = V_StringWidth(buffer, splitflags) / 2;
// vibes offset
V_DrawMappedPatch(row_position[0] - stwidth - 35, row_position[1], splitflags, faceprefix[skin][FACE_MINIMAP], skincolor);
patch_t *face = faceprefix[skin][FACE_MINIMAP];
V_DrawMappedPatch(row_position[0] - stwidth - 35 + face->leftoffset, row_position[1] + face->topoffset, splitflags, face, skincolor);
if (pos > 1)
{

View file

@ -4182,6 +4182,7 @@ void MD_DrawReplayStartMenu(void)
{
const char *warning;
UINT8 i;
INT32 xoffs, yoffs;
MD_DrawGenericMenu();
@ -4189,6 +4190,7 @@ void MD_DrawReplayStartMenu(void)
// Draw rankings beyond first
for (i = 1; i < MAXPLAYERS && demolist[dir_on[menudepthleft]].standings[i].ranking; i++)
{
xoffs = yoffs = 0;
patch_t *patch;
UINT8 *colormap;
@ -4210,6 +4212,10 @@ void MD_DrawReplayStartMenu(void)
if (demolist[dir_on[menudepthleft]].standings[i].skin < numskins && W_CheckNumForName(skins[demolist[dir_on[menudepthleft]].standings[i].skin].facewant) != LUMPERROR)
{
patch = faceprefix[demolist[dir_on[menudepthleft]].standings[i].skin][FACE_RANK];
xoffs = SHORT(patch->leftoffset);
yoffs = SHORT(patch->topoffset);
colormap = R_GetTranslationColormap(
demolist[dir_on[menudepthleft]].standings[i].skin,
demolist[dir_on[menudepthleft]].standings[i].color,
@ -4224,7 +4230,7 @@ void MD_DrawReplayStartMenu(void)
GTC_MENUCACHE);
}
V_DrawMappedPatch(BASEVIDWIDTH-5 - SHORT(patch->width), STARTY + i*20, V_SNAPTOTOP, patch, colormap);
V_DrawMappedPatch(BASEVIDWIDTH-5 - SHORT(patch->width) + xoffs, STARTY + i*20 + yoffs, V_SNAPTOTOP, patch, colormap);
}
#undef STARTY
@ -4378,8 +4384,11 @@ void MD_DrawPlaybackMenu(void)
//M_DrawTextBox(currentMenu->x-68, currentMenu->y-7, 15, 15);
//M_DrawCenteredMenu();
INT32 xoffs, yoffs;
for (i = 0; i < currentMenu->numitems; i++)
{
xoffs = yoffs = 0;
UINT8 *inactivemap = NULL;
INT16 splitnum = i == M_GetMenuIndex(MN_PLAYBACK, "VIEW1") ? 0 :
@ -4396,6 +4405,10 @@ void MD_DrawPlaybackMenu(void)
INT32 ply = displayplayers[splitnum];
icon = faceprefix[players[ply].skin][FACE_RANK];
xoffs = icon->leftoffset;
yoffs = icon->topoffset;
if (i != itemOn)
inactivemap = R_GetTranslationColormap(players[ply].skin, players[ply].skincolor, GTC_MENUCACHE);
}
@ -4412,9 +4425,9 @@ void MD_DrawPlaybackMenu(void)
icon = W_CachePatchName("PLAYRANK", PU_CACHE); // temp
if ((i == M_GetMenuIndex(MN_PLAYBACK, "FASTFORWARD") && cv_playbackspeed.value > 1) || (i == M_GetMenuIndex(MN_PLAYBACK, "REWIND") && demo.rewinding))
V_DrawMappedPatch(currentMenu->x + currentMenu->menuitems[i].x, currentMenu->y, transmap|V_SNAPTOTOP, icon, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_JAWZ, GTC_MENUCACHE));
V_DrawMappedPatch(currentMenu->x + currentMenu->menuitems[i].x + xoffs, currentMenu->y + yoffs, transmap|V_SNAPTOTOP, icon, R_GetTranslationColormap(TC_RAINBOW, SKINCOLOR_JAWZ, GTC_MENUCACHE));
else
V_DrawMappedPatch(currentMenu->x + currentMenu->menuitems[i].x, currentMenu->y, transmap|V_SNAPTOTOP, icon, (i == itemOn) ? activemap : inactivemap);
V_DrawMappedPatch(currentMenu->x + currentMenu->menuitems[i].x + xoffs, currentMenu->y + yoffs, transmap|V_SNAPTOTOP, icon, (i == itemOn) ? activemap : inactivemap);
if (i == itemOn)
{
@ -7096,8 +7109,8 @@ void MD_DrawBarCssSelector(void)
{
scale = FRACUNIT/2;
face = faceprefix[col][FACE_RANK];
offx = 8;
offy = 8;
offx = 8 + face->leftoffset;
offy = 8 + face->topoffset;
}
colmap = R_GetTranslationColormap(col, cv_dummycolor.value, GTC_MENUCACHE);
if (face)
@ -7209,7 +7222,7 @@ void MD_DrawGridCssSelector(void)
{
face = faceprefix[skinn][FACE_RANK];
colmap = R_GetTranslationColormap(skinn, skins[skinn].prefcolor, GTC_MENUCACHE);
V_DrawFixedPatch(gridx * FRACUNIT, gridy * FRACUNIT, FRACUNIT, 0, face, colmap);
V_DrawFixedPatch((gridx + face->leftoffset) * FRACUNIT, (gridy + face->topoffset) * FRACUNIT, FRACUNIT, 0, face, colmap);
}
}
@ -7232,7 +7245,7 @@ void MD_DrawGridCssSelector(void)
{
face = faceprefix[skintodisplay][FACE_RANK];
colmap = R_GetTranslationColormap(skintodisplay, cv_dummycolor.value, GTC_MENUCACHE);
V_DrawFixedPatch(cursorx * FRACUNIT, cursory * FRACUNIT, FRACUNIT, 0, face, colmap);
V_DrawFixedPatch((cursorx + face->leftoffset) * FRACUNIT, (cursory + face->topoffset) * FRACUNIT, FRACUNIT, 0, face, colmap);
cursor = W_CachePatchName("M_FSEL", PU_CACHE);
if (skullAnimCounter < 4)
@ -8644,7 +8657,7 @@ void MD_DrawViewServer(void)
}
V_DrawFixedPatch(x<<FRACBITS, (y+5)<<FRACBITS, FRACUNIT, flags, facerank, colormap);
V_DrawFixedPatch((x + facerank->leftoffset)<<FRACBITS, (y + 5 + facerank->topoffset)<<FRACBITS, FRACUNIT, flags, facerank, colormap);
}
strlcpy(player_name, playerinfo[i].name, 12);

View file

@ -12325,6 +12325,7 @@ void P_SpawnPlayer(INT32 playernum)
P_FlashPal(p, 0, 0); // Resets
p->grieftime = 0;
p->spinoutrot = 0;
if (gametyperules & GTR_BUMPERS)
{

View file

@ -258,6 +258,7 @@ static void P_NetArchivePlayers(savebuffer_t *save)
WRITEUINT16(save->p, players[i].flashing);
WRITEUINT16(save->p, players[i].spinouttimer);
WRITEINT32(save->p, players[i].spinoutrot);
WRITEUINT8(save->p, players[i].spinouttype);
WRITEUINT16(save->p, players[i].flipovertimer);
WRITEANGLE(save->p, players[i].flipoverangle);
@ -610,6 +611,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save)
players[i].flashing = READUINT16(save->p);
players[i].spinouttimer = READUINT16(save->p);
players[i].spinoutrot = READINT32(save->p);
players[i].spinouttype = READUINT8(save->p);
players[i].flipoverangle = READUINT16(save->p);
players[i].flipovertimer = READANGLE(save->p);

View file

@ -3785,6 +3785,9 @@ DoABarrelRoll (player_t *player)
player->tilt = slope;
}
#define SPINOUTROTSPEED (24 * FRACUNIT)
#define MAXSPINROT (360 * FRACUNIT)
//
// P_PlayerThink
//
@ -3946,6 +3949,36 @@ void P_PlayerThink(player_t *player)
}
}
// MKWii-styled icon spinouts: do a full 360 rotation before stopping.
if (P_PlayerInPain(player))
{
if (player->spinoutrot < MAXSPINROT)
{
if ((player->spinoutrot + SPINOUTROTSPEED) >= MAXSPINROT)
{
player->spinoutrot = (player->spinoutrot + SPINOUTROTSPEED) % MAXSPINROT;
}
else
{
player->spinoutrot += SPINOUTROTSPEED;
}
}
}
else
{
if ((player->spinoutrot) && (player->spinoutrot < MAXSPINROT))
{
if ((player->spinoutrot + SPINOUTROTSPEED) >= MAXSPINROT)
{
player->spinoutrot = 0;
}
else
{
player->spinoutrot += SPINOUTROTSPEED;
}
}
}
// If it is set, start subtracting
// Don't allow it to go back to 0
if (player->exiting > 1 && (player->exiting < raceexittime+2 || !(gametyperules & GTR_CIRCUIT))) // SRB2kart - "&& player->exiting > 1"

View file

@ -190,6 +190,11 @@ void ST_LoadGraphics(void)
#endif
}
static boolean ST_IconCanSpinout(UINT8 icon)
{
return ((icon == FACE_MINIMAP)||(icon == FACE_RANK));
}
// made separate so that skins code can reload custom face graphics
void ST_LoadFaceGraphics(INT32 skinnum)
{
@ -201,6 +206,21 @@ void ST_LoadFaceGraphics(INT32 skinnum)
{
sprframe = &sprdef->spriteframes[i];
faceprefix[skinnum][i] = W_CachePatchNum(sprframe->lumppat[0], PU_HUDGFX);
if (ST_IconCanSpinout(i))
{
// Auto-center all minimap and rank patches with no offsets defined.
// This is a shitty, hacky solution... but it's less work for spinout rotations!
if (faceprefix[skinnum][i]->leftoffset == 0)
{
faceprefix[skinnum][i]->leftoffset = faceprefix[skinnum][i]->width / 2;
}
if (faceprefix[skinnum][i]->topoffset == 0)
{
faceprefix[skinnum][i]->topoffset = faceprefix[skinnum][i]->height / 2;
}
}
i++;
}
if (i < FACE_MAX)

View file

@ -525,13 +525,16 @@ void Y_IntermissionDrawer(void)
if (data.color[i])
{
UINT8 *colormap = R_GetTranslationColormap(*data.character[i], *data.color[i], GTC_CACHE);
V_DrawMappedPatch(x+16, y-4, 0, faceprefix[*data.character[i]][FACE_RANK], colormap);
patch_t *facerank = faceprefix[*data.character[i]][FACE_RANK];
V_DrawMappedPatch(x+16+facerank->leftoffset, y-4+facerank->topoffset, 0, facerank, colormap);
}
if (data.num[i] == whiteplayer)
{
UINT8 cursorframe = (intertic / 4) % 8;
V_DrawScaledPatch(x+16, y-4, 0, W_CachePatchName(va("K_CHILI%d", cursorframe+1), PU_CACHE));
patch_t *highlight = W_CachePatchName(va("K_CHILI%d", cursorframe+1), PU_CACHE);
V_DrawScaledPatch(x+16+highlight->leftoffset, y-4+highlight->topoffset, 0, highlight);
}
if ((players[data.num[i]].pflags & PF_NOCONTEST) && players[data.num[i]].bot)
@ -1467,13 +1470,16 @@ void Y_VoteDrawer(void)
if (players[i].skincolor)
{
UINT8 *colormap = R_GetTranslationColormap(players[i].skin, players[i].skincolor, GTC_CACHE);
V_DrawMappedPatch(x+24, y+9, V_SNAPTOLEFT, faceprefix[players[i].skin][FACE_RANK], colormap);
patch_t *facerank = faceprefix[*data.character[i]][FACE_RANK];
V_DrawMappedPatch(x+24+facerank->leftoffset, y+9+facerank->topoffset, V_SNAPTOLEFT, facerank, colormap);
}
if (!splitscreen && i == consoleplayer)
{
UINT8 cursorframe = (votetic / 4) % 8;
V_DrawScaledPatch(x+24, y+9, V_SNAPTOLEFT, W_CachePatchName(va("K_CHILI%d", cursorframe+1), PU_CACHE));
patch_t *highlight = W_CachePatchName(va("K_CHILI%d", cursorframe+1), PU_CACHE);
V_DrawScaledPatch(x+24+highlight->leftoffset, y+9+highlight->topoffset, V_SNAPTOLEFT, highlight);
}
}