Add support for changing viewpoint via console

This isn't just a shameless console-empowerement. More precise "spying" can
benefit everybody. But especially in net-replays, this is almost necessary.
This commit is contained in:
James R 2019-02-04 03:09:40 -08:00
parent 7aa83635ae
commit ee8948d627
5 changed files with 181 additions and 12 deletions

View file

@ -129,6 +129,8 @@ static void Command_StopMovie_f(void);
static void Command_Map_f(void);
static void Command_ResetCamera_f(void);
static void Command_View_f (void);
static void Command_Addfile(void);
static void Command_ListWADS_f(void);
#ifdef DELFILE
@ -708,6 +710,11 @@ void D_RegisterClientCommands(void)
COM_AddCommand("resetcamera", Command_ResetCamera_f);
COM_AddCommand("view", Command_View_f);
COM_AddCommand("view2", Command_View_f);
COM_AddCommand("view3", Command_View_f);
COM_AddCommand("view4", Command_View_f);
COM_AddCommand("setcontrol", Command_Setcontrol_f);
COM_AddCommand("setcontrol2", Command_Setcontrol2_f);
COM_AddCommand("setcontrol3", Command_Setcontrol3_f);
@ -1885,6 +1892,138 @@ static void Command_ResetCamera_f(void)
P_ResetCamera(&players[displayplayer], &camera);
}
static INT32
RoundToValidPlayerNum (INT32 playernum)
{
INT32 playernuml, playernumr;
for (playernuml = playernum; --playernuml > 0; )
{
if (playeringame[playernuml])
break;
}
for (playernumr = playernum ;; )
{
if (++playernumr == MAXPLAYERS)
{
playernum = playernuml;
break;
}
if (playeringame[playernumr])
{
if (playernum - playernuml < playernumr - playernum)
playernum = playernuml;/* "round" down */
else
playernum = playernumr;
break;
}
}
return playernum;
}
static INT32/* Consider replacing nametonum with this */
LookupPlayer (const char *s)
{
INT32 playernum;
if (*s == '0')/* clever way to bypass atoi */
return 0;
if (( playernum = atoi(s) ))
{
playernum = max(min(playernum, MAXPLAYERS-1), 0);/* not out of range */
return playernum;
}
for (playernum = 0; playernum < MAXPLAYERS; ++playernum)
{
/* Consider strcasestr? */
/* Match name (case-insensitively) fully, or partially the start. */
if (playeringame[playernum])
if (stricmp(player_names[playernum], s) == 0 ||
strstr(player_names[playernum], s) == player_names[playernum] )
{
return playernum;
}
}
return -1;/* We can't "round" a name! */
}
#define PRINTVIEWPOINT( pre,suf ) \
CONS_Printf(pre"viewing \x84(%d) \x83%s\x80"suf".\n",\
(*displayplayerp), player_names[(*displayplayerp)]);
static void
Command_View_f (void)
{
INT32 *displayplayerp;
int viewnum;
INT32 playernum, oldplayernum;
char c;
/* easy peasy */
c = COM_Argv(0)[strlen(COM_Argv(0))-1];/* may be digit */
switch (c)
{
case '2': viewnum = 2; break;
case '3': viewnum = 3; break;
case '4': viewnum = 4; break;
default: viewnum = 1;
}
displayplayerp = G_GetDisplayplayerPtr(viewnum);
if (COM_Argc() > 1)/* switch to player */
{
if (viewnum > splitscreen+2)/* We must arrange in order. */
{
CONS_Alert(CONS_WARNING,
"You may not change viewpoints more than "
"once ahead the current number of splits. "
"Use view%d instead.\n", splitscreen+2);
return;
}
if (( playernum = LookupPlayer(COM_Argv(1)) ) == -1)
{
CONS_Alert(CONS_WARNING, "There is no player by that name!\n");
return;
}
oldplayernum = playernum;
if (!playeringame[playernum])
{
playernum = RoundToValidPlayerNum(playernum);
}
if ((*displayplayerp) == playernum)
return;
(*displayplayerp) = playernum;
G_ResetViews(viewnum);
if ((*displayplayerp) != oldplayernum)/* differ parameter */
{
if (playernum == oldplayernum)/* skipped some */
{
CONS_Alert(CONS_NOTICE,
"Another viewpoint is already set to that player.\n");
}
else
{
CONS_Alert(CONS_NOTICE, "There is no player using that slot.\n");
}
PRINTVIEWPOINT ("Now "," instead")
}
else
PRINTVIEWPOINT ("Now ",)
}
else/* print current view */
{
if (splitscreen < viewnum-1)/* We can't see those guys! */
return;
PRINTVIEWPOINT ("Currently ",)
}
}
#undef PRINTVIEWPOINT
// ========================================================================
// play a demo, add .lmp for external demos

