mirror of
https://git.do.srb2.org/KartKrew/Kart-Public.git
synced 2024-11-10 15:22:20 +00:00
Merge branch 'net-screen' into 'master'
Splitscreen in netgames See merge request KartKrew/Kart!22
This commit is contained in:
commit
2e3f6b09af
17 changed files with 837 additions and 434 deletions
|
@ -748,6 +748,19 @@ boolean CON_Responder(event_t *ev)
|
||||||
if (modeattacking || metalrecording)
|
if (modeattacking || metalrecording)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
if (ev->data1 >= KEY_MOUSE1) // See also: HUD_Responder
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
for (i = 0; i < num_gamecontrols; i++)
|
||||||
|
{
|
||||||
|
if (gamecontrol[i][0] == ev->data1 || gamecontrol[i][1] == ev->data1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == num_gamecontrols)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (key == gamecontrol[gc_console][0] || key == gamecontrol[gc_console][1])
|
if (key == gamecontrol[gc_console][0] || key == gamecontrol[gc_console][1])
|
||||||
{
|
{
|
||||||
if (consdown) // ignore repeat
|
if (consdown) // ignore repeat
|
||||||
|
|
148
src/d_clisrv.c
148
src/d_clisrv.c
|
@ -2375,8 +2375,11 @@ static void Command_connect(void)
|
||||||
CONS_Alert(CONS_ERROR, M_GetText("There is no network driver\n"));
|
CONS_Alert(CONS_ERROR, M_GetText("There is no network driver\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
splitscreen = 0;
|
if (splitscreen != cv_splitplayers.value-1)
|
||||||
|
{
|
||||||
|
splitscreen = cv_splitplayers.value-1;
|
||||||
SplitScreen_OnChange();
|
SplitScreen_OnChange();
|
||||||
|
}
|
||||||
botingame = false;
|
botingame = false;
|
||||||
botskin = 0;
|
botskin = 0;
|
||||||
CL_ConnectToServer(viams);
|
CL_ConnectToServer(viams);
|
||||||
|
@ -2417,14 +2420,15 @@ static void CL_RemovePlayer(INT32 playernum)
|
||||||
if (server && !demoplayback)
|
if (server && !demoplayback)
|
||||||
{
|
{
|
||||||
INT32 node = playernode[playernum];
|
INT32 node = playernode[playernum];
|
||||||
|
//playerpernode[node] = 0; // It'd be better to remove them all at once, but ghosting happened, so continue to let CL_RemovePlayer do it one-by-one
|
||||||
playerpernode[node]--;
|
playerpernode[node]--;
|
||||||
if (playerpernode[node] <= 0)
|
if (playerpernode[node] <= 0)
|
||||||
{
|
{
|
||||||
// If a resynch was in progress, well, it no longer needs to be.
|
// If a resynch was in progress, well, it no longer needs to be.
|
||||||
SV_InitResynchVars(playernode[playernum]);
|
SV_InitResynchVars(node);
|
||||||
|
|
||||||
nodeingame[playernode[playernum]] = false;
|
nodeingame[node] = false;
|
||||||
Net_CloseConnection(playernode[playernum]);
|
Net_CloseConnection(node);
|
||||||
ResetNode(node);
|
ResetNode(node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2759,11 +2763,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is playernum authorized to make this kick?
|
// Is playernum authorized to make this kick?
|
||||||
if (playernum != serverplayer && !IsPlayerAdmin(playernum)
|
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
|
||||||
&& !(playerpernode[playernode[playernum]] >= 2
|
|
||||||
&& (nodetoplayer2[playernode[playernum]] == pnum
|
|
||||||
|| nodetoplayer3[playernode[playernum]] == pnum
|
|
||||||
|| nodetoplayer4[playernode[playernum]] == pnum)))
|
|
||||||
{
|
{
|
||||||
// We received a kick command from someone who isn't the
|
// We received a kick command from someone who isn't the
|
||||||
// server or admin, and who isn't in splitscreen removing
|
// server or admin, and who isn't in splitscreen removing
|
||||||
|
@ -2775,12 +2775,6 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
// "consistency failure" and kicking the offending user
|
// "consistency failure" and kicking the offending user
|
||||||
// instead.
|
// instead.
|
||||||
|
|
||||||
// Note: Splitscreen in netgames is broken because of
|
|
||||||
// this. Only the server has any idea of which players
|
|
||||||
// are using splitscreen on the same computer, so
|
|
||||||
// clients cannot always determine if a kick is
|
|
||||||
// legitimate.
|
|
||||||
|
|
||||||
CONS_Alert(CONS_WARNING, M_GetText("Illegal kick command received from %s for player %d\n"), player_names[playernum], pnum);
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal kick command received from %s for player %d\n"), player_names[playernum], pnum);
|
||||||
|
|
||||||
// In debug, print a longer message with more details.
|
// In debug, print a longer message with more details.
|
||||||
|
@ -2890,7 +2884,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pnum == consoleplayer)
|
if (playernode[pnum] == playernode[consoleplayer])
|
||||||
{
|
{
|
||||||
#ifdef DUMPCONSISTENCY
|
#ifdef DUMPCONSISTENCY
|
||||||
if (msg == KICK_MSG_CON_FAIL) SV_SavedGame();
|
if (msg == KICK_MSG_CON_FAIL) SV_SavedGame();
|
||||||
|
@ -2899,7 +2893,7 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
CL_Reset();
|
CL_Reset();
|
||||||
D_StartTitle();
|
D_StartTitle();
|
||||||
if (msg == KICK_MSG_CON_FAIL)
|
if (msg == KICK_MSG_CON_FAIL)
|
||||||
M_StartMessage(M_GetText("Server closed connection\n(synch failure)\nPress ESC\n"), NULL, MM_NOTHING);
|
M_StartMessage(M_GetText("Server closed connection\n(Synch failure)\nPress ESC\n"), NULL, MM_NOTHING);
|
||||||
#ifdef NEWPING
|
#ifdef NEWPING
|
||||||
else if (msg == KICK_MSG_PING_HIGH)
|
else if (msg == KICK_MSG_PING_HIGH)
|
||||||
M_StartMessage(M_GetText("Server closed connection\n(Broke ping limit)\nPress ESC\n"), NULL, MM_NOTHING);
|
M_StartMessage(M_GetText("Server closed connection\n(Broke ping limit)\nPress ESC\n"), NULL, MM_NOTHING);
|
||||||
|
@ -2913,8 +2907,32 @@ static void Got_KickCmd(UINT8 **p, INT32 playernum)
|
||||||
else
|
else
|
||||||
M_StartMessage(M_GetText("You have been kicked by the server\n\nPress ESC\n"), NULL, MM_NOTHING);
|
M_StartMessage(M_GetText("You have been kicked by the server\n\nPress ESC\n"), NULL, MM_NOTHING);
|
||||||
}
|
}
|
||||||
else
|
else if (server)
|
||||||
CL_RemovePlayer(pnum);
|
{
|
||||||
|
XBOXSTATIC UINT8 buf[0];
|
||||||
|
|
||||||
|
// Sal: Because kicks (and a lot of other commands) are player-based, we can't tell which player pnum is on the node from a glance.
|
||||||
|
// When we want to remove everyone from a node, we have to get the kicked player's node, then remove everyone on that node manually so we don't miss any.
|
||||||
|
// This avoids the bugs with older SRB2 version's online splitscreen kicks, specifically ghosting.
|
||||||
|
// On top of this, it can't just be a CL_RemovePlayer call; it has to be a server-sided.
|
||||||
|
// Clients don't bother setting any nodes for anything but THE server player (even ignoring the server's extra players!), so it'll often remove everyone because they all have node -1/255, insta-desync!
|
||||||
|
// And yes. This is a netxcmd wrap for just CL_RemovePlayer! :V
|
||||||
|
|
||||||
|
#define removethisplayer(otherp) \
|
||||||
|
if (otherp >= 0) \
|
||||||
|
{ \
|
||||||
|
if (otherp != pnum) \
|
||||||
|
CONS_Printf("\x82%s\x80 left the game (Joined with \x82%s\x80)\n", player_names[otherp], player_names[pnum]); \
|
||||||
|
buf[0] = (UINT8)otherp; \
|
||||||
|
SendNetXCmd(XD_REMOVEPLAYER, &buf, 1); \
|
||||||
|
otherp = -1; \
|
||||||
|
}
|
||||||
|
removethisplayer(nodetoplayer[playernode[pnum]])
|
||||||
|
removethisplayer(nodetoplayer2[playernode[pnum]])
|
||||||
|
removethisplayer(nodetoplayer3[playernode[pnum]])
|
||||||
|
removethisplayer(nodetoplayer4[playernode[pnum]])
|
||||||
|
#undef removethisplayer
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
|
consvar_t cv_allownewplayer = {"allowjoin", "On", CV_NETVAR, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL };
|
||||||
|
@ -2937,6 +2955,7 @@ static CV_PossibleValue_t downloadspeed_cons_t[] = {{0, "MIN"}, {32, "MAX"}, {0,
|
||||||
consvar_t cv_downloadspeed = {"downloadspeed", "16", CV_SAVE, downloadspeed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_downloadspeed = {"downloadspeed", "16", CV_SAVE, downloadspeed_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
static void Got_AddPlayer(UINT8 **p, INT32 playernum);
|
static void Got_AddPlayer(UINT8 **p, INT32 playernum);
|
||||||
|
static void Got_RemovePlayer(UINT8 **p, INT32 playernum);
|
||||||
|
|
||||||
// called one time at init
|
// called one time at init
|
||||||
void D_ClientServerInit(void)
|
void D_ClientServerInit(void)
|
||||||
|
@ -2964,6 +2983,7 @@ void D_ClientServerInit(void)
|
||||||
|
|
||||||
RegisterNetXCmd(XD_KICK, Got_KickCmd);
|
RegisterNetXCmd(XD_KICK, Got_KickCmd);
|
||||||
RegisterNetXCmd(XD_ADDPLAYER, Got_AddPlayer);
|
RegisterNetXCmd(XD_ADDPLAYER, Got_AddPlayer);
|
||||||
|
RegisterNetXCmd(XD_REMOVEPLAYER, Got_RemovePlayer);
|
||||||
#ifndef NONET
|
#ifndef NONET
|
||||||
CV_RegisterVar(&cv_allownewplayer);
|
CV_RegisterVar(&cv_allownewplayer);
|
||||||
#ifdef VANILLAJOINNEXTROUND
|
#ifdef VANILLAJOINNEXTROUND
|
||||||
|
@ -3157,9 +3177,8 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
||||||
newplayernum %= MAXPLAYERS;
|
newplayernum %= MAXPLAYERS;
|
||||||
|
|
||||||
// Clear player before joining, lest some things get set incorrectly
|
// Clear player before joining, lest some things get set incorrectly
|
||||||
// HACK: don't do this for splitscreen, it relies on preset values
|
|
||||||
if (!splitscreen && !botingame)
|
|
||||||
CL_ClearPlayer(newplayernum);
|
CL_ClearPlayer(newplayernum);
|
||||||
|
|
||||||
playeringame[newplayernum] = true;
|
playeringame[newplayernum] = true;
|
||||||
G_AddPlayer(newplayernum);
|
G_AddPlayer(newplayernum);
|
||||||
if (newplayernum+1 > doomcom->numslots)
|
if (newplayernum+1 > doomcom->numslots)
|
||||||
|
@ -3241,6 +3260,27 @@ static void Got_AddPlayer(UINT8 **p, INT32 playernum)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Xcmd XD_REMOVEPLAYER
|
||||||
|
static void Got_RemovePlayer(UINT8 **p, INT32 playernum)
|
||||||
|
{
|
||||||
|
if (playernum != serverplayer && !IsPlayerAdmin(playernum))
|
||||||
|
{
|
||||||
|
// protect against hacked/buggy client
|
||||||
|
CONS_Alert(CONS_WARNING, M_GetText("Illegal remove player command received from %s\n"), player_names[playernum]);
|
||||||
|
if (server)
|
||||||
|
{
|
||||||
|
XBOXSTATIC UINT8 buf[2];
|
||||||
|
|
||||||
|
buf[0] = (UINT8)playernum;
|
||||||
|
buf[1] = KICK_MSG_CON_FAIL;
|
||||||
|
SendNetXCmd(XD_KICK, &buf, 2);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
CL_RemovePlayer(READUINT8(*p));
|
||||||
|
}
|
||||||
|
|
||||||
static boolean SV_AddWaitingPlayers(void)
|
static boolean SV_AddWaitingPlayers(void)
|
||||||
{
|
{
|
||||||
INT32 node, n, newplayer = false;
|
INT32 node, n, newplayer = false;
|
||||||
|
@ -3258,58 +3298,6 @@ static boolean SV_AddWaitingPlayers(void)
|
||||||
{
|
{
|
||||||
newplayer = true;
|
newplayer = true;
|
||||||
|
|
||||||
if (netgame)
|
|
||||||
// !!!!!!!!! EXTREMELY SUPER MEGA GIGA ULTRA ULTIMATELY TERRIBLY IMPORTANT !!!!!!!!!
|
|
||||||
//
|
|
||||||
// The line just after that comment is an awful, horrible, terrible, TERRIBLE hack.
|
|
||||||
//
|
|
||||||
// Basically, the fix I did in order to fix the download freezes happens
|
|
||||||
// to cause situations in which a player number does not match
|
|
||||||
// the node number associated to that player.
|
|
||||||
// That is totally normal, there is absolutely *nothing* wrong with that.
|
|
||||||
// Really. Player 7 being tied to node 29, for instance, is totally fine.
|
|
||||||
//
|
|
||||||
// HOWEVER. A few (broken) parts of the netcode do the TERRIBLE mistake
|
|
||||||
// of mixing up the concepts of node and player, resulting in
|
|
||||||
// incorrect handling of cases where a player is tied to a node that has
|
|
||||||
// a different number (which is a totally normal case, or at least should be).
|
|
||||||
// This incorrect handling can go as far as literally
|
|
||||||
// anyone from joining your server at all, forever.
|
|
||||||
//
|
|
||||||
// Given those two facts, there are two options available
|
|
||||||
// in order to let this download freeze fix be:
|
|
||||||
// 1) Fix the broken parts that assume a node is a player or similar bullshit.
|
|
||||||
// 2) Change the part this comment is located at, so that any player who joins
|
|
||||||
// is given the same number as their associated node.
|
|
||||||
//
|
|
||||||
// No need to say, 1) is by far the obvious best, whereas 2) is a terrible hack.
|
|
||||||
// Unfortunately, after trying 1), I most likely didn't manage to find all
|
|
||||||
// of those broken parts, and thus 2) has become the only safe option that remains.
|
|
||||||
//
|
|
||||||
// So I did this hack.
|
|
||||||
//
|
|
||||||
// If it isn't clear enough, in order to get rid of this ugly hack,
|
|
||||||
// you will have to fix all parts of the netcode that
|
|
||||||
// make a confusion between nodes and players.
|
|
||||||
//
|
|
||||||
// And if it STILL isn't clear enough, a node and a player
|
|
||||||
// is NOT the same thing. Never. NEVER. *NEVER*.
|
|
||||||
//
|
|
||||||
// And if someday you make the terrible mistake of
|
|
||||||
// daring to have the unforgivable idea to try thinking
|
|
||||||
// that a node might possibly be the same as a player,
|
|
||||||
// or that a player should have the same number as its node,
|
|
||||||
// be sure that I will somehow know about it and
|
|
||||||
// hunt you down tirelessly and make you regret it,
|
|
||||||
// even if you live on the other side of the world.
|
|
||||||
//
|
|
||||||
// TODO: vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
|
|
||||||
// \todo >>>>>>>>>> Remove this horrible hack as soon as possible <<<<<<<<<<
|
|
||||||
// TODO: ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
|
||||||
//
|
|
||||||
// !!!!!!!!! EXTREMELY SUPER MEGA GIGA ULTRA ULTIMATELY TERRIBLY IMPORTANT !!!!!!!!!
|
|
||||||
newplayernum = node; // OMFG SAY WELCOME TO TEH NEW HACK FOR FIX FIL DOWNLOAD!!1!
|
|
||||||
else // Don't use the hack if we don't have to
|
|
||||||
// search for a free playernum
|
// search for a free playernum
|
||||||
// we can't use playeringame since it is not updated here
|
// we can't use playeringame since it is not updated here
|
||||||
for (; newplayernum < MAXPLAYERS; newplayernum++)
|
for (; newplayernum < MAXPLAYERS; newplayernum++)
|
||||||
|
@ -3495,7 +3483,7 @@ static void HandleConnect(SINT8 node)
|
||||||
SV_SendRefuse(node, M_GetText("The server is not accepting\njoins for the moment"));
|
SV_SendRefuse(node, M_GetText("The server is not accepting\njoins for the moment"));
|
||||||
else if (D_NumPlayers() >= cv_maxplayers.value)
|
else if (D_NumPlayers() >= cv_maxplayers.value)
|
||||||
SV_SendRefuse(node, va(M_GetText("Maximum players reached: %d"), cv_maxplayers.value));
|
SV_SendRefuse(node, va(M_GetText("Maximum players reached: %d"), cv_maxplayers.value));
|
||||||
else if (netgame && netbuffer->u.clientcfg.localplayers > 1) // Hacked client?
|
else if (netgame && netbuffer->u.clientcfg.localplayers > 4) // Hacked client?
|
||||||
SV_SendRefuse(node, M_GetText("Too many players from\nthis node."));
|
SV_SendRefuse(node, M_GetText("Too many players from\nthis node."));
|
||||||
else if (netgame && !netbuffer->u.clientcfg.localplayers) // Stealth join?
|
else if (netgame && !netbuffer->u.clientcfg.localplayers) // Stealth join?
|
||||||
SV_SendRefuse(node, M_GetText("No players from\nthis node."));
|
SV_SendRefuse(node, M_GetText("No players from\nthis node."));
|
||||||
|
@ -3529,8 +3517,8 @@ static void HandleConnect(SINT8 node)
|
||||||
{
|
{
|
||||||
G_SetGamestate(backupstate);
|
G_SetGamestate(backupstate);
|
||||||
/// \note Shouldn't SV_SendRefuse be called before ResetNode?
|
/// \note Shouldn't SV_SendRefuse be called before ResetNode?
|
||||||
ResetNode(node);
|
|
||||||
SV_SendRefuse(node, M_GetText("Server couldn't send info, please try again"));
|
SV_SendRefuse(node, M_GetText("Server couldn't send info, please try again"));
|
||||||
|
ResetNode(node); // Yeah, lets try it!
|
||||||
/// \todo fix this !!!
|
/// \todo fix this !!!
|
||||||
return; // restart the while
|
return; // restart the while
|
||||||
}
|
}
|
||||||
|
@ -3983,10 +3971,10 @@ FILESTAMP
|
||||||
--resynch_score[node];
|
--resynch_score[node];
|
||||||
break;
|
break;
|
||||||
case PT_TEXTCMD:
|
case PT_TEXTCMD:
|
||||||
case PT_TEXTCMD2: // splitscreen special
|
case PT_TEXTCMD2:
|
||||||
case PT_TEXTCMD3:
|
case PT_TEXTCMD3:
|
||||||
case PT_TEXTCMD4:
|
case PT_TEXTCMD4:
|
||||||
if (netbuffer->packettype == PT_TEXTCMD2)
|
if (netbuffer->packettype == PT_TEXTCMD2) // splitscreen special
|
||||||
netconsole = nodetoplayer2[node];
|
netconsole = nodetoplayer2[node];
|
||||||
else if (netbuffer->packettype == PT_TEXTCMD3)
|
else if (netbuffer->packettype == PT_TEXTCMD3)
|
||||||
netconsole = nodetoplayer3[node];
|
netconsole = nodetoplayer3[node];
|
||||||
|
@ -4073,9 +4061,9 @@ FILESTAMP
|
||||||
else
|
else
|
||||||
buf[1] = KICK_MSG_PLAYER_QUIT;
|
buf[1] = KICK_MSG_PLAYER_QUIT;
|
||||||
SendNetXCmd(XD_KICK, &buf, 2);
|
SendNetXCmd(XD_KICK, &buf, 2);
|
||||||
nodetoplayer[node] = -1;
|
//nodetoplayer[node] = -1;
|
||||||
|
|
||||||
if (nodetoplayer2[node] != -1 && nodetoplayer2[node] >= 0
|
/*if (nodetoplayer2[node] != -1 && nodetoplayer2[node] >= 0
|
||||||
&& playeringame[(UINT8)nodetoplayer2[node]])
|
&& playeringame[(UINT8)nodetoplayer2[node]])
|
||||||
{
|
{
|
||||||
buf[0] = nodetoplayer2[node];
|
buf[0] = nodetoplayer2[node];
|
||||||
|
@ -4097,7 +4085,7 @@ FILESTAMP
|
||||||
buf[0] = nodetoplayer4[node];
|
buf[0] = nodetoplayer4[node];
|
||||||
SendNetXCmd(XD_KICK, &buf, 2);
|
SendNetXCmd(XD_KICK, &buf, 2);
|
||||||
nodetoplayer4[node] = -1;
|
nodetoplayer4[node] = -1;
|
||||||
}
|
}*/
|
||||||
}
|
}
|
||||||
Net_CloseConnection(node);
|
Net_CloseConnection(node);
|
||||||
nodeingame[node] = false;
|
nodeingame[node] = false;
|
||||||
|
|
15
src/d_main.c
15
src/d_main.c
|
@ -1362,11 +1362,26 @@ void D_SRB2Main(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Set up splitscreen players before joining!
|
||||||
|
if (!dedicated && (M_CheckParm("-splitscreen") && M_IsNextParm()))
|
||||||
|
{
|
||||||
|
UINT8 num = atoi(M_GetNextParm());
|
||||||
|
if (num >= 1 && num <= 4)
|
||||||
|
{
|
||||||
|
CV_StealthSetValue(&cv_splitplayers, num);
|
||||||
|
splitscreen = num-1;
|
||||||
|
SplitScreen_OnChange();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// init all NETWORK
|
// init all NETWORK
|
||||||
CONS_Printf("D_CheckNetGame(): Checking network game status.\n");
|
CONS_Printf("D_CheckNetGame(): Checking network game status.\n");
|
||||||
if (D_CheckNetGame())
|
if (D_CheckNetGame())
|
||||||
autostart = true;
|
autostart = true;
|
||||||
|
|
||||||
|
if (splitscreen) // Make sure multiplayer & autostart is set if you have splitscreen, even after D_CheckNetGame
|
||||||
|
multiplayer = autostart = true;
|
||||||
|
|
||||||
// check for a driver that wants intermission stats
|
// check for a driver that wants intermission stats
|
||||||
// start the apropriate game based on parms
|
// start the apropriate game based on parms
|
||||||
if (M_CheckParm("-metal"))
|
if (M_CheckParm("-metal"))
|
||||||
|
|
140
src/d_netcmd.c
140
src/d_netcmd.c
|
@ -375,6 +375,7 @@ consvar_t cv_kartdebugdistribution = {"kartdebugdistribution", "Off", CV_NETVAR|
|
||||||
consvar_t cv_kartdebughuddrop = {"kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_kartdebughuddrop = {"kartdebughuddrop", "Off", CV_NETVAR|CV_CHEAT, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
consvar_t cv_kartdebugcheckpoint = {"kartdebugcheckpoint", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_kartdebugcheckpoint = {"kartdebugcheckpoint", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
consvar_t cv_kartdebugnodes = {"kartdebugnodes", "Off", 0, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
|
||||||
static CV_PossibleValue_t votetime_cons_t[] = {{10, "MIN"}, {3600, "MAX"}, {0, NULL}};
|
static CV_PossibleValue_t votetime_cons_t[] = {{10, "MIN"}, {3600, "MAX"}, {0, NULL}};
|
||||||
consvar_t cv_votetime = {"votetime", "20", CV_NETVAR, votetime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
consvar_t cv_votetime = {"votetime", "20", CV_NETVAR, votetime_cons_t, NULL, 0, NULL, NULL, 0, 0, NULL};
|
||||||
|
@ -753,6 +754,8 @@ void D_RegisterClientCommands(void)
|
||||||
CV_RegisterVar(&cv_playername4);
|
CV_RegisterVar(&cv_playername4);
|
||||||
CV_RegisterVar(&cv_playercolor4);
|
CV_RegisterVar(&cv_playercolor4);
|
||||||
CV_RegisterVar(&cv_skin4);
|
CV_RegisterVar(&cv_skin4);
|
||||||
|
// preferred number of players
|
||||||
|
CV_RegisterVar(&cv_splitplayers);
|
||||||
|
|
||||||
#ifdef SEENAMES
|
#ifdef SEENAMES
|
||||||
CV_RegisterVar(&cv_seenames);
|
CV_RegisterVar(&cv_seenames);
|
||||||
|
@ -1345,16 +1348,23 @@ static void SendNameAndColor(void)
|
||||||
// splitscreen
|
// splitscreen
|
||||||
static void SendNameAndColor2(void)
|
static void SendNameAndColor2(void)
|
||||||
{
|
{
|
||||||
INT32 secondplaya;
|
INT32 secondplaya = -1;
|
||||||
|
XBOXSTATIC char buf[MAXPLAYERNAME+2];
|
||||||
|
char *p;
|
||||||
|
|
||||||
if (splitscreen < 1 && !botingame)
|
if (splitscreen < 1 && !botingame)
|
||||||
return; // can happen if skin2/color2/name2 changed
|
return; // can happen if skin2/color2/name2 changed
|
||||||
|
|
||||||
if (secondarydisplayplayer != consoleplayer)
|
if (secondarydisplayplayer != consoleplayer)
|
||||||
secondplaya = secondarydisplayplayer;
|
secondplaya = secondarydisplayplayer;
|
||||||
else // HACK
|
else if (!netgame) // HACK
|
||||||
secondplaya = 1;
|
secondplaya = 1;
|
||||||
|
|
||||||
|
if (secondplaya == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
p = buf;
|
||||||
|
|
||||||
// normal player colors
|
// normal player colors
|
||||||
if (G_GametypeHasTeams())
|
if (G_GametypeHasTeams())
|
||||||
{
|
{
|
||||||
|
@ -1431,21 +1441,53 @@ static void SendNameAndColor2(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't actually send anything because splitscreen isn't actually allowed in netgames anyway!
|
snac2pending++;
|
||||||
|
|
||||||
|
// Don't change name if muted
|
||||||
|
if (cv_mute.value && !(server || IsPlayerAdmin(secondarydisplayplayer)))
|
||||||
|
CV_StealthSet(&cv_playername2, player_names[secondarydisplayplayer]);
|
||||||
|
else // Cleanup name if changing it
|
||||||
|
CleanupPlayerName(secondarydisplayplayer, cv_playername2.zstring);
|
||||||
|
|
||||||
|
// Don't change skin if the server doesn't want you to.
|
||||||
|
if (!CanChangeSkin(secondarydisplayplayer))
|
||||||
|
CV_StealthSet(&cv_skin2, skins[players[secondarydisplayplayer].skin].name);
|
||||||
|
|
||||||
|
// check if player has the skin loaded (cv_skin2 may have
|
||||||
|
// the name of a skin that was available in the previous game)
|
||||||
|
cv_skin2.value = R_SkinAvailable(cv_skin2.string);
|
||||||
|
if (cv_skin2.value < 0)
|
||||||
|
{
|
||||||
|
CV_StealthSet(&cv_skin2, DEFAULTSKIN);
|
||||||
|
cv_skin2.value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally write out the complete packet and send it off.
|
||||||
|
WRITESTRINGN(p, cv_playername2.zstring, MAXPLAYERNAME);
|
||||||
|
WRITEUINT8(p, (UINT8)cv_playercolor2.value);
|
||||||
|
WRITEUINT8(p, (UINT8)cv_skin2.value);
|
||||||
|
SendNetXCmd2(XD_NAMEANDCOLOR, buf, p - buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SendNameAndColor3(void)
|
static void SendNameAndColor3(void)
|
||||||
{
|
{
|
||||||
INT32 thirdplaya;
|
INT32 thirdplaya = -1;
|
||||||
|
XBOXSTATIC char buf[MAXPLAYERNAME+2];
|
||||||
|
char *p;
|
||||||
|
|
||||||
if (splitscreen < 2)
|
if (splitscreen < 2)
|
||||||
return; // can happen if skin3/color3/name3 changed
|
return; // can happen if skin3/color3/name3 changed
|
||||||
|
|
||||||
if (thirddisplayplayer != consoleplayer)
|
if (thirddisplayplayer != consoleplayer)
|
||||||
thirdplaya = thirddisplayplayer;
|
thirdplaya = thirddisplayplayer;
|
||||||
else // HACK
|
else if (!netgame) // HACK
|
||||||
thirdplaya = 2;
|
thirdplaya = 2;
|
||||||
|
|
||||||
|
if (thirdplaya == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
p = buf;
|
||||||
|
|
||||||
// normal player colors
|
// normal player colors
|
||||||
if (G_GametypeHasTeams())
|
if (G_GametypeHasTeams())
|
||||||
{
|
{
|
||||||
|
@ -1514,21 +1556,53 @@ static void SendNameAndColor3(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't actually send anything because splitscreen isn't actually allowed in netgames anyway!
|
snac3pending++;
|
||||||
|
|
||||||
|
// Don't change name if muted
|
||||||
|
if (cv_mute.value && !(server || IsPlayerAdmin(thirddisplayplayer)))
|
||||||
|
CV_StealthSet(&cv_playername3, player_names[thirddisplayplayer]);
|
||||||
|
else // Cleanup name if changing it
|
||||||
|
CleanupPlayerName(thirddisplayplayer, cv_playername3.zstring);
|
||||||
|
|
||||||
|
// Don't change skin if the server doesn't want you to.
|
||||||
|
if (!CanChangeSkin(thirddisplayplayer))
|
||||||
|
CV_StealthSet(&cv_skin3, skins[players[thirddisplayplayer].skin].name);
|
||||||
|
|
||||||
|
// check if player has the skin loaded (cv_skin3 may have
|
||||||
|
// the name of a skin that was available in the previous game)
|
||||||
|
cv_skin3.value = R_SkinAvailable(cv_skin3.string);
|
||||||
|
if (cv_skin3.value < 0)
|
||||||
|
{
|
||||||
|
CV_StealthSet(&cv_skin3, DEFAULTSKIN);
|
||||||
|
cv_skin3.value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally write out the complete packet and send it off.
|
||||||
|
WRITESTRINGN(p, cv_playername3.zstring, MAXPLAYERNAME);
|
||||||
|
WRITEUINT8(p, (UINT8)cv_playercolor3.value);
|
||||||
|
WRITEUINT8(p, (UINT8)cv_skin3.value);
|
||||||
|
SendNetXCmd3(XD_NAMEANDCOLOR, buf, p - buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void SendNameAndColor4(void)
|
static void SendNameAndColor4(void)
|
||||||
{
|
{
|
||||||
INT32 fourthplaya;
|
INT32 fourthplaya = -1;
|
||||||
|
XBOXSTATIC char buf[MAXPLAYERNAME+2];
|
||||||
|
char *p;
|
||||||
|
|
||||||
if (splitscreen < 3)
|
if (splitscreen < 3)
|
||||||
return; // can happen if skin4/color4/name4 changed
|
return; // can happen if skin4/color4/name4 changed
|
||||||
|
|
||||||
if (fourthdisplayplayer != consoleplayer)
|
if (fourthdisplayplayer != consoleplayer)
|
||||||
fourthplaya = fourthdisplayplayer;
|
fourthplaya = fourthdisplayplayer;
|
||||||
else // HACK
|
else if (!netgame) // HACK
|
||||||
fourthplaya = 3;
|
fourthplaya = 3;
|
||||||
|
|
||||||
|
if (fourthplaya == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
p = buf;
|
||||||
|
|
||||||
// normal player colors
|
// normal player colors
|
||||||
if (G_GametypeHasTeams())
|
if (G_GametypeHasTeams())
|
||||||
{
|
{
|
||||||
|
@ -1605,7 +1679,32 @@ static void SendNameAndColor4(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't actually send anything because splitscreen isn't actually allowed in netgames anyway!
|
snac4pending++;
|
||||||
|
|
||||||
|
// Don't change name if muted
|
||||||
|
if (cv_mute.value && !(server || IsPlayerAdmin(fourthdisplayplayer)))
|
||||||
|
CV_StealthSet(&cv_playername4, player_names[fourthdisplayplayer]);
|
||||||
|
else // Cleanup name if changing it
|
||||||
|
CleanupPlayerName(fourthdisplayplayer, cv_playername4.zstring);
|
||||||
|
|
||||||
|
// Don't change skin if the server doesn't want you to.
|
||||||
|
if (!CanChangeSkin(fourthdisplayplayer))
|
||||||
|
CV_StealthSet(&cv_skin4, skins[players[fourthdisplayplayer].skin].name);
|
||||||
|
|
||||||
|
// check if player has the skin loaded (cv_skin4 may have
|
||||||
|
// the name of a skin that was available in the previous game)
|
||||||
|
cv_skin4.value = R_SkinAvailable(cv_skin4.string);
|
||||||
|
if (cv_skin4.value < 0)
|
||||||
|
{
|
||||||
|
CV_StealthSet(&cv_skin4, DEFAULTSKIN);
|
||||||
|
cv_skin4.value = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally write out the complete packet and send it off.
|
||||||
|
WRITESTRINGN(p, cv_playername4.zstring, MAXPLAYERNAME);
|
||||||
|
WRITEUINT8(p, (UINT8)cv_playercolor4.value);
|
||||||
|
WRITEUINT8(p, (UINT8)cv_skin4.value);
|
||||||
|
SendNetXCmd4(XD_NAMEANDCOLOR, buf, p - buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
||||||
|
@ -2005,16 +2104,20 @@ void D_SetupVote(void)
|
||||||
|
|
||||||
void D_ModifyClientVote(SINT8 voted, UINT8 splitplayer)
|
void D_ModifyClientVote(SINT8 voted, UINT8 splitplayer)
|
||||||
{
|
{
|
||||||
char buf[1];
|
char buf[2];
|
||||||
char *p = buf;
|
char *p = buf;
|
||||||
|
UINT8 player = consoleplayer;
|
||||||
|
|
||||||
|
if (splitplayer == 1)
|
||||||
|
player = secondarydisplayplayer;
|
||||||
|
else if (splitplayer == 2)
|
||||||
|
player = thirddisplayplayer;
|
||||||
|
else if (splitplayer == 3)
|
||||||
|
player = fourthdisplayplayer;
|
||||||
|
|
||||||
if (splitplayer > 0) // Don't actually send anything for splitscreen
|
|
||||||
votes[splitplayer] = voted;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WRITESINT8(p, voted);
|
WRITESINT8(p, voted);
|
||||||
SendNetXCmd(XD_MODIFYVOTE, &buf, 1);
|
WRITEUINT8(p, player);
|
||||||
}
|
SendNetXCmd(XD_MODIFYVOTE, &buf, 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
void D_PickVote(void)
|
void D_PickVote(void)
|
||||||
|
@ -4631,7 +4734,10 @@ static void Got_SetupVotecmd(UINT8 **cp, INT32 playernum)
|
||||||
static void Got_ModifyVotecmd(UINT8 **cp, INT32 playernum)
|
static void Got_ModifyVotecmd(UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
SINT8 voted = READSINT8(*cp);
|
SINT8 voted = READSINT8(*cp);
|
||||||
votes[playernum] = voted;
|
UINT8 p = READUINT8(*cp);
|
||||||
|
|
||||||
|
(void)playernum;
|
||||||
|
votes[p] = voted;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Got_PickVotecmd(UINT8 **cp, INT32 playernum)
|
static void Got_PickVotecmd(UINT8 **cp, INT32 playernum)
|
||||||
|
|
|
@ -132,7 +132,7 @@ extern consvar_t cv_karteliminatelast;
|
||||||
extern consvar_t cv_votetime;
|
extern consvar_t cv_votetime;
|
||||||
|
|
||||||
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugshrink, cv_kartdebugdistribution, cv_kartdebughuddrop;
|
extern consvar_t cv_kartdebugitem, cv_kartdebugamount, cv_kartdebugshrink, cv_kartdebugdistribution, cv_kartdebughuddrop;
|
||||||
extern consvar_t cv_kartdebugcheckpoint;
|
extern consvar_t cv_kartdebugcheckpoint, cv_kartdebugnodes;
|
||||||
|
|
||||||
extern consvar_t cv_itemfinder;
|
extern consvar_t cv_itemfinder;
|
||||||
|
|
||||||
|
@ -195,9 +195,10 @@ typedef enum
|
||||||
XD_SETUPVOTE, // 22
|
XD_SETUPVOTE, // 22
|
||||||
XD_MODIFYVOTE, // 23
|
XD_MODIFYVOTE, // 23
|
||||||
XD_PICKVOTE, // 24
|
XD_PICKVOTE, // 24
|
||||||
|
XD_REMOVEPLAYER,// 25
|
||||||
#ifdef HAVE_BLUA
|
#ifdef HAVE_BLUA
|
||||||
XD_LUACMD, // 25
|
XD_LUACMD, // 26
|
||||||
XD_LUAVAR, // 26
|
XD_LUAVAR, // 27
|
||||||
#endif
|
#endif
|
||||||
MAXNETXCMD
|
MAXNETXCMD
|
||||||
} netxcmd_t;
|
} netxcmd_t;
|
||||||
|
|
|
@ -3122,7 +3122,7 @@ boolean G_GametypeHasSpectators(void)
|
||||||
#if 0
|
#if 0
|
||||||
return (gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE);
|
return (gametype != GT_COOP && gametype != GT_COMPETITION && gametype != GT_RACE);
|
||||||
#else
|
#else
|
||||||
return (!splitscreen);//true;
|
return (netgame); //true
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,6 +62,7 @@ extern consvar_t cv_turnaxis2,cv_moveaxis2,cv_brakeaxis2,cv_aimaxis2,cv_lookaxis
|
||||||
extern consvar_t cv_turnaxis3,cv_moveaxis3,cv_brakeaxis3,cv_aimaxis3,cv_lookaxis3,cv_fireaxis3,cv_driftaxis3;
|
extern consvar_t cv_turnaxis3,cv_moveaxis3,cv_brakeaxis3,cv_aimaxis3,cv_lookaxis3,cv_fireaxis3,cv_driftaxis3;
|
||||||
extern consvar_t cv_turnaxis4,cv_moveaxis4,cv_brakeaxis4,cv_aimaxis4,cv_lookaxis4,cv_fireaxis4,cv_driftaxis4;
|
extern consvar_t cv_turnaxis4,cv_moveaxis4,cv_brakeaxis4,cv_aimaxis4,cv_lookaxis4,cv_fireaxis4,cv_driftaxis4;
|
||||||
extern consvar_t cv_ghost_besttime, cv_ghost_bestlap, cv_ghost_last, cv_ghost_guest, cv_ghost_staff;
|
extern consvar_t cv_ghost_besttime, cv_ghost_bestlap, cv_ghost_last, cv_ghost_guest, cv_ghost_staff;
|
||||||
|
extern consvar_t cv_splitplayers;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
|
|
111
src/hu_stuff.c
111
src/hu_stuff.c
|
@ -1066,6 +1066,26 @@ boolean HU_Responder(event_t *ev)
|
||||||
|
|
||||||
// only KeyDown events now...
|
// only KeyDown events now...
|
||||||
|
|
||||||
|
// Shoot, to prevent P1 chatting from ruining the game for everyone else, it's either:
|
||||||
|
// A. completely disallow opening chat entirely in online splitscreen
|
||||||
|
// or B. iterate through all controls to make sure it's bound to player 1 before eating
|
||||||
|
// You can see which one I chose.
|
||||||
|
// (Unless if you're sharing a keyboard, since you probably establish when you start chatting that you have dibs on it...)
|
||||||
|
// (Ahhh, the good ol days when I was a kid who couldn't afford an extra USB controller...)
|
||||||
|
|
||||||
|
if (ev->data1 >= KEY_MOUSE1)
|
||||||
|
{
|
||||||
|
INT32 i;
|
||||||
|
for (i = 0; i < num_gamecontrols; i++)
|
||||||
|
{
|
||||||
|
if (gamecontrol[i][0] == ev->data1 || gamecontrol[i][1] == ev->data1)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == num_gamecontrols)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if (!chat_on)
|
if (!chat_on)
|
||||||
{
|
{
|
||||||
// enter chat mode
|
// enter chat mode
|
||||||
|
@ -1269,6 +1289,7 @@ static void HU_drawMiniChat(void)
|
||||||
{
|
{
|
||||||
INT32 x = chatx+2;
|
INT32 x = chatx+2;
|
||||||
INT32 charwidth = 4, charheight = 6;
|
INT32 charwidth = 4, charheight = 6;
|
||||||
|
INT32 boxw = cv_chatwidth.value;
|
||||||
INT32 dx = 0, dy = 0;
|
INT32 dx = 0, dy = 0;
|
||||||
size_t i = chat_nummsg_min;
|
size_t i = chat_nummsg_min;
|
||||||
boolean prev_linereturn = false; // a hack to prevent double \n while I have no idea why they happen in the first place.
|
boolean prev_linereturn = false; // a hack to prevent double \n while I have no idea why they happen in the first place.
|
||||||
|
@ -1280,9 +1301,12 @@ static void HU_drawMiniChat(void)
|
||||||
if (!chat_nummsg_min)
|
if (!chat_nummsg_min)
|
||||||
return; // needless to say it's useless to do anything if we don't have anything to draw.
|
return; // needless to say it's useless to do anything if we don't have anything to draw.
|
||||||
|
|
||||||
|
if (splitscreen > 1)
|
||||||
|
boxw = max(64, boxw/2);
|
||||||
|
|
||||||
for (; i>0; i--)
|
for (; i>0; i--)
|
||||||
{
|
{
|
||||||
const char *msg = CHAT_WordWrap(x+2, cv_chatwidth.value-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
|
const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
|
||||||
size_t j = 0;
|
size_t j = 0;
|
||||||
INT32 linescount = 0;
|
INT32 linescount = 0;
|
||||||
|
|
||||||
|
@ -1315,7 +1339,7 @@ static void HU_drawMiniChat(void)
|
||||||
}
|
}
|
||||||
prev_linereturn = false;
|
prev_linereturn = false;
|
||||||
dx += charwidth;
|
dx += charwidth;
|
||||||
if (dx >= cv_chatwidth.value)
|
if (dx >= boxw)
|
||||||
{
|
{
|
||||||
dx = 0;
|
dx = 0;
|
||||||
linescount += 1;
|
linescount += 1;
|
||||||
|
@ -1326,7 +1350,17 @@ static void HU_drawMiniChat(void)
|
||||||
msglines += linescount+1;
|
msglines += linescount+1;
|
||||||
}
|
}
|
||||||
|
|
||||||
y = chaty - charheight*(msglines+1) - (cv_kartspeedometer.value ? 16 : 0);
|
y = chaty - charheight*(msglines+1);
|
||||||
|
|
||||||
|
if (splitscreen)
|
||||||
|
{
|
||||||
|
y -= BASEVIDHEIGHT/2;
|
||||||
|
if (splitscreen > 1)
|
||||||
|
y += 16;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
y -= (cv_kartspeedometer.value ? 16 : 0);
|
||||||
|
|
||||||
dx = 0;
|
dx = 0;
|
||||||
dy = 0;
|
dy = 0;
|
||||||
i = 0;
|
i = 0;
|
||||||
|
@ -1338,7 +1372,7 @@ static void HU_drawMiniChat(void)
|
||||||
INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below...
|
INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below...
|
||||||
INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one.
|
INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one.
|
||||||
size_t j = 0;
|
size_t j = 0;
|
||||||
const char *msg = CHAT_WordWrap(x+2, cv_chatwidth.value-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
|
const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
|
||||||
UINT8 *colormap = NULL;
|
UINT8 *colormap = NULL;
|
||||||
|
|
||||||
while(msg[j]) // iterate through msg
|
while(msg[j]) // iterate through msg
|
||||||
|
@ -1376,7 +1410,7 @@ static void HU_drawMiniChat(void)
|
||||||
|
|
||||||
dx += charwidth;
|
dx += charwidth;
|
||||||
prev_linereturn = false;
|
prev_linereturn = false;
|
||||||
if (dx >= cv_chatwidth.value)
|
if (dx >= boxw)
|
||||||
{
|
{
|
||||||
dx = 0;
|
dx = 0;
|
||||||
dy += charheight;
|
dy += charheight;
|
||||||
|
@ -1397,6 +1431,7 @@ static void HU_drawMiniChat(void)
|
||||||
static void HU_drawChatLog(INT32 offset)
|
static void HU_drawChatLog(INT32 offset)
|
||||||
{
|
{
|
||||||
INT32 charwidth = 4, charheight = 6;
|
INT32 charwidth = 4, charheight = 6;
|
||||||
|
INT32 boxw = cv_chatwidth.value, boxh = cv_chatheight.value;
|
||||||
INT32 x = chatx+2, y, dx = 0, dy = 0;
|
INT32 x = chatx+2, y, dx = 0, dy = 0;
|
||||||
UINT32 i = 0;
|
UINT32 i = 0;
|
||||||
INT32 chat_topy, chat_bottomy;
|
INT32 chat_topy, chat_bottomy;
|
||||||
|
@ -1406,17 +1441,34 @@ static void HU_drawChatLog(INT32 offset)
|
||||||
if (chat_scroll > chat_maxscroll)
|
if (chat_scroll > chat_maxscroll)
|
||||||
chat_scroll = chat_maxscroll;
|
chat_scroll = chat_maxscroll;
|
||||||
|
|
||||||
y = chaty - offset*charheight - (chat_scroll*charheight) - cv_chatheight.value*charheight - 12 - (cv_kartspeedometer.value ? 16 : 0);
|
if (splitscreen)
|
||||||
chat_topy = y + chat_scroll*charheight;
|
{
|
||||||
chat_bottomy = chat_topy + cv_chatheight.value*charheight;
|
boxh = max(6, boxh/2);
|
||||||
|
if (splitscreen > 1)
|
||||||
|
boxw = max(64, boxw/2);
|
||||||
|
}
|
||||||
|
|
||||||
V_DrawFillConsoleMap(chatx, chat_topy, cv_chatwidth.value, cv_chatheight.value*charheight +2, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); // log box
|
y = chaty - offset*charheight - (chat_scroll*charheight) - boxh*charheight - 12;
|
||||||
|
|
||||||
|
if (splitscreen)
|
||||||
|
{
|
||||||
|
y -= BASEVIDHEIGHT/2;
|
||||||
|
if (splitscreen > 1)
|
||||||
|
y += 16;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
y -= (cv_kartspeedometer.value ? 16 : 0);
|
||||||
|
|
||||||
|
chat_topy = y + chat_scroll*charheight;
|
||||||
|
chat_bottomy = chat_topy + boxh*charheight;
|
||||||
|
|
||||||
|
V_DrawFillConsoleMap(chatx, chat_topy, boxw, boxh*charheight +2, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); // log box
|
||||||
|
|
||||||
for (i=0; i<chat_nummsg_log; i++) // iterate through our chatlog
|
for (i=0; i<chat_nummsg_log; i++) // iterate through our chatlog
|
||||||
{
|
{
|
||||||
INT32 clrflag = 0;
|
INT32 clrflag = 0;
|
||||||
INT32 j = 0;
|
INT32 j = 0;
|
||||||
const char *msg = CHAT_WordWrap(x+2, cv_chatwidth.value-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
|
const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
|
||||||
UINT8 *colormap = NULL;
|
UINT8 *colormap = NULL;
|
||||||
while(msg[j]) // iterate through msg
|
while(msg[j]) // iterate through msg
|
||||||
{
|
{
|
||||||
|
@ -1448,7 +1500,7 @@ static void HU_drawChatLog(INT32 offset)
|
||||||
}
|
}
|
||||||
|
|
||||||
dx += charwidth;
|
dx += charwidth;
|
||||||
if (dx >= cv_chatwidth.value-charwidth-2 && i<chat_nummsg_log && msg[j] >= HU_FONTSTART) // end of message shouldn't count, nor should invisible characters!!!!
|
if (dx >= boxw-charwidth-2 && i<chat_nummsg_log && msg[j] >= HU_FONTSTART) // end of message shouldn't count, nor should invisible characters!!!!
|
||||||
{
|
{
|
||||||
dx = 0;
|
dx = 0;
|
||||||
dy += charheight;
|
dy += charheight;
|
||||||
|
@ -1466,10 +1518,10 @@ static void HU_drawChatLog(INT32 offset)
|
||||||
|
|
||||||
// getmaxscroll through a lazy hack. We do all these loops, so let's not do more loops that are gonna lag the game more. :P
|
// getmaxscroll through a lazy hack. We do all these loops, so let's not do more loops that are gonna lag the game more. :P
|
||||||
chat_maxscroll = (dy/charheight); // welcome to C, we don't know what min() and max() are.
|
chat_maxscroll = (dy/charheight); // welcome to C, we don't know what min() and max() are.
|
||||||
if (chat_maxscroll <= (UINT32)cv_chatheight.value)
|
if (chat_maxscroll <= (UINT32)boxh)
|
||||||
chat_maxscroll = 0;
|
chat_maxscroll = 0;
|
||||||
else
|
else
|
||||||
chat_maxscroll -= cv_chatheight.value;
|
chat_maxscroll -= boxh;
|
||||||
|
|
||||||
// if we're not bound by the time, autoscroll for next frame:
|
// if we're not bound by the time, autoscroll for next frame:
|
||||||
if (atbottom)
|
if (atbottom)
|
||||||
|
@ -1502,13 +1554,26 @@ static INT16 typelines = 1; // number of drawfill lines we need. it's some weird
|
||||||
static void HU_DrawChat(void)
|
static void HU_DrawChat(void)
|
||||||
{
|
{
|
||||||
INT32 charwidth = 4, charheight = 6;
|
INT32 charwidth = 4, charheight = 6;
|
||||||
INT32 t = 0, c = 0, y = chaty - (typelines*charheight) - (cv_kartspeedometer.value ? 16 : 0);
|
INT32 boxw = cv_chatwidth.value;
|
||||||
|
INT32 t = 0, c = 0, y = chaty - (typelines*charheight);
|
||||||
UINT32 i = 0, saylen = strlen(w_chat); // You learn new things everyday!
|
UINT32 i = 0, saylen = strlen(w_chat); // You learn new things everyday!
|
||||||
INT32 cflag = 0;
|
INT32 cflag = 0;
|
||||||
const char *ntalk = "Say: ", *ttalk = "Team: ";
|
const char *ntalk = "Say: ", *ttalk = "Team: ";
|
||||||
const char *talk = ntalk;
|
const char *talk = ntalk;
|
||||||
const char *mute = "Chat has been muted.";
|
const char *mute = "Chat has been muted.";
|
||||||
|
|
||||||
|
if (splitscreen)
|
||||||
|
{
|
||||||
|
y -= BASEVIDHEIGHT/2;
|
||||||
|
if (splitscreen > 1)
|
||||||
|
{
|
||||||
|
y += 16;
|
||||||
|
boxw = max(64, boxw/2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
y -= (cv_kartspeedometer.value ? 16 : 0);
|
||||||
|
|
||||||
if (teamtalk)
|
if (teamtalk)
|
||||||
{
|
{
|
||||||
talk = ttalk;
|
talk = ttalk;
|
||||||
|
@ -1527,7 +1592,7 @@ static void HU_DrawChat(void)
|
||||||
cflag = V_GRAYMAP; // set text in gray if chat is muted.
|
cflag = V_GRAYMAP; // set text in gray if chat is muted.
|
||||||
}
|
}
|
||||||
|
|
||||||
V_DrawFillConsoleMap(chatx, y-1, cv_chatwidth.value, (typelines*charheight), 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT);
|
V_DrawFillConsoleMap(chatx, y-1, boxw, (typelines*charheight), 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT);
|
||||||
|
|
||||||
while (talk[i])
|
while (talk[i])
|
||||||
{
|
{
|
||||||
|
@ -1560,7 +1625,7 @@ static void HU_DrawChat(void)
|
||||||
boolean skippedline = false;
|
boolean skippedline = false;
|
||||||
if (c_input == (i+1))
|
if (c_input == (i+1))
|
||||||
{
|
{
|
||||||
int cursorx = (c+charwidth < cv_chatwidth.value-charwidth) ? (chatx + 2 + c+charwidth) : (chatx+1); // we may have to go down.
|
int cursorx = (c+charwidth < boxw-charwidth) ? (chatx + 2 + c+charwidth) : (chatx+1); // we may have to go down.
|
||||||
int cursory = (cursorx != chatx+1) ? (y) : (y+charheight);
|
int cursory = (cursorx != chatx+1) ? (y) : (y+charheight);
|
||||||
if (hu_tick < 4)
|
if (hu_tick < 4)
|
||||||
V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
|
V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
|
||||||
|
@ -1580,7 +1645,7 @@ static void HU_DrawChat(void)
|
||||||
V_DrawChatCharacter(chatx + c + 2, y, w_chat[i++] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, !cv_allcaps.value, NULL);
|
V_DrawChatCharacter(chatx + c + 2, y, w_chat[i++] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, !cv_allcaps.value, NULL);
|
||||||
|
|
||||||
c += charwidth;
|
c += charwidth;
|
||||||
if (c > cv_chatwidth.value-(charwidth*2) && !skippedline)
|
if (c > boxw-(charwidth*2) && !skippedline)
|
||||||
{
|
{
|
||||||
c = 0;
|
c = 0;
|
||||||
y += charheight;
|
y += charheight;
|
||||||
|
@ -1593,6 +1658,14 @@ static void HU_DrawChat(void)
|
||||||
{
|
{
|
||||||
INT32 count = 0;
|
INT32 count = 0;
|
||||||
INT32 p_dispy = chaty - charheight -1;
|
INT32 p_dispy = chaty - charheight -1;
|
||||||
|
if (splitscreen)
|
||||||
|
{
|
||||||
|
p_dispy -= BASEVIDHEIGHT/2;
|
||||||
|
if (splitscreen > 1)
|
||||||
|
p_dispy += 16;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
p_dispy -= (cv_kartspeedometer.value ? 16 : 0);
|
||||||
i = 0;
|
i = 0;
|
||||||
for(i=0; (i<MAXPLAYERS); i++)
|
for(i=0; (i<MAXPLAYERS); i++)
|
||||||
{
|
{
|
||||||
|
@ -1643,8 +1716,8 @@ static void HU_DrawChat(void)
|
||||||
{
|
{
|
||||||
char name[MAXPLAYERNAME+1];
|
char name[MAXPLAYERNAME+1];
|
||||||
strlcpy(name, player_names[i], 7); // shorten name to 7 characters.
|
strlcpy(name, player_names[i], 7); // shorten name to 7 characters.
|
||||||
V_DrawFillConsoleMap(chatx+ cv_chatwidth.value + 2, p_dispy- (6*count), 48, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); // fill it like the chat so the text doesn't become hard to read because of the hud.
|
V_DrawFillConsoleMap(chatx+ boxw + 2, p_dispy- (6*count), 48, 6, 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); // fill it like the chat so the text doesn't become hard to read because of the hud.
|
||||||
V_DrawSmallString(chatx+ cv_chatwidth.value + 4, p_dispy- (6*count), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, va("\x82%d\x80 - %s", i, name));
|
V_DrawSmallString(chatx+ boxw + 4, p_dispy- (6*count), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, va("\x82%d\x80 - %s", i, name));
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
51
src/k_kart.c
51
src/k_kart.c
|
@ -434,6 +434,7 @@ void K_RegisterKartStuff(void)
|
||||||
CV_RegisterVar(&cv_kartdebughuddrop);
|
CV_RegisterVar(&cv_kartdebughuddrop);
|
||||||
|
|
||||||
CV_RegisterVar(&cv_kartdebugcheckpoint);
|
CV_RegisterVar(&cv_kartdebugcheckpoint);
|
||||||
|
CV_RegisterVar(&cv_kartdebugnodes);
|
||||||
}
|
}
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
@ -895,7 +896,35 @@ static void K_KartItemRoulette(player_t *player, ticcmd_t *cmd)
|
||||||
|
|
||||||
// This makes the roulette produce the random noises.
|
// This makes the roulette produce the random noises.
|
||||||
if ((player->kartstuff[k_itemroulette] % 3) == 1 && P_IsLocalPlayer(player))
|
if ((player->kartstuff[k_itemroulette] % 3) == 1 && P_IsLocalPlayer(player))
|
||||||
S_StartSound(NULL, sfx_mkitm1 + ((player->kartstuff[k_itemroulette] / 3) % 8));
|
{
|
||||||
|
#define PLAYROULETTESND S_StartSound(NULL, sfx_mkitm1 + ((player->kartstuff[k_itemroulette] / 3) % 8));
|
||||||
|
if (splitscreen)
|
||||||
|
{
|
||||||
|
if (players[displayplayer].kartstuff[k_itemroulette])
|
||||||
|
{
|
||||||
|
if (player == &players[displayplayer])
|
||||||
|
PLAYROULETTESND;
|
||||||
|
}
|
||||||
|
else if (players[secondarydisplayplayer].kartstuff[k_itemroulette])
|
||||||
|
{
|
||||||
|
if (player == &players[secondarydisplayplayer])
|
||||||
|
PLAYROULETTESND;
|
||||||
|
}
|
||||||
|
else if (players[thirddisplayplayer].kartstuff[k_itemroulette] && splitscreen > 1)
|
||||||
|
{
|
||||||
|
if (player == &players[thirddisplayplayer])
|
||||||
|
PLAYROULETTESND;
|
||||||
|
}
|
||||||
|
else if (players[fourthdisplayplayer].kartstuff[k_itemroulette] && splitscreen > 2)
|
||||||
|
{
|
||||||
|
if (player == &players[fourthdisplayplayer])
|
||||||
|
PLAYROULETTESND;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
PLAYROULETTESND;
|
||||||
|
#undef PLAYROULETTESND
|
||||||
|
}
|
||||||
|
|
||||||
roulettestop = TICRATE + (3*(pingame - player->kartstuff[k_position]));
|
roulettestop = TICRATE + (3*(pingame - player->kartstuff[k_position]));
|
||||||
|
|
||||||
|
@ -1242,7 +1271,7 @@ static void K_UpdateOffroad(player_t *player)
|
||||||
}
|
}
|
||||||
|
|
||||||
// These have to go earlier than its sisters because of K_RespawnChecker...
|
// These have to go earlier than its sisters because of K_RespawnChecker...
|
||||||
static void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master)
|
void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master)
|
||||||
{
|
{
|
||||||
// flipping
|
// flipping
|
||||||
mo->eflags = (mo->eflags & ~MFE_VERTICALFLIP)|(master->eflags & MFE_VERTICALFLIP);
|
mo->eflags = (mo->eflags & ~MFE_VERTICALFLIP)|(master->eflags & MFE_VERTICALFLIP);
|
||||||
|
@ -5109,8 +5138,10 @@ void K_MoveKartPlayer(player_t *player, boolean onground)
|
||||||
player->mo->eflags |= MFE_DRAWONLYFORP3;
|
player->mo->eflags |= MFE_DRAWONLYFORP3;
|
||||||
else if (player == &players[fourthdisplayplayer] && splitscreen > 2)
|
else if (player == &players[fourthdisplayplayer] && splitscreen > 2)
|
||||||
player->mo->eflags |= MFE_DRAWONLYFORP4;
|
player->mo->eflags |= MFE_DRAWONLYFORP4;
|
||||||
else
|
else if (player == &players[consoleplayer])
|
||||||
player->mo->eflags |= MFE_DRAWONLYFORP1;
|
player->mo->eflags |= MFE_DRAWONLYFORP1;
|
||||||
|
else
|
||||||
|
player->mo->flags2 |= MF2_DONTDRAW;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
player->mo->eflags &= ~(MFE_DRAWONLYFORP1|MFE_DRAWONLYFORP2|MFE_DRAWONLYFORP3|MFE_DRAWONLYFORP4);
|
player->mo->eflags &= ~(MFE_DRAWONLYFORP1|MFE_DRAWONLYFORP2|MFE_DRAWONLYFORP3|MFE_DRAWONLYFORP4);
|
||||||
|
@ -7049,12 +7080,17 @@ static void K_drawBattleFullscreen(void)
|
||||||
x = BASEVIDWIDTH/4;
|
x = BASEVIDWIDTH/4;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
if (stplyr->exiting)
|
||||||
{
|
{
|
||||||
if (stplyr == &players[secondarydisplayplayer])
|
if (stplyr == &players[secondarydisplayplayer])
|
||||||
x = BASEVIDWIDTH-96;
|
x = BASEVIDWIDTH-96;
|
||||||
else
|
else
|
||||||
x = 96;
|
x = 96;
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
scale /= 2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stplyr->exiting)
|
if (stplyr->exiting)
|
||||||
|
@ -7574,7 +7610,7 @@ void K_drawKartHUD(void)
|
||||||
K_drawKartMinimap();
|
K_drawKartMinimap();
|
||||||
|
|
||||||
// Draw full screen stuff that turns off the rest of the HUD
|
// Draw full screen stuff that turns off the rest of the HUD
|
||||||
if (mapreset)
|
if (mapreset && stplyr == &players[displayplayer])
|
||||||
{
|
{
|
||||||
K_drawChallengerScreen();
|
K_drawChallengerScreen();
|
||||||
return;
|
return;
|
||||||
|
@ -7690,6 +7726,13 @@ void K_drawKartHUD(void)
|
||||||
|
|
||||||
if (cv_kartdebugcheckpoint.value)
|
if (cv_kartdebugcheckpoint.value)
|
||||||
K_drawCheckpointDebugger();
|
K_drawCheckpointDebugger();
|
||||||
|
|
||||||
|
if (cv_kartdebugnodes.value)
|
||||||
|
{
|
||||||
|
UINT8 p;
|
||||||
|
for (p = 0; p < MAXPLAYERS; p++)
|
||||||
|
V_DrawString(8, 64+(8*p), V_YELLOWMAP, va("%d - %d", p, playernode[p]));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//}
|
//}
|
||||||
|
|
|
@ -21,6 +21,7 @@ void K_RegisterKartStuff(void);
|
||||||
boolean K_IsPlayerLosing(player_t *player);
|
boolean K_IsPlayerLosing(player_t *player);
|
||||||
boolean K_IsPlayerWanted(player_t *player);
|
boolean K_IsPlayerWanted(player_t *player);
|
||||||
void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid);
|
void K_KartBouncing(mobj_t *mobj1, mobj_t *mobj2, boolean bounce, boolean solid);
|
||||||
|
void K_MatchGenericExtraFlags(mobj_t *mo, mobj_t *master);
|
||||||
void K_RespawnChecker(player_t *player);
|
void K_RespawnChecker(player_t *player);
|
||||||
void K_KartMoveAnimation(player_t *player);
|
void K_KartMoveAnimation(player_t *player);
|
||||||
void K_KartPlayerThink(player_t *player, ticcmd_t *cmd);
|
void K_KartPlayerThink(player_t *player, ticcmd_t *cmd);
|
||||||
|
|
|
@ -2094,6 +2094,19 @@ static int lib_kKartBouncing(lua_State *L)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int lib_kMatchGenericExtraFlags(lua_State *L)
|
||||||
|
{
|
||||||
|
mobj_t *mo = *((mobj_t **)luaL_checkudata(L, 1, META_MOBJ));
|
||||||
|
mobj_t *master = *((mobj_t **)luaL_checkudata(L, 2, META_MOBJ));
|
||||||
|
NOHUD
|
||||||
|
if (!mo)
|
||||||
|
return LUA_ErrInvalid(L, "mobj_t");
|
||||||
|
if (!master)
|
||||||
|
return LUA_ErrInvalid(L, "mobj_t");
|
||||||
|
K_MatchGenericExtraFlags(mo, master);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int lib_kDoInstashield(lua_State *L)
|
static int lib_kDoInstashield(lua_State *L)
|
||||||
{
|
{
|
||||||
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
player_t *player = *((player_t **)luaL_checkudata(L, 1, META_PLAYER));
|
||||||
|
@ -2490,6 +2503,7 @@ static luaL_Reg lib[] = {
|
||||||
{"K_IsPlayerLosing",lib_kIsPlayerLosing},
|
{"K_IsPlayerLosing",lib_kIsPlayerLosing},
|
||||||
{"K_IsPlayerWanted",lib_kIsPlayerWanted},
|
{"K_IsPlayerWanted",lib_kIsPlayerWanted},
|
||||||
{"K_KartBouncing",lib_kKartBouncing},
|
{"K_KartBouncing",lib_kKartBouncing},
|
||||||
|
{"K_MatchGenericExtraFlags",lib_kMatchGenericExtraFlags},
|
||||||
{"K_DoInstashield",lib_kDoInstashield},
|
{"K_DoInstashield",lib_kDoInstashield},
|
||||||
{"K_SpinPlayer",lib_kSpinPlayer},
|
{"K_SpinPlayer",lib_kSpinPlayer},
|
||||||
{"K_SquishPlayer",lib_kSquishPlayer},
|
{"K_SquishPlayer",lib_kSquishPlayer},
|
||||||
|
|
598
src/m_menu.c
598
src/m_menu.c
File diff suppressed because it is too large
Load diff
17
src/p_mobj.c
17
src/p_mobj.c
|
@ -6792,22 +6792,18 @@ void P_MobjThinker(mobj_t *mobj)
|
||||||
if (mobj->target && mobj->target->health
|
if (mobj->target && mobj->target->health
|
||||||
&& mobj->target->player && !mobj->target->player->spectator
|
&& mobj->target->player && !mobj->target->player->spectator
|
||||||
&& mobj->target->player->health && mobj->target->player->playerstate != PST_DEAD
|
&& mobj->target->player->health && mobj->target->player->playerstate != PST_DEAD
|
||||||
&& players[displayplayer].mo && !players[displayplayer].spectator)
|
/*&& players[displayplayer].mo && !players[displayplayer].spectator*/)
|
||||||
{
|
{
|
||||||
fixed_t scale = mobj->target->scale;
|
fixed_t scale = mobj->target->scale;
|
||||||
mobj->color = mobj->target->color;
|
mobj->color = mobj->target->color;
|
||||||
|
K_MatchGenericExtraFlags(mobj, mobj->target);
|
||||||
|
|
||||||
if (G_RaceGametype()
|
if ((G_RaceGametype() || mobj->target->player->kartstuff[k_bumper] <= 0)
|
||||||
|| mobj->target->player == &players[displayplayer]
|
|
||||||
|| mobj->target->player->kartstuff[k_bumper] <= 0
|
|
||||||
|| (mobj->target->player->mo->flags2 & MF2_DONTDRAW)
|
|
||||||
#if 1 // Set to 0 to test without needing to host
|
#if 1 // Set to 0 to test without needing to host
|
||||||
|| !netgame
|
|| ((mobj->target->player == &players[displayplayer]) || P_IsLocalPlayer(mobj->target->player))
|
||||||
#endif
|
#endif
|
||||||
)
|
)
|
||||||
mobj->flags2 |= MF2_DONTDRAW;
|
mobj->flags2 |= MF2_DONTDRAW;
|
||||||
else
|
|
||||||
mobj->flags2 &= ~MF2_DONTDRAW;
|
|
||||||
|
|
||||||
P_UnsetThingPosition(mobj);
|
P_UnsetThingPosition(mobj);
|
||||||
mobj->x = mobj->target->x;
|
mobj->x = mobj->target->x;
|
||||||
|
@ -6827,10 +6823,13 @@ void P_MobjThinker(mobj_t *mobj)
|
||||||
}
|
}
|
||||||
P_SetThingPosition(mobj);
|
P_SetThingPosition(mobj);
|
||||||
|
|
||||||
|
if (!splitscreen)
|
||||||
|
{
|
||||||
scale += FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayer].mo->x-mobj->target->x,
|
scale += FixedMul(FixedDiv(abs(P_AproxDistance(players[displayplayer].mo->x-mobj->target->x,
|
||||||
players[displayplayer].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale);
|
players[displayplayer].mo->y-mobj->target->y)), RING_DIST), mobj->target->scale);
|
||||||
if (scale > 16*FRACUNIT)
|
if (scale > 16*FRACUNIT)
|
||||||
scale = 16*FRACUNIT;
|
scale = 16*FRACUNIT;
|
||||||
|
}
|
||||||
mobj->destscale = scale;
|
mobj->destscale = scale;
|
||||||
|
|
||||||
if (!mobj->tracer)
|
if (!mobj->tracer)
|
||||||
|
@ -10122,6 +10121,8 @@ void P_SpawnPlayer(INT32 playernum)
|
||||||
continue;
|
continue;
|
||||||
if (!playeringame[i] || players[i].spectator)
|
if (!playeringame[i] || players[i].spectator)
|
||||||
continue;
|
continue;
|
||||||
|
if (players[i].jointime <= 1) // Prevent splitscreen hosters/joiners from only adding 1 player at a time in empty servers
|
||||||
|
continue;
|
||||||
pcount++;
|
pcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
69
src/p_user.c
69
src/p_user.c
|
@ -1140,35 +1140,58 @@ boolean P_EndingMusic(player_t *player)
|
||||||
{
|
{
|
||||||
char buffer[9];
|
char buffer[9];
|
||||||
boolean looping = true;
|
boolean looping = true;
|
||||||
|
INT32 bestlocalpos;
|
||||||
|
player_t *bestlocalplayer;
|
||||||
|
|
||||||
if (!P_IsLocalPlayer(player)) // Only applies to a local player
|
if (!P_IsLocalPlayer(player)) // Only applies to a local player
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Event - Level Finish
|
// Event - Level Finish
|
||||||
if (splitscreen
|
// Check for if this is valid or not
|
||||||
&& (players[displayplayer].exiting
|
if (splitscreen)
|
||||||
|| players[secondarydisplayplayer].exiting
|
|
||||||
|| ((splitscreen < 2) && players[thirddisplayplayer].exiting)
|
|
||||||
|| ((splitscreen < 3) && players[fourthdisplayplayer].exiting)))
|
|
||||||
{
|
{
|
||||||
sprintf(buffer, "k*ok");
|
if (!((players[displayplayer].exiting || (players[displayplayer].pflags & PF_TIMEOVER))
|
||||||
}
|
|| (players[secondarydisplayplayer].exiting || (players[secondarydisplayplayer].pflags & PF_TIMEOVER))
|
||||||
else if (player->pflags & PF_TIMEOVER) // || !player->lives) -- outta lives, outta time
|
|| ((splitscreen < 2) && (players[thirddisplayplayer].exiting || (players[thirddisplayplayer].pflags & PF_TIMEOVER)))
|
||||||
{
|
|| ((splitscreen < 3) && (players[fourthdisplayplayer].exiting || (players[fourthdisplayplayer].pflags & PF_TIMEOVER)))))
|
||||||
sprintf(buffer, "k*lose");
|
|
||||||
}
|
|
||||||
else if (player->exiting)
|
|
||||||
{
|
|
||||||
if (player->kartstuff[k_position] == 1)
|
|
||||||
sprintf(buffer, "k*win");
|
|
||||||
else if (K_IsPlayerLosing(player))
|
|
||||||
sprintf(buffer, "k*lose");
|
|
||||||
else
|
|
||||||
sprintf(buffer, "k*ok");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
|
bestlocalplayer = &players[displayplayer];
|
||||||
|
bestlocalpos = ((players[displayplayer].pflags & PF_TIMEOVER) ? MAXPLAYERS+1 : players[displayplayer].kartstuff[k_position]);
|
||||||
|
#define setbests(p) \
|
||||||
|
if (((players[p].pflags & PF_TIMEOVER) ? MAXPLAYERS+1 : players[p].kartstuff[k_position]) < bestlocalpos) \
|
||||||
|
{ \
|
||||||
|
bestlocalplayer = &players[p]; \
|
||||||
|
bestlocalpos = ((players[p].pflags & PF_TIMEOVER) ? MAXPLAYERS+1 : players[p].kartstuff[k_position]); \
|
||||||
|
}
|
||||||
|
setbests(secondarydisplayplayer);
|
||||||
|
if (splitscreen > 1)
|
||||||
|
setbests(thirddisplayplayer);
|
||||||
|
if (splitscreen > 2)
|
||||||
|
setbests(fourthdisplayplayer);
|
||||||
|
#undef setbests
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!(player->exiting || (player->pflags & PF_TIMEOVER)))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bestlocalplayer = player;
|
||||||
|
bestlocalpos = ((player->pflags & PF_TIMEOVER) ? MAXPLAYERS+1 : player->kartstuff[k_position]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (G_RaceGametype() && bestlocalpos == MAXPLAYERS+1)
|
||||||
|
sprintf(buffer, "k*lose"); // krfail, for eventual F-Zero death results theme
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (bestlocalpos == 1)
|
||||||
|
sprintf(buffer, "k*win");
|
||||||
|
else if (K_IsPlayerLosing(bestlocalplayer))
|
||||||
|
sprintf(buffer, "k*lose");
|
||||||
|
else
|
||||||
|
sprintf(buffer, "k*ok");
|
||||||
|
}
|
||||||
|
|
||||||
S_SpeedMusic(1.0f);
|
S_SpeedMusic(1.0f);
|
||||||
|
|
||||||
if (G_RaceGametype())
|
if (G_RaceGametype())
|
||||||
|
@ -8931,7 +8954,7 @@ void P_PlayerThink(player_t *player)
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SEENAMES
|
#ifdef SEENAMES
|
||||||
if (netgame && player == &players[displayplayer] && !(leveltime % (TICRATE/5)))
|
if (netgame && player == &players[displayplayer] && !(leveltime % (TICRATE/5)) && !splitscreen)
|
||||||
{
|
{
|
||||||
seenplayer = NULL;
|
seenplayer = NULL;
|
||||||
|
|
||||||
|
@ -9145,7 +9168,7 @@ void P_PlayerThink(player_t *player)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((netgame || splitscreen) && player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing])
|
if ((netgame || multiplayer) && player->spectator && cmd->buttons & BT_ATTACK && !player->powers[pw_flashing])
|
||||||
{
|
{
|
||||||
player->pflags ^= PF_WANTSTOJOIN;
|
player->pflags ^= PF_WANTSTOJOIN;
|
||||||
player->powers[pw_flashing] = TICRATE/2 + 1;
|
player->powers[pw_flashing] = TICRATE/2 + 1;
|
||||||
|
|
10
src/r_main.c
10
src/r_main.c
|
@ -185,16 +185,6 @@ void SplitScreen_OnChange(void)
|
||||||
{
|
{
|
||||||
UINT8 i;
|
UINT8 i;
|
||||||
|
|
||||||
if (!cv_debug && netgame)
|
|
||||||
{
|
|
||||||
if (splitscreen)
|
|
||||||
{
|
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("Splitscreen not supported in netplay, sorry!\n"));
|
|
||||||
splitscreen = 0;
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// recompute screen size
|
// recompute screen size
|
||||||
R_ExecuteSetViewSize();
|
R_ExecuteSetViewSize();
|
||||||
|
|
||||||
|
|
|
@ -1927,7 +1927,7 @@ static void ST_overlayDrawer(void)
|
||||||
)
|
)
|
||||||
ST_drawLevelTitle();
|
ST_drawLevelTitle();
|
||||||
|
|
||||||
if (!hu_showscores && !splitscreen && netgame && displayplayer == consoleplayer && !mapreset)
|
if (!hu_showscores && netgame && !mapreset)
|
||||||
{
|
{
|
||||||
/*if (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1)
|
/*if (G_GametypeUsesLives() && stplyr->lives <= 0 && countdown != 1)
|
||||||
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press F12 to watch another player."));
|
V_DrawCenteredString(BASEVIDWIDTH/2, STRINGY(132), 0, M_GetText("Press F12 to watch another player."));
|
||||||
|
@ -1952,6 +1952,21 @@ static void ST_overlayDrawer(void)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
// SRB2kart: changed positions & text
|
// SRB2kart: changed positions & text
|
||||||
|
if (splitscreen)
|
||||||
|
{
|
||||||
|
INT32 splitflags = K_calcSplitFlags(0);
|
||||||
|
V_DrawThinString(2, (BASEVIDHEIGHT/2)-20, V_YELLOWMAP|V_HUDTRANSHALF|splitflags, M_GetText("- SPECTATING -"));
|
||||||
|
if (stplyr->powers[pw_flashing])
|
||||||
|
V_DrawString(2, (BASEVIDHEIGHT/2)-10, V_HUDTRANSHALF|splitflags, M_GetText("Item - . . ."));
|
||||||
|
else if (stplyr->pflags & PF_WANTSTOJOIN)
|
||||||
|
V_DrawThinString(2, (BASEVIDHEIGHT/2)-10, V_HUDTRANSHALF|splitflags, M_GetText("Item - Cancel Join"));
|
||||||
|
/*else if (G_GametypeHasTeams())
|
||||||
|
V_DrawThinString(2, (BASEVIDHEIGHT/2)-10, V_HUDTRANSHALF|splitflags, M_GetText("Item - Join Team"));*/
|
||||||
|
else
|
||||||
|
V_DrawThinString(2, (BASEVIDHEIGHT/2)-10, V_HUDTRANSHALF|splitflags, M_GetText("Item - Join Game"));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
V_DrawString(2, BASEVIDHEIGHT-40, V_HUDTRANSHALF|V_YELLOWMAP, M_GetText("- SPECTATING -"));
|
V_DrawString(2, BASEVIDHEIGHT-40, V_HUDTRANSHALF|V_YELLOWMAP, M_GetText("- SPECTATING -"));
|
||||||
if (stplyr->powers[pw_flashing])
|
if (stplyr->powers[pw_flashing])
|
||||||
V_DrawString(2, BASEVIDHEIGHT-30, V_HUDTRANSHALF, M_GetText("Item - . . ."));
|
V_DrawString(2, BASEVIDHEIGHT-30, V_HUDTRANSHALF, M_GetText("Item - . . ."));
|
||||||
|
@ -1965,6 +1980,7 @@ static void ST_overlayDrawer(void)
|
||||||
V_DrawString(2, BASEVIDHEIGHT-10, V_HUDTRANSHALF, M_GetText("Brake - Sink"));
|
V_DrawString(2, BASEVIDHEIGHT-10, V_HUDTRANSHALF, M_GetText("Brake - Sink"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ST_drawDebugInfo();
|
ST_drawDebugInfo();
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue