mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-10-30 08:01:28 +00:00
Merge branch 'green-eggs-and-eggs' into 'master'
Write skins, colors, weaponprefs into XD_ADDPLAYER See merge request kart-krew-dev/ring-racers-internal!2808
This commit is contained in:
commit
ace8fb95be
5 changed files with 254 additions and 152 deletions
155
src/d_clisrv.c
155
src/d_clisrv.c
|
|
@ -964,12 +964,32 @@ static boolean CL_SendJoin(void)
|
||||||
for (i = 0; i <= splitscreen; i++)
|
for (i = 0; i <= splitscreen; i++)
|
||||||
{
|
{
|
||||||
// the MAXPLAYERS addition is necessary to communicate that g_localplayers is not yet safe to reference
|
// the MAXPLAYERS addition is necessary to communicate that g_localplayers is not yet safe to reference
|
||||||
|
player_config_t temp;
|
||||||
|
|
||||||
CleanupPlayerName(MAXPLAYERS+i, cv_playername[i].zstring);
|
CleanupPlayerName(MAXPLAYERS+i, cv_playername[i].zstring);
|
||||||
strncpy(netbuffer->u.clientcfg.names[i], cv_playername[i].zstring, MAXPLAYERNAME);
|
|
||||||
|
strncpy(temp.name, cv_playername[i].zstring, MAXPLAYERNAME);
|
||||||
|
D_FillPlayerSkinAndColor(i, NULL, &temp);
|
||||||
|
D_FillPlayerWeaponPref(i, &temp);
|
||||||
|
|
||||||
|
netbuffer->u.clientcfg.player_configs[i] = temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
// privacy shield for the local players not joining this session
|
// privacy shield for the local players not joining this session
|
||||||
for (; i < MAXSPLITSCREENPLAYERS; i++)
|
for (; i < MAXSPLITSCREENPLAYERS; i++)
|
||||||
strncpy(netbuffer->u.clientcfg.names[i], va("Player %c", 'A' + i), MAXPLAYERNAME);
|
{
|
||||||
|
player_config_t temp;
|
||||||
|
|
||||||
|
strncpy(temp.name, va("Player %c", 'A' + i), MAXPLAYERNAME);
|
||||||
|
temp.skin = 0;
|
||||||
|
temp.color = SKINCOLOR_NONE;
|
||||||
|
temp.follower = -1;
|
||||||
|
temp.follower_color = SKINCOLOR_NONE;
|
||||||
|
temp.weapon_prefs = 0;
|
||||||
|
temp.min_delay = 0;
|
||||||
|
|
||||||
|
netbuffer->u.clientcfg.player_configs[i] = temp;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(&netbuffer->u.clientcfg.availabilities, R_GetSkinAvailabilities(false, -1), MAXAVAILABILITY*sizeof(UINT8));
|
memcpy(&netbuffer->u.clientcfg.availabilities, R_GetSkinAvailabilities(false, -1), MAXAVAILABILITY*sizeof(UINT8));
|
||||||
|
|
||||||
|
|
@ -3751,6 +3771,12 @@ static void Got_AddPlayer(const UINT8 **p, INT32 playernum)
|
||||||
newplayer = &players[newplayernum];
|
newplayer = &players[newplayernum];
|
||||||
|
|
||||||
READSTRINGN(*p, player_names[newplayernum], MAXPLAYERNAME);
|
READSTRINGN(*p, player_names[newplayernum], MAXPLAYERNAME);
|
||||||
|
UINT16 skin = READUINT16(*p);
|
||||||
|
UINT16 color = READUINT16(*p);
|
||||||
|
INT16 follower = READINT16(*p);
|
||||||
|
UINT16 followercolor = READUINT16(*p);
|
||||||
|
UINT8 weaponprefs = READUINT8(*p);
|
||||||
|
UINT8 mindelay = READUINT8(*p);
|
||||||
READMEM(*p, public_key, PUBKEYLENGTH);
|
READMEM(*p, public_key, PUBKEYLENGTH);
|
||||||
READMEM(*p, clientpowerlevels[newplayernum], sizeof(((serverplayer_t *)0)->powerlevels));
|
READMEM(*p, clientpowerlevels[newplayernum], sizeof(((serverplayer_t *)0)->powerlevels));
|
||||||
|
|
||||||
|
|
@ -3790,13 +3816,20 @@ static void Got_AddPlayer(const UINT8 **p, INT32 playernum)
|
||||||
}
|
}
|
||||||
|
|
||||||
P_ForceLocalAngle(newplayer, newplayer->angleturn);
|
P_ForceLocalAngle(newplayer, newplayer->angleturn);
|
||||||
|
|
||||||
D_SendPlayerConfig(splitscreenplayer);
|
|
||||||
addedtogame = true;
|
addedtogame = true;
|
||||||
|
|
||||||
|
if (server)
|
||||||
|
{
|
||||||
|
for (i = 0; i < G_LocalSplitscreenPartySize(newplayernum); ++i)
|
||||||
|
playerdelaytable[G_LocalSplitscreenPartyMember(newplayernum, i)] = mindelay;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
players[newplayernum].splitscreenindex = splitscreenplayer;
|
newplayer->splitscreenindex = splitscreenplayer;
|
||||||
players[newplayernum].bot = false;
|
newplayer->bot = false;
|
||||||
|
|
||||||
|
D_PlayerChangeSkinAndColor(newplayer, skin, color, follower, followercolor);
|
||||||
|
WeaponPref_Set(newplayernum, weaponprefs);
|
||||||
|
|
||||||
// Previously called at the top of this function, commented as
|
// Previously called at the top of this function, commented as
|
||||||
// "caused desyncs in this spot :(". But we can't do this in
|
// "caused desyncs in this spot :(". But we can't do this in
|
||||||
|
|
@ -3979,14 +4012,10 @@ static void Got_ServerDeafenPlayer(const UINT8 **p, INT32 playernum)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static boolean SV_AddWaitingPlayers(SINT8 node, UINT8 *availabilities,
|
static boolean SV_AddWaitingPlayers(SINT8 node, UINT8 *availabilities, player_config_t configs[MAXSPLITSCREENPLAYERS])
|
||||||
const char *name, uint8_t *key, UINT16 *pwr,
|
|
||||||
const char *name2, uint8_t *key2, UINT16 *pwr2,
|
|
||||||
const char *name3, uint8_t *key3, UINT16 *pwr3,
|
|
||||||
const char *name4, uint8_t *key4, UINT16 *pwr4)
|
|
||||||
{
|
{
|
||||||
INT32 n, newplayernum, i;
|
INT32 n, newplayernum, i;
|
||||||
UINT8 buf[4 + MAXPLAYERNAME + PUBKEYLENGTH + MAXAVAILABILITY + sizeof(((serverplayer_t *)0)->powerlevels)];
|
UINT8 buf[4 + MAXPLAYERNAME + 10 + PUBKEYLENGTH + MAXAVAILABILITY + sizeof(((serverplayer_t *)0)->powerlevels)];
|
||||||
UINT8 *buf_p = buf;
|
UINT8 *buf_p = buf;
|
||||||
boolean newplayer = false;
|
boolean newplayer = false;
|
||||||
|
|
||||||
|
|
@ -4037,6 +4066,30 @@ static boolean SV_AddWaitingPlayers(SINT8 node, UINT8 *availabilities,
|
||||||
// before accepting the join
|
// before accepting the join
|
||||||
I_Assert(newplayernum < MAXPLAYERS);
|
I_Assert(newplayernum < MAXPLAYERS);
|
||||||
|
|
||||||
|
if (playerpernode[node] < 1)
|
||||||
|
{
|
||||||
|
nodetoplayer[node] = newplayernum;
|
||||||
|
}
|
||||||
|
else if (playerpernode[node] < 2)
|
||||||
|
{
|
||||||
|
nodetoplayer2[node] = newplayernum;
|
||||||
|
}
|
||||||
|
else if (playerpernode[node] < 3)
|
||||||
|
{
|
||||||
|
nodetoplayer3[node] = newplayernum;
|
||||||
|
}
|
||||||
|
else if (playerpernode[node] < 4)
|
||||||
|
{
|
||||||
|
nodetoplayer4[node] = newplayernum;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// I don't know if it's safe to assert here,
|
||||||
|
// but I do know this should not be allowed
|
||||||
|
// to be reached.
|
||||||
|
return newplayer;
|
||||||
|
}
|
||||||
|
|
||||||
playernode[newplayernum] = (UINT8)node;
|
playernode[newplayernum] = (UINT8)node;
|
||||||
|
|
||||||
// Reset the buffer to the start for multiple joiners
|
// Reset the buffer to the start for multiple joiners
|
||||||
|
|
@ -4045,34 +4098,16 @@ static boolean SV_AddWaitingPlayers(SINT8 node, UINT8 *availabilities,
|
||||||
WRITEUINT8(buf_p, (UINT8)node);
|
WRITEUINT8(buf_p, (UINT8)node);
|
||||||
WRITEUINT8(buf_p, newplayernum);
|
WRITEUINT8(buf_p, newplayernum);
|
||||||
|
|
||||||
if (playerpernode[node] < 1)
|
const player_config_t *config = &configs[playerpernode[node]];
|
||||||
{
|
WRITESTRINGN(buf_p, config->name, MAXPLAYERNAME);
|
||||||
nodetoplayer[node] = newplayernum;
|
WRITEUINT16(buf_p, config->skin);
|
||||||
WRITESTRINGN(buf_p, name, MAXPLAYERNAME);
|
WRITEUINT16(buf_p, config->color);
|
||||||
WRITEMEM(buf_p, key, PUBKEYLENGTH);
|
WRITEINT16(buf_p, config->follower);
|
||||||
WRITEMEM(buf_p, pwr, sizeof(((serverplayer_t *)0)->powerlevels));
|
WRITEUINT16(buf_p, config->follower_color);
|
||||||
}
|
WRITEUINT8(buf_p, config->weapon_prefs);
|
||||||
else if (playerpernode[node] < 2)
|
WRITEUINT8(buf_p, config->min_delay);
|
||||||
{
|
WRITEMEM(buf_p, config->key, PUBKEYLENGTH);
|
||||||
nodetoplayer2[node] = newplayernum;
|
WRITEMEM(buf_p, config->pwr, sizeof(((serverplayer_t *)0)->powerlevels));
|
||||||
WRITESTRINGN(buf_p, name2, MAXPLAYERNAME);
|
|
||||||
WRITEMEM(buf_p, key2, PUBKEYLENGTH);
|
|
||||||
WRITEMEM(buf_p, pwr2, sizeof(((serverplayer_t *)0)->powerlevels));
|
|
||||||
}
|
|
||||||
else if (playerpernode[node] < 3)
|
|
||||||
{
|
|
||||||
nodetoplayer3[node] = newplayernum;
|
|
||||||
WRITESTRINGN(buf_p, name3, MAXPLAYERNAME);
|
|
||||||
WRITEMEM(buf_p, key3, PUBKEYLENGTH);
|
|
||||||
WRITEMEM(buf_p, pwr3, sizeof(((serverplayer_t *)0)->powerlevels));
|
|
||||||
}
|
|
||||||
else if (playerpernode[node] < 4)
|
|
||||||
{
|
|
||||||
nodetoplayer4[node] = newplayernum;
|
|
||||||
WRITESTRINGN(buf_p, name4, MAXPLAYERNAME);
|
|
||||||
WRITEMEM(buf_p, key4, PUBKEYLENGTH);
|
|
||||||
WRITEMEM(buf_p, pwr4, sizeof(((serverplayer_t *)0)->powerlevels));
|
|
||||||
}
|
|
||||||
|
|
||||||
WRITEUINT8(buf_p, nodetoplayer[node]); // consoleplayer
|
WRITEUINT8(buf_p, nodetoplayer[node]); // consoleplayer
|
||||||
WRITEUINT8(buf_p, playerpernode[node]); // splitscreen num
|
WRITEUINT8(buf_p, playerpernode[node]); // splitscreen num
|
||||||
|
|
@ -4251,11 +4286,21 @@ boolean SV_SpawnServer(void)
|
||||||
UINT8 *availabilitiesbuffer = R_GetSkinAvailabilities(false, -1);
|
UINT8 *availabilitiesbuffer = R_GetSkinAvailabilities(false, -1);
|
||||||
SINT8 node = 0;
|
SINT8 node = 0;
|
||||||
for (; node < MAXNETNODES; node++)
|
for (; node < MAXNETNODES; node++)
|
||||||
result |= SV_AddWaitingPlayers(node, availabilitiesbuffer,
|
{
|
||||||
cv_playername[0].zstring, PR_GetLocalPlayerProfile(0)->public_key, SV_GetStatsByKey(PR_GetLocalPlayerProfile(0)->public_key)->powerlevels,
|
player_config_t configs[MAXSPLITSCREENPLAYERS];
|
||||||
cv_playername[1].zstring, PR_GetLocalPlayerProfile(1)->public_key, SV_GetStatsByKey(PR_GetLocalPlayerProfile(1)->public_key)->powerlevels,
|
|
||||||
cv_playername[2].zstring, PR_GetLocalPlayerProfile(2)->public_key, SV_GetStatsByKey(PR_GetLocalPlayerProfile(2)->public_key)->powerlevels,
|
INT32 i;
|
||||||
cv_playername[3].zstring, PR_GetLocalPlayerProfile(3)->public_key, SV_GetStatsByKey(PR_GetLocalPlayerProfile(3)->public_key)->powerlevels);
|
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||||
|
{
|
||||||
|
strncpy(configs[i].name, cv_playername[i].zstring, MAXPLAYERNAME);
|
||||||
|
D_FillPlayerSkinAndColor(i, NULL, &configs[i]);
|
||||||
|
D_FillPlayerWeaponPref(i, &configs[i]);
|
||||||
|
memcpy(configs[i].key, PR_GetLocalPlayerProfile(i)->public_key, sizeof(configs[i].key));
|
||||||
|
memcpy(configs[i].pwr, SV_GetStatsByKey(PR_GetLocalPlayerProfile(i)->public_key)->powerlevels, sizeof(configs[i].pwr));
|
||||||
|
}
|
||||||
|
|
||||||
|
result |= SV_AddWaitingPlayers(node, availabilitiesbuffer, configs);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -4364,6 +4409,7 @@ static boolean IsPlayerGuest(UINT8 player)
|
||||||
*/
|
*/
|
||||||
static void HandleConnect(SINT8 node)
|
static void HandleConnect(SINT8 node)
|
||||||
{
|
{
|
||||||
|
player_config_t configs[MAXSPLITSCREENPLAYERS];
|
||||||
char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1];
|
char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME + 1];
|
||||||
INT32 i, j;
|
INT32 i, j;
|
||||||
UINT8 availabilitiesbuffer[MAXAVAILABILITY];
|
UINT8 availabilitiesbuffer[MAXAVAILABILITY];
|
||||||
|
|
@ -4487,9 +4533,12 @@ static void HandleConnect(SINT8 node)
|
||||||
int sigcheck;
|
int sigcheck;
|
||||||
boolean newnode = false;
|
boolean newnode = false;
|
||||||
|
|
||||||
|
memcpy(configs, netbuffer->u.clientcfg.player_configs, sizeof(configs));
|
||||||
|
|
||||||
for (i = 0; i < netbuffer->u.clientcfg.localplayers - playerpernode[node]; i++)
|
for (i = 0; i < netbuffer->u.clientcfg.localplayers - playerpernode[node]; i++)
|
||||||
{
|
{
|
||||||
strlcpy(names[i], netbuffer->u.clientcfg.names[i], MAXPLAYERNAME + 1);
|
strlcpy(names[i], configs[i].name, MAXPLAYERNAME + 1);
|
||||||
|
|
||||||
if (!EnsurePlayerNameIsGood(names[i], -1))
|
if (!EnsurePlayerNameIsGood(names[i], -1))
|
||||||
{
|
{
|
||||||
SV_SendRefuse(node, "Bad player name");
|
SV_SendRefuse(node, "Bad player name");
|
||||||
|
|
@ -4610,11 +4659,15 @@ static void HandleConnect(SINT8 node)
|
||||||
DEBFILE("send savegame\n");
|
DEBFILE("send savegame\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
SV_AddWaitingPlayers(node, availabilitiesbuffer,
|
for (i = 0; i < MAXSPLITSCREENPLAYERS; i++)
|
||||||
names[0], lastReceivedKey[node][0], SV_GetStatsByKey(lastReceivedKey[node][0])->powerlevels,
|
{
|
||||||
names[1], lastReceivedKey[node][1], SV_GetStatsByKey(lastReceivedKey[node][1])->powerlevels,
|
strlcpy(configs[i].name, names[i], MAXPLAYERNAME + 1);
|
||||||
names[2], lastReceivedKey[node][2], SV_GetStatsByKey(lastReceivedKey[node][2])->powerlevels,
|
memcpy(configs[i].key, lastReceivedKey[node][i], sizeof(configs[i].key));
|
||||||
names[3], lastReceivedKey[node][3], SV_GetStatsByKey(lastReceivedKey[node][3])->powerlevels);
|
memcpy(configs[i].pwr, SV_GetStatsByKey(lastReceivedKey[node][i])->powerlevels, sizeof(configs[i].pwr));
|
||||||
|
}
|
||||||
|
|
||||||
|
SV_AddWaitingPlayers(node, availabilitiesbuffer, configs);
|
||||||
|
|
||||||
joindelay += cv_joindelay.value * TICRATE;
|
joindelay += cv_joindelay.value * TICRATE;
|
||||||
player_joining = true;
|
player_joining = true;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -273,6 +273,19 @@ struct fileack_pak
|
||||||
|
|
||||||
#define MAXAPPLICATION 16
|
#define MAXAPPLICATION 16
|
||||||
|
|
||||||
|
struct player_config_t
|
||||||
|
{
|
||||||
|
char name[MAXPLAYERNAME];
|
||||||
|
UINT16 skin;
|
||||||
|
UINT16 color;
|
||||||
|
INT16 follower;
|
||||||
|
UINT16 follower_color;
|
||||||
|
UINT8 weapon_prefs;
|
||||||
|
UINT8 min_delay;
|
||||||
|
uint8_t key[PUBKEYLENGTH];
|
||||||
|
UINT16 pwr[PWRLV_NUMTYPES];
|
||||||
|
};
|
||||||
|
|
||||||
struct clientconfig_pak
|
struct clientconfig_pak
|
||||||
{
|
{
|
||||||
UINT8 _255;/* see serverinfo_pak */
|
UINT8 _255;/* see serverinfo_pak */
|
||||||
|
|
@ -282,9 +295,10 @@ struct clientconfig_pak
|
||||||
UINT8 subversion; // Contains build version
|
UINT8 subversion; // Contains build version
|
||||||
UINT8 localplayers; // number of splitscreen players
|
UINT8 localplayers; // number of splitscreen players
|
||||||
UINT8 mode;
|
UINT8 mode;
|
||||||
char names[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME];
|
char _names_outdated[MAXSPLITSCREENPLAYERS][MAXPLAYERNAME];
|
||||||
UINT8 availabilities[MAXAVAILABILITY];
|
UINT8 availabilities[MAXAVAILABILITY];
|
||||||
uint8_t challengeResponse[MAXSPLITSCREENPLAYERS][SIGNATURELENGTH];
|
uint8_t challengeResponse[MAXSPLITSCREENPLAYERS][SIGNATURELENGTH];
|
||||||
|
player_config_t player_configs[MAXSPLITSCREENPLAYERS];
|
||||||
} ATTRPACK;
|
} ATTRPACK;
|
||||||
|
|
||||||
#define SV_SPEEDMASK 0x03 // used to send kartspeed
|
#define SV_SPEEDMASK 0x03 // used to send kartspeed
|
||||||
|
|
|
||||||
230
src/d_netcmd.c
230
src/d_netcmd.c
|
|
@ -932,35 +932,24 @@ VaguePartyDescription (int playernum, int size, int default_color)
|
||||||
return party_description;
|
return party_description;
|
||||||
}
|
}
|
||||||
|
|
||||||
static INT32 snacpending[MAXSPLITSCREENPLAYERS] = {0,0,0,0};
|
void D_FillPlayerSkinAndColor(const UINT8 n, const player_t *player, player_config_t *config)
|
||||||
static INT32 chmappending = 0;
|
|
||||||
|
|
||||||
// name, color, or skin has changed
|
|
||||||
//
|
|
||||||
static void SendNameAndColor(const UINT8 n)
|
|
||||||
{
|
{
|
||||||
const INT32 playernum = g_localplayers[n];
|
if (player != NULL)
|
||||||
player_t *player = NULL;
|
|
||||||
|
|
||||||
if (splitscreen < n)
|
|
||||||
{
|
{
|
||||||
return; // can happen if skin4/color4/name4 changed
|
// We cannot return during this function,
|
||||||
|
// handle your input sanitizing before
|
||||||
|
I_Assert(splitscreen >= n);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (playernum == -1)
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
player = &players[playernum];
|
|
||||||
|
|
||||||
UINT16 sendColor = cv_playercolor[n].value;
|
UINT16 sendColor = cv_playercolor[n].value;
|
||||||
UINT16 sendFollowerColor = cv_followercolor[n].value;
|
UINT16 sendFollowerColor = cv_followercolor[n].value;
|
||||||
|
|
||||||
// don't allow inaccessible colors
|
// don't allow inaccessible colors
|
||||||
if (sendColor != SKINCOLOR_NONE && K_ColorUsable(sendColor, false, true) == false)
|
if (sendColor != SKINCOLOR_NONE && K_ColorUsable(sendColor, false, true) == false)
|
||||||
{
|
{
|
||||||
if (player->skincolor && K_ColorUsable(player->skincolor, false, true) == true)
|
if (player != NULL // in-game change
|
||||||
|
&& player->skincolor != SKINCOLOR_NONE
|
||||||
|
&& K_ColorUsable(player->skincolor, false, true) == true)
|
||||||
{
|
{
|
||||||
// Use our previous color
|
// Use our previous color
|
||||||
CV_StealthSetValue(&cv_playercolor[n], player->skincolor);
|
CV_StealthSetValue(&cv_playercolor[n], player->skincolor);
|
||||||
|
|
@ -971,7 +960,11 @@ static void SendNameAndColor(const UINT8 n)
|
||||||
CV_StealthSetValue(&cv_playercolor[n], SKINCOLOR_NONE);
|
CV_StealthSetValue(&cv_playercolor[n], SKINCOLOR_NONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
lastgoodcolor[playernum] = sendColor = cv_playercolor[n].value;
|
sendColor = cv_playercolor[n].value;
|
||||||
|
if (player != NULL)
|
||||||
|
{
|
||||||
|
lastgoodcolor[player - players] = sendColor;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ditto for follower colour:
|
// ditto for follower colour:
|
||||||
|
|
@ -981,14 +974,8 @@ static void SendNameAndColor(const UINT8 n)
|
||||||
sendFollowerColor = cv_followercolor[n].value;
|
sendFollowerColor = cv_followercolor[n].value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We'll handle it later if we're not playing.
|
|
||||||
if (!Playing())
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Don't change skin if the server doesn't want you to.
|
// Don't change skin if the server doesn't want you to.
|
||||||
if (!CanChangeSkin(playernum))
|
if (player != NULL && !CanChangeSkin(player - players))
|
||||||
{
|
{
|
||||||
CV_StealthSet(&cv_skin[n], skins[player->skin]->name);
|
CV_StealthSet(&cv_skin[n], skins[player->skin]->name);
|
||||||
}
|
}
|
||||||
|
|
@ -996,7 +983,7 @@ static void SendNameAndColor(const UINT8 n)
|
||||||
// check if player has the skin loaded (cv_skin may have
|
// check if player has the skin loaded (cv_skin may have
|
||||||
// the name of a skin that was available in the previous game)
|
// the name of a skin that was available in the previous game)
|
||||||
cv_skin[n].value = R_SkinAvailableEx(cv_skin[n].string, false);
|
cv_skin[n].value = R_SkinAvailableEx(cv_skin[n].string, false);
|
||||||
if ((cv_skin[n].value < 0) || !R_SkinUsable(playernum, cv_skin[n].value, false))
|
if ((cv_skin[n].value < 0) || !R_SkinUsable((player ? player - players : -1), cv_skin[n].value, false))
|
||||||
{
|
{
|
||||||
CV_StealthSet(&cv_skin[n], DEFAULTSKIN);
|
CV_StealthSet(&cv_skin[n], DEFAULTSKIN);
|
||||||
cv_skin[n].value = 0;
|
cv_skin[n].value = 0;
|
||||||
|
|
@ -1021,52 +1008,66 @@ static void SendNameAndColor(const UINT8 n)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't send if everything was identical.
|
config->skin = (UINT16)cv_skin[n].value;
|
||||||
if (!strcmp(cv_playername[n].string, player_names[playernum])
|
config->color = sendColor;
|
||||||
&& sendColor == player->prefcolor
|
config->follower = (horngoner ? -1 : (INT16)cv_follower[n].value);
|
||||||
&& !stricmp(cv_skin[n].string, skins[player->prefskin]->name)
|
config->follower_color = sendFollowerColor;
|
||||||
&& !stricmp(cv_follower[n].string,
|
}
|
||||||
(player->preffollower < 0 ? "None" : followers[player->preffollower].name))
|
|
||||||
&& sendFollowerColor == player->preffollowercolor)
|
static INT32 snacpending[MAXSPLITSCREENPLAYERS] = {0,0,0,0};
|
||||||
|
static INT32 chmappending = 0;
|
||||||
|
|
||||||
|
// name, color, or skin has changed
|
||||||
|
//
|
||||||
|
static void SendNameAndColor(const UINT8 n)
|
||||||
|
{
|
||||||
|
if (!Playing())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
snacpending[n]++;
|
if (splitscreen < n)
|
||||||
|
{
|
||||||
|
return; // can happen if skin4/color4/name4 changed
|
||||||
|
}
|
||||||
|
|
||||||
|
const INT32 playernum = g_localplayers[n];
|
||||||
|
if (playernum == -1)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
player_t *player = &players[playernum];
|
||||||
|
|
||||||
// Don't change name if muted
|
// Don't change name if muted
|
||||||
if (player_name_changes[playernum] >= MAXNAMECHANGES)
|
if (player_name_changes[player - players] >= MAXNAMECHANGES)
|
||||||
{
|
{
|
||||||
CV_StealthSet(&cv_playername[n], player_names[playernum]);
|
CV_StealthSet(&cv_playername[n], player_names[player - players]);
|
||||||
HU_AddChatText("\x85* You must wait to change your name again.", false);
|
HU_AddChatText("\x85* You must wait to change your name again.", false);
|
||||||
}
|
}
|
||||||
else if (cv_mute.value && !(server || IsPlayerAdmin(playernum)))
|
else if (cv_mute.value && !(server || IsPlayerAdmin(player - players)))
|
||||||
{
|
{
|
||||||
CV_StealthSet(&cv_playername[n], player_names[playernum]);
|
CV_StealthSet(&cv_playername[n], player_names[player - players]);
|
||||||
}
|
}
|
||||||
else // Cleanup name if changing it
|
else // Cleanup name if changing it
|
||||||
{
|
{
|
||||||
CleanupPlayerName(playernum, cv_playername[n].zstring);
|
CleanupPlayerName(player - players, cv_playername[n].zstring);
|
||||||
}
|
}
|
||||||
|
|
||||||
char buf[MAXPLAYERNAME+13];
|
player_config_t config;
|
||||||
char *p = buf;
|
D_FillPlayerSkinAndColor(n, player, &config);
|
||||||
|
|
||||||
|
UINT8 buf[MAXPLAYERNAME + 13];
|
||||||
|
UINT8 *p = buf;
|
||||||
|
|
||||||
// Finally write out the complete packet and send it off.
|
|
||||||
WRITESTRINGN(p, cv_playername[n].zstring, MAXPLAYERNAME);
|
WRITESTRINGN(p, cv_playername[n].zstring, MAXPLAYERNAME);
|
||||||
WRITEUINT16(p, sendColor);
|
WRITEUINT16(p, config.skin);
|
||||||
WRITEUINT16(p, (UINT16)cv_skin[n].value);
|
WRITEUINT16(p, config.color);
|
||||||
if (horngoner)
|
WRITEINT16(p, config.follower);
|
||||||
{
|
//CONS_Printf("Sending follower id %d\n", config.follower);
|
||||||
WRITEINT16(p, (-1));
|
WRITEUINT16(p, config.follower_color);
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
WRITEINT16(p, (INT16)cv_follower[n].value);
|
|
||||||
}
|
|
||||||
//CONS_Printf("Sending follower id %d\n", (INT16)cv_follower[n].value);
|
|
||||||
WRITEUINT16(p, sendFollowerColor);
|
|
||||||
|
|
||||||
|
snacpending[n]++;
|
||||||
SendNetXCmdForPlayer(n, XD_NAMEANDCOLOR, buf, p - buf);
|
SendNetXCmdForPlayer(n, XD_NAMEANDCOLOR, buf, p - buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1131,6 +1132,46 @@ static void FinalisePlaystateChange(INT32 playernum)
|
||||||
P_CheckRacers(); // also SRB2Kart
|
P_CheckRacers(); // also SRB2Kart
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void D_PlayerChangeSkinAndColor(player_t *p, UINT16 skin, UINT16 color, INT16 follower, UINT16 followercolor)
|
||||||
|
{
|
||||||
|
const UINT16 old_color = p->prefcolor;
|
||||||
|
const UINT16 old_skin = p->prefskin;
|
||||||
|
const INT16 old_follower = p->preffollower;
|
||||||
|
const UINT16 old_follower_color = p->preffollowercolor;
|
||||||
|
|
||||||
|
// queue the rest for next round
|
||||||
|
p->prefcolor = color % numskincolors;
|
||||||
|
|
||||||
|
if (K_ColorUsable(p->prefcolor, false, false) == false)
|
||||||
|
{
|
||||||
|
p->prefcolor = SKINCOLOR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
p->prefskin = skin;
|
||||||
|
p->preffollowercolor = followercolor;
|
||||||
|
p->preffollower = follower;
|
||||||
|
|
||||||
|
if (
|
||||||
|
(p->jointime <= 1) // Just entered
|
||||||
|
|| (cv_restrictskinchange.value == 0 // Not restricted
|
||||||
|
&& !Y_IntermissionPlayerLock()) // Not start of intermission
|
||||||
|
)
|
||||||
|
{
|
||||||
|
// update preferences immediately
|
||||||
|
G_UpdatePlayerPreferences(p);
|
||||||
|
}
|
||||||
|
else if (P_IsMachineLocalPlayer(p) == true)
|
||||||
|
{
|
||||||
|
if (old_color != p->prefcolor
|
||||||
|
|| old_skin != p->prefskin
|
||||||
|
|| old_follower != p->preffollower
|
||||||
|
|| old_follower_color != p->preffollowercolor)
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_NOTICE, "Your changes will take effect next match.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void Got_NameAndColor(const UINT8 **cp, INT32 playernum)
|
static void Got_NameAndColor(const UINT8 **cp, INT32 playernum)
|
||||||
{
|
{
|
||||||
player_t *p = &players[playernum];
|
player_t *p = &players[playernum];
|
||||||
|
|
@ -1164,8 +1205,8 @@ static void Got_NameAndColor(const UINT8 **cp, INT32 playernum)
|
||||||
}
|
}
|
||||||
|
|
||||||
READSTRINGN(*cp, name, MAXPLAYERNAME);
|
READSTRINGN(*cp, name, MAXPLAYERNAME);
|
||||||
color = READUINT16(*cp);
|
|
||||||
skin = READUINT16(*cp);
|
skin = READUINT16(*cp);
|
||||||
|
color = READUINT16(*cp);
|
||||||
follower = READINT16(*cp);
|
follower = READINT16(*cp);
|
||||||
followercolor = READUINT16(*cp);
|
followercolor = READUINT16(*cp);
|
||||||
|
|
||||||
|
|
@ -1176,26 +1217,7 @@ static void Got_NameAndColor(const UINT8 **cp, INT32 playernum)
|
||||||
SetPlayerName(playernum, name);
|
SetPlayerName(playernum, name);
|
||||||
}
|
}
|
||||||
|
|
||||||
// queue the rest for next round
|
D_PlayerChangeSkinAndColor(p, skin, color, follower, followercolor);
|
||||||
p->prefcolor = color % numskincolors;
|
|
||||||
if (K_ColorUsable(p->prefcolor, false, false) == false)
|
|
||||||
{
|
|
||||||
p->prefcolor = SKINCOLOR_NONE;
|
|
||||||
}
|
|
||||||
|
|
||||||
p->prefskin = skin;
|
|
||||||
p->preffollowercolor = followercolor;
|
|
||||||
p->preffollower = follower;
|
|
||||||
|
|
||||||
if (
|
|
||||||
(p->jointime <= 1) // Just entered
|
|
||||||
|| (cv_restrictskinchange.value == 0 // Not restricted
|
|
||||||
&& !Y_IntermissionPlayerLock()) // Not start of intermission
|
|
||||||
)
|
|
||||||
{
|
|
||||||
// update preferences immediately
|
|
||||||
G_UpdatePlayerPreferences(p);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
@ -1215,26 +1237,26 @@ enum {
|
||||||
// HOURS LOST TO G_PlayerReborn: UNCOUNTABLE
|
// HOURS LOST TO G_PlayerReborn: UNCOUNTABLE
|
||||||
};
|
};
|
||||||
|
|
||||||
void WeaponPref_Send(UINT8 ssplayer)
|
void D_FillPlayerWeaponPref(const UINT8 n, player_config_t *config)
|
||||||
{
|
{
|
||||||
UINT8 prefs = 0;
|
UINT8 prefs = 0;
|
||||||
|
|
||||||
if (cv_kickstartaccel[ssplayer].value)
|
if (cv_kickstartaccel[n].value)
|
||||||
prefs |= WP_KICKSTARTACCEL;
|
prefs |= WP_KICKSTARTACCEL;
|
||||||
|
|
||||||
if (cv_autoroulette[ssplayer].value)
|
if (cv_autoroulette[n].value)
|
||||||
prefs |= WP_AUTOROULETTE;
|
prefs |= WP_AUTOROULETTE;
|
||||||
|
|
||||||
if (cv_shrinkme[ssplayer].value)
|
if (cv_shrinkme[n].value)
|
||||||
prefs |= WP_SHRINKME;
|
prefs |= WP_SHRINKME;
|
||||||
|
|
||||||
if (gamecontrolflags[ssplayer] & GCF_ANALOGSTICK)
|
if (gamecontrolflags[n] & GCF_ANALOGSTICK)
|
||||||
prefs |= WP_ANALOGSTICK;
|
prefs |= WP_ANALOGSTICK;
|
||||||
|
|
||||||
if (cv_autoring[ssplayer].value)
|
if (cv_autoring[n].value)
|
||||||
prefs |= WP_AUTORING;
|
prefs |= WP_AUTORING;
|
||||||
|
|
||||||
if (ssplayer == 0)
|
if (n == 0)
|
||||||
{
|
{
|
||||||
if (cv_voice_selfmute.value)
|
if (cv_voice_selfmute.value)
|
||||||
prefs |= WP_SELFMUTE;
|
prefs |= WP_SELFMUTE;
|
||||||
|
|
@ -1243,14 +1265,25 @@ void WeaponPref_Send(UINT8 ssplayer)
|
||||||
prefs |= WP_SELFDEAFEN;
|
prefs |= WP_SELFDEAFEN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cv_strictfastfall[ssplayer].value)
|
if (cv_strictfastfall[n].value)
|
||||||
prefs |= WP_STRICTFASTFALL;
|
prefs |= WP_STRICTFASTFALL;
|
||||||
|
|
||||||
UINT8 buf[2];
|
config->weapon_prefs = prefs;
|
||||||
buf[0] = prefs;
|
config->min_delay = cv_mindelay.value;
|
||||||
buf[1] = cv_mindelay.value;
|
}
|
||||||
|
|
||||||
SendNetXCmdForPlayer(ssplayer, XD_WEAPONPREF, buf, sizeof buf);
|
void WeaponPref_Send(UINT8 ssplayer)
|
||||||
|
{
|
||||||
|
player_config_t config;
|
||||||
|
D_FillPlayerWeaponPref(ssplayer, &config);
|
||||||
|
|
||||||
|
UINT8 buf[2];
|
||||||
|
UINT8 *p = buf;
|
||||||
|
|
||||||
|
WRITEUINT8(p, config.weapon_prefs);
|
||||||
|
WRITEUINT8(p, config.min_delay);
|
||||||
|
|
||||||
|
SendNetXCmdForPlayer(ssplayer, XD_WEAPONPREF, buf, p - buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void WeaponPref_Save(UINT8 **cp, INT32 playernum)
|
void WeaponPref_Save(UINT8 **cp, INT32 playernum)
|
||||||
|
|
@ -1280,13 +1313,10 @@ void WeaponPref_Save(UINT8 **cp, INT32 playernum)
|
||||||
WRITEUINT8(*cp, prefs);
|
WRITEUINT8(*cp, prefs);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t WeaponPref_Parse(const UINT8 *bufstart, INT32 playernum)
|
void WeaponPref_Set(INT32 playernum, UINT8 prefs)
|
||||||
{
|
{
|
||||||
const UINT8 *p = bufstart;
|
|
||||||
player_t *player = &players[playernum];
|
player_t *player = &players[playernum];
|
||||||
|
|
||||||
UINT8 prefs = READUINT8(p);
|
|
||||||
|
|
||||||
player->pflags &= ~(PF_KICKSTARTACCEL|PF_SHRINKME|PF_AUTOROULETTE|PF_AUTORING);
|
player->pflags &= ~(PF_KICKSTARTACCEL|PF_SHRINKME|PF_AUTOROULETTE|PF_AUTORING);
|
||||||
player->pflags2 &= ~(PF2_SELFMUTE | PF2_SELFDEAFEN | PF2_STRICTFASTFALL);
|
player->pflags2 &= ~(PF2_SELFMUTE | PF2_SELFDEAFEN | PF2_STRICTFASTFALL);
|
||||||
|
|
||||||
|
|
@ -1315,14 +1345,14 @@ size_t WeaponPref_Parse(const UINT8 *bufstart, INT32 playernum)
|
||||||
|
|
||||||
if (prefs & WP_STRICTFASTFALL)
|
if (prefs & WP_STRICTFASTFALL)
|
||||||
player->pflags2 |= PF2_STRICTFASTFALL;
|
player->pflags2 |= PF2_STRICTFASTFALL;
|
||||||
|
}
|
||||||
|
|
||||||
if (leveltime < 2)
|
size_t WeaponPref_Parse(const UINT8 *bufstart, INT32 playernum)
|
||||||
{
|
{
|
||||||
// BAD HACK: No other place I tried to slot this in
|
const UINT8 *p = bufstart;
|
||||||
// made it work for the host when they initally host,
|
|
||||||
// so this will have to do.
|
UINT8 prefs = READUINT8(p);
|
||||||
K_UpdateShrinkCheat(player);
|
WeaponPref_Set(playernum, prefs);
|
||||||
}
|
|
||||||
|
|
||||||
return p - bufstart;
|
return p - bufstart;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -201,7 +201,11 @@ void D_RegisterServerCommands(void);
|
||||||
void D_RegisterClientCommands(void);
|
void D_RegisterClientCommands(void);
|
||||||
void CleanupPlayerName(INT32 playernum, const char *newname);
|
void CleanupPlayerName(INT32 playernum, const char *newname);
|
||||||
boolean EnsurePlayerNameIsGood(char *name, INT32 playernum);
|
boolean EnsurePlayerNameIsGood(char *name, INT32 playernum);
|
||||||
|
void D_FillPlayerSkinAndColor(const UINT8 n, const player_t *player, player_config_t *config);
|
||||||
|
void D_PlayerChangeSkinAndColor(player_t *player, UINT16 skin, UINT16 color, INT16 follower, UINT16 followercolor);
|
||||||
|
void D_FillPlayerWeaponPref(const UINT8 n, player_config_t *config);
|
||||||
void WeaponPref_Send(UINT8 ssplayer);
|
void WeaponPref_Send(UINT8 ssplayer);
|
||||||
|
void WeaponPref_Set(INT32 playernum, UINT8 prefs);
|
||||||
void WeaponPref_Save(UINT8 **cp, INT32 playernum);
|
void WeaponPref_Save(UINT8 **cp, INT32 playernum);
|
||||||
size_t WeaponPref_Parse(const UINT8 *p, INT32 playernum);
|
size_t WeaponPref_Parse(const UINT8 *p, INT32 playernum);
|
||||||
void D_SendPlayerConfig(UINT8 n);
|
void D_SendPlayerConfig(UINT8 n);
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ TYPEDEF (serverconfig_pak);
|
||||||
TYPEDEF (filetx_pak);
|
TYPEDEF (filetx_pak);
|
||||||
TYPEDEF (fileacksegment_t);
|
TYPEDEF (fileacksegment_t);
|
||||||
TYPEDEF (fileack_pak);
|
TYPEDEF (fileack_pak);
|
||||||
|
TYPEDEF (player_config_t);
|
||||||
TYPEDEF (clientconfig_pak);
|
TYPEDEF (clientconfig_pak);
|
||||||
TYPEDEF (serverinfo_pak);
|
TYPEDEF (serverinfo_pak);
|
||||||
TYPEDEF (serverrefuse_pak);
|
TYPEDEF (serverrefuse_pak);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue