diff --git a/src/d_netcmd.c b/src/d_netcmd.c index e0491a74c..3085d4ee4 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -545,8 +545,6 @@ static CV_PossibleValue_t perfstats_cons_t[] = { }; consvar_t cv_perfstats = CVAR_INIT ("perfstats", "Off", 0, perfstats_cons_t, NULL); -consvar_t cv_director = CVAR_INIT ("director", "Off", 0, CV_OnOff, NULL); - consvar_t cv_schedule = CVAR_INIT ("schedule", "On", CV_NETVAR|CV_CALL, CV_OnOff, Schedule_OnChange); consvar_t cv_automate = CVAR_INIT ("automate", "On", CV_NETVAR, CV_OnOff, NULL); @@ -1053,8 +1051,6 @@ void D_RegisterClientCommands(void) CV_RegisterVar(&cv_scr_width); CV_RegisterVar(&cv_scr_height); - CV_RegisterVar(&cv_director); - CV_RegisterVar(&cv_soundtest); CV_RegisterVar(&cv_invincmusicfade); diff --git a/src/d_netcmd.h b/src/d_netcmd.h index 61171d393..a126de023 100644 --- a/src/d_netcmd.h +++ b/src/d_netcmd.h @@ -128,8 +128,6 @@ extern consvar_t cv_sleep; extern consvar_t cv_perfstats; -extern consvar_t cv_director; - extern consvar_t cv_schedule; extern consvar_t cv_livestudioaudience; diff --git a/src/g_game.c b/src/g_game.c index 136ca8a1d..9dc0b2fc8 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -61,6 +61,7 @@ #include "k_specialstage.h" #include "k_bot.h" #include "doomstat.h" +#include "k_director.h" #ifdef HAVE_DISCORDRPC #include "discord.h" @@ -1164,6 +1165,28 @@ void G_BuildTiccmd(ticcmd_t *cmd, INT32 realtics, UINT8 ssplayer) goto aftercmdinput; } + if (displayplayers[forplayer] != g_localplayers[forplayer]) + { + if (M_MenuButtonPressed(forplayer, MBT_A)) + { + G_AdjustView(ssplayer, 1, true); + K_ToggleDirector(false); + } + + if (M_MenuButtonPressed(forplayer, MBT_X)) + { + G_AdjustView(ssplayer, -1, true); + K_ToggleDirector(false); + } + + if (M_MenuButtonPressed(forplayer, MBT_R)) + { + K_ToggleDirector(true); + } + + goto aftercmdinput; + } + if (K_PlayerUsesBotMovement(player)) { // Bot ticcmd is generated by K_BuildBotTiccmd @@ -1352,16 +1375,6 @@ aftercmdinput: cmd->throwdir = -KART_FULLTURN; G_DoAnglePrediction(cmd, realtics, ssplayer, player); - - // Reset away view if a command is given. - if ((cmd->forwardmove || cmd->buttons) - && !r_splitscreen && displayplayers[0] != consoleplayer && ssplayer == 1) - { - // Call ViewpointSwitch hooks here. - // The viewpoint was forcibly changed. - LUA_HookViewpointSwitch(player, &players[consoleplayer], true); - displayplayers[0] = consoleplayer; - } } ticcmd_t *G_CopyTiccmd(ticcmd_t* dest, const ticcmd_t* src, const size_t n) @@ -1695,44 +1708,8 @@ boolean G_Responder(event_t *ev) return true; // chat ate the event } - // allow spy mode changes even during the demo - if (gamestate == GS_LEVEL && ev->type == ev_keydown - && (ev->data1 == KEY_F12 /*|| ev->data1 == gamecontrol[0][gc_viewpoint][0] || ev->data1 == gamecontrol[0][gc_viewpoint][1]*/)) - { - if (!demo.playback && (r_splitscreen || !netgame)) - g_localplayers[0] = consoleplayer; - else - { - G_AdjustView(1, 1, true); - - // change statusbar also if playing back demo - if (demo.quitafterplaying) - ST_changeDemoView(); - - return true; - } - } - if (gamestate == GS_LEVEL && ev->type == ev_keydown && multiplayer && demo.playback && !demo.freecam) { - /* - if (ev->data1 == gamecontrol[1][gc_viewpoint][0] || ev->data1 == gamecontrol[1][gc_viewpoint][1]) - { - G_AdjustView(2, 1, true); - return true; - } - else if (ev->data1 == gamecontrol[2][gc_viewpoint][0] || ev->data1 == gamecontrol[2][gc_viewpoint][1]) - { - G_AdjustView(3, 1, true); - return true; - } - else if (ev->data1 == gamecontrol[3][gc_viewpoint][0] || ev->data1 == gamecontrol[3][gc_viewpoint][1]) - { - G_AdjustView(4, 1, true); - return true; - } - */ - // Allow pausing if ( //ev->data1 == gamecontrol[0][gc_pause][0] @@ -2026,6 +2003,10 @@ void G_ResetView(UINT8 viewnum, INT32 playernum, boolean onlyactive) if (viewnum == 1 && demo.playback) consoleplayer = displayplayers[0]; + + // change statusbar also if playing back demo + if (demo.quitafterplaying) + ST_changeDemoView(); } // diff --git a/src/k_director.c b/src/k_director.c index 4f5737b4b..51158f8eb 100644 --- a/src/k_director.c +++ b/src/k_director.c @@ -25,6 +25,7 @@ void K_InitDirector(void) { INT32 playernum; + directorinfo.active = false; directorinfo.cooldown = SWITCHTIME; directorinfo.freeze = 0; directorinfo.attacker = 0; @@ -109,6 +110,11 @@ static boolean K_CanSwitchDirector(void) return false; } + if (!directorinfo.active) + { + return false; + } + return true; } @@ -218,11 +224,6 @@ void K_UpdateDirector(void) INT32 *displayplayerp = &displayplayers[0]; INT32 targetposition; - if (!cv_director.value) - { - return; - } - K_UpdateDirectorPositions(); if (directorinfo.cooldown > 0) { @@ -299,3 +300,13 @@ void K_UpdateDirector(void) break; } } + +void K_ToggleDirector(boolean active) +{ + if (directorinfo.active != active) + { + directorinfo.cooldown = 0; // switch immediately + } + + directorinfo.active = active; +} diff --git a/src/k_director.h b/src/k_director.h index 29bb01721..47b4b2265 100644 --- a/src/k_director.h +++ b/src/k_director.h @@ -12,6 +12,7 @@ extern "C" { extern struct directorinfo { + boolean active; // is view point switching enabled? tic_t cooldown; // how long has it been since we last switched? tic_t freeze; // when nonzero, fixed switch pending, freeze logic! INT32 attacker; // who to switch to when freeze delay elapses @@ -26,6 +27,7 @@ void K_InitDirector(void); void K_UpdateDirector(void); void K_DrawDirectorDebugger(void); void K_DirectorFollowAttack(player_t *player, mobj_t *inflictor, mobj_t *source); +void K_ToggleDirector(boolean active); #ifdef __cplusplus } // extern "C" diff --git a/src/k_hud.c b/src/k_hud.c index 2edb1f3d5..d53a39d95 100644 --- a/src/k_hud.c +++ b/src/k_hud.c @@ -4639,6 +4639,33 @@ K_drawMiniPing (void) } } +static void K_DrawDirectorButton(INT32 idx, const char *label, patch_t *kp[2]) +{ + const INT32 flags = V_SNAPTORIGHT | V_SLIDEIN; + const INT32 textflags = flags | V_6WIDTHSPACE | V_ALLOWLOWERCASE; + + const UINT8 anim_duration = 16; + const UINT8 anim = (leveltime % (anim_duration * 2)) < anim_duration; + + const INT32 x = BASEVIDWIDTH - 60; + const INT32 y = BASEVIDHEIGHT - 70 + (idx * 16); + + V_DrawScaledPatch(x, y - 4, flags, kp[anim]); + V_DrawRightAlignedThinString(x - 2, y, textflags, label); +} + +static void K_drawDirectorHUD(void) +{ + if (!LUA_HudEnabled(hud_textspectator)) + { + return; + } + + K_DrawDirectorButton(0, "Next Player", kp_button_a[0]); + K_DrawDirectorButton(1, "Prev Player", kp_button_x[0]); + K_DrawDirectorButton(2, "Director", kp_button_r); +} + static void K_drawDistributionDebugger(void) { itemroulette_t rouletteData = {0}; @@ -4957,6 +4984,11 @@ void K_drawKartHUD(void) K_drawMiniPing(); } + if (displayplayers[viewnum] != g_localplayers[viewnum]) + { + K_drawDirectorHUD(); + } + if (cv_kartdebugdistribution.value) K_drawDistributionDebugger(); diff --git a/src/p_mobj.c b/src/p_mobj.c index 52e48da51..d9920a928 100644 --- a/src/p_mobj.c +++ b/src/p_mobj.c @@ -46,6 +46,7 @@ #include "k_collide.h" #include "k_objects.h" #include "k_grandprix.h" +#include "k_director.h" static CV_PossibleValue_t CV_BobSpeed[] = {{0, "MIN"}, {4*FRACUNIT, "MAX"}, {0, NULL}}; consvar_t cv_movebob = CVAR_INIT ("movebob", "1.0", CV_FLOAT|CV_SAVE, CV_BobSpeed, NULL); @@ -11827,6 +11828,22 @@ void P_SpawnPlayer(INT32 playernum) K_SpawnPlayerBattleBumpers(p); } } + + // I'm not refactoring the loop at the top of this file. + pcount = 0; + + for (i = 0; i < MAXPLAYERS; ++i) + { + if (G_CouldView(i)) + { + pcount++; + } + } + + // Spectating when there is literally any other player in + // the level enables director cam. + // TODO: how do we support splitscreen? + K_ToggleDirector(players[consoleplayer].spectator && pcount > 0); } void P_AfterPlayerSpawn(INT32 playernum) diff --git a/src/st_stuff.c b/src/st_stuff.c index 01350c6ce..289a6c3a7 100644 --- a/src/st_stuff.c +++ b/src/st_stuff.c @@ -1095,6 +1095,8 @@ void ST_preLevelTitleCardDrawer(void) // static void ST_overlayDrawer(void) { + const UINT8 viewnum = R_GetViewNumber(); + // hu_showscores = auto hide score/time/rings when tab rankings are shown if (!(hu_showscores && (netgame || multiplayer))) { @@ -1135,7 +1137,7 @@ static void ST_overlayDrawer(void) if (!hu_showscores && netgame && !mapreset) { - if (stplyr->spectator && LUA_HudEnabled(hud_textspectator)) + if (stplyr->spectator && displayplayers[viewnum] == g_localplayers[viewnum] && LUA_HudEnabled(hud_textspectator)) { const char *itemtxt = M_GetText("Item - Join Game");