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_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..4fe7f352d 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -174,10 +174,11 @@ 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_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++) { @@ -832,7 +840,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) @@ -3175,217 +3183,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; @@ -3485,84 +3282,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 = kitemcap; 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++) { @@ -3927,7 +3647,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_hud.h b/src/k_hud.h index 9b783f710..b80760c2c 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); @@ -44,8 +44,14 @@ 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_far_text[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..beaaea31f --- /dev/null +++ b/src/k_hud_track.cpp @@ -0,0 +1,270 @@ +#include +#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 TargetTracking +{ + mobj_t* mobj; + vector3_t point; + fixed_t camDist; +}; + +void K_DrawTargetTracking(const TargetTracking& target) +{ + trackingResult_t result = {}; + int32_t timer = 0; + + K_ObjectTracking(&result, &target.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 targetPos = {}; + patch_t* targetPatch = 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(target.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; + } + + targetPatch = 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; + + 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; + + targetPos.x -= (targetPatch->width << FRACBITS) >> 1; + targetPos.y -= (targetPatch->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(targetPos.x, targetPos.y, FRACUNIT, V_SPLITSCREEN, targetPatch, 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 = (target.camDist < farDistance); + + vector2_t targetPos = {}; + + bool visible = P_CheckSight(stplyr->mo, target.mobj); + + if (visible == false && (leveltime & 1)) + { + // Flicker when not visible. + return; + } + + 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); + draw(kp_capsuletarget_near[timer % 8]); + } + else + { + timer = (leveltime / 3); + draw(kp_capsuletarget_far[timer & 1]); + + if (r_splitscreen <= 1) + { + draw(kp_capsuletarget_far_text[timer & 1]); + } + } + } +} + +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) +{ + std::vector targetList; + + mobj_t* mobj = nullptr; + mobj_t* next = nullptr; + + for (mobj = trackercap; mobj; mobj = next) + { + next = mobj->itnext; + + if (mobj->health <= 0) + { + continue; + } + + if (is_object_tracking_target(mobj) == false) + { + continue; + } + + 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), + }; + + targetList.push_back({mobj, pos, R_PointToDist2(origin->x, origin->y, pos.x, pos.y)}); + } + + // 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; }); + + std::for_each(targetList.cbegin(), targetList.cend(), K_DrawTargetTracking); +} diff --git a/src/k_kart.c b/src/k_kart.c index 1622ce27d..45a8eb900 100644 --- a/src/k_kart.c +++ b/src/k_kart.c @@ -5816,7 +5816,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; @@ -6108,7 +6108,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 2dafb177a..e04fe01c5 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; @@ -5206,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) @@ -5256,16 +5236,34 @@ 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: + case MT_SPECIAL_UFO: + return true; + + default: + return false; + } +} + +static void P_LinkTracker(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); @@ -5276,12 +5274,12 @@ 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 = &kitemcap); mo; mo = *(p = &mo->itnext)) + for (mo = *(p = &trackercap); mo; mo = *(p = &mo->itnext)) { if (mo != thing) continue; @@ -5292,20 +5290,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 = kitemcap; mobj; mobj = next) - { - next = mobj->itnext; - P_SetTarget(&mobj->itnext, NULL); - } - P_SetTarget(&kitemcap, NULL); -} - void P_RunOverlays(void) { // run overlays @@ -9808,9 +9792,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; } @@ -10051,9 +10032,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); @@ -10967,6 +10945,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; } @@ -11109,8 +11091,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 323bcc4ae..dd448841e 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,20 +504,16 @@ struct actioncache_t extern actioncache_t actioncachehead; -extern mobj_t *kitemcap; +extern mobj_t *trackercap; extern mobj_t *waypointcap; 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_RunKartItems(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 86c4ac3b3..453eae49c 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -2195,7 +2195,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; @@ -3614,7 +3614,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); @@ -4255,7 +4255,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..91be6d183 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]; } @@ -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();