Fix spectate button, allow respawning local players 2-4, allow respawn to be binded to button

This commit is contained in:
NepDisk 2025-03-24 18:54:58 -04:00
parent ceed76cc73
commit 35a7f420af
5 changed files with 85 additions and 10 deletions

View file

@ -179,7 +179,11 @@ static void Command_ListWADS_f(void);
static void Command_ListDoomednums_f(void);
static void Command_RunSOC(void);
static void Command_Pause(void);
static void Command_Respawn(void);
static void Command_Respawn2(void);
static void Command_Respawn3(void);
static void Command_Respawn4(void);
static void Command_Version_f(void);
#ifdef UPDATE_ALERT
@ -740,7 +744,11 @@ void D_RegisterServerCommands(void)
COM_AddCommand("runsoc", Command_RunSOC);
COM_AddCommand("pause", Command_Pause);
COM_AddCommand("respawn", Command_Respawn);
COM_AddCommand("respawn2", Command_Respawn2);
COM_AddCommand("respawn3", Command_Respawn3);
COM_AddCommand("respawn4", Command_Respawn4);
COM_AddCommand("gametype", Command_ShowGametype_f);
COM_AddCommand("version", Command_Version_f);
@ -3317,34 +3325,58 @@ static void Got_Pause(UINT8 **cp, INT32 playernum)
}
// Command for stuck characters in netgames, griefing, etc.
static void Command_Respawn(void)
static void HandleRespawnCommand(UINT8 localplayer)
{
UINT8 buf[4];
UINT8 *cp = buf;
if (!(gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING))
{
CONS_Printf(M_GetText("You must be in a level to use this.\n"));
return;
}
if (players[consoleplayer].mo && !P_IsObjectOnGround(players[consoleplayer].mo)) // KART: Nice try, but no, you won't be cheesing spb anymore.
if (players[g_localplayers[localplayer]].mo && !P_IsObjectOnGround(players[g_localplayers[localplayer]].mo)) // KART: Nice try, but no, you won't be cheesing spb anymore.
{
CONS_Printf(M_GetText("You must be on the floor to use this.\n"));
return;
}
// todo: this probably isnt necessary anymore with v2
if (players[consoleplayer].mo && (P_PlayerInPain(&players[consoleplayer]) || spbplace == players[consoleplayer].position)) // KART: Nice try, but no, you won't be cheesing spb anymore (x2)
if (players[g_localplayers[localplayer]].mo && (P_PlayerInPain(&players[g_localplayers[localplayer]]) || spbplace == players[g_localplayers[localplayer]].position)) // KART: Nice try, but no, you won't be cheesing spb anymore (x2)
{
CONS_Printf(M_GetText("Nice try.\n"));
return;
}
WRITEINT32(cp, consoleplayer);
SendNetXCmd(XD_RESPAWN, &buf, 4);
if (localplayer != 0 && !g_localplayers[localplayer])
{
CONS_Printf(M_GetText("There is no player to respawn.\n"));
return;
}
WRITEINT32(cp, g_localplayers[localplayer]);
SendNetXCmdForPlayer(localplayer, XD_RESPAWN, &buf, sizeof(buf));
}
// Command for stuck characters in netgames, griefing, etc.
static void Command_Respawn(void)
{
HandleRespawnCommand(0);
}
static void Command_Respawn2(void)
{
HandleRespawnCommand(1);
}
static void Command_Respawn3(void)
{
HandleRespawnCommand(2);
}
static void Command_Respawn4(void)
{
HandleRespawnCommand(3);
}
static void Got_Respawn(UINT8 **cp, INT32 playernum)
@ -3366,7 +3398,7 @@ static void Got_Respawn(UINT8 **cp, INT32 playernum)
if (!P_IsObjectOnGround(players[respawnplayer].mo))
return;
P_DamageMobj(players[respawnplayer].mo, NULL, NULL, 1,DMG_INSTAKILL);
P_DamageMobj(players[respawnplayer].mo, NULL, NULL, 1, DMG_INSTAKILL);
demo_extradata[playernum] |= DXD_RESPAWN;
}
}

View file

@ -1450,6 +1450,8 @@ boolean G_IsTitleCardAvailable(void)
INT32 pausedelay = 0;
boolean pausebreakkey = false;
static INT32 camtoggledelay[MAXSPLITSCREENPLAYERS];
static INT32 spectatedelay[MAXSPLITSCREENPLAYERS];
static INT32 respawndelay[MAXSPLITSCREENPLAYERS];
//
// G_Responder
@ -1678,6 +1680,40 @@ boolean G_Responder(event_t *ev)
CV_SetValue(&cv_chasecam[i], cv_chasecam[i].value ? 0 : 1);
}
}
if (G_ControlBoundToKey(i, gc_spectate, ev->data1, false))
{
if (!spectatedelay[i])
{
char *commandname = va("changeteam");
if (i > 0)
{
// Add one for command names.
commandname = va("changeteam%d", i+1);
}
spectatedelay[i] = NEWTICRATE / 7;
COM_ImmedExecute(va("%s spectator", commandname));
}
}
if (G_ControlBoundToKey(i, gc_respawn, ev->data1, false))
{
if (!respawndelay[i])
{
char *commandname = va("respawn");
if (i > 0)
{
// Add one for command names.
commandname = va("respawn%d", i+1);
}
respawndelay[i] = NEWTICRATE / 4;
COM_ImmedExecute(commandname);
}
}
}
return true;
@ -2157,6 +2193,10 @@ void G_Ticker(boolean run)
{
if (camtoggledelay[i])
camtoggledelay[i]--;
if (spectatedelay[i])
spectatedelay[i]--;
if (respawndelay[i])
respawndelay[i]--;
}
if (gametic % NAMECHANGERATE == 0)

View file

@ -405,6 +405,7 @@ static const char *gamecontrolname[num_gamecontrols] =
"custom1",
"custom2",
"custom3",
"respawn",
};
#define NUMKEYNAMES (sizeof (keynames)/sizeof (keyname_t))
@ -681,7 +682,7 @@ static void setcontrol(UINT8 player)
namectrl = COM_Argv(1);
for (numctrl = 0;
numctrl < num_gamecontrols && stricmp(namectrl, gamecontrolname[numctrl]);
numctrl < num_gamecontrols && gamecontrolname[numctrl] && stricmp(namectrl, gamecontrolname[numctrl]);
numctrl++)
{ ; }

View file

@ -85,6 +85,7 @@ typedef enum
gc_custom1, // Lua scriptable
gc_custom2, // Lua scriptable
gc_custom3, // Lua scriptable
gc_respawn,
num_gamecontrols
} gamecontrols_e;

View file

@ -1200,6 +1200,7 @@ static menuitem_t OP_AllControlsMenu[] =
//{IT_CONTROL, NULL, "Team Chat", M_ChangeControl, gc_teamkey },
{IT_CONTROL, NULL, "Show Rankings", {.routine = M_ChangeControl}, gc_scores },
{IT_CONTROL, NULL, "Change Viewpoint", {.routine = M_ChangeControl}, gc_viewpoint },
{IT_CONTROL, NULL, "Respawn", {.routine = M_ChangeControl}, gc_respawn },
{IT_CONTROL, NULL, "Reset Camera", {.routine = M_ChangeControl}, gc_camreset },
{IT_CONTROL, NULL, "Toggle Chasecam", {.routine = M_ChangeControl}, gc_camtoggle },
{IT_CONTROL, NULL, "Pause", {.routine = M_ChangeControl}, gc_pause },