mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2025-01-31 05:20:51 +00:00
* Make cancelling a join work on the pause menu and console. (You need to write "changeteam spectator" to cancel a PF_WANTSTOJOIN.)
* Stop respawning spectators when their PF_WANTSTOJOIN request hasn't been processed yet. * Handle PF_WANTSTOJOIN requests in GS_WAITINGPLAYERS. * Refactor K_CheckSpectateStatus, and make it so PF_WANTSTOJOIN requests are processed if there's only one player in the server, even if they're on lap 2 or up. * Make the player entry mechanism in P_SpawnPlayer use the PF_WANTSTOJOIN mechanism so that it can also take advantage of the level refresh mechanism with no extra code. * NOTE: This does a bad hack in order to not send multiple mapchanges while the joining timer is low! If you can think of a better way to do this, please let me know/commit it. * Change the timer until you can hit ITEM again when a spectator who has to wait to join shorter. * (controversial, but I think necessary) - flash the ITEM text when the above-mentioned timer is nonzero.
This commit is contained in:
parent
75f339f6c1
commit
b818c8a2cf
7 changed files with 136 additions and 118 deletions
110
src/d_netcmd.c
110
src/d_netcmd.c
|
@ -2522,18 +2522,12 @@ static void Command_Teamchange_f(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
if (NetPacket.packet.newteam == (unsigned)players[consoleplayer].ctfteam ||
|
||||
(players[consoleplayer].spectator && !NetPacket.packet.newteam))
|
||||
error = true;
|
||||
}
|
||||
else if (G_GametypeHasSpectators())
|
||||
{
|
||||
if ((players[consoleplayer].spectator && !NetPacket.packet.newteam) ||
|
||||
(!players[consoleplayer].spectator && NetPacket.packet.newteam == 3))
|
||||
error = true;
|
||||
}
|
||||
if (players[consoleplayer].spectator && !(players[consoleplayer].pflags & PF_WANTSTOJOIN) && !NetPacket.packet.newteam)
|
||||
error = true;
|
||||
else if (G_GametypeHasTeams() && NetPacket.packet.newteam == (unsigned)players[consoleplayer].ctfteam)
|
||||
error = true;
|
||||
else if (G_GametypeHasSpectators() && !players[consoleplayer].spectator && NetPacket.packet.newteam == 3)
|
||||
error = true;
|
||||
#ifdef PARANOIA
|
||||
else
|
||||
I_Error("Invalid gametype after initial checks!");
|
||||
|
@ -2619,18 +2613,12 @@ static void Command_Teamchange2_f(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
if (NetPacket.packet.newteam == (unsigned)players[secondarydisplayplayer].ctfteam ||
|
||||
(players[secondarydisplayplayer].spectator && !NetPacket.packet.newteam))
|
||||
error = true;
|
||||
}
|
||||
else if (G_GametypeHasSpectators())
|
||||
{
|
||||
if ((players[secondarydisplayplayer].spectator && !NetPacket.packet.newteam) ||
|
||||
(!players[secondarydisplayplayer].spectator && NetPacket.packet.newteam == 3))
|
||||
error = true;
|
||||
}
|
||||
if (players[secondarydisplayplayer].spectator && !(players[secondarydisplayplayer].pflags & PF_WANTSTOJOIN) && !NetPacket.packet.newteam)
|
||||
error = true;
|
||||
else if (G_GametypeHasTeams() && NetPacket.packet.newteam == (unsigned)players[secondarydisplayplayer].ctfteam)
|
||||
error = true;
|
||||
else if (G_GametypeHasSpectators() && !players[secondarydisplayplayer].spectator && NetPacket.packet.newteam == 3)
|
||||
error = true;
|
||||
#ifdef PARANOIA
|
||||
else
|
||||
I_Error("Invalid gametype after initial checks!");
|
||||
|
@ -2716,18 +2704,12 @@ static void Command_Teamchange3_f(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
if (NetPacket.packet.newteam == (unsigned)players[thirddisplayplayer].ctfteam ||
|
||||
(players[thirddisplayplayer].spectator && !NetPacket.packet.newteam))
|
||||
error = true;
|
||||
}
|
||||
else if (G_GametypeHasSpectators())
|
||||
{
|
||||
if ((players[thirddisplayplayer].spectator && !NetPacket.packet.newteam) ||
|
||||
(!players[thirddisplayplayer].spectator && NetPacket.packet.newteam == 3))
|
||||
error = true;
|
||||
}
|
||||
if (players[thirddisplayplayer].spectator && !(players[thirddisplayplayer].pflags & PF_WANTSTOJOIN) && !NetPacket.packet.newteam)
|
||||
error = true;
|
||||
else if (G_GametypeHasTeams() && NetPacket.packet.newteam == (unsigned)players[thirddisplayplayer].ctfteam)
|
||||
error = true;
|
||||
else if (G_GametypeHasSpectators() && !players[thirddisplayplayer].spectator && NetPacket.packet.newteam == 3)
|
||||
error = true;
|
||||
#ifdef PARANOIA
|
||||
else
|
||||
I_Error("Invalid gametype after initial checks!");
|
||||
|
@ -2813,18 +2795,12 @@ static void Command_Teamchange4_f(void)
|
|||
return;
|
||||
}
|
||||
|
||||
if (G_GametypeHasTeams())
|
||||
{
|
||||
if (NetPacket.packet.newteam == (unsigned)players[fourthdisplayplayer].ctfteam ||
|
||||
(players[fourthdisplayplayer].spectator && !NetPacket.packet.newteam))
|
||||
error = true;
|
||||
}
|
||||
else if (G_GametypeHasSpectators())
|
||||
{
|
||||
if ((players[fourthdisplayplayer].spectator && !NetPacket.packet.newteam) ||
|
||||
(!players[fourthdisplayplayer].spectator && NetPacket.packet.newteam == 3))
|
||||
error = true;
|
||||
}
|
||||
if (players[fourthdisplayplayer].spectator && !(players[fourthdisplayplayer].pflags & PF_WANTSTOJOIN) && !NetPacket.packet.newteam)
|
||||
error = true;
|
||||
else if (G_GametypeHasTeams() && NetPacket.packet.newteam == (unsigned)players[fourthdisplayplayer].ctfteam)
|
||||
error = true;
|
||||
else if (G_GametypeHasSpectators() && !players[fourthdisplayplayer].spectator && NetPacket.packet.newteam == 3)
|
||||
error = true;
|
||||
#ifdef PARANOIA
|
||||
else
|
||||
I_Error("Invalid gametype after initial checks!");
|
||||
|
@ -3024,24 +3000,23 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
|||
}
|
||||
|
||||
// Prevent multiple changes in one go.
|
||||
if (G_TagGametype())
|
||||
if (players[playernum].spectator && !(players[playernum].pflags & PF_WANTSTOJOIN) && !NetPacket.packet.newteam)
|
||||
return;
|
||||
else if (G_TagGametype())
|
||||
{
|
||||
if (((players[playernum].pflags & PF_TAGIT) && NetPacket.packet.newteam == 1) ||
|
||||
(!(players[playernum].pflags & PF_TAGIT) && NetPacket.packet.newteam == 2) ||
|
||||
(players[playernum].spectator && NetPacket.packet.newteam == 0) ||
|
||||
(!players[playernum].spectator && NetPacket.packet.newteam == 3))
|
||||
return;
|
||||
}
|
||||
else if (G_GametypeHasTeams())
|
||||
{
|
||||
if ((NetPacket.packet.newteam && (NetPacket.packet.newteam == (unsigned)players[playernum].ctfteam)) ||
|
||||
(players[playernum].spectator && !NetPacket.packet.newteam))
|
||||
if (NetPacket.packet.newteam && (NetPacket.packet.newteam == (unsigned)players[playernum].ctfteam))
|
||||
return;
|
||||
}
|
||||
else if (G_GametypeHasSpectators())
|
||||
{
|
||||
if ((players[playernum].spectator && !NetPacket.packet.newteam) ||
|
||||
(!players[playernum].spectator && NetPacket.packet.newteam == 3))
|
||||
if (!players[playernum].spectator && NetPacket.packet.newteam == 3)
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
@ -3113,19 +3088,26 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
|||
}
|
||||
|
||||
//Safety first!
|
||||
if (players[playernum].mo)
|
||||
// (not respawning spectators here...)
|
||||
if (!players[playernum].spectator)
|
||||
{
|
||||
if (!players[playernum].spectator)
|
||||
P_DamageMobj(players[playernum].mo, NULL, NULL, 10000);
|
||||
/*else
|
||||
if (players[playernum].mo)
|
||||
{
|
||||
P_RemoveMobj(players[playernum].mo);
|
||||
players[playernum].mo = NULL;
|
||||
//if (!players[playernum].spectator)
|
||||
P_DamageMobj(players[playernum].mo, NULL, NULL, 10000);
|
||||
/*else
|
||||
{
|
||||
if (players[playernum].mo)
|
||||
{
|
||||
P_RemoveMobj(players[playernum].mo);
|
||||
players[playernum].mo = NULL;
|
||||
}
|
||||
players[playernum].playerstate = PST_REBORN;
|
||||
}*/
|
||||
}
|
||||
else
|
||||
players[playernum].playerstate = PST_REBORN;
|
||||
}*/
|
||||
}
|
||||
else
|
||||
players[playernum].playerstate = PST_REBORN;
|
||||
|
||||
//Now that we've done our error checking and killed the player
|
||||
//if necessary, put the player on the correct team/status.
|
||||
|
@ -3210,6 +3192,8 @@ static void Got_Teamchange(UINT8 **cp, INT32 playernum)
|
|||
}
|
||||
else if (NetPacket.packet.newteam == 3)
|
||||
/*CONS_Printf(M_GetText("%s entered the game.\n"), player_names[playernum])*/;
|
||||
else if (players[playernum].pflags & PF_WANTSTOJOIN)
|
||||
players[playernum].pflags &= ~PF_WANTSTOJOIN;
|
||||
else
|
||||
CONS_Printf(M_GetText("%s became a spectator.\n"), player_names[playernum]);
|
||||
|
||||
|
|
|
@ -2174,7 +2174,9 @@ void G_Ticker(boolean run)
|
|||
|
||||
if (run)
|
||||
{
|
||||
if (G_GametypeHasSpectators() && (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING))
|
||||
if (G_GametypeHasSpectators()
|
||||
&& (gamestate == GS_LEVEL || gamestate == GS_INTERMISSION || gamestate == GS_VOTING // definitely good
|
||||
|| gamestate == GS_WAITINGPLAYERS)) // definitely a problem if we don't do it at all in this gamestate, but might need more protection?
|
||||
K_CheckSpectateStatus();
|
||||
|
||||
if (pausedelay)
|
||||
|
|
61
src/k_kart.c
61
src/k_kart.c
|
@ -4057,33 +4057,54 @@ void K_CheckBumpers(void)
|
|||
void K_CheckSpectateStatus(void)
|
||||
{
|
||||
UINT8 respawnlist[MAXPLAYERS];
|
||||
UINT8 i, no = 0;
|
||||
UINT8 numingame = 0, numjoiners = 0;
|
||||
UINT8 i, numingame = 0, numjoiners = 0;
|
||||
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
if (!cv_allowteamchange.value)
|
||||
return;
|
||||
|
||||
if (!players[i].spectator)
|
||||
{
|
||||
// Get the number of players in game, and the players to be de-spectated.
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i])
|
||||
continue;
|
||||
|
||||
if (!players[i].spectator)
|
||||
{
|
||||
numingame++;
|
||||
if (gamestate != GS_LEVEL)
|
||||
continue;
|
||||
if (G_RaceGametype() && players[i].laps > 0)
|
||||
return;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
else if (!(players[i].pflags & PF_WANTSTOJOIN))
|
||||
continue;
|
||||
|
||||
if (cv_allowteamchange.value && !(players[i].pflags & PF_WANTSTOJOIN))
|
||||
continue;
|
||||
respawnlist[numjoiners++] = i;
|
||||
}
|
||||
|
||||
respawnlist[no++] = i;
|
||||
}
|
||||
// literally zero point in going any further if nobody is joining
|
||||
if (!numjoiners)
|
||||
return;
|
||||
|
||||
numjoiners = no; // Move the map change stuff up here when it gets a delay, and remove this redundant numjoiners var
|
||||
// Check if there are any conditions that should prevent de-spectating.
|
||||
if ((gamestate == GS_LEVEL) && (numingame > 1))
|
||||
{
|
||||
// If anyone's on lap two or up in a race gametype, HALT.
|
||||
if (G_RaceGametype())
|
||||
{
|
||||
for (i = 0; i < MAXPLAYERS; i++)
|
||||
{
|
||||
if (!playeringame[i] || players[i].spectator)
|
||||
continue;
|
||||
|
||||
while (no)
|
||||
P_SpectatorJoinGame(&players[respawnlist[--no]]);
|
||||
if (!players[i].laps)
|
||||
continue;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, we can de-spectate everyone!
|
||||
for (i = 0; i < numjoiners; i++)
|
||||
P_SpectatorJoinGame(&players[respawnlist[i]]);
|
||||
|
||||
if (!server)
|
||||
return;
|
||||
|
|
16
src/m_menu.c
16
src/m_menu.c
|
@ -535,6 +535,7 @@ static menuitem_t MPauseMenu[] =
|
|||
|
||||
{IT_STRING | IT_CALL, NULL, "Spectate", M_ConfirmSpectate, 48},
|
||||
{IT_STRING | IT_CALL, NULL, "Enter Game", M_ConfirmEnterGame, 48},
|
||||
{IT_STRING | IT_CALL, NULL, "Cancel Join", M_ConfirmSpectate, 48},
|
||||
{IT_STRING | IT_SUBMENU, NULL, "Switch Team...", &MISC_ChangeTeamDef, 48},
|
||||
{IT_CALL | IT_STRING, NULL, "Player Setup...", M_SetupMultiPlayer, 56}, // alone
|
||||
{IT_CALL | IT_STRING, NULL, "Options", M_Options, 64},
|
||||
|
@ -557,6 +558,7 @@ typedef enum
|
|||
#endif
|
||||
mpause_spectate,
|
||||
mpause_entergame,
|
||||
mpause_canceljoin,
|
||||
mpause_switchteam,
|
||||
mpause_psetup,
|
||||
mpause_options,
|
||||
|
@ -2842,6 +2844,7 @@ void M_StartControlPanel(void)
|
|||
#endif
|
||||
MPauseMenu[mpause_spectate].status = IT_DISABLED;
|
||||
MPauseMenu[mpause_entergame].status = IT_DISABLED;
|
||||
MPauseMenu[mpause_canceljoin].status = IT_DISABLED;
|
||||
MPauseMenu[mpause_switchteam].status = IT_DISABLED;
|
||||
MPauseMenu[mpause_psetup].status = IT_DISABLED;
|
||||
// Reset these in case splitscreen messes things up
|
||||
|
@ -2889,7 +2892,14 @@ void M_StartControlPanel(void)
|
|||
if (G_GametypeHasTeams())
|
||||
MPauseMenu[mpause_switchteam].status = IT_STRING | IT_SUBMENU;
|
||||
else if (G_GametypeHasSpectators())
|
||||
MPauseMenu[((&players[consoleplayer] && players[consoleplayer].spectator) ? mpause_entergame : mpause_spectate)].status = IT_STRING | IT_CALL;
|
||||
{
|
||||
if (!players[consoleplayer].spectator)
|
||||
MPauseMenu[mpause_spectate].status = IT_STRING | IT_CALL;
|
||||
else if (players[consoleplayer].pflags & PF_WANTSTOJOIN)
|
||||
MPauseMenu[mpause_canceljoin].status = IT_STRING | IT_CALL;
|
||||
else
|
||||
MPauseMenu[mpause_entergame].status = IT_STRING | IT_CALL;
|
||||
}
|
||||
else // in this odd case, we still want something to be on the menu even if it's useless
|
||||
MPauseMenu[mpause_spectate].status = IT_GRAYEDOUT;
|
||||
}
|
||||
|
@ -4207,11 +4217,11 @@ static void M_ConfirmSpectate(INT32 choice)
|
|||
static void M_ConfirmEnterGame(INT32 choice)
|
||||
{
|
||||
(void)choice;
|
||||
if (!cv_allowteamchange.value)
|
||||
/*if (!cv_allowteamchange.value)
|
||||
{
|
||||
M_StartMessage(M_GetText("The server is not allowing\nteam changes at this time.\nPress a key.\n"), NULL, MM_NOTHING);
|
||||
return;
|
||||
}
|
||||
}*/
|
||||
M_ClearMenus(true);
|
||||
COM_ImmedExecute("changeteam playing");
|
||||
}
|
||||
|
|
55
src/p_mobj.c
55
src/p_mobj.c
|
@ -9830,8 +9830,13 @@ void P_SpawnPlayer(INT32 playernum)
|
|||
// spawn as spectator determination
|
||||
if (!G_GametypeHasSpectators())
|
||||
p->spectator = false;
|
||||
else if (netgame && p->jointime <= 1 && pcount > 1)
|
||||
else if (netgame && p->jointime <= 1 && pcount)
|
||||
{
|
||||
p->spectator = true;
|
||||
if (pcount == 1)
|
||||
p->pflags |= PF_WANTSTOJOIN;
|
||||
p->jointime = 2; // HACK???????
|
||||
}
|
||||
else if (multiplayer && !netgame)
|
||||
{
|
||||
// If you're in a team game and you don't have a team assigned yet...
|
||||
|
@ -9912,41 +9917,35 @@ void P_SpawnPlayer(INT32 playernum)
|
|||
overheadarrow->flags2 |= MF2_DONTDRAW;
|
||||
P_SetScale(overheadarrow, mobj->destscale);
|
||||
|
||||
if (p->spectator) // HEY! No being cheap...
|
||||
if (p->spectator && pcount > 1) // HEY! No being cheap...
|
||||
p->kartstuff[k_bumper] = 0;
|
||||
else if (p->kartstuff[k_bumper] > 0 || leveltime < 1
|
||||
|| (p->jointime <= 1 && pcount <= 1))
|
||||
{
|
||||
INT32 i;
|
||||
angle_t newangle;
|
||||
angle_t diff;
|
||||
fixed_t newx;
|
||||
fixed_t newy;
|
||||
mobj_t *mo;
|
||||
|
||||
if (leveltime < 1 || (p->jointime <= 1 && pcount <= 1)) // Start of the map?
|
||||
p->kartstuff[k_bumper] = cv_kartbumpers.value; // Reset those bumpers!
|
||||
|
||||
if (p->kartstuff[k_bumper] <= 1)
|
||||
diff = 0;
|
||||
else
|
||||
diff = FixedAngle(360*FRACUNIT/p->kartstuff[k_bumper]);
|
||||
|
||||
newangle = mobj->angle;
|
||||
newx = mobj->x + P_ReturnThrustX(mobj, newangle + ANGLE_180, 64*FRACUNIT);
|
||||
newy = mobj->y + P_ReturnThrustY(mobj, newangle + ANGLE_180, 64*FRACUNIT);
|
||||
|
||||
for (i = 0; i < p->kartstuff[k_bumper]; i++)
|
||||
if (p->kartstuff[k_bumper])
|
||||
{
|
||||
mo = P_SpawnMobj(newx, newy, mobj->z, MT_BATTLEBUMPER);
|
||||
mo->threshold = i;
|
||||
P_SetTarget(&mo->target, mobj);
|
||||
mo->angle = (diff * (i-1));
|
||||
mo->color = mobj->color;
|
||||
if (mobj->flags2 & MF2_DONTDRAW)
|
||||
mo->flags2 |= MF2_DONTDRAW;
|
||||
else
|
||||
mo->flags2 &= ~MF2_DONTDRAW;
|
||||
INT32 i;
|
||||
angle_t diff = FixedAngle(360*FRACUNIT/p->kartstuff[k_bumper]);
|
||||
angle_t newangle = mobj->angle;
|
||||
fixed_t newx = mobj->x + P_ReturnThrustX(mobj, newangle + ANGLE_180, 64*FRACUNIT);
|
||||
fixed_t newy = mobj->y + P_ReturnThrustY(mobj, newangle + ANGLE_180, 64*FRACUNIT);
|
||||
mobj_t *mo;
|
||||
|
||||
for (i = 0; i < p->kartstuff[k_bumper]; i++)
|
||||
{
|
||||
mo = P_SpawnMobj(newx, newy, mobj->z, MT_BATTLEBUMPER);
|
||||
mo->threshold = i;
|
||||
P_SetTarget(&mo->target, mobj);
|
||||
mo->angle = (diff * (i-1));
|
||||
mo->color = mobj->color;
|
||||
if (mobj->flags2 & MF2_DONTDRAW)
|
||||
mo->flags2 |= MF2_DONTDRAW;
|
||||
else
|
||||
mo->flags2 &= ~MF2_DONTDRAW;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (p->kartstuff[k_bumper] <= 0)
|
||||
|
|
|
@ -8812,7 +8812,7 @@ boolean P_SpectatorJoinGame(player_t *player)
|
|||
{
|
||||
if (P_IsLocalPlayer(player))
|
||||
CONS_Printf(M_GetText("Server does not allow team change.\n"));
|
||||
player->powers[pw_flashing] = 2*TICRATE; //to prevent message spam.
|
||||
player->powers[pw_flashing] = TICRATE + 1; //to prevent message spam.
|
||||
}
|
||||
// Team changing in Team Match and CTF
|
||||
// Pressing fire assigns you to a team that needs players if allowed.
|
||||
|
@ -9301,7 +9301,7 @@ void P_PlayerThink(player_t *player)
|
|||
if ((netgame || splitscreen) && player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing])
|
||||
{
|
||||
player->pflags ^= PF_WANTSTOJOIN;
|
||||
player->powers[pw_flashing] = 2*TICRATE;
|
||||
player->powers[pw_flashing] = TICRATE + 1;
|
||||
/*if (P_SpectatorJoinGame(player))
|
||||
return; // player->mo was removed.*/
|
||||
}
|
||||
|
|
|
@ -1952,7 +1952,9 @@ static void ST_overlayDrawer(void)
|
|||
{
|
||||
// SRB2kart: changed positions & text
|
||||
V_DrawString(2, BASEVIDHEIGHT-50, V_HUDTRANSHALF|V_YELLOWMAP, M_GetText("- SPECTATING -"));
|
||||
if (stplyr->pflags & PF_WANTSTOJOIN)
|
||||
if (stplyr->powers[pw_flashing] & 1)
|
||||
;
|
||||
else if (stplyr->pflags & PF_WANTSTOJOIN)
|
||||
V_DrawString(2, BASEVIDHEIGHT-40, V_HUDTRANSHALF, M_GetText("Item - Cancel Join"));
|
||||
/*else if (G_GametypeHasTeams())
|
||||
V_DrawString(2, BASEVIDHEIGHT-40, V_HUDTRANSHALF, M_GetText("Item - Join Team"));*/
|
||||
|
|
Loading…
Reference in a new issue