View file

@ -1825,13 +1825,9 @@ boolean G_Responder(event_t *ev)
{
if (!splitscreen)
{
splitscreen = 1;
secondarydisplayplayer = displayplayer;
G_ResetViews(2);
P_ResetCamera(&players[secondarydisplayplayer], &camera2);
R_ExecuteSetViewSize();
return true;
}
@ -1844,13 +1840,9 @@ boolean G_Responder(event_t *ev)
{
if (splitscreen == 1)
{
splitscreen = 2;
thirddisplayplayer = displayplayer;
G_ResetViews(3);
P_ResetCamera(&players[thirddisplayplayer], &camera3);
R_ExecuteSetViewSize();
return true;
}
@ -1863,13 +1855,9 @@ boolean G_Responder(event_t *ev)
{
if (splitscreen == 2)
{
splitscreen = 3;
fourthdisplayplayer = displayplayer;
G_ResetViews(4);
P_ResetCamera(&players[fourthdisplayplayer], &camera4);
R_ExecuteSetViewSize();
return true;
}
@ -2156,6 +2144,18 @@ static INT32 G_FindView(INT32 startview)
return startview;
}
INT32 *
G_GetDisplayplayerPtr (UINT8 viewnum)
{
switch (viewnum)
{
case 2: return &secondarydisplayplayer;
case 3: return &thirddisplayplayer;
case 4: return &fourthdisplayplayer;
}
return &displayplayer;
}
//
// G_ResetViews
// Ensures all viewpoints are valid
@ -2163,6 +2163,8 @@ static INT32 G_FindView(INT32 startview)
void G_ResetViews(UINT8 viewnum)
{
INT32 tempplayer;
INT32 *displayplayerp;
camera_t *camerap;
if (!viewnum || viewnum == 1)
{
@ -2171,6 +2173,18 @@ void G_ResetViews(UINT8 viewnum)
displayplayer = G_FindView(tempplayer);
}
if (viewnum > 1 && multiplayer && demoplayback)
if (viewnum == splitscreen+2)
{
splitscreen = viewnum-1;
displayplayerp = (G_GetDisplayplayerPtr(viewnum));
camerap = (P_GetCameraPtr(viewnum));
P_ResetCamera(&players[(*displayplayerp)], camerap);
R_ExecuteSetViewSize();
}
if (splitscreen && demoplayback)
{

View file

@ -226,6 +226,8 @@ void G_EndGame(void); // moved from y_inter.c/h and renamed
void G_Ticker(boolean run);
boolean G_Responder(event_t *ev);
INT32 * G_GetDisplayplayerPtr (UINT8 viewnum);
void G_ResetViews(UINT8 viewnum);
void G_AddPlayer(INT32 playernum);

View file

@ -126,6 +126,8 @@ extern fixed_t t_cam2_dist, t_cam2_height, t_cam2_rotate;
extern fixed_t t_cam3_dist, t_cam3_height, t_cam3_rotate;
extern fixed_t t_cam4_dist, t_cam4_height, t_cam4_rotate;
camera_t * P_GetCameraPtr (UINT8 viewnum);
fixed_t P_GetPlayerHeight(player_t *player);
fixed_t P_GetPlayerSpinHeight(player_t *player);
void P_AddPlayerScore(player_t *player, UINT32 amount);

View file

@ -8124,6 +8124,18 @@ fixed_t t_cam4_rotate = -42;
#define MAXCAMERADIST 140*FRACUNIT // Max distance the camera can be in front of the player (2D mode)
camera_t *
P_GetCameraPtr (UINT8 viewnum)
{
switch (viewnum)
{
case 2: return &camera2;
case 3: return &camera3;
case 4: return &camera4;
}
return &camera;
}
void P_ResetCamera(player_t *player, camera_t *thiscam)
{
tic_t tries = 0;