Merge branch 'spectator-rework' into 'master'

Rework spectator mode

See merge request KartKrew/Kart!980
This commit is contained in:
Oni 2023-02-28 05:08:50 +00:00
commit 85f3d66f2c
8 changed files with 97 additions and 58 deletions

View file

@ -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);

View file

@ -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;

View file

@ -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();
}
//

View file

@ -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;
}

View file

@ -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"

View file

@ -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();

View file

@ -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)

View file

@ -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");