From 8ac2efe82ccfdbae723557686958af3eb4805ff3 Mon Sep 17 00:00:00 2001 From: James R Date: Thu, 25 Jan 2024 21:58:40 -0800 Subject: [PATCH] HUD tracking: refactor nametags to use generic HUD tracker sorting --- src/k_hud.cpp | 188 ++++++++++++-------------------------------- src/k_hud.h | 12 +++ src/k_hud_track.cpp | 87 +++++++++++++++++++- 3 files changed, 145 insertions(+), 142 deletions(-) diff --git a/src/k_hud.cpp b/src/k_hud.cpp index 3fa62a007..cf82dfb2e 100644 --- a/src/k_hud.cpp +++ b/src/k_hud.cpp @@ -3749,6 +3749,55 @@ static void K_DrawNameTagForPlayer(fixed_t x, fixed_t y, player_t *p) V_DrawThinStringAtFixed(x + (5*FRACUNIT), y - (26*FRACUNIT), clr, player_names[p - players]); } +playertagtype_t K_WhichPlayerTag(player_t *p) +{ + UINT8 cnum = R_GetViewNumber(); + + if (!(demo.playback == true && camera[cnum].freecam == true) && P_IsDisplayPlayer(p) && + p != &players[displayplayers[cnum]]) + { + return PLAYERTAG_LOCAL; + } + else if (p->bot) + { + if (p->botvars.rival == true) + { + return PLAYERTAG_RIVAL; + } + } + else if (netgame || demo.playback) + { + if (K_ShowPlayerNametag(p) == true) + { + return PLAYERTAG_NAME; + } + } + + return PLAYERTAG_NONE; +} + +void K_DrawPlayerTag(fixed_t x, fixed_t y, player_t *p, playertagtype_t type) +{ + switch (type) + { + case PLAYERTAG_LOCAL: + K_DrawLocalTagForPlayer(x, y, p, G_PartyPosition(p - players)); + break; + + case PLAYERTAG_RIVAL: + K_DrawRivalTagForPlayer(x, y); + break; + + case PLAYERTAG_NAME: + K_DrawNameTagForPlayer(x, y, p); + K_DrawTypingNotifier(x, y, p); + break; + + default: + break; + } +} + typedef struct weakspotdraw_t { UINT8 i; @@ -3788,12 +3837,8 @@ static void K_DrawWeakSpot(weakspotdraw_t *ws) static void K_drawKartNameTags(void) { - const fixed_t maxdistance = 8192*mapobjectscale; vector3_t c; UINT8 cnum = R_GetViewNumber(); - UINT8 tobesorted[MAXPLAYERS]; - fixed_t sortdist[MAXPLAYERS]; - UINT8 sortlen = 0; size_t i, j; if (stplyr == NULL || stplyr->mo == NULL || P_MobjWasRemoved(stplyr->mo)) @@ -3912,141 +3957,6 @@ static void K_drawKartNameTags(void) K_drawTargetHUD(&c, stplyr); - for (i = 0; i < MAXPLAYERS; i++) - { - player_t *ntplayer = &players[i]; - fixed_t distance = maxdistance+1; - vector3_t v; - - if (!playeringame[i] || ntplayer->spectator) - { - // Not in-game - continue; - } - - if (ntplayer->mo == NULL || P_MobjWasRemoved(ntplayer->mo)) - { - // No object - continue; - } - - if (ntplayer->mo->renderflags & K_GetPlayerDontDrawFlag(stplyr)) - { - // Invisible on this screen - continue; - } - - if (!P_CheckSight(stplyr->mo, ntplayer->mo)) - { - // Can't see - continue; - } - - v.x = R_InterpolateFixed(ntplayer->mo->old_x, ntplayer->mo->x); - v.y = R_InterpolateFixed(ntplayer->mo->old_y, ntplayer->mo->y); - v.z = R_InterpolateFixed(ntplayer->mo->old_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; - } - - tobesorted[sortlen] = ntplayer - players; - sortdist[sortlen] = distance; - sortlen++; - } - - if (sortlen > 0) - { - UINT8 sortedplayers[MAXPLAYERS]; - - for (i = 0; i < sortlen; i++) - { - UINT8 pos = 0; - - for (j = 0; j < sortlen; j++) - { - if (j == i) - { - continue; - } - - if (sortdist[i] < sortdist[j] - || (sortdist[i] == sortdist[j] && i > j)) - { - pos++; - } - } - - sortedplayers[pos] = tobesorted[i]; - } - - for (i = 0; i < sortlen; i++) - { - trackingResult_t result; - player_t *ntplayer = &players[sortedplayers[i]]; - - fixed_t headOffset = 36*ntplayer->mo->scale; - - SINT8 localindicator = -1; - vector3_t v; - - v.x = R_InterpolateFixed(ntplayer->mo->old_x, ntplayer->mo->x); - v.y = R_InterpolateFixed(ntplayer->mo->old_y, ntplayer->mo->y); - v.z = R_InterpolateFixed(ntplayer->mo->old_z, ntplayer->mo->z); - - v.z += (ntplayer->mo->height / 2); - - if (stplyr->mo->eflags & MFE_VERTICALFLIP) - { - v.z -= headOffset; - } - else - { - v.z += headOffset; - } - - K_ObjectTracking(&result, &v, false); - - if (result.onScreen == true) - { - if (!(demo.playback == true && camera[cnum].freecam == true) && P_IsDisplayPlayer(ntplayer) && - ntplayer != &players[displayplayers[cnum]]) - { - localindicator = G_PartyPosition(ntplayer - players); - } - - if (localindicator >= 0) - { - K_DrawLocalTagForPlayer(result.x, result.y, ntplayer, localindicator); - } - else if (ntplayer->bot) - { - if (ntplayer->botvars.rival == true) - { - K_DrawRivalTagForPlayer(result.x, result.y); - } - } - else if (netgame || demo.playback) - { - if (K_ShowPlayerNametag(ntplayer) == true) - { - K_DrawNameTagForPlayer(result.x, result.y, ntplayer); - K_DrawTypingNotifier(result.x, result.y, ntplayer); - } - } - } - } - } - V_ClearClipRect(); } diff --git a/src/k_hud.h b/src/k_hud.h index d91d0c5c0..9381beefc 100644 --- a/src/k_hud.h +++ b/src/k_hud.h @@ -99,6 +99,18 @@ void K_ClearPersistentMessages(void); void K_ClearPersistentMessageForPlayer(player_t *player); void K_TickMessages(void); +typedef enum +{ + PLAYERTAG_NONE, + PLAYERTAG_LOCAL, + PLAYERTAG_RIVAL, + PLAYERTAG_NAME, +} +playertagtype_t; + +playertagtype_t K_WhichPlayerTag(player_t *p); +void K_DrawPlayerTag(fixed_t x, fixed_t y, player_t *p, playertagtype_t type); + #ifdef __cplusplus } // extern "C" #endif diff --git a/src/k_hud_track.cpp b/src/k_hud_track.cpp index 802e2e640..5d5524b9c 100644 --- a/src/k_hud_track.cpp +++ b/src/k_hud_track.cpp @@ -6,6 +6,7 @@ #include "core/static_vec.hpp" #include "v_draw.hpp" +#include "g_game.h" #include "k_battle.h" #include "k_hud.h" #include "k_kart.h" @@ -67,6 +68,7 @@ struct TargetTracking trackingResult_t result; fixed_t camDist; bool foreground; + playertagtype_t nametag; skincolornum_t color() const { @@ -165,6 +167,42 @@ struct TargetTracking return nullptr; } + bool is_player_nametag_on_screen() const + { + const player_t* player = mobj->player; + + if (nametag == PLAYERTAG_NONE) + { + return false; + } + + if (player->spectator) + { + // Not in-game + return false; + } + + if (mobj->renderflags & K_GetPlayerDontDrawFlag(stplyr)) + { + // Invisible on this screen + return false; + } + + if (camDist > 8192*mapobjectscale) + { + // Too far away + return false; + } + + if (!P_CheckSight(stplyr->mo, const_cast(mobj))) + { + // Can't see + return false; + } + + return true; + } + private: Graphics graphics() const { @@ -320,6 +358,12 @@ Visibility is_object_visible(const mobj_t* mobj) void K_DrawTargetTracking(const TargetTracking& target) { + if (target.nametag != PLAYERTAG_NONE) + { + K_DrawPlayerTag(target.result.x, target.result.y, target.mobj->player, target.nametag); + return; + } + Visibility visibility = is_object_visible(target.mobj); if (visibility == Visibility::kFlicker && (leveltime & 1)) @@ -553,6 +597,11 @@ void K_CullTargetList(std::vector& targetList) return; } + if (tr.nametag != PLAYERTAG_NONE) + { + return; + } + fixed_t x1 = std::max(((tr.result.x - kTrackerRadius) / kBlockSize) / FRACUNIT, 0); fixed_t x2 = std::min(((tr.result.x + kTrackerRadius) / kBlockSize) / FRACUNIT, kXBlocks - 1); fixed_t y1 = std::max(((tr.result.y - kTrackerRadius) / kBlockSize) / FRACUNIT, 0); @@ -618,7 +667,10 @@ void K_drawTargetHUD(const vector3_t* origin, player_t* player) continue; } - if (is_object_tracking_target(mobj) == false) + bool tracking = is_object_tracking_target(mobj); + playertagtype_t nametag = mobj->player ? K_WhichPlayerTag(mobj->player) : PLAYERTAG_NONE; + + if (tracking == false && nametag == PLAYERTAG_NONE) { continue; } @@ -634,10 +686,39 @@ void K_drawTargetHUD(const vector3_t* origin, player_t* player) tr.mobj = mobj; tr.camDist = R_PointToDist2(origin->x, origin->y, pos.x, pos.y); tr.foreground = false; + tr.nametag = PLAYERTAG_NONE; - K_ObjectTracking(&tr.result, &pos, false); + if (tracking) + { + K_ObjectTracking(&tr.result, &pos, false); + targetList.push_back(tr); + } - targetList.push_back(tr); + if (!mobj->player) + { + continue; + } + + tr.nametag = nametag; + + if (tr.is_player_nametag_on_screen()) + { + fixed_t headOffset = 36*mobj->scale; + if (stplyr->mo->eflags & MFE_VERTICALFLIP) + { + pos.z -= headOffset; + } + else + { + pos.z += headOffset; + } + K_ObjectTracking(&tr.result, &pos, false); + + if (tr.result.onScreen == true) + { + targetList.push_back(tr); + } + } } // Sort by distance from camera. Further trackers get