Proper object HUD tracking -- apply to CHECK and Rival tag

This commit is contained in:
Sally Coolatta 2020-06-03 19:49:21 -04:00
parent fac8f7f538
commit 3ca0e4a48b
2 changed files with 304 additions and 58 deletions

View file

@ -8024,6 +8024,8 @@ static patch_t *kp_sadface[2];
static patch_t *kp_check[6];
static patch_t *kp_rival[2];
static patch_t *kp_eggnum[4];
static patch_t *kp_flameshieldmeter[104][2];
@ -8318,6 +8320,14 @@ void K_LoadKartHUDGraphics(void)
kp_check[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX);
}
// Rival indicators
sprintf(buffer, "K_RIVALx");
for (i = 0; i < 2; i++)
{
buffer[7] = '1'+i;
kp_rival[i] = (patch_t *) W_CachePatchName(buffer, PU_HUDGFX);
}
// Eggman warning numbers
sprintf(buffer, "K_EGGNx");
for (i = 0; i < 4; i++)
@ -9904,34 +9914,6 @@ static void K_drawKartBumpersOrKarma(void)
}
}
static fixed_t K_FindCheckX(fixed_t px, fixed_t py, angle_t ang, fixed_t mx, fixed_t my)
{
fixed_t dist, x;
fixed_t range = RING_DIST/3;
angle_t diff;
range *= gamespeed+1;
dist = abs(R_PointToDist2(px, py, mx, my));
if (dist > range)
return -320;
diff = R_PointToAngle2(px, py, mx, my) - ang;
if (diff < ANGLE_90 || diff > ANGLE_270)
return -320;
else
x = (FixedMul(FINETANGENT(((diff+ANGLE_90)>>ANGLETOFINESHIFT) & 4095), 160<<FRACBITS) + (160<<FRACBITS))>>FRACBITS;
if (encoremode)
x = 320-x;
if (r_splitscreen > 1)
x /= 2;
return x;
}
static void K_drawKartWanted(void)
{
UINT8 i, numwanted = 0;
@ -10004,52 +9986,309 @@ static void K_drawKartWanted(void)
}
}
static void K_ObjectTracking(fixed_t *hud_x, fixed_t *hud_y, vertex_t *campos, angle_t camang, angle_t camaim, UINT8 camnum, vertex_t *point)
{
const INT32 swhalf = (BASEVIDWIDTH / 2);
const fixed_t swhalffixed = swhalf * FRACUNIT;
const INT32 shhalf = (BASEVIDHEIGHT / 2);
const fixed_t shhalffixed = shhalf * FRACUNIT;
INT32 anglediff = (signed)(camang - R_PointToAngle2(campos->x, campos->y, point->x, point->y));
fixed_t distance = R_PointToDist2(campos->x, campos->y, point->x, point->y);
fixed_t factor = INT32_MAX;
if (abs(anglediff) > ANGLE_90)
{
if (hud_x != NULL)
{
*hud_x = -BASEVIDWIDTH * FRACUNIT;
}
if (hud_y != NULL)
{
*hud_y = -BASEVIDWIDTH * FRACUNIT;
}
//*hud_scale = FRACUNIT;
return;
}
factor = max(1, FINECOSINE(anglediff >> ANGLETOFINESHIFT));
#define NEWTAN(n) FINETANGENT(((n + ANGLE_90) >> ANGLETOFINESHIFT) & 4095)
if (hud_x != NULL)
{
*hud_x = FixedMul(NEWTAN(anglediff), swhalffixed) + swhalffixed;
if (r_splitscreen >= 2)
{
*hud_x /= 2;
if (camnum & 1)
{
*hud_x += swhalffixed;
}
}
}
if (hud_y != NULL)
{
*hud_y = campos->z - point->z;
*hud_y = FixedDiv(*hud_y, FixedMul(factor, distance));
*hud_y = (*hud_y * swhalf) + shhalffixed;
*hud_y = *hud_y + NEWTAN(camaim) * swhalf;
if (r_splitscreen >= 1)
{
*hud_y /= 2;
if (camnum > 1)
{
*hud_y += shhalffixed;
}
}
}
//*hud_scale = FixedDiv(swhalffixed, FixedMul(factor, distance));
#undef NEWTAN
}
static void K_drawKartPlayerCheck(void)
{
INT32 i;
UINT8 *colormap;
INT32 x;
const fixed_t maxdistance = FixedMul(1280 * mapobjectscale, K_GetKartGameSpeedScalar(gamespeed));
camera_t *thiscam;
vertex_t c;
UINT8 cnum = 0;
UINT8 i;
INT32 splitflags = K_calcSplitFlags(V_SNAPTOBOTTOM);
if (!stplyr->mo || stplyr->spectator)
if (stplyr == NULL || stplyr->mo == NULL || P_MobjWasRemoved(stplyr->mo))
{
return;
}
if (stplyr->awayviewtics)
if (stplyr->spectator || stplyr->awayviewtics)
{
return;
}
if (( stplyr->cmd.buttons & BT_LOOKBACK ))
if (stplyr->cmd.buttons & BT_LOOKBACK)
{
return;
}
if (r_splitscreen)
{
for (i = 1; i <= r_splitscreen; i++)
{
if (stplyr == &players[displayplayers[i]])
{
cnum = i;
break;
}
}
}
thiscam = &camera[cnum];
c.x = thiscam->x;
c.y = thiscam->y;
c.z = thiscam->z;
for (i = 0; i < MAXPLAYERS; i++)
{
player_t *checkplayer = &players[i];
fixed_t distance = maxdistance+1;
UINT8 pnum = 0;
fixed_t x = 0;
vertex_t v;
if (&players[i] == stplyr)
continue;
if (!playeringame[i] || players[i].spectator)
continue;
if (!players[i].mo)
continue;
if ((players[i].kartstuff[k_invincibilitytimer] <= 0) && (leveltime & 2))
pnum++; // white frames
if (players[i].kartstuff[k_itemtype] == KITEM_GROW || players[i].kartstuff[k_growshrinktimer] > 0)
pnum += 4;
else if (players[i].kartstuff[k_itemtype] == KITEM_INVINCIBILITY || players[i].kartstuff[k_invincibilitytimer])
pnum += 2;
x = K_FindCheckX(stplyr->mo->x, stplyr->mo->y, stplyr->mo->angle, players[i].mo->x, players[i].mo->y);
if (x <= 320 && x >= 0)
if (!playeringame[i] || checkplayer->spectator)
{
if (x < 14)
x = 14;
else if (x > 306)
x = 306;
// Not in-game
continue;
}
colormap = R_GetTranslationColormap(TC_DEFAULT, players[i].mo->color, GTC_CACHE);
V_DrawMappedPatch(x, CHEK_Y, V_HUDTRANS|splitflags, kp_check[pnum], colormap);
if (checkplayer->mo == NULL || P_MobjWasRemoved(checkplayer->mo))
{
// No object
continue;
}
if (checkplayer == stplyr)
{
// This is you!
continue;
}
v.x = checkplayer->mo->x;
v.y = checkplayer->mo->y;
v.z = checkplayer->mo->z;
distance = R_PointToDist2(c.x, c.y, v.x, v.y);
if (distance > maxdistance)
{
// Too far away
continue;
}
if ((checkplayer->kartstuff[k_invincibilitytimer] <= 0) && (leveltime & 2))
{
pnum++; // white frames
}
if (checkplayer->kartstuff[k_itemtype] == KITEM_GROW || checkplayer->kartstuff[k_growshrinktimer] > 0)
{
pnum += 4;
}
else if (checkplayer->kartstuff[k_itemtype] == KITEM_INVINCIBILITY || checkplayer->kartstuff[k_invincibilitytimer])
{
pnum += 2;
}
K_ObjectTracking(&x, NULL, &c, thiscam->angle + ANGLE_180, 0, cnum, &v);
if (x <= 320*FRACUNIT && x >= 0)
{
UINT8 *colormap = R_GetTranslationColormap(TC_DEFAULT, checkplayer->mo->color, GTC_CACHE);
if (x < 14*FRACUNIT)
{
x = 14*FRACUNIT;
}
else if (x > 306*FRACUNIT)
{
x = 306*FRACUNIT;
}
V_DrawFixedPatch(x, CHEK_Y * FRACUNIT, FRACUNIT, V_HUDTRANS|splitflags, kp_check[pnum], colormap);
}
}
}
static void K_drawKartNameTags(void)
{
const fixed_t maxdistance = 4096*mapobjectscale;
camera_t *thiscam;
vertex_t c;
UINT8 cnum = 0;
UINT8 i;
if (stplyr == NULL || stplyr->mo == NULL || P_MobjWasRemoved(stplyr->mo))
{
return;
}
if (stplyr->awayviewtics)
{
return;
}
if (r_splitscreen)
{
for (i = 1; i <= r_splitscreen; i++)
{
if (stplyr == &players[displayplayers[i]])
{
cnum = i;
break;
}
}
}
thiscam = &camera[cnum];
c.x = thiscam->x;
c.y = thiscam->y;
c.z = thiscam->z;
for (i = 0; i < MAXPLAYERS; i++)
{
player_t *ntplayer = &players[i];
fixed_t distance = maxdistance+1;
fixed_t x = -BASEVIDWIDTH * FRACUNIT;
fixed_t y = -BASEVIDWIDTH * FRACUNIT;
vertex_t v;
UINT8 j;
if (!playeringame[i] || ntplayer->spectator)
{
// Not in-game
continue;
}
if (ntplayer->mo == NULL || P_MobjWasRemoved(ntplayer->mo))
{
// No object
continue;
}
if (!P_CheckSight(stplyr->mo, ntplayer->mo))
{
// Can't see
continue;
}
for (j = 0; j <= r_splitscreen; j++)
{
if (ntplayer == &players[displayplayers[j]])
{
break;
}
}
if (j < r_splitscreen)
{
// Is a player that's being shown on this computer
continue;
}
v.x = ntplayer->mo->x;
v.y = ntplayer->mo->y;
v.z = ntplayer->mo->z;
if (!(ntplayer->mo->eflags & MFE_VERTICALFLIP))
{
v.z += ntplayer->mo->height;
}
distance = R_PointToDist2(c.x, c.y, v.x, v.y);
if (distance > maxdistance)
{
// Too far away
continue;
}
K_ObjectTracking(&x, &y, &c, thiscam->angle, thiscam->aiming, cnum, &v);
if (x == -BASEVIDWIDTH * FRACUNIT)
{
// Off-screen
continue;
}
if (ntplayer->bot)
{
if (ntplayer->botvars.rival == true)
{
UINT8 blink = ((leveltime / 7) & 1);
V_DrawFixedPatch(x, y, FRACUNIT, V_HUDTRANS, kp_rival[blink], NULL);
}
}
else
{
if ((ntplayer->kartstuff[k_position] >= stplyr->kartstuff[k_position]-1)
&& (ntplayer->kartstuff[k_position] <= stplyr->kartstuff[k_position]+1))
{
; // TODO: Draw a cool name tag for online
}
}
}
}
@ -11063,6 +11302,12 @@ void K_drawKartHUD(void)
if (cv_kartcheck.value && !splitscreen && !players[displayplayers[0]].exiting && !freecam)
K_drawKartPlayerCheck();
// nametags
#ifdef HAVE_BLUA
if (LUA_HudEnabled(hud_names))
#endif
K_drawKartNameTags();
// Draw WANTED status
if (G_BattleGametype())
{

View file

@ -19,6 +19,7 @@ enum hud {
hud_minimap,
hud_item,
hud_position,
hud_names, // online nametags
hud_check, // "CHECK" f-zero indicator
hud_minirankings, // Rankings to the left
hud_battlebumpers, // mini rankings battle bumpers.