diff --git a/src/d_netcmd.c b/src/d_netcmd.c index e926cf520..7252a9d34 100644 --- a/src/d_netcmd.c +++ b/src/d_netcmd.c @@ -996,11 +996,6 @@ static void SendNameAndColor(const UINT8 n) cv_follower[n].value = -1; } - if (sendColor == SKINCOLOR_NONE) - { - sendColor = skins[cv_skin[n].value].prefcolor; - } - if (sendFollowerColor == SKINCOLOR_NONE) { if (cv_follower[n].value >= 0) @@ -1015,11 +1010,11 @@ static void SendNameAndColor(const UINT8 n) // Don't send if everything was identical. if (!strcmp(cv_playername[n].string, player_names[playernum]) - && sendColor == player->skincolor - && !stricmp(cv_skin[n].string, skins[player->skin].name) + && sendColor == player->prefcolor + && !stricmp(cv_skin[n].string, skins[player->prefskin].name) && !stricmp(cv_follower[n].string, - (player->followerskin < 0 ? "None" : followers[player->followerskin].name)) - && sendFollowerColor == player->followercolor) + (player->preffollower < 0 ? "None" : followers[player->preffollower].name)) + && sendFollowerColor == player->preffollowercolor) { return; } @@ -1123,7 +1118,6 @@ static void Got_NameAndColor(const UINT8 **cp, INT32 playernum) UINT16 color, followercolor; UINT8 skin; INT16 follower; - SINT8 localplayer = -1; UINT8 i; #ifdef PARANOIA @@ -1145,8 +1139,6 @@ static void Got_NameAndColor(const UINT8 **cp, INT32 playernum) I_Error("snacpending[%d] negative!", i); } #endif - - localplayer = i; break; } } @@ -1164,95 +1156,22 @@ static void Got_NameAndColor(const UINT8 **cp, INT32 playernum) SetPlayerName(playernum, name); } - // set color - p->skincolor = color % numskincolors; - if (p->mo) - p->mo->color = (UINT16)p->skincolor; - demo_extradata[playernum] |= DXD_COLOR; - - // normal player colors - if (server && !P_IsMachineLocalPlayer(p)) + // queue the rest for next round + p->prefcolor = color % numskincolors; + if (K_ColorUsable(p->prefcolor, false, false) == false) { - boolean kick = false; - - // don't allow inaccessible colors - if (K_ColorUsable(p->skincolor, false, false) == false) - { - kick = true; - } - - if (kick) - { - CONS_Alert(CONS_WARNING, M_GetText("Illegal color change received from %s, color: %d)\n"), player_names[playernum], p->skincolor); - SendKick(playernum, KICK_MSG_CON_FAIL); - return; - } + p->prefcolor = SKINCOLOR_NONE; } - // set skin - if (cv_forceskin.value >= 0 && K_CanChangeRules(true)) // Server wants everyone to use the same player + p->prefskin = skin; + p->preffollowercolor = followercolor; + p->preffollower = follower; + + if (p->jointime < 1) { - const INT32 forcedskin = cv_forceskin.value; - SetPlayerSkinByNum(playernum, forcedskin); - - if (localplayer != -1) - CV_StealthSet(&cv_skin[localplayer], skins[forcedskin].name); + // Just entered, update preferences immediately + G_UpdatePlayerPreferences(p); } - else - { - UINT8 oldskin = players[playernum].skin; - - SetPlayerSkinByNum(playernum, skin); - - // The following is a miniature subset of Got_Teamchange. - if ((gamestate == GS_LEVEL) // In a level? - && (players[playernum].jointime > 1) // permit on join - && (leveltime > introtime) // permit during intro turnaround - && (players[playernum].skin != oldskin)) // a skin change actually happened? - { - players[playernum].roundconditions.switched_skin = true; - - if ( - cv_restrictskinchange.value // Skin changes are restricted? - && G_GametypeHasSpectators() // not a spectator... - && players[playernum].spectator == false // ...but could be? - ) - { - for (i = 0; i < MAXPLAYERS; ++i) - { - if (i == playernum) - continue; - if (!playeringame[i]) - continue; - if (players[i].spectator) - continue; - break; - } - - if (i != MAXPLAYERS // Someone on your server who isn't you? - && LUA_HookTeamSwitch(&players[playernum], 0, false, false, false)) // fiiiine, lua can except it - { - P_DamageMobj(players[playernum].mo, NULL, NULL, 1, DMG_SPECTATOR); - - if (players[i].spectator) - { - HU_AddChatText(va("\x82*%s became a spectator.", player_names[playernum]), false); - - FinalisePlaystateChange(playernum); - } - } - } - } - } - - // set follower colour: - // Don't bother doing garbage and kicking if we receive None, - // this is both silly and a waste of time, - // this will be handled properly in K_HandleFollower. - p->followercolor = followercolor; - - // set follower - K_SetFollowerByNum(playernum, follower); } enum { diff --git a/src/d_player.h b/src/d_player.h index 00bb5d1c5..507345629 100644 --- a/src/d_player.h +++ b/src/d_player.h @@ -671,6 +671,11 @@ struct player_t UINT8 carry; UINT16 dye; + INT32 prefskin; // Queued skin change + UINT16 prefcolor; // Queued color change + INT32 preffollower; // Queued follower change + UINT16 preffollowercolor; // Queued follower color change + // SRB2kart stuff INT32 karthud[NUMKARTHUD]; diff --git a/src/g_game.c b/src/g_game.c index 0158f6e6b..cacfd7d4f 100644 --- a/src/g_game.c +++ b/src/g_game.c @@ -1778,6 +1778,65 @@ void G_FixCamera(UINT8 view) R_ResetViewInterpolation(view); } +void G_UpdatePlayerPreferences(player_t *const player) +{ + // set skin + INT32 new_skin = player->prefskin; + if (K_CanChangeRules(true) == true && cv_forceskin.value >= 0) + { + // Server wants everyone to use the same player + new_skin = cv_forceskin.value; + } + + if (player->skin != new_skin) + { + SetPlayerSkinByNum(player - players, new_skin); + } + + // set color + UINT16 new_color = player->prefcolor; + if (new_color == SKINCOLOR_NONE) + { + new_color = skins[player->skin].prefcolor; + } + + if (player->skincolor != new_color) + { + player->skincolor = new_color; + K_KartResetPlayerColor(player); + } + + // set follower + if (player->followerskin != player->preffollower) + { + K_SetFollowerByNum(player - players, player->preffollower); + } + + // set follower color + if (player->followercolor != player->preffollowercolor) + { + // Don't bother doing garbage and kicking if we receive None, + // this is both silly and a waste of time, + // this will be handled properly in K_HandleFollower. + player->followercolor = player->preffollowercolor; + } +} + +void G_UpdateAllPlayerPreferences(void) +{ + INT32 i; + + for (i = 0; i < MAXPLAYERS; i++) + { + if (playeringame[i] == false) + { + continue; + } + + G_UpdatePlayerPreferences(&players[i]); + } +} + // // G_Ticker // Make ticcmd_ts for the players. @@ -1871,6 +1930,13 @@ void G_Ticker(boolean run) K_UpdateAllPlayerPositions(); } } + else + { + if (run) + { + G_UpdateAllPlayerPreferences(); + } + } P_MapEnd(); @@ -2186,6 +2252,11 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) tic_t laptime[LAP__MAX]; + UINT16 prefcolor; + INT32 prefskin; + UINT16 preffollowercolor; + INT32 preffollower; + INT32 i; // This needs to be first, to permit it to wipe extra information @@ -2209,6 +2280,11 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) skincolor = players[player].skincolor; skin = players[player].skin; + prefcolor = players[player].prefcolor; + prefskin = players[player].prefskin; + preffollower = players[player].preffollower; + preffollowercolor = players[player].preffollowercolor; + if (betweenmaps) { fakeskin = MAXSKINS; @@ -2463,6 +2539,11 @@ void G_PlayerReborn(INT32 player, boolean betweenmaps) p->skincolor = skincolor; p->skin = skin; + p->prefcolor = prefcolor; + p->prefskin = prefskin; + p->preffollower = preffollower; + p->preffollowercolor = preffollowercolor; + p->fakeskin = fakeskin; p->kartspeed = kartspeed; p->kartweight = kartweight; diff --git a/src/g_game.h b/src/g_game.h index 5d33303c8..5a1296aee 100644 --- a/src/g_game.h +++ b/src/g_game.h @@ -232,6 +232,9 @@ void G_UpdateTimeStickerMedals(UINT16 map, boolean showownrecord); void G_TickTimeStickerMedals(void); void G_UpdateRecords(void); +void G_UpdatePlayerPreferences(player_t *const player); +void G_UpdateAllPlayerPreferences(void); + void G_Ticker(boolean run); boolean G_Responder(event_t *ev); diff --git a/src/k_bot.cpp b/src/k_bot.cpp index 5e00814ff..841385f6a 100644 --- a/src/k_bot.cpp +++ b/src/k_bot.cpp @@ -174,16 +174,18 @@ void K_SetBot(UINT8 newplayernum, UINT8 skinnum, UINT8 difficulty, botStyle_e st break; } } - players[newplayernum].skincolor = color; - K_SetNameForBot(newplayernum, realname); - SetPlayerSkinByNum(newplayernum, skinnum); + K_SetNameForBot(newplayernum, realname); for (UINT8 i = 0; i < PWRLV_NUMTYPES; i++) { clientpowerlevels[newplayernum][i] = 0; } + players[newplayernum].prefcolor = color; + players[newplayernum].prefskin = skinnum; + G_UpdatePlayerPreferences(&players[newplayernum]); + if (netgame) { HU_AddChatText(va("\x82*Bot %d has been added to the game", newplayernum+1), false); diff --git a/src/k_grandprix.c b/src/k_grandprix.c index 8991a9606..ad7d17474 100644 --- a/src/k_grandprix.c +++ b/src/k_grandprix.c @@ -791,10 +791,12 @@ void K_RetireBots(void) bot->botvars.difficulty = newDifficulty; bot->botvars.diffincrease = 0; - SetPlayerSkinByNum(i, skinnum); - bot->skincolor = skins[skinnum].prefcolor; K_SetNameForBot(i, skins[skinnum].realname); + bot->prefskin = skinnum; + bot->prefcolor = skins[skinnum].prefcolor; + G_UpdatePlayerPreferences(bot); + bot->score = 0; bot->pflags &= ~PF_NOCONTEST; } diff --git a/src/lua_playerlib.c b/src/lua_playerlib.c index 9398ea373..c8d705d1f 100644 --- a/src/lua_playerlib.c +++ b/src/lua_playerlib.c @@ -557,6 +557,14 @@ static int player_get(lua_State *L) lua_pushinteger(L, plr->followercolor); else if (fastcmp(field,"follower")) LUA_PushUserdata(L, plr->follower, META_MOBJ); + else if (fastcmp(field,"prefskin")) + lua_pushinteger(L, plr->prefskin); + else if (fastcmp(field,"prefcolor")) + lua_pushinteger(L, plr->prefcolor); + else if (fastcmp(field,"preffollower")) + lua_pushinteger(L, plr->preffollower); + else if (fastcmp(field,"preffollowercolor")) + lua_pushinteger(L, plr->preffollowercolor); // // rideroids @@ -1122,8 +1130,16 @@ static int player_set(lua_State *L) plr->followercolor = luaL_checkinteger(L, 3); else if (fastcmp(field,"followerready")) plr->followerready = luaL_checkboolean(L, 3); - else if (fastcmp(field,"follower")) // it's probably best we don't allow the follower mobj to change. - return NOSET; + else if (fastcmp(field,"follower")) + return NOSET; // it's probably best we don't allow the follower mobj to change. + else if (fastcmp(field,"prefskin")) + return NOSET; // don't allow changing user preferences + else if (fastcmp(field,"prefcolor")) + return NOSET; // don't allow changing user preferences + else if (fastcmp(field,"preffollower")) + return NOSET; // don't allow changing user preferences + else if (fastcmp(field,"preffollowercolor")) + return NOSET; // don't allow changing user preferences // time to add to the endless elseif list!!!! // rideroids diff --git a/src/p_saveg.c b/src/p_saveg.c index a8638d03d..3858b13c1 100644 --- a/src/p_saveg.c +++ b/src/p_saveg.c @@ -247,7 +247,7 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT16(save->p, players[i].flashpal); WRITEUINT16(save->p, players[i].flashcount); - WRITEUINT8(save->p, players[i].skincolor); + WRITEUINT16(save->p, players[i].skincolor); WRITEINT32(save->p, players[i].skin); for (j = 0; j < MAXAVAILABILITY; j++) @@ -257,6 +257,12 @@ static void P_NetArchivePlayers(savebuffer_t *save) WRITEUINT8(save->p, players[i].fakeskin); WRITEUINT8(save->p, players[i].lastfakeskin); + + WRITEUINT16(save->p, players[i].prefcolor); + WRITEINT32(save->p, players[i].prefskin); + WRITEUINT16(save->p, players[i].preffollowercolor); + WRITEINT32(save->p, players[i].preffollower); + WRITEUINT32(save->p, players[i].score); WRITESINT8(save->p, players[i].lives); WRITESINT8(save->p, players[i].xtralife); @@ -919,7 +925,7 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].flashpal = READUINT16(save->p); players[i].flashcount = READUINT16(save->p); - players[i].skincolor = READUINT8(save->p); + players[i].skincolor = READUINT16(save->p); players[i].skin = READINT32(save->p); for (j = 0; j < MAXAVAILABILITY; j++) @@ -929,6 +935,12 @@ static void P_NetUnArchivePlayers(savebuffer_t *save) players[i].fakeskin = READUINT8(save->p); players[i].lastfakeskin = READUINT8(save->p); + + players[i].prefcolor = READUINT16(save->p); + players[i].prefskin = READINT32(save->p); + players[i].preffollowercolor = READUINT16(save->p); + players[i].preffollower = READINT32(save->p); + players[i].score = READUINT32(save->p); players[i].lives = READSINT8(save->p); players[i].xtralife = READSINT8(save->p); // Ring Extra Life counter diff --git a/src/p_setup.cpp b/src/p_setup.cpp index e719c755a..fea320794 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -7978,6 +7978,9 @@ static void P_InitPlayers(void) // Make sure objectplace is OFF when you first start the level! OP_ResetObjectplace(); + // Update skins / colors between levels. + G_UpdateAllPlayerPreferences(); + // Are we forcing a character? if (gametype == GT_TUTORIAL) { diff --git a/src/r_skins.c b/src/r_skins.c index fb184172f..2cb8793a8 100644 --- a/src/r_skins.c +++ b/src/r_skins.c @@ -408,22 +408,6 @@ static void SetSkin(player_t *player, INT32 skinnum) player->kartweight = skin->kartweight; player->charflags = skin->flags; -#if 0 - if (!CV_CheatsEnabled() && !(netgame || multiplayer || demo.playback)) - { - for (i = 0; i <= r_splitscreen; i++) - { - if (playernum == g_localplayers[i]) - { - CV_StealthSetValue(&cv_playercolor[i], skin->prefcolor); - } - } - - player->skincolor = skin->prefcolor; - K_KartResetPlayerColor(player); - } -#endif - if (player->followmobj) { P_RemoveMobj(player->followmobj);