From be4c3413163b2385e2e055f14bda06c227c54ac1 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 21 Feb 2023 17:48:14 -0800 Subject: [PATCH 1/7] Rename kitemcap to trackercap --- src/k_botitem.c | 2 +- src/k_hud.c | 4 ++-- src/k_kart.c | 2 +- src/p_mobj.c | 18 +++++++++++------- src/p_mobj.h | 6 +++--- src/p_saveg.c | 6 +++--- src/p_tick.c | 2 +- 7 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/k_botitem.c b/src/k_botitem.c index a591bc38c..58e448d1f 100644 --- a/src/k_botitem.c +++ b/src/k_botitem.c @@ -1094,7 +1094,7 @@ static void K_BotItemJawz(player_t *player, ticcmd_t *cmd) target = &players[lastTarg]; // Make sure no other Jawz are targetting this player. - for (mobj = kitemcap; mobj; mobj = next) + for (mobj = trackercap; mobj; mobj = next) { next = mobj->itnext; diff --git a/src/k_hud.c b/src/k_hud.c index 598d379e6..bdc14e596 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -3494,7 +3494,7 @@ static void K_drawKartNameTags(void) mobj_t *mobj = NULL; mobj_t *next = NULL; - for (mobj = kitemcap; mobj; mobj = next) + for (mobj = trackercap; mobj; mobj = next) { capsuletracking_t *caps = NULL; @@ -3927,7 +3927,7 @@ static void K_drawKartMinimap(void) } // draw minimap-pertinent objects - for (mobj = kitemcap; mobj; mobj = next) + for (mobj = trackercap; mobj; mobj = next) { next = mobj->itnext; diff --git a/src/k_kart.c b/src/k_kart.c index 5a73a74bc..c6f558575 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5813,7 +5813,7 @@ static void K_DoShrink(player_t *user) mobj_t *mobj, *next; // kill everything in the kitem list while we're at it: - for (mobj = kitemcap; mobj; mobj = next) + for (mobj = trackercap; mobj; mobj = next) { next = mobj->itnext; diff --git a/src/p_mobj.c b/src/p_mobj.c index 6041a5549..45420e1c3 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -53,9 +53,13 @@ consvar_t cv_movebob = CVAR_INIT ("movebob", "1.0", CV_FLOAT|CV_SAVE, CV_BobSpee actioncache_t actioncachehead; static mobj_t *overlaycap = NULL; -mobj_t *kitemcap = NULL; // Used for Kart offensive items (the ones that can get removed by sizedown) mobj_t *waypointcap = NULL; +// Used as a fast iterator to certain objects that help bot +// AI, need HUD tracking or appear on the minimap. It's pretty +// general purpose. +mobj_t *trackercap = NULL; + void P_InitCachedActions(void) { actioncachehead.prev = actioncachehead.next = &actioncachehead; @@ -5261,11 +5265,11 @@ void P_AddKartItem(mobj_t *thing) { I_Assert(thing != NULL); - if (kitemcap == NULL) - P_SetTarget(&kitemcap, thing); + if (trackercap == NULL) + P_SetTarget(&trackercap, thing); else { mobj_t *mo; - for (mo = kitemcap; mo && mo->itnext; mo = mo->itnext) + for (mo = trackercap; mo && mo->itnext; mo = mo->itnext) ; I_Assert(mo != NULL); @@ -5281,7 +5285,7 @@ void P_AddKartItem(mobj_t *thing) static void P_RemoveKartItem(mobj_t *thing) { mobj_t *mo, **p; - for (mo = *(p = &kitemcap); mo; mo = *(p = &mo->itnext)) + for (mo = *(p = &trackercap); mo; mo = *(p = &mo->itnext)) { if (mo != thing) continue; @@ -5298,12 +5302,12 @@ void P_RunKartItems(void) { mobj_t *mobj, *next; - for (mobj = kitemcap; mobj; mobj = next) + for (mobj = trackercap; mobj; mobj = next) { next = mobj->itnext; P_SetTarget(&mobj->itnext, NULL); } - P_SetTarget(&kitemcap, NULL); + P_SetTarget(&trackercap, NULL); } void P_RunOverlays(void) diff --git a/src/p_mobj.h b/src/p_mobj.h index 323bcc4ae..ce15af6b6 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -356,7 +356,7 @@ struct mobj_t mobj_t *hnext; mobj_t *hprev; - // One last pointer for kart item lists + // One last pointer for trackers lists mobj_t *itnext; INT32 health; // for player this is rings + 1 -- no it isn't, not any more!! @@ -504,7 +504,7 @@ struct actioncache_t extern actioncache_t actioncachehead; -extern mobj_t *kitemcap; +extern mobj_t *trackercap; extern mobj_t *waypointcap; void P_InitCachedActions(void); @@ -517,7 +517,7 @@ boolean P_IsKartItem(INT32 type); boolean K_IsMissileOrKartItem(mobj_t *mo); boolean P_CanDeleteKartItem(INT32 type); void P_AddKartItem(mobj_t *thing); // needs to be called in k_kart.c -void P_RunKartItems(void); +void P_RunTrackers(void); // check mobj against water content, before movement code void P_MobjCheckWater(mobj_t *mobj); diff --git a/src/p_saveg.c b/src/p_saveg.c index 0420d0520..90227a822 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2191,7 +2191,7 @@ static void SaveMobjThinker(savebuffer_t *save, const thinker_t *th, const UINT8 diff2 |= MD2_DISPOFFSET; if (mobj == waypointcap) diff2 |= MD2_WAYPOINTCAP; - if (mobj == kitemcap) + if (mobj == trackercap) diff2 |= MD2_KITEMCAP; if (mobj->itnext) diff2 |= MD2_ITNEXT; @@ -3610,7 +3610,7 @@ static thinker_t* LoadMobjThinker(savebuffer_t *save, actionf_p1 thinker) P_SetTarget(&waypointcap, mobj); if (diff2 & MD2_KITEMCAP) - P_SetTarget(&kitemcap, mobj); + P_SetTarget(&trackercap, mobj); R_AddMobjInterpolator(mobj); @@ -4251,7 +4251,7 @@ static void P_NetUnArchiveThinkers(savebuffer_t *save) P_InitThinkers(); // Oh my god don't blast random memory with our reference counts. - waypointcap = kitemcap = NULL; + waypointcap = trackercap = NULL; for (i = 0; i <= 15; i++) { skyboxcenterpnts[i] = skyboxviewpnts[i] = NULL; diff --git a/src/p_tick.c b/src/p_tick.c index 79f245a22..ca33cb028 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -210,7 +210,7 @@ void P_InitThinkers(void) { UINT8 i; waypointcap = NULL; - kitemcap = NULL; + trackercap = NULL; for (i = 0; i < NUM_THINKERLISTS; i++) thlist[i].prev = thlist[i].next = &thlist[i]; } From 061e5b01eca30d468444809afc2c33ff8b2a1b5e Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 21 Feb 2023 18:27:46 -0800 Subject: [PATCH 2/7] Refactor trackercap - Don't clear every tic. This is what P_RemoveTracker is for. - Link in P_SpawnMobj. Should cover all cases. - Remove excess objects. These were leftover from when Shrink destroyed items. Just track Jawz, SPB and Break the Capsules. --- src/k_kart.c | 1 - src/p_mobj.c | 79 +++++++++++++++++++--------------------------------- src/p_mobj.h | 4 --- src/p_tick.c | 3 -- 4 files changed, 28 insertions(+), 59 deletions(-) diff --git a/src/k_kart.c b/src/k_kart.c index c6f558575..4384b4a39 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -6105,7 +6105,6 @@ void K_DropHnextList(player_t *player, boolean keepshields) dropwork = P_SpawnMobj(work->x, work->y, work->z, type); P_SetTarget(&dropwork->target, player->mo); - P_AddKartItem(dropwork); // needs to be called here so shrink can bust items off players in front of the user. dropwork->angle = work->angle; diff --git a/src/p_mobj.c b/src/p_mobj.c index 45420e1c3..707f10a17 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5210,30 +5210,6 @@ boolean P_IsKartFieldItem(INT32 type) } } -boolean P_IsKartItem(INT32 type) -{ - switch (type) - { - case MT_EGGMANITEM_SHIELD: - case MT_BANANA_SHIELD: - case MT_DROPTARGET_SHIELD: - case MT_ORBINAUT_SHIELD: - case MT_JAWZ_SHIELD: - case MT_SSMINE_SHIELD: - case MT_SINK_SHIELD: - case MT_HYUDORO: - return true; - - // Primarily for minimap data, handle with care - case MT_SPB: - case MT_BATTLECAPSULE: - return true; - - default: - return P_IsKartFieldItem(type); - } -} - boolean K_IsMissileOrKartItem(mobj_t *mo) { if (mo->flags & MF_MISSILE) @@ -5260,8 +5236,25 @@ boolean P_CanDeleteKartItem(INT32 type) return P_IsKartFieldItem(type); } -// Called when a kart item "thinks" -void P_AddKartItem(mobj_t *thing) +static boolean P_IsTrackerType(INT32 type) +{ + switch (type) + { + // Bots need to know if another Jawz is targetting a player + case MT_JAWZ: + return true; + + // Primarily for minimap data, handle with care + case MT_SPB: + case MT_BATTLECAPSULE: + return true; + + default: + return false; + } +} + +static void P_LinkTracker(mobj_t *thing) { I_Assert(thing != NULL); @@ -5280,9 +5273,9 @@ void P_AddKartItem(mobj_t *thing) P_SetTarget(&thing->itnext, NULL); } -// Called only when a kart item is removed -// Keeps the hnext list from corrupting. -static void P_RemoveKartItem(mobj_t *thing) +// Called only when a tracker is removed +// Keeps the itnext list from corrupting. +static void P_RemoveTracker(mobj_t *thing) { mobj_t *mo, **p; for (mo = *(p = &trackercap); mo; mo = *(p = &mo->itnext)) @@ -5296,20 +5289,6 @@ static void P_RemoveKartItem(mobj_t *thing) } } -// Doesn't actually do anything since items have their own thinkers, -// but this is necessary for the sole purpose of updating kitemcap -void P_RunKartItems(void) -{ - mobj_t *mobj, *next; - - for (mobj = trackercap; mobj; mobj = next) - { - next = mobj->itnext; - P_SetTarget(&mobj->itnext, NULL); - } - P_SetTarget(&trackercap, NULL); -} - void P_RunOverlays(void) { // run overlays @@ -9811,9 +9790,6 @@ void P_MobjThinker(mobj_t *mobj) K_HandleDirectionalInfluence(mobj->player); } - if (P_IsKartItem(mobj->type)) // mobj is a kart item we want on the list: - P_AddKartItem(mobj); // add to kitem list - return; } @@ -10054,9 +10030,6 @@ void P_MobjThinker(mobj_t *mobj) if (P_MobjWasRemoved(mobj)) return; // obligatory paranoia check - if (P_IsKartItem(mobj->type)) // mobj is a kart item we want on the list: - P_AddKartItem(mobj); // add to kitem list - // Can end up here if a player dies. if (mobj->player) P_CyclePlayerMobjState(mobj); @@ -10970,6 +10943,10 @@ mobj_t *P_SpawnMobj(fixed_t x, fixed_t y, fixed_t z, mobjtype_t type) R_AddMobjInterpolator(mobj); + + if (P_IsTrackerType(mobj->type)) + P_LinkTracker(mobj); + return mobj; } @@ -11112,8 +11089,8 @@ void P_RemoveMobj(mobj_t *mobj) if (mobj->type == MT_SPB) spbplace = -1; - if (P_IsKartItem(mobj->type)) - P_RemoveKartItem(mobj); + if (P_IsTrackerType(mobj->type)) + P_RemoveTracker(mobj); if (mobj->player && mobj->player->followmobj) { diff --git a/src/p_mobj.h b/src/p_mobj.h index ce15af6b6..dd448841e 100644 --- a/src/p_mobj.h +++ b/src/p_mobj.h @@ -511,13 +511,9 @@ void P_InitCachedActions(void); void P_RunCachedActions(void); void P_AddCachedAction(mobj_t *mobj, INT32 statenum); -// kartitem stuff: Returns true if the specified 'type' is one of the kart item constants we want in the kitemcap list boolean P_IsKartFieldItem(INT32 type); -boolean P_IsKartItem(INT32 type); boolean K_IsMissileOrKartItem(mobj_t *mo); boolean P_CanDeleteKartItem(INT32 type); -void P_AddKartItem(mobj_t *thing); // needs to be called in k_kart.c -void P_RunTrackers(void); // check mobj against water content, before movement code void P_MobjCheckWater(mobj_t *mobj); diff --git a/src/p_tick.c b/src/p_tick.c index ca33cb028..91be6d183 100644 --- a/src/p_tick.c +++ b/src/p_tick.c @@ -636,9 +636,6 @@ void P_Ticker(boolean run) if (!demo.playback) // Don't increment if a demo is playing. gamedata->totalplaytime++; - // formality so kitemcap gets updated properly each frame. - P_RunKartItems(); - if (run) { ps_thinkertime = I_GetPreciseTime(); From 83051728f0809d066eea4593e27a6efbd05d5ea5 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 21 Feb 2023 18:45:22 -0800 Subject: [PATCH 3/7] Move capsule target code out of k_hud.c, to k_hud_track.cpp --- src/CMakeLists.txt | 1 + src/k_hud.c | 295 +------------------------------------------- src/k_hud.h | 5 + src/k_hud_track.cpp | 289 +++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 300 insertions(+), 290 deletions(-) create mode 100644 src/k_hud_track.cpp diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index ce816523e..ac592f89d 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -121,6 +121,7 @@ add_executable(SRB2SDL2 MACOSX_BUNDLE WIN32 k_grandprix.c k_boss.c k_hud.c + k_hud_track.cpp k_menufunc.c k_menudraw.c k_terrain.c diff --git a/src/k_hud.c b/src/k_hud.c index bdc14e596..5fbc5b1a3 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -174,10 +174,10 @@ static patch_t *kp_bossret[4]; static patch_t *kp_trickcool[2]; -static patch_t *kp_capsuletarget_arrow[2][2]; -static patch_t *kp_capsuletarget_icon[2]; -static patch_t *kp_capsuletarget_far[2]; -static patch_t *kp_capsuletarget_near[8]; +patch_t *kp_capsuletarget_arrow[2][2]; +patch_t *kp_capsuletarget_icon[2]; +patch_t *kp_capsuletarget_far[2]; +patch_t *kp_capsuletarget_near[8]; void K_LoadKartHUDGraphics(void) { @@ -3175,217 +3175,6 @@ static void K_DrawWeakSpot(weakspotdraw_t *ws) V_DrawFixedPatch(ws->x, ws->y, FRACUNIT, 0, kp_bossret[j+1], colormap); } -typedef struct capsuletracking_s -{ - mobj_t *mobj; - vector3_t point; - fixed_t camDist; -} capsuletracking_t; - -static void K_DrawCapsuleTracking(capsuletracking_t *caps) -{ - trackingResult_t result = {0}; - INT32 timer = 0; - - K_ObjectTracking(&result, &caps->point, false); - - if (result.onScreen == false) - { - // Off-screen, draw alongside the borders of the screen. - // Probably the most complicated thing. - - INT32 scrVal = 240; - vector2_t screenSize = {0}; - - INT32 borderSize = 7; - vector2_t borderWin = {0}; - vector2_t borderDir = {0}; - fixed_t borderLen = FRACUNIT; - - vector2_t arrowDir = {0}; - - vector2_t arrowPos = {0}; - patch_t *arrowPatch = NULL; - INT32 arrowFlags = 0; - - vector2_t capsulePos = {0}; - patch_t *capsulePatch = NULL; - - timer = (leveltime / 3); - - screenSize.x = vid.width / vid.dupx; - screenSize.y = vid.height / vid.dupy; - - if (r_splitscreen >= 2) - { - // Half-wide screens - screenSize.x >>= 1; - borderSize >>= 1; - } - - if (r_splitscreen >= 1) - { - // Half-tall screens - screenSize.y >>= 1; - } - - scrVal = max(screenSize.x, screenSize.y) - 80; - - borderWin.x = screenSize.x - borderSize; - borderWin.y = screenSize.y - borderSize; - - arrowDir.x = 0; - arrowDir.y = P_MobjFlip(caps->mobj) * FRACUNIT; - - // Simply pointing towards the result doesn't work, so inaccurate hack... - borderDir.x = FixedMul( - FixedMul( - FINESINE((-result.angle >> ANGLETOFINESHIFT) & FINEMASK), - FINECOSINE((-result.pitch >> ANGLETOFINESHIFT) & FINEMASK) - ), - result.fov - ); - - borderDir.y = FixedMul( - FINESINE((-result.pitch >> ANGLETOFINESHIFT) & FINEMASK), - result.fov - ); - - borderLen = R_PointToDist2(0, 0, borderDir.x, borderDir.y); - - if (borderLen > 0) - { - borderDir.x = FixedDiv(borderDir.x, borderLen); - borderDir.y = FixedDiv(borderDir.y, borderLen); - } - else - { - // Eh just put it at the bottom. - borderDir.x = 0; - borderDir.y = FRACUNIT; - } - - capsulePatch = kp_capsuletarget_icon[timer & 1]; - - if (abs(borderDir.x) > abs(borderDir.y)) - { - // Horizontal arrow - arrowPatch = kp_capsuletarget_arrow[1][timer & 1]; - arrowDir.y = 0; - - if (borderDir.x < 0) - { - // LEFT - arrowDir.x = -FRACUNIT; - } - else - { - // RIGHT - arrowDir.x = FRACUNIT; - } - } - else - { - // Vertical arrow - arrowPatch = kp_capsuletarget_arrow[0][timer & 1]; - arrowDir.x = 0; - - if (borderDir.y < 0) - { - // UP - arrowDir.y = -FRACUNIT; - } - else - { - // DOWN - arrowDir.y = FRACUNIT; - } - } - - arrowPos.x = (screenSize.x >> 1) + FixedMul(scrVal, borderDir.x); - arrowPos.y = (screenSize.y >> 1) + FixedMul(scrVal, borderDir.y); - - arrowPos.x = min(max(arrowPos.x, borderSize), borderWin.x) * FRACUNIT; - arrowPos.y = min(max(arrowPos.y, borderSize), borderWin.y) * FRACUNIT; - - capsulePos.x = arrowPos.x - (arrowDir.x * 12); - capsulePos.y = arrowPos.y - (arrowDir.y * 12); - - arrowPos.x -= (arrowPatch->width << FRACBITS) >> 1; - arrowPos.y -= (arrowPatch->height << FRACBITS) >> 1; - - capsulePos.x -= (capsulePatch->width << FRACBITS) >> 1; - capsulePos.y -= (capsulePatch->height << FRACBITS) >> 1; - - if (arrowDir.x < 0) - { - arrowPos.x += arrowPatch->width << FRACBITS; - arrowFlags |= V_FLIP; - } - - if (arrowDir.y < 0) - { - arrowPos.y += arrowPatch->height << FRACBITS; - arrowFlags |= V_VFLIP; - } - - V_DrawFixedPatch( - capsulePos.x, capsulePos.y, - FRACUNIT, - V_SPLITSCREEN, - capsulePatch, NULL - ); - - V_DrawFixedPatch( - arrowPos.x, arrowPos.y, - FRACUNIT, - V_SPLITSCREEN | arrowFlags, - arrowPatch, NULL - ); - } - else - { - // Draw simple overlay. - const fixed_t farDistance = 1280*mapobjectscale; - boolean useNear = (caps->camDist < farDistance); - - patch_t *capsulePatch = NULL; - vector2_t capsulePos = {0}; - - boolean visible = P_CheckSight(stplyr->mo, caps->mobj); - - if (visible == false && (leveltime & 1)) - { - // Flicker when not visible. - return; - } - - capsulePos.x = result.x; - capsulePos.y = result.y; - - if (useNear == true) - { - timer = (leveltime / 2); - capsulePatch = kp_capsuletarget_near[timer % 8]; - } - else - { - timer = (leveltime / 3); - capsulePatch = kp_capsuletarget_far[timer & 1]; - } - - capsulePos.x -= (capsulePatch->width << FRACBITS) >> 1; - capsulePos.y -= (capsulePatch->height << FRACBITS) >> 1; - - V_DrawFixedPatch( - capsulePos.x, capsulePos.y, - FRACUNIT, - V_SPLITSCREEN, - capsulePatch, NULL - ); - } -} - static void K_drawKartNameTags(void) { const fixed_t maxdistance = 8192*mapobjectscale; @@ -3487,81 +3276,7 @@ static void K_drawKartNameTags(void) if (battlecapsules == true) { -#define MAX_CAPSULE_HUD 32 - capsuletracking_t capsuleList[MAX_CAPSULE_HUD]; - size_t capsuleListLen = 0; - - mobj_t *mobj = NULL; - mobj_t *next = NULL; - - for (mobj = trackercap; mobj; mobj = next) - { - capsuletracking_t *caps = NULL; - - next = mobj->itnext; - - if (mobj->health <= 0) - { - continue; - } - - if (mobj->type != MT_BATTLECAPSULE) - { - continue; - } - - caps = &capsuleList[capsuleListLen]; - - caps->mobj = mobj; - caps->point.x = R_InterpolateFixed(mobj->old_x, mobj->x); - caps->point.y = R_InterpolateFixed(mobj->old_y, mobj->y); - caps->point.z = R_InterpolateFixed(mobj->old_z, mobj->z); - caps->point.z += (mobj->height >> 1); - caps->camDist = R_PointToDist2(c.x, c.y, caps->point.x, caps->point.y); - - capsuleListLen++; - - if (capsuleListLen >= MAX_CAPSULE_HUD) - { - break; - } - } - - if (capsuleListLen > 0) - { - // Sort by distance from camera. - if (capsuleListLen > 1) - { - for (i = 0; i < capsuleListLen-1; i++) - { - size_t swap = i; - - for (j = i + 1; j < capsuleListLen; j++) - { - capsuletracking_t *cj = &capsuleList[j]; - capsuletracking_t *cSwap = &capsuleList[swap]; - - if (cj->camDist > cSwap->camDist) - { - swap = j; - } - } - - if (swap != i) - { - capsuletracking_t temp = capsuleList[swap]; - capsuleList[swap] = capsuleList[i]; - capsuleList[i] = temp; - } - } - } - - for (i = 0; i < capsuleListLen; i++) - { - K_DrawCapsuleTracking(&capsuleList[i]); - } - } -#undef MAX_CAPSULE_HUD + K_drawTargetHUD(&c, stplyr); } for (i = 0; i < MAXPLAYERS; i++) diff --git a/src/k_hud.h b/src/k_hud.h index 9b783f710..7d2b5354a 100644 --- a/src/k_hud.h +++ b/src/k_hud.h @@ -44,8 +44,13 @@ void K_drawKartTimestamp(tic_t drawtime, INT32 TX, INT32 TY, INT32 splitflags, U void K_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer, INT32 hilicol); void K_DrawMapThumbnail(INT32 x, INT32 y, INT32 width, UINT32 flags, UINT16 map, UINT8 *colormap); void K_DrawLikeMapThumbnail(INT32 x, INT32 y, INT32 width, UINT32 flags, patch_t *patch, UINT8 *colormap); +void K_drawTargetHUD(const vector3_t *origin, player_t *player); extern patch_t *kp_facehighlight[8]; +extern patch_t *kp_capsuletarget_arrow[2][2]; +extern patch_t *kp_capsuletarget_icon[2]; +extern patch_t *kp_capsuletarget_far[2]; +extern patch_t *kp_capsuletarget_near[8]; #ifdef __cplusplus } // extern "C" diff --git a/src/k_hud_track.cpp b/src/k_hud_track.cpp new file mode 100644 index 000000000..8b6c782d5 --- /dev/null +++ b/src/k_hud_track.cpp @@ -0,0 +1,289 @@ +#include +#include + +#include "k_hud.h" +#include "m_fixed.h" +#include "p_local.h" +#include "p_mobj.h" +#include "r_fps.h" +#include "r_main.h" +#include "v_video.h" + +namespace +{ + +struct capsuletracking_t +{ + mobj_t* mobj; + vector3_t point; + fixed_t camDist; +}; + +void K_DrawCapsuleTracking(capsuletracking_t* caps) +{ + trackingResult_t result = {}; + int32_t timer = 0; + + K_ObjectTracking(&result, &caps->point, false); + + if (result.onScreen == false) + { + // Off-screen, draw alongside the borders of the screen. + // Probably the most complicated thing. + + int32_t scrVal = 240; + vector2_t screenSize = {}; + + int32_t borderSize = 7; + vector2_t borderWin = {}; + vector2_t borderDir = {}; + fixed_t borderLen = FRACUNIT; + + vector2_t arrowDir = {}; + + vector2_t arrowPos = {}; + patch_t* arrowPatch = nullptr; + int32_t arrowFlags = 0; + + vector2_t capsulePos = {}; + patch_t* capsulePatch = nullptr; + + timer = (leveltime / 3); + + screenSize.x = vid.width / vid.dupx; + screenSize.y = vid.height / vid.dupy; + + if (r_splitscreen >= 2) + { + // Half-wide screens + screenSize.x >>= 1; + borderSize >>= 1; + } + + if (r_splitscreen >= 1) + { + // Half-tall screens + screenSize.y >>= 1; + } + + scrVal = std::max(screenSize.x, screenSize.y) - 80; + + borderWin.x = screenSize.x - borderSize; + borderWin.y = screenSize.y - borderSize; + + arrowDir.x = 0; + arrowDir.y = P_MobjFlip(caps->mobj) * FRACUNIT; + + // Simply pointing towards the result doesn't work, so inaccurate hack... + borderDir.x = FixedMul( + FixedMul( + FINESINE((-result.angle >> ANGLETOFINESHIFT) & FINEMASK), + FINECOSINE((-result.pitch >> ANGLETOFINESHIFT) & FINEMASK) + ), + result.fov + ); + + borderDir.y = FixedMul(FINESINE((-result.pitch >> ANGLETOFINESHIFT) & FINEMASK), result.fov); + + borderLen = R_PointToDist2(0, 0, borderDir.x, borderDir.y); + + if (borderLen > 0) + { + borderDir.x = FixedDiv(borderDir.x, borderLen); + borderDir.y = FixedDiv(borderDir.y, borderLen); + } + else + { + // Eh just put it at the bottom. + borderDir.x = 0; + borderDir.y = FRACUNIT; + } + + capsulePatch = kp_capsuletarget_icon[timer & 1]; + + if (abs(borderDir.x) > abs(borderDir.y)) + { + // Horizontal arrow + arrowPatch = kp_capsuletarget_arrow[1][timer & 1]; + arrowDir.y = 0; + + if (borderDir.x < 0) + { + // LEFT + arrowDir.x = -FRACUNIT; + } + else + { + // RIGHT + arrowDir.x = FRACUNIT; + } + } + else + { + // Vertical arrow + arrowPatch = kp_capsuletarget_arrow[0][timer & 1]; + arrowDir.x = 0; + + if (borderDir.y < 0) + { + // UP + arrowDir.y = -FRACUNIT; + } + else + { + // DOWN + arrowDir.y = FRACUNIT; + } + } + + arrowPos.x = (screenSize.x >> 1) + FixedMul(scrVal, borderDir.x); + arrowPos.y = (screenSize.y >> 1) + FixedMul(scrVal, borderDir.y); + + arrowPos.x = std::clamp(arrowPos.x, borderSize, borderWin.x) * FRACUNIT; + arrowPos.y = std::clamp(arrowPos.y, borderSize, borderWin.y) * FRACUNIT; + + capsulePos.x = arrowPos.x - (arrowDir.x * 12); + capsulePos.y = arrowPos.y - (arrowDir.y * 12); + + arrowPos.x -= (arrowPatch->width << FRACBITS) >> 1; + arrowPos.y -= (arrowPatch->height << FRACBITS) >> 1; + + capsulePos.x -= (capsulePatch->width << FRACBITS) >> 1; + capsulePos.y -= (capsulePatch->height << FRACBITS) >> 1; + + if (arrowDir.x < 0) + { + arrowPos.x += arrowPatch->width << FRACBITS; + arrowFlags |= V_FLIP; + } + + if (arrowDir.y < 0) + { + arrowPos.y += arrowPatch->height << FRACBITS; + arrowFlags |= V_VFLIP; + } + + V_DrawFixedPatch(capsulePos.x, capsulePos.y, FRACUNIT, V_SPLITSCREEN, capsulePatch, nullptr); + + V_DrawFixedPatch(arrowPos.x, arrowPos.y, FRACUNIT, V_SPLITSCREEN | arrowFlags, arrowPatch, nullptr); + } + else + { + // Draw simple overlay. + const fixed_t farDistance = 1280 * mapobjectscale; + bool useNear = (caps->camDist < farDistance); + + patch_t* capsulePatch = nullptr; + vector2_t capsulePos = {}; + + bool visible = P_CheckSight(stplyr->mo, caps->mobj); + + if (visible == false && (leveltime & 1)) + { + // Flicker when not visible. + return; + } + + capsulePos.x = result.x; + capsulePos.y = result.y; + + if (useNear == true) + { + timer = (leveltime / 2); + capsulePatch = kp_capsuletarget_near[timer % 8]; + } + else + { + timer = (leveltime / 3); + capsulePatch = kp_capsuletarget_far[timer & 1]; + } + + capsulePos.x -= (capsulePatch->width << FRACBITS) >> 1; + capsulePos.y -= (capsulePatch->height << FRACBITS) >> 1; + + V_DrawFixedPatch(capsulePos.x, capsulePos.y, FRACUNIT, V_SPLITSCREEN, capsulePatch, nullptr); + } +} + +}; // namespace + +void K_drawTargetHUD(const vector3_t* origin, player_t* player) +{ + constexpr std::size_t kMaxCapsuleHUD = 32; + + std::size_t i, j; + + capsuletracking_t capsuleList[kMaxCapsuleHUD]; + std::size_t capsuleListLen = 0; + + mobj_t* mobj = nullptr; + mobj_t* next = nullptr; + + for (mobj = trackercap; mobj; mobj = next) + { + capsuletracking_t* caps = nullptr; + + next = mobj->itnext; + + if (mobj->health <= 0) + { + continue; + } + + if (mobj->type != MT_BATTLECAPSULE) + { + continue; + } + + caps = &capsuleList[capsuleListLen]; + + caps->mobj = mobj; + caps->point.x = R_InterpolateFixed(mobj->old_x, mobj->x); + caps->point.y = R_InterpolateFixed(mobj->old_y, mobj->y); + caps->point.z = R_InterpolateFixed(mobj->old_z, mobj->z); + caps->point.z += (mobj->height >> 1); + caps->camDist = R_PointToDist2(origin->x, origin->y, caps->point.x, caps->point.y); + + capsuleListLen++; + + if (capsuleListLen >= kMaxCapsuleHUD) + { + break; + } + } + + if (capsuleListLen > 0) + { + // Sort by distance from camera. + if (capsuleListLen > 1) + { + for (i = 0; i < capsuleListLen - 1; i++) + { + std::size_t swap = i; + + for (j = i + 1; j < capsuleListLen; j++) + { + capsuletracking_t* cj = &capsuleList[j]; + capsuletracking_t* cSwap = &capsuleList[swap]; + + if (cj->camDist > cSwap->camDist) + { + swap = j; + } + } + + if (swap != i) + { + capsuletracking_t temp = capsuleList[swap]; + capsuleList[swap] = capsuleList[i]; + capsuleList[i] = temp; + } + } + } + + for (i = 0; i < capsuleListLen; i++) + { + K_DrawCapsuleTracking(&capsuleList[i]); + } + } +} From 13762ee4e16fe7955c8717d106528f5791f8718d Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 21 Feb 2023 19:04:34 -0800 Subject: [PATCH 4/7] k_hud_track.cpp: "capsule" -> "track" --- src/k_hud_track.cpp | 94 ++++++++++++++++++++++----------------------- 1 file changed, 47 insertions(+), 47 deletions(-) diff --git a/src/k_hud_track.cpp b/src/k_hud_track.cpp index 8b6c782d5..a3b0be780 100644 --- a/src/k_hud_track.cpp +++ b/src/k_hud_track.cpp @@ -12,19 +12,19 @@ namespace { -struct capsuletracking_t +struct TargetTracking { mobj_t* mobj; vector3_t point; fixed_t camDist; }; -void K_DrawCapsuleTracking(capsuletracking_t* caps) +void K_DrawTargetTracking(TargetTracking* target) { trackingResult_t result = {}; int32_t timer = 0; - K_ObjectTracking(&result, &caps->point, false); + K_ObjectTracking(&result, &target->point, false); if (result.onScreen == false) { @@ -45,8 +45,8 @@ void K_DrawCapsuleTracking(capsuletracking_t* caps) patch_t* arrowPatch = nullptr; int32_t arrowFlags = 0; - vector2_t capsulePos = {}; - patch_t* capsulePatch = nullptr; + vector2_t targetPos = {}; + patch_t* targetPatch = nullptr; timer = (leveltime / 3); @@ -72,7 +72,7 @@ void K_DrawCapsuleTracking(capsuletracking_t* caps) borderWin.y = screenSize.y - borderSize; arrowDir.x = 0; - arrowDir.y = P_MobjFlip(caps->mobj) * FRACUNIT; + arrowDir.y = P_MobjFlip(target->mobj) * FRACUNIT; // Simply pointing towards the result doesn't work, so inaccurate hack... borderDir.x = FixedMul( @@ -99,7 +99,7 @@ void K_DrawCapsuleTracking(capsuletracking_t* caps) borderDir.y = FRACUNIT; } - capsulePatch = kp_capsuletarget_icon[timer & 1]; + targetPatch = kp_capsuletarget_icon[timer & 1]; if (abs(borderDir.x) > abs(borderDir.y)) { @@ -142,14 +142,14 @@ void K_DrawCapsuleTracking(capsuletracking_t* caps) arrowPos.x = std::clamp(arrowPos.x, borderSize, borderWin.x) * FRACUNIT; arrowPos.y = std::clamp(arrowPos.y, borderSize, borderWin.y) * FRACUNIT; - capsulePos.x = arrowPos.x - (arrowDir.x * 12); - capsulePos.y = arrowPos.y - (arrowDir.y * 12); + targetPos.x = arrowPos.x - (arrowDir.x * 12); + targetPos.y = arrowPos.y - (arrowDir.y * 12); arrowPos.x -= (arrowPatch->width << FRACBITS) >> 1; arrowPos.y -= (arrowPatch->height << FRACBITS) >> 1; - capsulePos.x -= (capsulePatch->width << FRACBITS) >> 1; - capsulePos.y -= (capsulePatch->height << FRACBITS) >> 1; + targetPos.x -= (targetPatch->width << FRACBITS) >> 1; + targetPos.y -= (targetPatch->height << FRACBITS) >> 1; if (arrowDir.x < 0) { @@ -163,7 +163,7 @@ void K_DrawCapsuleTracking(capsuletracking_t* caps) arrowFlags |= V_VFLIP; } - V_DrawFixedPatch(capsulePos.x, capsulePos.y, FRACUNIT, V_SPLITSCREEN, capsulePatch, nullptr); + V_DrawFixedPatch(targetPos.x, targetPos.y, FRACUNIT, V_SPLITSCREEN, targetPatch, nullptr); V_DrawFixedPatch(arrowPos.x, arrowPos.y, FRACUNIT, V_SPLITSCREEN | arrowFlags, arrowPatch, nullptr); } @@ -171,12 +171,12 @@ void K_DrawCapsuleTracking(capsuletracking_t* caps) { // Draw simple overlay. const fixed_t farDistance = 1280 * mapobjectscale; - bool useNear = (caps->camDist < farDistance); + bool useNear = (target->camDist < farDistance); - patch_t* capsulePatch = nullptr; - vector2_t capsulePos = {}; + patch_t* targetPatch = nullptr; + vector2_t targetPos = {}; - bool visible = P_CheckSight(stplyr->mo, caps->mobj); + bool visible = P_CheckSight(stplyr->mo, target->mobj); if (visible == false && (leveltime & 1)) { @@ -184,24 +184,24 @@ void K_DrawCapsuleTracking(capsuletracking_t* caps) return; } - capsulePos.x = result.x; - capsulePos.y = result.y; + targetPos.x = result.x; + targetPos.y = result.y; if (useNear == true) { timer = (leveltime / 2); - capsulePatch = kp_capsuletarget_near[timer % 8]; + targetPatch = kp_capsuletarget_near[timer % 8]; } else { timer = (leveltime / 3); - capsulePatch = kp_capsuletarget_far[timer & 1]; + targetPatch = kp_capsuletarget_far[timer & 1]; } - capsulePos.x -= (capsulePatch->width << FRACBITS) >> 1; - capsulePos.y -= (capsulePatch->height << FRACBITS) >> 1; + targetPos.x -= (targetPatch->width << FRACBITS) >> 1; + targetPos.y -= (targetPatch->height << FRACBITS) >> 1; - V_DrawFixedPatch(capsulePos.x, capsulePos.y, FRACUNIT, V_SPLITSCREEN, capsulePatch, nullptr); + V_DrawFixedPatch(targetPos.x, targetPos.y, FRACUNIT, V_SPLITSCREEN, targetPatch, nullptr); } } @@ -209,19 +209,19 @@ void K_DrawCapsuleTracking(capsuletracking_t* caps) void K_drawTargetHUD(const vector3_t* origin, player_t* player) { - constexpr std::size_t kMaxCapsuleHUD = 32; + constexpr std::size_t kMaxTargetHUD = 32; std::size_t i, j; - capsuletracking_t capsuleList[kMaxCapsuleHUD]; - std::size_t capsuleListLen = 0; + TargetTracking targetList[kMaxTargetHUD]; + std::size_t targetListLen = 0; mobj_t* mobj = nullptr; mobj_t* next = nullptr; for (mobj = trackercap; mobj; mobj = next) { - capsuletracking_t* caps = nullptr; + TargetTracking* target = nullptr; next = mobj->itnext; @@ -235,36 +235,36 @@ void K_drawTargetHUD(const vector3_t* origin, player_t* player) continue; } - caps = &capsuleList[capsuleListLen]; + target = &targetList[targetListLen]; - caps->mobj = mobj; - caps->point.x = R_InterpolateFixed(mobj->old_x, mobj->x); - caps->point.y = R_InterpolateFixed(mobj->old_y, mobj->y); - caps->point.z = R_InterpolateFixed(mobj->old_z, mobj->z); - caps->point.z += (mobj->height >> 1); - caps->camDist = R_PointToDist2(origin->x, origin->y, caps->point.x, caps->point.y); + target->mobj = mobj; + target->point.x = R_InterpolateFixed(mobj->old_x, mobj->x); + target->point.y = R_InterpolateFixed(mobj->old_y, mobj->y); + target->point.z = R_InterpolateFixed(mobj->old_z, mobj->z); + target->point.z += (mobj->height >> 1); + target->camDist = R_PointToDist2(origin->x, origin->y, target->point.x, target->point.y); - capsuleListLen++; + targetListLen++; - if (capsuleListLen >= kMaxCapsuleHUD) + if (targetListLen >= kMaxTargetHUD) { break; } } - if (capsuleListLen > 0) + if (targetListLen > 0) { // Sort by distance from camera. - if (capsuleListLen > 1) + if (targetListLen > 1) { - for (i = 0; i < capsuleListLen - 1; i++) + for (i = 0; i < targetListLen - 1; i++) { std::size_t swap = i; - for (j = i + 1; j < capsuleListLen; j++) + for (j = i + 1; j < targetListLen; j++) { - capsuletracking_t* cj = &capsuleList[j]; - capsuletracking_t* cSwap = &capsuleList[swap]; + TargetTracking* cj = &targetList[j]; + TargetTracking* cSwap = &targetList[swap]; if (cj->camDist > cSwap->camDist) { @@ -274,16 +274,16 @@ void K_drawTargetHUD(const vector3_t* origin, player_t* player) if (swap != i) { - capsuletracking_t temp = capsuleList[swap]; - capsuleList[swap] = capsuleList[i]; - capsuleList[i] = temp; + TargetTracking temp = targetList[swap]; + targetList[swap] = targetList[i]; + targetList[i] = temp; } } } - for (i = 0; i < capsuleListLen; i++) + for (i = 0; i < targetListLen; i++) { - K_DrawCapsuleTracking(&capsuleList[i]); + K_DrawTargetTracking(&targetList[i]); } } } From e79ff76758bd25e03f89a8051889c183dd6993b7 Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 21 Feb 2023 19:51:56 -0800 Subject: [PATCH 5/7] k_hud_track.cpp: refactor to use C++ STL - Use std::vector instead of fixed size array. - Use std::sort instead of custom sorting algorithm. --- src/k_hud.c | 2 +- src/k_hud.h | 2 +- src/k_hud_track.cpp | 77 ++++++++++----------------------------------- 3 files changed, 19 insertions(+), 62 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 5fbc5b1a3..86d36051c 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -832,7 +832,7 @@ INT32 POSI2_X, POSI2_Y; INT32 TCOOL_X, TCOOL_Y; // This version of the function was prototyped in Lua by Nev3r ... a HUGE thank you goes out to them! -void K_ObjectTracking(trackingResult_t *result, vector3_t *point, boolean reverse) +void K_ObjectTracking(trackingResult_t *result, const vector3_t *point, boolean reverse) { #define NEWTAN(x) FINETANGENT(((x + ANGLE_90) >> ANGLETOFINESHIFT) & 4095) // tan function used by Lua #define NEWCOS(x) FINECOSINE((x >> ANGLETOFINESHIFT) & FINEMASK) diff --git a/src/k_hud.h b/src/k_hud.h index 7d2b5354a..00839ed97 100644 --- a/src/k_hud.h +++ b/src/k_hud.h @@ -34,7 +34,7 @@ struct trackingResult_t fixed_t fov; }; -void K_ObjectTracking(trackingResult_t *result, vector3_t *point, boolean reverse); +void K_ObjectTracking(trackingResult_t *result, const vector3_t *point, boolean reverse); const char *K_GetItemPatch(UINT8 item, boolean tiny); void K_LoadKartHUDGraphics(void); diff --git a/src/k_hud_track.cpp b/src/k_hud_track.cpp index a3b0be780..c4063cccf 100644 --- a/src/k_hud_track.cpp +++ b/src/k_hud_track.cpp @@ -1,5 +1,6 @@ #include #include +#include #include "k_hud.h" #include "m_fixed.h" @@ -19,12 +20,12 @@ struct TargetTracking fixed_t camDist; }; -void K_DrawTargetTracking(TargetTracking* target) +void K_DrawTargetTracking(const TargetTracking& target) { trackingResult_t result = {}; int32_t timer = 0; - K_ObjectTracking(&result, &target->point, false); + K_ObjectTracking(&result, &target.point, false); if (result.onScreen == false) { @@ -72,7 +73,7 @@ void K_DrawTargetTracking(TargetTracking* target) borderWin.y = screenSize.y - borderSize; arrowDir.x = 0; - arrowDir.y = P_MobjFlip(target->mobj) * FRACUNIT; + arrowDir.y = P_MobjFlip(target.mobj) * FRACUNIT; // Simply pointing towards the result doesn't work, so inaccurate hack... borderDir.x = FixedMul( @@ -171,12 +172,12 @@ void K_DrawTargetTracking(TargetTracking* target) { // Draw simple overlay. const fixed_t farDistance = 1280 * mapobjectscale; - bool useNear = (target->camDist < farDistance); + bool useNear = (target.camDist < farDistance); patch_t* targetPatch = nullptr; vector2_t targetPos = {}; - bool visible = P_CheckSight(stplyr->mo, target->mobj); + bool visible = P_CheckSight(stplyr->mo, target.mobj); if (visible == false && (leveltime & 1)) { @@ -209,20 +210,13 @@ void K_DrawTargetTracking(TargetTracking* target) void K_drawTargetHUD(const vector3_t* origin, player_t* player) { - constexpr std::size_t kMaxTargetHUD = 32; - - std::size_t i, j; - - TargetTracking targetList[kMaxTargetHUD]; - std::size_t targetListLen = 0; + std::vector targetList; mobj_t* mobj = nullptr; mobj_t* next = nullptr; for (mobj = trackercap; mobj; mobj = next) { - TargetTracking* target = nullptr; - next = mobj->itnext; if (mobj->health <= 0) @@ -235,55 +229,18 @@ void K_drawTargetHUD(const vector3_t* origin, player_t* player) continue; } - target = &targetList[targetListLen]; + vector3_t pos = { + R_InterpolateFixed(mobj->old_x, mobj->x), + R_InterpolateFixed(mobj->old_y, mobj->y), + R_InterpolateFixed(mobj->old_z, mobj->z) + (mobj->height >> 1), + }; - target->mobj = mobj; - target->point.x = R_InterpolateFixed(mobj->old_x, mobj->x); - target->point.y = R_InterpolateFixed(mobj->old_y, mobj->y); - target->point.z = R_InterpolateFixed(mobj->old_z, mobj->z); - target->point.z += (mobj->height >> 1); - target->camDist = R_PointToDist2(origin->x, origin->y, target->point.x, target->point.y); - - targetListLen++; - - if (targetListLen >= kMaxTargetHUD) - { - break; - } + targetList.push_back({mobj, pos, R_PointToDist2(origin->x, origin->y, pos.x, pos.y)}); } - if (targetListLen > 0) - { - // Sort by distance from camera. - if (targetListLen > 1) - { - for (i = 0; i < targetListLen - 1; i++) - { - std::size_t swap = i; + // Sort by distance from camera. Further trackers get + // drawn first so nearer ones draw over them. + std::sort(targetList.begin(), targetList.end(), [](const auto& a, const auto& b) { return a.camDist > b.camDist; }); - for (j = i + 1; j < targetListLen; j++) - { - TargetTracking* cj = &targetList[j]; - TargetTracking* cSwap = &targetList[swap]; - - if (cj->camDist > cSwap->camDist) - { - swap = j; - } - } - - if (swap != i) - { - TargetTracking temp = targetList[swap]; - targetList[swap] = targetList[i]; - targetList[i] = temp; - } - } - } - - for (i = 0; i < targetListLen; i++) - { - K_DrawTargetTracking(&targetList[i]); - } - } + std::for_each(targetList.cbegin(), targetList.cend(), K_DrawTargetTracking); } From 4adf585590d1af07188f4736d43be4da7225a6ed Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 21 Feb 2023 20:08:00 -0800 Subject: [PATCH 6/7] Give TARGET HUD tracking to UFO Catcher --- src/k_hud.c | 5 +---- src/k_hud_track.cpp | 15 ++++++++++++++- src/p_mobj.c | 1 + 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 86d36051c..942405640 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -3274,10 +3274,7 @@ static void K_drawKartNameTags(void) } } - if (battlecapsules == true) - { - K_drawTargetHUD(&c, stplyr); - } + K_drawTargetHUD(&c, stplyr); for (i = 0; i < MAXPLAYERS; i++) { diff --git a/src/k_hud_track.cpp b/src/k_hud_track.cpp index c4063cccf..8a04dd7ae 100644 --- a/src/k_hud_track.cpp +++ b/src/k_hud_track.cpp @@ -206,6 +206,19 @@ void K_DrawTargetTracking(const TargetTracking& target) } } +bool is_object_tracking_target(const mobj_t* mobj) +{ + switch (mobj->type) + { + case MT_BATTLECAPSULE: + case MT_SPECIAL_UFO: + return true; + + default: + return false; + } +} + }; // namespace void K_drawTargetHUD(const vector3_t* origin, player_t* player) @@ -224,7 +237,7 @@ void K_drawTargetHUD(const vector3_t* origin, player_t* player) continue; } - if (mobj->type != MT_BATTLECAPSULE) + if (is_object_tracking_target(mobj) == false) { continue; } diff --git a/src/p_mobj.c b/src/p_mobj.c index 707f10a17..67c4e95d6 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -5247,6 +5247,7 @@ static boolean P_IsTrackerType(INT32 type) // Primarily for minimap data, handle with care case MT_SPB: case MT_BATTLECAPSULE: + case MT_SPECIAL_UFO: return true; default: From 75c9ee253e9ee2cb6c5d36417715a60ce341974d Mon Sep 17 00:00:00 2001 From: James R Date: Tue, 21 Feb 2023 21:09:32 -0800 Subject: [PATCH 7/7] k_hud_track.cpp: only draw TARGET text in 1P or 2P splitscreen --- src/k_hud.c | 8 ++++++++ src/k_hud.h | 1 + src/k_hud_track.cpp | 27 +++++++++++++++++++-------- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/src/k_hud.c b/src/k_hud.c index 942405640..4fe7f352d 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -177,6 +177,7 @@ static patch_t *kp_trickcool[2]; patch_t *kp_capsuletarget_arrow[2][2]; patch_t *kp_capsuletarget_icon[2]; patch_t *kp_capsuletarget_far[2]; +patch_t *kp_capsuletarget_far_text[2]; patch_t *kp_capsuletarget_near[8]; void K_LoadKartHUDGraphics(void) @@ -665,6 +666,13 @@ void K_LoadKartHUDGraphics(void) } } + sprintf(buffer, "HUDCAPDx"); + for (i = 0; i < 2; i++) + { + buffer[7] = '0'+i; + HU_UpdatePatch(&kp_capsuletarget_far_text[i], "%s", buffer); + } + sprintf(buffer, "HUDCAPCx"); for (i = 0; i < 2; i++) { diff --git a/src/k_hud.h b/src/k_hud.h index 00839ed97..b80760c2c 100644 --- a/src/k_hud.h +++ b/src/k_hud.h @@ -50,6 +50,7 @@ extern patch_t *kp_facehighlight[8]; extern patch_t *kp_capsuletarget_arrow[2][2]; extern patch_t *kp_capsuletarget_icon[2]; extern patch_t *kp_capsuletarget_far[2]; +extern patch_t *kp_capsuletarget_far_text[2]; extern patch_t *kp_capsuletarget_near[8]; #ifdef __cplusplus diff --git a/src/k_hud_track.cpp b/src/k_hud_track.cpp index 8a04dd7ae..beaaea31f 100644 --- a/src/k_hud_track.cpp +++ b/src/k_hud_track.cpp @@ -174,7 +174,6 @@ void K_DrawTargetTracking(const TargetTracking& target) const fixed_t farDistance = 1280 * mapobjectscale; bool useNear = (target.camDist < farDistance); - patch_t* targetPatch = nullptr; vector2_t targetPos = {}; bool visible = P_CheckSight(stplyr->mo, target.mobj); @@ -188,21 +187,33 @@ void K_DrawTargetTracking(const TargetTracking& target) targetPos.x = result.x; targetPos.y = result.y; + auto draw = [&](patch_t* patch) + { + V_DrawFixedPatch( + targetPos.x - ((patch->width << FRACBITS) >> 1), + targetPos.y - ((patch->height << FRACBITS) >> 1), + FRACUNIT, + V_SPLITSCREEN, + patch, + nullptr + ); + }; + if (useNear == true) { timer = (leveltime / 2); - targetPatch = kp_capsuletarget_near[timer % 8]; + draw(kp_capsuletarget_near[timer % 8]); } else { timer = (leveltime / 3); - targetPatch = kp_capsuletarget_far[timer & 1]; + draw(kp_capsuletarget_far[timer & 1]); + + if (r_splitscreen <= 1) + { + draw(kp_capsuletarget_far_text[timer & 1]); + } } - - targetPos.x -= (targetPatch->width << FRACBITS) >> 1; - targetPos.y -= (targetPatch->height << FRACBITS) >> 1; - - V_DrawFixedPatch(targetPos.x, targetPos.y, FRACUNIT, V_SPLITSCREEN, targetPatch, nullptr); } }