diff --git a/src/g_demo.cpp b/src/g_demo.cpp index 9ea033f53..405163790 100644 --- a/src/g_demo.cpp +++ b/src/g_demo.cpp @@ -1548,8 +1548,9 @@ skippedghosttic: if (*g->p == DEMOMARKER) { g->mo->momx = g->mo->momy = g->mo->momz = 0; -#if 1 // freeze frame (maybe more useful for time attackers) +#if 0 // freeze frame (maybe more useful for time attackers) (2024-03-11: you leave it behind anyway!) g->mo->colorized = true; + g->mo->fuse = 10*TICRATE; if (follow) follow->colorized = true; #else // dissapearing act diff --git a/src/k_director.cpp b/src/k_director.cpp index b50d4a11b..764eac4a3 100644 --- a/src/k_director.cpp +++ b/src/k_director.cpp @@ -22,6 +22,11 @@ extern "C" consvar_t cv_devmode_screen; +static bool race_rules() +{ + return gametyperules & GTR_CIRCUIT; +} + #define SWITCHTIME TICRATE * 5 // cooldown between unforced switches #define BOREDOMTIME 3 * TICRATE / 2 // how long until players considered far apart? #define TRANSFERTIME TICRATE // how long to delay reaction shots? @@ -86,7 +91,9 @@ struct DirectorInfo } // if there's only one player left in the list, just switch to that player - if (playerstat[0].sorted != -1 && playerstat[1].sorted == -1) + if (playerstat[0].sorted != -1 && (playerstat[1].sorted == -1 || + // TODO: Battle; I just threw this together quick. Focus on leader. + !race_rules())) { change(playerstat[0].sorted, false); return; diff --git a/src/k_hud.cpp b/src/k_hud.cpp index d5d16ab49..9d80582f6 100644 --- a/src/k_hud.cpp +++ b/src/k_hud.cpp @@ -4425,27 +4425,28 @@ static void K_drawKartMinimap(void) demoghost *g = ghosts; while (g) { - if (g->mo->skin) - skin = ((skin_t*)g->mo->skin)-skins; - else - skin = 0; - - workingPic = R_CanShowSkinInDemo(skin) ? faceprefix[skin][FACE_MINIMAP] : kp_unknownminimap; - - if (g->mo->color) + if (g->mo && !P_MobjWasRemoved(g->mo) && g->mo->skin) { - if (g->mo->colorized) - colormap = R_GetTranslationColormap(TC_RAINBOW, static_cast(g->mo->color), GTC_CACHE); + skin = ((skin_t*)g->mo->skin)-skins; + + workingPic = R_CanShowSkinInDemo(skin) ? faceprefix[skin][FACE_MINIMAP] : kp_unknownminimap; + + if (g->mo->color) + { + if (g->mo->colorized) + colormap = R_GetTranslationColormap(TC_RAINBOW, static_cast(g->mo->color), GTC_CACHE); + else + colormap = R_GetTranslationColormap(skin, static_cast(g->mo->color), GTC_CACHE); + } else - colormap = R_GetTranslationColormap(skin, static_cast(g->mo->color), GTC_CACHE); + colormap = NULL; + + 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, workingPic, colormap); } - else - colormap = NULL; - 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, workingPic, colormap); g = g->next; } } diff --git a/src/k_menu.h b/src/k_menu.h index a9348442d..ff21a8ee2 100644 --- a/src/k_menu.h +++ b/src/k_menu.h @@ -547,6 +547,7 @@ typedef enum playback_view2, playback_view3, playback_view4, + playback_director, playback_freecam, playback_quit } playback_e; diff --git a/src/k_respawn.c b/src/k_respawn.c index 6bb98db0e..d2da452db 100644 --- a/src/k_respawn.c +++ b/src/k_respawn.c @@ -509,6 +509,13 @@ static void K_MovePlayerToRespawnPoint(player_t *player) player->respawn.distanceleft = 0; } + // Almost all legitimate driving, no matter how clumsy, should be faster than death in TA. + // Advance only as far as we need to prevent respawn loops! + if (modeattacking) + { + player->respawn.distanceleft = 0; + } + player->respawn.wp = player->respawn.wp->nextwaypoints[nwp]; K_RespawnAtWaypoint(player, player->respawn.wp); diff --git a/src/menus/transient/pause-replay.c b/src/menus/transient/pause-replay.c index 411643c46..cc95e6d83 100644 --- a/src/menus/transient/pause-replay.c +++ b/src/menus/transient/pause-replay.c @@ -10,9 +10,22 @@ #include "../../d_main.h" // D_StartTitle #include "../../k_credits.h" #include "../../g_demo.h" +#include "../../k_director.h" static void M_PlaybackTick(void); +// This is barebones, just toggle director on all screens. +static void M_PlaybackToggleDirector(INT32 choice) +{ + (void)choice; + + UINT8 i; + for (i = 0; i <= r_splitscreen; ++i) + { + K_ToggleDirector(i, !K_DirectorIsEnabled(i)); + } +} + menuitem_t PAUSE_PlaybackMenu[] = { {IT_CALL | IT_STRING, "Hide Menu", NULL, "M_PHIDE", {.routine = M_SelectableClearMenus}, 0, 0}, @@ -30,8 +43,9 @@ menuitem_t PAUSE_PlaybackMenu[] = {IT_ARROWS | IT_STRING, "Viewpoint 3", NULL, "M_PNVIEW", {.routine = M_PlaybackAdjustView}, 120, 0}, {IT_ARROWS | IT_STRING, "Viewpoint 4", NULL, "M_PNVIEW", {.routine = M_PlaybackAdjustView}, 136, 0}, - {IT_CALL | IT_STRING, "Toggle Free Camera", NULL, "M_PVIEWS", {.routine = M_PlaybackToggleFreecam}, 156, 0}, - {IT_CALL | IT_STRING, "Stop Playback", NULL, "M_PEXIT", {.routine = M_PlaybackQuit}, 172, 0}, + {IT_CALL | IT_STRING, "Toggle Director", NULL, "UN_IC11A", {.routine = M_PlaybackToggleDirector}, 156, 0}, + {IT_CALL | IT_STRING, "Toggle Free Camera", NULL, "M_PVIEWS", {.routine = M_PlaybackToggleFreecam}, 172, 0}, + {IT_CALL | IT_STRING, "Stop Playback", NULL, "M_PEXIT", {.routine = M_PlaybackQuit}, 188, 0}, }; menu_t PAUSE_PlaybackMenuDef = { @@ -39,7 +53,7 @@ menu_t PAUSE_PlaybackMenuDef = { NULL, 0, PAUSE_PlaybackMenu, - BASEVIDWIDTH/2 - 88, 2, + BASEVIDWIDTH/2 - 96, 2, 0, 0, MBF_UD_LR_FLIPPED, NULL, @@ -155,7 +169,7 @@ static void M_PlaybackTick(void) if (modeattacking) { - for (i = playback_viewcount; i <= playback_view4; i++) + for (i = playback_viewcount; i <= playback_director; i++) PAUSE_PlaybackMenu[i].status = IT_DISABLED; PAUSE_PlaybackMenu[playback_freecam].mvar1 = 72; @@ -166,17 +180,18 @@ static void M_PlaybackTick(void) else { PAUSE_PlaybackMenu[playback_viewcount].status = IT_ARROWS|IT_STRING; + PAUSE_PlaybackMenu[playback_freecam].status = IT_CALL|IT_STRING; for (i = 0; i <= r_splitscreen; i++) PAUSE_PlaybackMenu[playback_view1+i].status = IT_ARROWS|IT_STRING; for (i = r_splitscreen+1; i < 4; i++) PAUSE_PlaybackMenu[playback_view1+i].status = IT_DISABLED; - PAUSE_PlaybackMenu[playback_freecam].mvar1 = 156; - PAUSE_PlaybackMenu[playback_quit].mvar1 = 172; + PAUSE_PlaybackMenu[playback_freecam].mvar1 = 172; + PAUSE_PlaybackMenu[playback_quit].mvar1 = 188; //currentMenu->x = BASEVIDWIDTH/2 - 94; - currentMenu->x = BASEVIDWIDTH/2 - 88; + currentMenu->x = BASEVIDWIDTH/2 - 96; } } diff --git a/src/p_inter.c b/src/p_inter.c index fa3652788..b586c7481 100644 --- a/src/p_inter.c +++ b/src/p_inter.c @@ -2571,7 +2571,7 @@ static boolean P_KillPlayer(player_t *player, mobj_t *inflictor, mobj_t *source, return false; } - if (modeattacking) + if (modeattacking & ATTACKING_SPB) { // Death in SPB Attack is an instant loss. P_DoPlayerExit(player, PF_NOCONTEST); diff --git a/src/p_user.c b/src/p_user.c index 63bfe58ba..02eaa62fd 100644 --- a/src/p_user.c +++ b/src/p_user.c @@ -3304,10 +3304,21 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall if (turn > turnspeed) { + // TODO: this code let the panning angle flip + // depending on your camera angle when entering + // the loop. + // It caused just about every loop to look weird + // sometimes, since the camera could move + // differently than configured. + // I don't know if this behavior should ever come + // back, but in case it should, I'm leaving this + // comment here. +#if 0 if (turn < ANGLE_90) { turnspeed = -(turnspeed); } +#endif focusangle += turnspeed; } @@ -3462,7 +3473,7 @@ boolean P_MoveChaseCamera(player_t *player, camera_t *thiscam, boolean resetcall y = mo->y - FixedMul(FINESINE((angle>>ANGLETOFINESHIFT) & FINEMASK), distxy); // SRB2Kart: set camera panning - if (camstill || resetcalled || player->playerstate == PST_DEAD) + if (camstill || resetcalled || player->playerstate == PST_DEAD || player->loop.radius) pan = xpan = ypan = 0; else {