mirror of
https://github.com/KartKrewDev/RingRacers.git
synced 2025-12-23 16:32:36 +00:00
SECRET_COLOR
This commit is contained in:
parent
7554943f02
commit
c486ec19af
21 changed files with 519 additions and 590 deletions
|
|
@ -38,6 +38,7 @@
|
|||
#include "r_skins.h"
|
||||
#include "m_random.h"
|
||||
#include "p_local.h" // P_ResetPlayerCheats
|
||||
#include "k_color.h"
|
||||
|
||||
//========
|
||||
// protos.
|
||||
|
|
@ -911,9 +912,9 @@ static void COM_Help_f(void)
|
|||
CONS_Printf(" On or Off (Yes or No, 1 or 0)\n");
|
||||
else if (cvar->PossibleValue == Color_cons_t)
|
||||
{
|
||||
for (i = 1; i < numskincolors; ++i)
|
||||
for (i = SKINCOLOR_NONE; i < numskincolors; ++i)
|
||||
{
|
||||
if (skincolors[i].accessible)
|
||||
if (K_ColorUsable(i, false) == true)
|
||||
{
|
||||
CONS_Printf(" %-2d : %s\n", i, skincolors[i].name);
|
||||
if (i == cvar->value)
|
||||
|
|
|
|||
|
|
@ -136,7 +136,7 @@ boolean digital_disabled = false;
|
|||
INT32 debugload = 0;
|
||||
#endif
|
||||
|
||||
UINT16 numskincolors;
|
||||
UINT16 numskincolors = SKINCOLOR_FIRSTFREESLOT;
|
||||
menucolor_t *menucolorhead, *menucolortail;
|
||||
|
||||
char savegamename[256];
|
||||
|
|
@ -1456,10 +1456,6 @@ void D_SRB2Main(void)
|
|||
if (M_CheckParm("-password") && M_IsNextParm())
|
||||
D_SetPassword(M_GetNextParm());
|
||||
|
||||
// player setup menu colors must be initialized before
|
||||
// any wad file is added, as they may contain colors themselves
|
||||
M_InitPlayerSetupColors();
|
||||
|
||||
CONS_Printf("Z_Init(): Init zone memory allocation daemon. \n");
|
||||
Z_Init();
|
||||
CON_SetLoadingProgress(LOADED_ZINIT);
|
||||
|
|
|
|||
324
src/d_netcmd.c
324
src/d_netcmd.c
|
|
@ -121,11 +121,11 @@ static void Lagless_OnChange (void);
|
|||
static void Gravity_OnChange(void);
|
||||
static void ForceSkin_OnChange(void);
|
||||
|
||||
static void Name_OnChange(void);
|
||||
static void Name1_OnChange(void);
|
||||
static void Name2_OnChange(void);
|
||||
static void Name3_OnChange(void);
|
||||
static void Name4_OnChange(void);
|
||||
static void Skin_OnChange(void);
|
||||
static void Skin1_OnChange(void);
|
||||
static void Skin2_OnChange(void);
|
||||
static void Skin3_OnChange(void);
|
||||
static void Skin4_OnChange(void);
|
||||
|
|
@ -139,7 +139,7 @@ static void Followercolor2_OnChange(void);
|
|||
static void Followercolor3_OnChange(void);
|
||||
static void Followercolor4_OnChange(void);
|
||||
|
||||
static void Color_OnChange(void);
|
||||
static void Color1_OnChange(void);
|
||||
static void Color2_OnChange(void);
|
||||
static void Color3_OnChange(void);
|
||||
static void Color4_OnChange(void);
|
||||
|
|
@ -271,7 +271,7 @@ consvar_t cv_seenames = CVAR_INIT ("seenames", "On", CV_SAVE, CV_OnOff, NULL);
|
|||
|
||||
// names
|
||||
consvar_t cv_playername[MAXSPLITSCREENPLAYERS] = {
|
||||
CVAR_INIT ("name", "Dr. Eggman", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name_OnChange),
|
||||
CVAR_INIT ("name", "Dr. Eggman", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name1_OnChange),
|
||||
CVAR_INIT ("name2", "Tails", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name2_OnChange),
|
||||
CVAR_INIT ("name3", "Sonic", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name3_OnChange),
|
||||
CVAR_INIT ("name4", "Knuckles", CV_SAVE|CV_CALL|CV_NOINIT, NULL, Name4_OnChange)
|
||||
|
|
@ -279,14 +279,14 @@ consvar_t cv_playername[MAXSPLITSCREENPLAYERS] = {
|
|||
// player colors
|
||||
UINT16 lastgoodcolor[MAXSPLITSCREENPLAYERS] = {SKINCOLOR_BLUE, SKINCOLOR_BLUE, SKINCOLOR_BLUE, SKINCOLOR_BLUE};
|
||||
consvar_t cv_playercolor[MAXSPLITSCREENPLAYERS] = {
|
||||
CVAR_INIT ("color", "Red", CV_SAVE|CV_CALL|CV_NOINIT, Color_cons_t, Color_OnChange),
|
||||
CVAR_INIT ("color", "Red", CV_SAVE|CV_CALL|CV_NOINIT, Color_cons_t, Color1_OnChange),
|
||||
CVAR_INIT ("color2", "Orange", CV_SAVE|CV_CALL|CV_NOINIT, Color_cons_t, Color2_OnChange),
|
||||
CVAR_INIT ("color3", "Blue", CV_SAVE|CV_CALL|CV_NOINIT, Color_cons_t, Color3_OnChange),
|
||||
CVAR_INIT ("color4", "Red", CV_SAVE|CV_CALL|CV_NOINIT, Color_cons_t, Color4_OnChange)
|
||||
};
|
||||
// player's skin, saved for commodity, when using a favorite skins wad..
|
||||
consvar_t cv_skin[MAXSPLITSCREENPLAYERS] = {
|
||||
CVAR_INIT ("skin", DEFAULTSKIN, CV_SAVE|CV_CALL|CV_NOINIT, NULL, Skin_OnChange),
|
||||
CVAR_INIT ("skin", DEFAULTSKIN, CV_SAVE|CV_CALL|CV_NOINIT, NULL, Skin1_OnChange),
|
||||
CVAR_INIT ("skin2", DEFAULTSKIN2, CV_SAVE|CV_CALL|CV_NOINIT, NULL, Skin2_OnChange),
|
||||
CVAR_INIT ("skin3", DEFAULTSKIN3, CV_SAVE|CV_CALL|CV_NOINIT, NULL, Skin3_OnChange),
|
||||
CVAR_INIT ("skin4", DEFAULTSKIN4, CV_SAVE|CV_CALL|CV_NOINIT, NULL, Skin4_OnChange)
|
||||
|
|
@ -1451,94 +1451,69 @@ static INT32 chmappending = 0;
|
|||
|
||||
// name, color, or skin has changed
|
||||
//
|
||||
static void SendNameAndColor(UINT8 n)
|
||||
static void SendNameAndColor(const UINT8 n)
|
||||
{
|
||||
const INT32 playernum = g_localplayers[n];
|
||||
player_t *player = &players[playernum];
|
||||
player_t *player = NULL;
|
||||
|
||||
char buf[MAXPLAYERNAME+12];
|
||||
char *p;
|
||||
|
||||
UINT16 i = 0;
|
||||
UINT16 sendColor = cv_playercolor[n].value;
|
||||
UINT16 sendFollowerColor = cv_followercolor[n].value;
|
||||
|
||||
if (splitscreen < n)
|
||||
{
|
||||
return; // can happen if skin4/color4/name4 changed
|
||||
}
|
||||
|
||||
if (playernum == -1)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
player = &players[playernum];
|
||||
|
||||
p = buf;
|
||||
|
||||
// don't allow inaccessible colors
|
||||
if (!skincolors[cv_playercolor[n].value].accessible)
|
||||
if (sendColor != SKINCOLOR_NONE && K_ColorUsable(sendColor, false) == false)
|
||||
{
|
||||
if (player->skincolor && skincolors[player->skincolor].accessible)
|
||||
if (player->skincolor && K_ColorUsable(player->skincolor, false) == true)
|
||||
{
|
||||
// Use our previous color
|
||||
CV_StealthSetValue(&cv_playercolor[n], player->skincolor);
|
||||
else if (skins[player->skin].prefcolor && skincolors[skins[player->skin].prefcolor].accessible)
|
||||
CV_StealthSetValue(&cv_playercolor[n], skins[player->skin].prefcolor);
|
||||
else if (skincolors[atoi(cv_playercolor[n].defaultvalue)].accessible)
|
||||
CV_StealthSet(&cv_playercolor[n], cv_playercolor[n].defaultvalue);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (i < numskincolors && !skincolors[i].accessible)
|
||||
i++;
|
||||
CV_StealthSetValue(&cv_playercolor[n], (i != numskincolors) ? i : SKINCOLOR_BLUE);
|
||||
// Use our old color
|
||||
CV_StealthSetValue(&cv_playercolor[n], SKINCOLOR_NONE);
|
||||
}
|
||||
|
||||
sendColor = cv_playercolor[n].value;
|
||||
}
|
||||
|
||||
// ditto for follower colour:
|
||||
if (!cv_followercolor[n].value)
|
||||
if (sendFollowerColor != SKINCOLOR_NONE && K_ColorUsable(sendFollowerColor, true) == false)
|
||||
{
|
||||
CV_StealthSet(&cv_followercolor[n], "Match"); // set it to "Match". I don't care about your stupidity!
|
||||
sendFollowerColor = cv_followercolor[n].value;
|
||||
}
|
||||
|
||||
// Don't send if everything was identical.
|
||||
if (!strcmp(cv_playername[n].string, player_names[playernum])
|
||||
&& cv_playercolor[n].value == player->skincolor
|
||||
&& sendColor == player->skincolor
|
||||
&& !stricmp(cv_skin[n].string, skins[player->skin].name)
|
||||
&& !stricmp(cv_follower[n].string,
|
||||
(player->followerskin < 0 ? "None" : followers[player->followerskin].name))
|
||||
&& cv_followercolor[n].value == player->followercolor)
|
||||
&& sendFollowerColor == player->followercolor)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// We'll handle it later if we're not playing.
|
||||
if (!Playing())
|
||||
return;
|
||||
|
||||
// If you're not in a netgame, merely update the skin, color, and name.
|
||||
if (!netgame)
|
||||
{
|
||||
INT32 foundskin;
|
||||
|
||||
CleanupPlayerName(playernum, cv_playername[n].zstring);
|
||||
strcpy(player_names[playernum], cv_playername[n].zstring);
|
||||
|
||||
player->skincolor = cv_playercolor[n].value;
|
||||
|
||||
K_KartResetPlayerColor(player);
|
||||
|
||||
foundskin = R_SkinAvailable(cv_skin[n].string);
|
||||
if (foundskin != -1 && R_SkinUsable(playernum, foundskin, false))
|
||||
{
|
||||
SetPlayerSkin(playernum, cv_skin[n].string);
|
||||
CV_StealthSet(&cv_skin[n], skins[foundskin].name);
|
||||
cv_skin[n].value = foundskin;
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_StealthSet(&cv_skin[n], skins[player->skin].name);
|
||||
cv_skin[n].value = player->skin;
|
||||
// will always be same as current
|
||||
SetPlayerSkin(playernum, cv_skin[n].string);
|
||||
}
|
||||
|
||||
player->followercolor = cv_followercolor[n].value;
|
||||
|
||||
// Update follower for local games:
|
||||
foundskin = K_FollowerAvailable(cv_follower[n].string);
|
||||
if (!K_FollowerUsable(foundskin))
|
||||
foundskin = -1;
|
||||
CV_StealthSet(&cv_follower[n], (foundskin == -1) ? "None" : followers[foundskin].name);
|
||||
cv_follower[n].value = foundskin;
|
||||
K_SetFollowerByNum(playernum, foundskin);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -1548,16 +1523,22 @@ static void SendNameAndColor(UINT8 n)
|
|||
if (player_name_changes[playernum] >= MAXNAMECHANGES)
|
||||
{
|
||||
CV_StealthSet(&cv_playername[n], player_names[playernum]);
|
||||
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)))
|
||||
{
|
||||
CV_StealthSet(&cv_playername[n], player_names[playernum]);
|
||||
}
|
||||
else // Cleanup name if changing it
|
||||
{
|
||||
CleanupPlayerName(playernum, cv_playername[n].zstring);
|
||||
}
|
||||
|
||||
// Don't change skin if the server doesn't want you to.
|
||||
if (!CanChangeSkin(playernum))
|
||||
{
|
||||
CV_StealthSet(&cv_skin[n], skins[player->skin].name);
|
||||
}
|
||||
|
||||
// check if player has the skin loaded (cv_skin may have
|
||||
// the name of a skin that was available in the previous game)
|
||||
|
|
@ -1575,6 +1556,16 @@ static void SendNameAndColor(UINT8 n)
|
|||
cv_follower[n].value = -1;
|
||||
}
|
||||
|
||||
if (sendColor == SKINCOLOR_NONE)
|
||||
{
|
||||
sendColor = skins[cv_skin[n].value].prefcolor;
|
||||
}
|
||||
|
||||
if (sendFollowerColor == SKINCOLOR_NONE)
|
||||
{
|
||||
sendFollowerColor = followers[cv_follower[n].value].defaultcolor;
|
||||
}
|
||||
|
||||
// Finally write out the complete packet and send it off.
|
||||
WRITESTRINGN(p, cv_playername[n].zstring, MAXPLAYERNAME);
|
||||
WRITEUINT16(p, (UINT16)cv_playercolor[n].value);
|
||||
|
|
@ -1674,8 +1665,10 @@ static void Got_NameAndColor(UINT8 **cp, INT32 playernum)
|
|||
boolean kick = false;
|
||||
|
||||
// don't allow inaccessible colors
|
||||
if (skincolors[p->skincolor].accessible == false)
|
||||
if (K_ColorUsable(p->skincolor, false) == false)
|
||||
{
|
||||
kick = true;
|
||||
}
|
||||
|
||||
if (kick)
|
||||
{
|
||||
|
|
@ -6425,50 +6418,36 @@ static void ForceSkin_OnChange(void)
|
|||
}
|
||||
|
||||
//Allows the player's name to be changed if cv_mute is off.
|
||||
static void Name_OnChange(void)
|
||||
static void Name_OnChange(const UINT8 p)
|
||||
{
|
||||
if (cv_mute.value && !(server || IsPlayerAdmin(consoleplayer)))
|
||||
if (cv_mute.value && !(server || IsPlayerAdmin(g_localplayers[p])))
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n"));
|
||||
CV_StealthSet(&cv_playername[0], player_names[consoleplayer]);
|
||||
CV_StealthSet(&cv_playername[p], player_names[g_localplayers[p]]);
|
||||
return;
|
||||
}
|
||||
else
|
||||
SendNameAndColor(0);
|
||||
|
||||
SendNameAndColor(p);
|
||||
}
|
||||
|
||||
static void Name1_OnChange(void)
|
||||
{
|
||||
Name_OnChange(0);
|
||||
}
|
||||
|
||||
static void Name2_OnChange(void)
|
||||
{
|
||||
if (cv_mute.value) //Secondary player can't be admin.
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n"));
|
||||
CV_StealthSet(&cv_playername[1], player_names[g_localplayers[1]]);
|
||||
}
|
||||
else
|
||||
SendNameAndColor(1);
|
||||
Name_OnChange(1);
|
||||
}
|
||||
|
||||
static void Name3_OnChange(void)
|
||||
{
|
||||
if (cv_mute.value) //Third player can't be admin.
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n"));
|
||||
CV_StealthSet(&cv_playername[2], player_names[g_localplayers[2]]);
|
||||
}
|
||||
else
|
||||
SendNameAndColor(2);
|
||||
Name_OnChange(2);
|
||||
}
|
||||
|
||||
static void Name4_OnChange(void)
|
||||
{
|
||||
if (cv_mute.value) //Secondary player can't be admin.
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("You may not change your name when chat is muted.\n"));
|
||||
CV_StealthSet(&cv_playername[3], player_names[g_localplayers[3]]);
|
||||
}
|
||||
else
|
||||
SendNameAndColor(3);
|
||||
Name_OnChange(3);
|
||||
}
|
||||
|
||||
// sends the follower change for players
|
||||
|
|
@ -6529,29 +6508,40 @@ static void Followercolor4_OnChange(void)
|
|||
* \sa cv_skin, Skin2_OnChange, Color_OnChange
|
||||
* \author Graue <graue@oceanbase.org>
|
||||
*/
|
||||
static void Skin_OnChange(void)
|
||||
static void Skin_OnChange(const UINT8 p)
|
||||
{
|
||||
if (!Playing())
|
||||
return; // do whatever you want
|
||||
|
||||
if (!CV_CheatsEnabled() && !(multiplayer || netgame) // In single player.
|
||||
&& (gamestate != GS_WAITINGPLAYERS)) // allows command line -warp x +skin y
|
||||
if (!Playing() || splitscreen < p)
|
||||
{
|
||||
CV_StealthSet(&cv_skin[0], skins[players[consoleplayer].skin].name);
|
||||
// do whatever you want
|
||||
return;
|
||||
}
|
||||
|
||||
if (CanChangeSkin(consoleplayer))
|
||||
if (p == 0)
|
||||
{
|
||||
SendNameAndColor(0);
|
||||
if (!CV_CheatsEnabled() && !(multiplayer || netgame) // In single player.
|
||||
&& (gamestate != GS_WAITINGPLAYERS)) // allows command line -warp x +skin y
|
||||
{
|
||||
CV_StealthSet(&cv_skin[p], skins[players[g_localplayers[p]].skin].name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (CanChangeSkin(g_localplayers[p]))
|
||||
{
|
||||
SendNameAndColor(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
|
||||
CV_StealthSet(&cv_skin[0], skins[players[consoleplayer].skin].name);
|
||||
CV_StealthSet(&cv_skin[p], skins[players[g_localplayers[p]].skin].name);
|
||||
}
|
||||
}
|
||||
|
||||
static void Skin1_OnChange(void)
|
||||
{
|
||||
Skin_OnChange(0);
|
||||
}
|
||||
|
||||
/** Sends a skin change for the secondary splitscreen player, unless that
|
||||
* player is moving. Forces spectate the player if the change is done during gameplay.
|
||||
* \sa cv_skin2, Skin_OnChange, Color2_OnChange
|
||||
|
|
@ -6559,79 +6549,63 @@ static void Skin_OnChange(void)
|
|||
*/
|
||||
static void Skin2_OnChange(void)
|
||||
{
|
||||
if (!Playing() || !splitscreen)
|
||||
return; // do whatever you want
|
||||
|
||||
if (CanChangeSkin(g_localplayers[1]))
|
||||
SendNameAndColor(1);
|
||||
else
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
|
||||
CV_StealthSet(&cv_skin[1], skins[players[g_localplayers[1]].skin].name);
|
||||
}
|
||||
Skin_OnChange(1);
|
||||
}
|
||||
|
||||
static void Skin3_OnChange(void)
|
||||
{
|
||||
if (!Playing() || splitscreen < 2)
|
||||
return; // do whatever you want
|
||||
|
||||
if (CanChangeSkin(g_localplayers[2]))
|
||||
SendNameAndColor(2);
|
||||
else
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
|
||||
CV_StealthSet(&cv_skin[2], skins[players[g_localplayers[2]].skin].name);
|
||||
}
|
||||
Skin_OnChange(2);
|
||||
}
|
||||
|
||||
static void Skin4_OnChange(void)
|
||||
{
|
||||
if (!Playing() || splitscreen < 3)
|
||||
return; // do whatever you want
|
||||
|
||||
if (CanChangeSkin(g_localplayers[3]))
|
||||
SendNameAndColor(3);
|
||||
else
|
||||
{
|
||||
CONS_Alert(CONS_NOTICE, M_GetText("You can't change your skin at the moment.\n"));
|
||||
CV_StealthSet(&cv_skin[3], skins[players[g_localplayers[3]].skin].name);
|
||||
}
|
||||
Skin_OnChange(3);
|
||||
}
|
||||
|
||||
/** Sends a color change for the console player, unless that player is moving.
|
||||
* \sa cv_playercolor, Color2_OnChange, Skin_OnChange
|
||||
* \author Graue <graue@oceanbase.org>
|
||||
*/
|
||||
static void Color_OnChange(void)
|
||||
static void Color_OnChange(const UINT8 p)
|
||||
{
|
||||
if (!Playing())
|
||||
UINT16 color = SKINCOLOR_NONE;
|
||||
|
||||
I_Assert(p < MAXSPLITSCREENPLAYERS);
|
||||
|
||||
color = cv_playercolor[p].value;
|
||||
|
||||
if (!Playing() || splitscreen < p)
|
||||
{
|
||||
if (!cv_playercolor[0].value || !skincolors[cv_playercolor[0].value].accessible)
|
||||
CV_StealthSetValue(&cv_playercolor[0], lastgoodcolor[0]);
|
||||
if (color != SKINCOLOR_NONE && K_ColorUsable(color, false) == false)
|
||||
{
|
||||
CV_StealthSetValue(&cv_playercolor[p], lastgoodcolor[p]);
|
||||
color = cv_playercolor[p].value;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!CV_CheatsEnabled() && !(multiplayer || netgame)) // In single player.
|
||||
{
|
||||
CV_StealthSet(&cv_skin[0], skins[players[consoleplayer].skin].name);
|
||||
return;
|
||||
}
|
||||
player_t *const player = &players[ g_localplayers[p] ];
|
||||
|
||||
if (!P_PlayerMoving(consoleplayer) && skincolors[players[consoleplayer].skincolor].accessible == true)
|
||||
if (P_PlayerMoving(g_localplayers[p]) == false && K_ColorUsable(color, false) == true)
|
||||
{
|
||||
// Color change menu scrolling fix is no longer necessary
|
||||
SendNameAndColor(0);
|
||||
SendNameAndColor(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_StealthSetValue(&cv_playercolor[0],
|
||||
players[consoleplayer].skincolor);
|
||||
CV_StealthSetValue(&cv_playercolor[p], player->skincolor);
|
||||
color = cv_playercolor[p].value;
|
||||
}
|
||||
}
|
||||
lastgoodcolor[0] = cv_playercolor[0].value;
|
||||
|
||||
G_SetPlayerGamepadIndicatorToPlayerColor(0);
|
||||
lastgoodcolor[p] = color;
|
||||
|
||||
G_SetPlayerGamepadIndicatorToPlayerColor(p);
|
||||
}
|
||||
|
||||
static void Color1_OnChange(void)
|
||||
{
|
||||
Color_OnChange(0);
|
||||
}
|
||||
|
||||
/** Sends a color change for the secondary splitscreen player, unless that
|
||||
|
|
@ -6641,77 +6615,17 @@ static void Color_OnChange(void)
|
|||
*/
|
||||
static void Color2_OnChange(void)
|
||||
{
|
||||
if (!Playing() || splitscreen < 1)
|
||||
{
|
||||
if (!cv_playercolor[1].value || !skincolors[cv_playercolor[1].value].accessible)
|
||||
CV_StealthSetValue(&cv_playercolor[1], lastgoodcolor[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!P_PlayerMoving(g_localplayers[1]) && skincolors[players[g_localplayers[1]].skincolor].accessible == true)
|
||||
{
|
||||
// Color change menu scrolling fix is no longer necessary
|
||||
SendNameAndColor(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_StealthSetValue(&cv_playercolor[1],
|
||||
players[g_localplayers[1]].skincolor);
|
||||
}
|
||||
}
|
||||
lastgoodcolor[1] = cv_playercolor[1].value;
|
||||
|
||||
G_SetPlayerGamepadIndicatorToPlayerColor(1);
|
||||
Color_OnChange(1);
|
||||
}
|
||||
|
||||
static void Color3_OnChange(void)
|
||||
{
|
||||
if (!Playing() || splitscreen < 2)
|
||||
{
|
||||
if (!cv_playercolor[2].value || !skincolors[cv_playercolor[2].value].accessible)
|
||||
CV_StealthSetValue(&cv_playercolor[2], lastgoodcolor[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!P_PlayerMoving(g_localplayers[2]) && skincolors[players[g_localplayers[2]].skincolor].accessible == true)
|
||||
{
|
||||
// Color change menu scrolling fix is no longer necessary
|
||||
SendNameAndColor(2);
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_StealthSetValue(&cv_playercolor[2],
|
||||
players[g_localplayers[2]].skincolor);
|
||||
}
|
||||
}
|
||||
lastgoodcolor[2] = cv_playercolor[2].value;
|
||||
|
||||
G_SetPlayerGamepadIndicatorToPlayerColor(2);
|
||||
Color_OnChange(2);
|
||||
}
|
||||
|
||||
static void Color4_OnChange(void)
|
||||
{
|
||||
if (!Playing() || splitscreen < 3)
|
||||
{
|
||||
if (!cv_playercolor[3].value || !skincolors[cv_playercolor[3].value].accessible)
|
||||
CV_StealthSetValue(&cv_playercolor[3], lastgoodcolor[3]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!P_PlayerMoving(g_localplayers[3]) && skincolors[players[g_localplayers[3]].skincolor].accessible == true)
|
||||
{
|
||||
// Color change menu scrolling fix is no longer necessary
|
||||
SendNameAndColor(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
CV_StealthSetValue(&cv_playercolor[3],
|
||||
players[g_localplayers[3]].skincolor);
|
||||
}
|
||||
}
|
||||
lastgoodcolor[3] = cv_playercolor[3].value;
|
||||
|
||||
G_SetPlayerGamepadIndicatorToPlayerColor(3);
|
||||
Color_OnChange(3);
|
||||
}
|
||||
|
||||
/** Displays the result of the chat being muted or unmuted.
|
||||
|
|
|
|||
|
|
@ -142,7 +142,7 @@ static inline int lib_freeslot(lua_State *L)
|
|||
CONS_Printf("Skincolor SKINCOLOR_%s allocated.\n",word);
|
||||
FREE_SKINCOLORS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
|
||||
strcpy(FREE_SKINCOLORS[i],word);
|
||||
M_AddMenuColor(numskincolors++);
|
||||
numskincolors++;
|
||||
lua_pushinteger(L, SKINCOLOR_FIRSTFREESLOT + i);
|
||||
r++;
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -321,7 +321,7 @@ void readfreeslots(MYFILE *f)
|
|||
CONS_Printf("Skincolor SKINCOLOR_%s allocated.\n",word);
|
||||
FREE_SKINCOLORS[i] = Z_Malloc(strlen(word)+1, PU_STATIC, NULL);
|
||||
strcpy(FREE_SKINCOLORS[i],word);
|
||||
M_AddMenuColor(numskincolors++);
|
||||
numskincolors++;
|
||||
break;
|
||||
}
|
||||
if (i == NUMCOLORFREESLOTS)
|
||||
|
|
@ -2297,6 +2297,8 @@ void readunlockable(MYFILE *f, INT32 num)
|
|||
unlockables[num].type = SECRET_SKIN;
|
||||
else if (fastcmp(word2, "FOLLOWER"))
|
||||
unlockables[num].type = SECRET_FOLLOWER;
|
||||
else if (fastcmp(word2, "COLOR"))
|
||||
unlockables[num].type = SECRET_COLOR;
|
||||
else if (fastcmp(word2, "HARDSPEED"))
|
||||
unlockables[num].type = SECRET_HARDSPEED;
|
||||
else if (fastcmp(word2, "MASTERMODE"))
|
||||
|
|
|
|||
|
|
@ -236,7 +236,7 @@ struct skincolor_t
|
|||
|
||||
#define FOLLOWERCOLOR_MATCH UINT16_MAX
|
||||
#define FOLLOWERCOLOR_OPPOSITE (UINT16_MAX-1)
|
||||
UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, UINT16 playercolor);
|
||||
UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, follower_t *follower, UINT16 playercolor, skin_t *playerskin);
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
|
|
|||
|
|
@ -29546,7 +29546,7 @@ mobjinfo_t mobjinfo[NUMMOBJTYPES] =
|
|||
};
|
||||
|
||||
skincolor_t skincolors[MAXSKINCOLORS] = {
|
||||
{"None", { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_NONE
|
||||
{"Default", { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, SKINCOLOR_NONE, 0, 0, false}, // SKINCOLOR_NONE
|
||||
|
||||
{"White", { 0, 0, 0, 0, 1, 2, 5, 8, 9, 11, 14, 17, 20, 22, 25, 28}, SKINCOLOR_BLACK, 8, 0, true}, // SKINCOLOR_WHITE
|
||||
{"Silver", { 0, 1, 2, 3, 5, 7, 9, 12, 13, 15, 18, 20, 23, 25, 27, 30}, SKINCOLOR_NICKEL, 8, 0, true}, // SKINCOLOR_SILVER
|
||||
|
|
|
|||
|
|
@ -16,6 +16,9 @@
|
|||
#include "r_draw.h"
|
||||
#include "r_things.h"
|
||||
#include "v_video.h"
|
||||
#include "m_cond.h"
|
||||
#include "g_demo.h"
|
||||
#include "k_follower.h"
|
||||
|
||||
/*--------------------------------------------------
|
||||
UINT8 K_ColorRelativeLuminance(UINT8 r, UINT8 g, UINT8 b)
|
||||
|
|
@ -213,4 +216,63 @@ void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color)
|
|||
}
|
||||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
boolean K_ColorUsable(skincolornum_t color, boolean follower)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
boolean K_ColorUsable(skincolornum_t color, boolean follower)
|
||||
{
|
||||
INT32 i = MAXUNLOCKABLES;
|
||||
|
||||
if (color == FOLLOWERCOLOR_MATCH || color == FOLLOWERCOLOR_OPPOSITE)
|
||||
{
|
||||
// Special follower colors, always allow if follower.
|
||||
return follower;
|
||||
}
|
||||
|
||||
if (skincolors[color].accessible == false)
|
||||
{
|
||||
// Never intended to be used.
|
||||
return false;
|
||||
}
|
||||
|
||||
if (demo.playback)
|
||||
{
|
||||
// Simplifies things elsewhere...
|
||||
return true;
|
||||
}
|
||||
|
||||
// Determine if this follower is supposed to be unlockable or not
|
||||
for (i = 0; i < MAXUNLOCKABLES; i++)
|
||||
{
|
||||
skincolornum_t cid = SKINCOLOR_NONE;
|
||||
|
||||
if (unlockables[i].type != SECRET_COLOR)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
cid = M_UnlockableColorNum(&unlockables[i]);
|
||||
|
||||
if (cid != color)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// i is now the unlockable index, we can use this later
|
||||
break;
|
||||
}
|
||||
|
||||
if (i == MAXUNLOCKABLES)
|
||||
{
|
||||
// Didn't trip anything, so we can use this color.
|
||||
return true;
|
||||
}
|
||||
|
||||
// Use the unlockables table directly
|
||||
// DEFINITELY not M_CheckNetUnlockByID
|
||||
return (boolean)(gamedata->unlocked[i]);
|
||||
}
|
||||
|
||||
//}
|
||||
|
|
|
|||
|
|
@ -112,8 +112,27 @@ void K_HitlagColormap(UINT8 *dest_colormap);
|
|||
Return:-
|
||||
None
|
||||
--------------------------------------------------*/
|
||||
|
||||
void K_GenerateKartColormap(UINT8 *dest_colormap, INT32 skinnum, UINT8 color);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
boolean K_ColorUsable(skincolornum_t color, skin_t *skin, follower_t *follower);
|
||||
|
||||
Determines whenever or not we meet the unlockable conditions
|
||||
to use a certain color.
|
||||
|
||||
Input Arguments:-
|
||||
color - Color we want to use.
|
||||
follower - Set to include the special follower-only color options.
|
||||
|
||||
Return:-
|
||||
true if we can use it, otherwise false.
|
||||
--------------------------------------------------*/
|
||||
|
||||
boolean K_ColorUsable(skincolornum_t color, boolean follower);
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
} // extern "C"
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -234,19 +234,33 @@ static void K_SetFollowerState(mobj_t *f, statenum_t state)
|
|||
}
|
||||
|
||||
/*--------------------------------------------------
|
||||
UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, UINT16 playercolor)
|
||||
UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, follower_t *follower, UINT16 playercolor, skin_t *playerskin)
|
||||
|
||||
See header file for description.
|
||||
--------------------------------------------------*/
|
||||
UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, UINT16 playercolor)
|
||||
UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, follower_t *follower, UINT16 playercolor, skin_t *playerskin)
|
||||
{
|
||||
if (followercolor < numskincolors) // bog standard
|
||||
if (followercolor == SKINCOLOR_NONE && follower != NULL) // "Default"
|
||||
{
|
||||
return follower->defaultcolor;
|
||||
}
|
||||
|
||||
if (followercolor > SKINCOLOR_NONE && followercolor < numskincolors) // bog standard
|
||||
{
|
||||
return followercolor;
|
||||
}
|
||||
|
||||
if (followercolor == FOLLOWERCOLOR_OPPOSITE) // "Opposite"
|
||||
{
|
||||
return skincolors[playercolor].invcolor;
|
||||
}
|
||||
|
||||
// "Match"
|
||||
if (playercolor == SKINCOLOR_NONE && playerskin != NULL)
|
||||
{
|
||||
return playerskin->prefcolor;
|
||||
}
|
||||
|
||||
//if (followercolor == FOLLOWERCOLOR_MATCH) -- "Match"
|
||||
return playercolor;
|
||||
}
|
||||
|
||||
|
|
@ -286,7 +300,7 @@ static void K_UpdateFollowerState(mobj_t *f, statenum_t state, followerstate_t t
|
|||
--------------------------------------------------*/
|
||||
void K_HandleFollower(player_t *player)
|
||||
{
|
||||
follower_t fl;
|
||||
follower_t *fl;
|
||||
angle_t an;
|
||||
fixed_t zoffs;
|
||||
fixed_t ourheight;
|
||||
|
|
@ -326,22 +340,22 @@ void K_HandleFollower(player_t *player)
|
|||
}
|
||||
|
||||
// Before we do anything, let's be sure of where we're supposed to be
|
||||
fl = followers[player->followerskin];
|
||||
fl = &followers[player->followerskin];
|
||||
|
||||
an = player->mo->angle + fl.atangle;
|
||||
zoffs = fl.zoffs;
|
||||
bubble = fl.bubblescale; // 0 if no bubble to spawn.
|
||||
an = player->mo->angle + fl->atangle;
|
||||
zoffs = fl->zoffs;
|
||||
bubble = fl->bubblescale; // 0 if no bubble to spawn.
|
||||
|
||||
// do you like angle maths? I certainly don't...
|
||||
sx = player->mo->x + player->mo->momx + FixedMul(FixedMul(player->mo->scale, fl.dist), FINECOSINE((an) >> ANGLETOFINESHIFT));
|
||||
sy = player->mo->y + player->mo->momy + FixedMul(FixedMul(player->mo->scale, fl.dist), FINESINE((an) >> ANGLETOFINESHIFT));
|
||||
sx = player->mo->x + player->mo->momx + FixedMul(FixedMul(player->mo->scale, fl->dist), FINECOSINE((an) >> ANGLETOFINESHIFT));
|
||||
sy = player->mo->y + player->mo->momy + FixedMul(FixedMul(player->mo->scale, fl->dist), FINESINE((an) >> ANGLETOFINESHIFT));
|
||||
|
||||
// interp info helps with stretchy fix
|
||||
deltaz = (player->mo->z - player->mo->old_z);
|
||||
|
||||
// for the z coordinate, don't be a doof like Steel and forget that MFE_VERTICALFLIP exists :P
|
||||
sz = player->mo->z + player->mo->momz + FixedMul(player->mo->scale, zoffs * P_MobjFlip(player->mo));
|
||||
ourheight = FixedMul(fl.height, player->mo->scale);
|
||||
ourheight = FixedMul(fl->height, player->mo->scale);
|
||||
if (player->mo->eflags & MFE_VERTICALFLIP)
|
||||
{
|
||||
sz += ourheight;
|
||||
|
|
@ -350,7 +364,7 @@ void K_HandleFollower(player_t *player)
|
|||
fh = player->mo->floorz;
|
||||
ch = player->mo->ceilingz - ourheight;
|
||||
|
||||
switch (fl.mode)
|
||||
switch (fl->mode)
|
||||
{
|
||||
case FOLLOWERMODE_GROUND:
|
||||
{
|
||||
|
|
@ -369,9 +383,9 @@ void K_HandleFollower(player_t *player)
|
|||
{
|
||||
// finally, add a cool floating effect to the z height.
|
||||
// not stolen from k_kart I swear!!
|
||||
fixed_t sine = FixedMul(fl.bobamp,
|
||||
fixed_t sine = FixedMul(fl->bobamp,
|
||||
FINESINE(((
|
||||
FixedMul(4 * M_TAU_FIXED, fl.bobspeed) * leveltime
|
||||
FixedMul(4 * M_TAU_FIXED, fl->bobspeed) * leveltime
|
||||
) >> ANGLETOFINESHIFT) & FINEMASK));
|
||||
sz += FixedMul(player->mo->scale, sine) * P_MobjFlip(player->mo);
|
||||
break;
|
||||
|
|
@ -379,7 +393,7 @@ void K_HandleFollower(player_t *player)
|
|||
}
|
||||
|
||||
// Set follower colour
|
||||
color = K_GetEffectiveFollowerColor(player->followercolor, player->skincolor);
|
||||
color = K_GetEffectiveFollowerColor(player->followercolor, fl, player->skincolor, &skins[player->skin]);
|
||||
|
||||
if (player->follower == NULL || P_MobjWasRemoved(player->follower)) // follower doesn't exist / isn't valid
|
||||
{
|
||||
|
|
@ -390,7 +404,7 @@ void K_HandleFollower(player_t *player)
|
|||
if (player->follower == NULL)
|
||||
return;
|
||||
|
||||
K_UpdateFollowerState(player->follower, fl.idlestate, FOLLOWERSTATE_IDLE);
|
||||
K_UpdateFollowerState(player->follower, fl->idlestate, FOLLOWERSTATE_IDLE);
|
||||
|
||||
P_SetTarget(&player->follower->target, player->mo); // we need that to know when we need to disappear
|
||||
player->follower->angle = player->follower->old_angle = player->mo->angle;
|
||||
|
|
@ -422,12 +436,12 @@ void K_HandleFollower(player_t *player)
|
|||
}
|
||||
|
||||
// move the follower next to us (yes, this is really basic maths but it looks pretty damn clean in practice)!
|
||||
player->follower->momx = FixedDiv(sx - player->follower->x, fl.horzlag);
|
||||
player->follower->momy = FixedDiv(sy - player->follower->y, fl.horzlag);
|
||||
player->follower->momx = FixedDiv(sx - player->follower->x, fl->horzlag);
|
||||
player->follower->momy = FixedDiv(sy - player->follower->y, fl->horzlag);
|
||||
|
||||
player->follower->z += FixedDiv(deltaz, fl.vertlag);
|
||||
player->follower->z += FixedDiv(deltaz, fl->vertlag);
|
||||
|
||||
if (fl.mode == FOLLOWERMODE_GROUND)
|
||||
if (fl->mode == FOLLOWERMODE_GROUND)
|
||||
{
|
||||
sector_t *sec = R_PointInSubsector(sx, sy)->sector;
|
||||
|
||||
|
|
@ -448,12 +462,12 @@ void K_HandleFollower(player_t *player)
|
|||
|
||||
// Player is on the ground ... try to get the follower
|
||||
// back to the ground also if it is above it.
|
||||
player->follower->momz += FixedDiv(fg * 6, fl.vertlag); // Scaled against the default value of vertlag
|
||||
player->follower->momz += FixedDiv(fg * 6, fl->vertlag); // Scaled against the default value of vertlag
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
player->follower->momz = FixedDiv(sz - player->follower->z, fl.vertlag);
|
||||
player->follower->momz = FixedDiv(sz - player->follower->z, fl->vertlag);
|
||||
}
|
||||
|
||||
if (player->mo->colorized)
|
||||
|
|
@ -467,7 +481,7 @@ void K_HandleFollower(player_t *player)
|
|||
|
||||
player->follower->colorized = player->mo->colorized;
|
||||
|
||||
P_SetScale(player->follower, FixedMul(fl.scale, player->mo->scale));
|
||||
P_SetScale(player->follower, FixedMul(fl->scale, player->mo->scale));
|
||||
K_GenericExtraFlagsNoZAdjust(player->follower, player->mo); // Not K_MatchGenericExtraFlag because the Z adjust it has only works properly if master & mo have the same Z height.
|
||||
|
||||
// Match how the player is being drawn
|
||||
|
|
@ -501,20 +515,20 @@ void K_HandleFollower(player_t *player)
|
|||
|
||||
if (angleDiff != 0)
|
||||
{
|
||||
player->follower->angle += FixedDiv(angleDiff, fl.anglelag);
|
||||
player->follower->angle += FixedDiv(angleDiff, fl->anglelag);
|
||||
}
|
||||
|
||||
// Ground follower slope rotation
|
||||
if (fl.mode == FOLLOWERMODE_GROUND)
|
||||
if (fl->mode == FOLLOWERMODE_GROUND)
|
||||
{
|
||||
if (player->follower->z <= fh)
|
||||
{
|
||||
player->follower->z = fh;
|
||||
|
||||
if (!(player->mo->eflags & MFE_VERTICALFLIP) && player->follower->momz <= 0 && fl.bobamp != 0)
|
||||
if (!(player->mo->eflags & MFE_VERTICALFLIP) && player->follower->momz <= 0 && fl->bobamp != 0)
|
||||
{
|
||||
// Ground bounce
|
||||
player->follower->momz = P_GetMobjZMovement(player->mo) + FixedMul(fl.bobamp, player->follower->scale);
|
||||
player->follower->momz = P_GetMobjZMovement(player->mo) + FixedMul(fl->bobamp, player->follower->scale);
|
||||
player->follower->extravalue1 = FOLLOWERSTATE_RESET;
|
||||
}
|
||||
else if (player->follower->momz < 0)
|
||||
|
|
@ -527,10 +541,10 @@ void K_HandleFollower(player_t *player)
|
|||
{
|
||||
player->follower->z = ch;
|
||||
|
||||
if ((player->mo->eflags & MFE_VERTICALFLIP) && player->follower->momz >= 0 && fl.bobamp != 0)
|
||||
if ((player->mo->eflags & MFE_VERTICALFLIP) && player->follower->momz >= 0 && fl->bobamp != 0)
|
||||
{
|
||||
// Ground bounce
|
||||
player->follower->momz = P_GetMobjZMovement(player->mo) - FixedMul(fl.bobamp, player->follower->scale);
|
||||
player->follower->momz = P_GetMobjZMovement(player->mo) - FixedMul(fl->bobamp, player->follower->scale);
|
||||
player->follower->extravalue1 = FOLLOWERSTATE_RESET;
|
||||
}
|
||||
else if (player->follower->momz > 0)
|
||||
|
|
@ -559,7 +573,7 @@ void K_HandleFollower(player_t *player)
|
|||
// match follower's momentums and (e)flags(2).
|
||||
bmobj->momx = player->follower->momx;
|
||||
bmobj->momy = player->follower->momy;
|
||||
bmobj->z += FixedDiv(deltaz, fl.vertlag);
|
||||
bmobj->z += FixedDiv(deltaz, fl->vertlag);
|
||||
bmobj->momz = player->follower->momz;
|
||||
|
||||
P_SetScale(bmobj, FixedMul(bubble, player->mo->scale));
|
||||
|
|
@ -594,7 +608,7 @@ void K_HandleFollower(player_t *player)
|
|||
// spin out
|
||||
player->follower->angle = player->drawangle;
|
||||
|
||||
K_UpdateFollowerState(player->follower, fl.hurtstate, FOLLOWERSTATE_HURT);
|
||||
K_UpdateFollowerState(player->follower, fl->hurtstate, FOLLOWERSTATE_HURT);
|
||||
|
||||
if (player->mo->health <= 0)
|
||||
{
|
||||
|
|
@ -608,26 +622,26 @@ void K_HandleFollower(player_t *player)
|
|||
if (K_IsPlayerLosing(player))
|
||||
{
|
||||
// L
|
||||
K_UpdateFollowerState(player->follower, fl.losestate, FOLLOWERSTATE_LOSE);
|
||||
K_UpdateFollowerState(player->follower, fl->losestate, FOLLOWERSTATE_LOSE);
|
||||
}
|
||||
else
|
||||
{
|
||||
// W
|
||||
K_UpdateFollowerState(player->follower, fl.winstate, FOLLOWERSTATE_WIN);
|
||||
K_UpdateFollowerState(player->follower, fl->winstate, FOLLOWERSTATE_WIN);
|
||||
}
|
||||
}
|
||||
else if (player->follower->movecount)
|
||||
{
|
||||
K_UpdateFollowerState(player->follower, fl.hitconfirmstate, FOLLOWERSTATE_HITCONFIRM);
|
||||
K_UpdateFollowerState(player->follower, fl->hitconfirmstate, FOLLOWERSTATE_HITCONFIRM);
|
||||
player->follower->movecount--;
|
||||
}
|
||||
else if (player->speed > 10*player->mo->scale) // animation for moving fast enough
|
||||
{
|
||||
K_UpdateFollowerState(player->follower, fl.followstate, FOLLOWERSTATE_FOLLOW);
|
||||
K_UpdateFollowerState(player->follower, fl->followstate, FOLLOWERSTATE_FOLLOW);
|
||||
}
|
||||
else
|
||||
{
|
||||
K_UpdateFollowerState(player->follower, fl.idlestate, FOLLOWERSTATE_IDLE);
|
||||
K_UpdateFollowerState(player->follower, fl->idlestate, FOLLOWERSTATE_IDLE);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -170,20 +170,22 @@ void K_SetFollowerByNum(INT32 playernum, INT32 skinnum);
|
|||
|
||||
|
||||
/*--------------------------------------------------
|
||||
UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, UINT16 playercolor)
|
||||
UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, follower_t *follower, UINT16 playercolor, skin_t *playerskin)
|
||||
|
||||
Updates a player's follower pointer, and does
|
||||
its positioning and animations.
|
||||
|
||||
Input Arguments:-
|
||||
followercolor - The raw color setting for the follower
|
||||
follower - Follower struct to retrieve default color from. Can be NULL
|
||||
playercolor - The player's associated colour, for reference
|
||||
playerskin - Skin struct to retrieve default color from. Can be NULL
|
||||
|
||||
Return:-
|
||||
The resultant skincolor enum for the follower
|
||||
--------------------------------------------------*/
|
||||
|
||||
UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, UINT16 playercolor);
|
||||
UINT16 K_GetEffectiveFollowerColor(UINT16 followercolor, follower_t *follower, UINT16 playercolor, skin_t *playerskin);
|
||||
|
||||
|
||||
/*--------------------------------------------------
|
||||
|
|
|
|||
20
src/k_menu.h
20
src/k_menu.h
|
|
@ -614,17 +614,12 @@ void M_DrawMenuMessage(void);
|
|||
void M_QuitResponse(INT32 ch);
|
||||
void M_QuitSRB2(INT32 choice);
|
||||
|
||||
extern UINT16 nummenucolors;
|
||||
void M_AddMenuColor(UINT16 color);
|
||||
void M_MoveColorBefore(UINT16 color, UINT16 targ);
|
||||
void M_MoveColorAfter(UINT16 color, UINT16 targ);
|
||||
UINT16 M_GetColorBefore(UINT16 color, UINT16 amount, boolean follower);
|
||||
UINT16 M_GetColorAfter(UINT16 color, UINT16 amount, boolean follower);
|
||||
void M_InitPlayerSetupColors(void);
|
||||
void M_FreePlayerSetupColors(void);
|
||||
UINT16 M_GetColorAfter(setup_player_colors_t *colors, UINT16 value, INT32 amount);
|
||||
#define M_GetColorBefore(a, b, c) M_GetColorAfter(a, b, -c)
|
||||
|
||||
// If you want to waste a bunch of memory for a limit no one will hit, feel free to boost this to MAXSKINS :P
|
||||
// I figure this will be enough clone characters to fit onto one grid space.
|
||||
// TODO: Dynamically allocate instead, you KNOW this limit will get hit by someone eventually
|
||||
#define MAXCLONES MAXSKINS/8
|
||||
|
||||
extern struct setup_chargrid_s {
|
||||
|
|
@ -649,6 +644,13 @@ typedef enum
|
|||
CSSTEP_READY
|
||||
} setup_mdepth_t;
|
||||
|
||||
struct setup_player_colors_t
|
||||
{
|
||||
UINT16 *list;
|
||||
size_t listLen;
|
||||
size_t listCap;
|
||||
};
|
||||
|
||||
struct setup_player_t
|
||||
{
|
||||
SINT8 gridx, gridy;
|
||||
|
|
@ -676,6 +678,8 @@ struct setup_player_t
|
|||
tic_t follower_timer;
|
||||
UINT8 follower_frame;
|
||||
state_t *follower_state;
|
||||
|
||||
setup_player_colors_t colors;
|
||||
};
|
||||
|
||||
extern setup_player_t setup_player[MAXSPLITSCREENPLAYERS];
|
||||
|
|
|
|||
116
src/k_menudraw.c
116
src/k_menudraw.c
|
|
@ -972,7 +972,8 @@ static void M_DrawCharSelectCircle(setup_player_t *p, INT16 x, INT16 y)
|
|||
numoptions = setup_chargrid[p->gridx][p->gridy].numskins;
|
||||
break;
|
||||
case CSSTEP_COLORS:
|
||||
numoptions = nummenucolors;
|
||||
case CSSTEP_FOLLOWERCOLORS:
|
||||
numoptions = p->colors.listLen;
|
||||
break;
|
||||
case CSSTEP_FOLLOWERCATEGORY:
|
||||
numoptions = setup_numfollowercategories+1;
|
||||
|
|
@ -980,9 +981,6 @@ static void M_DrawCharSelectCircle(setup_player_t *p, INT16 x, INT16 y)
|
|||
case CSSTEP_FOLLOWER:
|
||||
numoptions = setup_followercategories[p->followercategory][0];
|
||||
break;
|
||||
case CSSTEP_FOLLOWERCOLORS:
|
||||
numoptions = nummenucolors+2;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
|
@ -1035,20 +1033,20 @@ static void M_DrawCharSelectCircle(setup_player_t *p, INT16 x, INT16 y)
|
|||
|
||||
if (i == 0)
|
||||
{
|
||||
n = l = r = M_GetColorBefore(p->color, numoptions/2, false);
|
||||
n = l = r = M_GetColorBefore(&p->colors, p->color, (numoptions/2) - 1);
|
||||
}
|
||||
else if (subtract)
|
||||
{
|
||||
n = l = M_GetColorBefore(l, 1, false);
|
||||
n = l = M_GetColorBefore(&p->colors, l, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = r = M_GetColorAfter(r, 1, false);
|
||||
n = r = M_GetColorAfter(&p->colors, r, 1);
|
||||
}
|
||||
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, n, GTC_MENUCACHE);
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, (n == SKINCOLOR_NONE) ? skins[p->skin].prefcolor : n, GTC_MENUCACHE);
|
||||
|
||||
diff = (numoptions - i)/2; // only 0 when i == numoptions-1
|
||||
diff = (numoptions - i) / 2; // only 0 when i == numoptions-1
|
||||
|
||||
if (diff == 0)
|
||||
patch = W_CachePatchName("COLORSP2", PU_CACHE);
|
||||
|
|
@ -1145,7 +1143,7 @@ static void M_DrawCharSelectCircle(setup_player_t *p, INT16 x, INT16 y)
|
|||
patch = W_CachePatchName(fl->icon, PU_CACHE);
|
||||
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT,
|
||||
K_GetEffectiveFollowerColor(fl->defaultcolor, p->color),
|
||||
K_GetEffectiveFollowerColor(fl->defaultcolor, fl, p->color, &skins[p->skin]),
|
||||
GTC_MENUCACHE
|
||||
);
|
||||
}
|
||||
|
|
@ -1164,18 +1162,18 @@ static void M_DrawCharSelectCircle(setup_player_t *p, INT16 x, INT16 y)
|
|||
|
||||
if (i == 0)
|
||||
{
|
||||
n = l = r = M_GetColorBefore(p->followercolor, numoptions/2, true);
|
||||
n = l = r = M_GetColorBefore(&p->colors, p->followercolor, (numoptions/2) - 1);
|
||||
}
|
||||
else if (subtract)
|
||||
{
|
||||
n = l = M_GetColorBefore(l, 1, true);
|
||||
n = l = M_GetColorBefore(&p->colors, l, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
n = r = M_GetColorAfter(r, 1, true);
|
||||
n = r = M_GetColorAfter(&p->colors, r, 1);
|
||||
}
|
||||
|
||||
col = K_GetEffectiveFollowerColor(n, p->color);
|
||||
col = K_GetEffectiveFollowerColor(n, &followers[p->followern], p->color, &skins[p->skin]);
|
||||
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE);
|
||||
|
||||
|
|
@ -1265,14 +1263,13 @@ static boolean M_DrawCharacterSprite(INT16 x, INT16 y, INT16 skin, boolean charf
|
|||
// if a setup_player_t is specified instead, its data will be used to animate the follower sprite.
|
||||
static boolean M_DrawFollowerSprite(INT16 x, INT16 y, INT32 num, boolean charflip, INT32 addflags, UINT8 *colormap, setup_player_t *p)
|
||||
{
|
||||
|
||||
spritedef_t *sprdef;
|
||||
spriteframe_t *sprframe;
|
||||
patch_t *patch;
|
||||
INT32 followernum;
|
||||
state_t *usestate;
|
||||
UINT32 useframe;
|
||||
follower_t fl;
|
||||
follower_t *fl;
|
||||
UINT8 rotation = (charflip ? 1 : 7);
|
||||
|
||||
if (p != NULL)
|
||||
|
|
@ -1284,7 +1281,7 @@ static boolean M_DrawFollowerSprite(INT16 x, INT16 y, INT32 num, boolean charfli
|
|||
if (followernum < 0 || followernum >= numfollowers)
|
||||
return false;
|
||||
|
||||
fl = followers[followernum];
|
||||
fl = &followers[followernum];
|
||||
|
||||
if (p != NULL)
|
||||
{
|
||||
|
|
@ -1317,13 +1314,16 @@ static boolean M_DrawFollowerSprite(INT16 x, INT16 y, INT32 num, boolean charfli
|
|||
if (p != NULL)
|
||||
{
|
||||
UINT16 color = K_GetEffectiveFollowerColor(
|
||||
(p->mdepth < CSSTEP_FOLLOWERCOLORS) ? fl.defaultcolor : p->followercolor,
|
||||
p->color);
|
||||
sine = FixedMul(fl.bobamp, FINESINE(((FixedMul(4 * M_TAU_FIXED, fl.bobspeed) * p->follower_timer)>>ANGLETOFINESHIFT) & FINEMASK));
|
||||
(p->mdepth < CSSTEP_FOLLOWERCOLORS) ? fl->defaultcolor : p->followercolor,
|
||||
fl,
|
||||
p->color,
|
||||
&skins[p->skin]
|
||||
);
|
||||
sine = FixedMul(fl->bobamp, FINESINE(((FixedMul(4 * M_TAU_FIXED, fl->bobspeed) * p->follower_timer)>>ANGLETOFINESHIFT) & FINEMASK));
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, color, GTC_MENUCACHE);
|
||||
}
|
||||
|
||||
V_DrawFixedPatch((x*FRACUNIT), ((y-12)*FRACUNIT) + sine, fl.scale, addflags, patch, colormap);
|
||||
V_DrawFixedPatch((x*FRACUNIT), ((y-12)*FRACUNIT) + sine, fl->scale, addflags, patch, colormap);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -1335,12 +1335,24 @@ static void M_DrawCharSelectSprite(UINT8 num, INT16 x, INT16 y, boolean charflip
|
|||
UINT8 *colormap;
|
||||
|
||||
if (p->skin < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (p->mdepth < CSSTEP_COLORS)
|
||||
{
|
||||
color = skins[p->skin].prefcolor;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = p->color;
|
||||
}
|
||||
|
||||
if (color == SKINCOLOR_NONE)
|
||||
{
|
||||
color = skins[p->skin].prefcolor;
|
||||
}
|
||||
|
||||
colormap = R_GetTranslationColormap(p->skin, color, GTC_MENUCACHE);
|
||||
|
||||
M_DrawCharacterSprite(x, y, p->skin, charflip, (p->mdepth == CSSTEP_READY), 0, colormap);
|
||||
|
|
@ -1387,9 +1399,9 @@ static void M_DrawCharSelectPreview(UINT8 num)
|
|||
M_DrawFollowerSprite(x+32+((charflip ? 1 : -1)*16), y+75, -1, charflip, 0, 0, p);
|
||||
}
|
||||
|
||||
if ((setup_animcounter/10) & 1 && gamestate == GS_MENU) // Not drawn outside of GS_MENU.
|
||||
if ((setup_animcounter/10) & 1)
|
||||
{
|
||||
if (p->mdepth == CSSTEP_NONE && num == setup_numplayers)
|
||||
if (p->mdepth == CSSTEP_NONE && num == setup_numplayers && gamestate == GS_MENU)
|
||||
{
|
||||
V_DrawScaledPatch(x+1, y+36, 0, W_CachePatchName("4PSTART", PU_CACHE));
|
||||
}
|
||||
|
|
@ -1620,6 +1632,7 @@ static void M_DrawCharSelectCursor(UINT8 num)
|
|||
|
||||
setup_player_t *p = &setup_player[num];
|
||||
char letter = 'A' + num;
|
||||
UINT16 color = SKINCOLOR_NONE;
|
||||
UINT8 *colormap;
|
||||
INT16 x, y;
|
||||
INT16 quadx, quady;
|
||||
|
|
@ -1637,7 +1650,20 @@ static void M_DrawCharSelectCursor(UINT8 num)
|
|||
if (optionsmenu.profile)
|
||||
x += 64;
|
||||
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, (p->color != SKINCOLOR_NONE ? p->color : SKINCOLOR_GREY), GTC_MENUCACHE);
|
||||
color = p->color;
|
||||
if (color == SKINCOLOR_NONE)
|
||||
{
|
||||
if (p->skin >= 0)
|
||||
{
|
||||
color = skins[p->skin].prefcolor;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = SKINCOLOR_GREY;
|
||||
}
|
||||
}
|
||||
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, color, GTC_MENUCACHE);
|
||||
|
||||
if (p->mdepth >= CSSTEP_READY)
|
||||
{
|
||||
|
|
@ -1722,7 +1748,7 @@ static void M_DrawProfileCard(INT32 x, INT32 y, boolean greyedout, profile_t *p)
|
|||
{
|
||||
if (M_DrawFollowerSprite(x-22 - 16, y+119, 0, false, 0, 0, sp))
|
||||
{
|
||||
UINT16 col = K_GetEffectiveFollowerColor(sp->followercolor, sp->color);;
|
||||
UINT16 col = K_GetEffectiveFollowerColor(sp->followercolor, &followers[sp->followern], sp->color, &skins[sp->skin]);
|
||||
patch_t *ico = W_CachePatchName(followers[sp->followern].icon, PU_CACHE);
|
||||
UINT8 *fcolormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE);
|
||||
V_DrawMappedPatch(x+14+18, y+66, 0, ico, fcolormap);
|
||||
|
|
@ -1732,8 +1758,13 @@ static void M_DrawProfileCard(INT32 x, INT32 y, boolean greyedout, profile_t *p)
|
|||
else if (skinnum > -1) // otherwise, read from profile.
|
||||
{
|
||||
UINT8 *ccolormap, *fcolormap;
|
||||
UINT16 col = K_GetEffectiveFollowerColor(p->followercolor, p->color);
|
||||
UINT8 fln = K_FollowerAvailable(p->follower);
|
||||
UINT16 col = K_GetEffectiveFollowerColor(
|
||||
p->followercolor,
|
||||
K_FollowerUsable(fln) ? &followers[fln] : 0,
|
||||
p->color,
|
||||
&skins[skinnum]
|
||||
);
|
||||
|
||||
if (R_SkinUsable(g_localplayers[0], skinnum, false))
|
||||
ccolormap = colormap;
|
||||
|
|
@ -4857,9 +4888,9 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, boolean hili
|
|||
case SECRET_FOLLOWER:
|
||||
categoryid = '2';
|
||||
break;
|
||||
/*case SECRET_COLOR:
|
||||
case SECRET_COLOR:
|
||||
categoryid = '3';
|
||||
break;*/
|
||||
break;
|
||||
case SECRET_CUP:
|
||||
categoryid = '4';
|
||||
break;
|
||||
|
|
@ -4922,12 +4953,23 @@ static void M_DrawChallengeTile(INT16 i, INT16 j, INT32 x, INT32 y, boolean hili
|
|||
INT32 skin = M_UnlockableFollowerNum(ref);
|
||||
if (skin != -1)
|
||||
{
|
||||
UINT16 col = K_GetEffectiveFollowerColor(followers[skin].defaultcolor, cv_playercolor[0].value);
|
||||
INT32 psk = R_SkinAvailable(cv_skin[0].string);
|
||||
UINT16 col = K_GetEffectiveFollowerColor(followers[skin].defaultcolor, &followers[skin], cv_playercolor[0].value, (psk != -1) ? &skins[psk] : &skins[0]);
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE);
|
||||
pat = W_CachePatchName(followers[skin].icon, PU_CACHE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SECRET_COLOR:
|
||||
{
|
||||
INT32 colorid = M_UnlockableColorNum(ref);
|
||||
if (colorid != SKINCOLOR_NONE)
|
||||
{
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, colorid, GTC_MENUCACHE);
|
||||
}
|
||||
iconid = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
case SECRET_HARDSPEED:
|
||||
iconid = 3;
|
||||
|
|
@ -5160,7 +5202,7 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
|
|||
// Draw follower next to them
|
||||
if (fskin != -1)
|
||||
{
|
||||
UINT16 col = K_GetEffectiveFollowerColor(followers[fskin].defaultcolor, cv_playercolor[0].value);
|
||||
UINT16 col = K_GetEffectiveFollowerColor(followers[fskin].defaultcolor, &followers[fskin], cv_playercolor[0].value, &skins[skin]);
|
||||
colormap = R_GetTranslationColormap(TC_DEFAULT, col, GTC_MENUCACHE);
|
||||
M_DrawFollowerSprite(x - 16, y, fskin, false, 0, colormap, NULL);
|
||||
|
||||
|
|
@ -5174,6 +5216,20 @@ static void M_DrawChallengePreview(INT32 x, INT32 y)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case SECRET_COLOR:
|
||||
{
|
||||
INT32 colorid = M_UnlockableColorNum(ref);
|
||||
if (colorid == SKINCOLOR_NONE)
|
||||
break;
|
||||
INT32 skin = R_SkinAvailable(cv_skin[0].string);
|
||||
if (skin == -1)
|
||||
skin = 0;
|
||||
colormap = R_GetTranslationColormap(skin, colorid, GTC_MENUCACHE);
|
||||
|
||||
// Draw reference for character bathed in coloured slime
|
||||
M_DrawCharacterSprite(x, y, skin, false, false, 0, colormap);
|
||||
break;
|
||||
}
|
||||
case SECRET_CUP:
|
||||
{
|
||||
levelsearch_t templevelsearch;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@
|
|||
#include "r_skins.h"
|
||||
#include "monocypher/monocypher.h"
|
||||
#include "stun.h"
|
||||
#include "k_color.h"
|
||||
|
||||
// List of all the profiles.
|
||||
static profile_t *profilesList[MAXPROFILES+1]; // +1 because we're gonna add a default "GUEST' profile.
|
||||
|
|
@ -367,7 +368,7 @@ void PR_LoadProfiles(void)
|
|||
; // Valid, even outside the bounds
|
||||
}
|
||||
else if (profilesList[i]->color >= numskincolors
|
||||
|| skincolors[profilesList[i]->color].accessible == false)
|
||||
|| K_ColorUsable(profilesList[i]->color, false) == false)
|
||||
{
|
||||
profilesList[i]->color = PROFILEDEFAULTCOLOR;
|
||||
}
|
||||
|
|
@ -383,7 +384,7 @@ void PR_LoadProfiles(void)
|
|||
}
|
||||
else if (profilesList[i]->followercolor >= numskincolors
|
||||
|| profilesList[i]->followercolor == SKINCOLOR_NONE
|
||||
|| skincolors[profilesList[i]->followercolor].accessible == false)
|
||||
|| K_ColorUsable(profilesList[i]->followercolor, true) == false)
|
||||
{
|
||||
profilesList[i]->followercolor = PROFILEDEFAULTFOLLOWERCOLOR;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -337,49 +337,11 @@ static int lib_reserveLuabanks(lua_State *L)
|
|||
// M_MENU
|
||||
//////////////
|
||||
|
||||
static int lib_pMoveColorBefore(lua_State *L)
|
||||
{
|
||||
UINT16 color = (UINT16)luaL_checkinteger(L, 1);
|
||||
UINT16 targ = (UINT16)luaL_checkinteger(L, 2);
|
||||
|
||||
NOHUD
|
||||
M_MoveColorBefore(color, targ);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pMoveColorAfter(lua_State *L)
|
||||
{
|
||||
UINT16 color = (UINT16)luaL_checkinteger(L, 1);
|
||||
UINT16 targ = (UINT16)luaL_checkinteger(L, 2);
|
||||
|
||||
NOHUD
|
||||
M_MoveColorAfter(color, targ);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int lib_pGetColorBefore(lua_State *L)
|
||||
{
|
||||
UINT16 color = (UINT16)luaL_checkinteger(L, 1);
|
||||
UINT16 amount = (UINT16)luaL_checkinteger(L, 2);
|
||||
boolean follower = lua_optboolean(L, 3);
|
||||
lua_pushinteger(L, M_GetColorBefore(color, amount, follower));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_pGetColorAfter(lua_State *L)
|
||||
{
|
||||
UINT16 color = (UINT16)luaL_checkinteger(L, 1);
|
||||
UINT16 amount = (UINT16)luaL_checkinteger(L, 2);
|
||||
boolean follower = lua_optboolean(L, 3);
|
||||
lua_pushinteger(L, M_GetColorAfter(color, amount, follower));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int lib_pGetEffectiveFollowerColor(lua_State *L)
|
||||
{
|
||||
UINT16 followercolor = (UINT16)luaL_checkinteger(L, 1);
|
||||
UINT16 playercolor = (UINT16)luaL_checkinteger(L, 2);
|
||||
lua_pushinteger(L, K_GetEffectiveFollowerColor(followercolor, playercolor));
|
||||
lua_pushinteger(L, K_GetEffectiveFollowerColor(followercolor, NULL, playercolor, NULL)); // FIXME: follower / skin
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
|
@ -3935,12 +3897,6 @@ static luaL_Reg lib[] = {
|
|||
{"IsPlayerAdmin", lib_isPlayerAdmin},
|
||||
{"reserveLuabanks", lib_reserveLuabanks},
|
||||
|
||||
// m_menu
|
||||
{"M_MoveColorAfter",lib_pMoveColorAfter},
|
||||
{"M_MoveColorBefore",lib_pMoveColorBefore},
|
||||
{"M_GetColorAfter",lib_pGetColorAfter},
|
||||
{"M_GetColorBefore",lib_pGetColorBefore},
|
||||
|
||||
// m_random
|
||||
{"P_RandomFixed",lib_pRandomFixed},
|
||||
{"P_RandomByte",lib_pRandomByte},
|
||||
|
|
|
|||
36
src/m_cond.c
36
src/m_cond.c
|
|
@ -2048,6 +2048,42 @@ INT32 M_UnlockableFollowerNum(unlockable_t *unlock)
|
|||
return -1;
|
||||
}
|
||||
|
||||
INT32 M_UnlockableColorNum(unlockable_t *unlock)
|
||||
{
|
||||
if (unlock->type != SECRET_COLOR)
|
||||
{
|
||||
// This isn't a color unlockable...
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (unlock->stringVar && unlock->stringVar[0])
|
||||
{
|
||||
skincolornum_t colornum = SKINCOLOR_NONE;
|
||||
|
||||
if (unlock->stringVarCache != -1)
|
||||
{
|
||||
return unlock->stringVarCache;
|
||||
}
|
||||
|
||||
// Get the skin from the string.
|
||||
colornum = R_GetColorByName(unlock->stringVar);
|
||||
if (colornum != SKINCOLOR_NONE)
|
||||
{
|
||||
unlock->stringVarCache = colornum;
|
||||
return colornum;
|
||||
}
|
||||
}
|
||||
|
||||
if (unlock->variable > SKINCOLOR_NONE && unlock->variable < numskincolors)
|
||||
{
|
||||
// Use the number directly.
|
||||
return unlock->variable;
|
||||
}
|
||||
|
||||
// Invalid color unlockable.
|
||||
return -1;
|
||||
}
|
||||
|
||||
cupheader_t *M_UnlockableCup(unlockable_t *unlock)
|
||||
{
|
||||
cupheader_t *cup = kartcupheaders;
|
||||
|
|
|
|||
|
|
@ -181,6 +181,7 @@ typedef enum
|
|||
// Player restrictions
|
||||
SECRET_SKIN, // Permit this character
|
||||
SECRET_FOLLOWER, // Permit this follower
|
||||
SECRET_COLOR, // Permit this color
|
||||
|
||||
// Difficulty restrictions
|
||||
SECRET_HARDSPEED, // Permit Hard gamespeed
|
||||
|
|
@ -358,6 +359,7 @@ UINT8 M_GotLowEnoughTime(INT32 tictime);
|
|||
|
||||
INT32 M_UnlockableSkinNum(unlockable_t *unlock);
|
||||
INT32 M_UnlockableFollowerNum(unlockable_t *unlock);
|
||||
INT32 M_UnlockableColorNum(unlockable_t *unlock);
|
||||
cupheader_t *M_UnlockableCup(unlockable_t *unlock);
|
||||
UINT16 M_UnlockableMapNum(unlockable_t *unlock);
|
||||
|
||||
|
|
|
|||
|
|
@ -462,7 +462,8 @@ void M_ChallengesTick(void)
|
|||
INT32 skin = M_UnlockableFollowerNum(ref);
|
||||
if (skin != -1)
|
||||
{
|
||||
bombcolor = K_GetEffectiveFollowerColor(followers[skin].defaultcolor, cv_playercolor[0].value);
|
||||
INT32 psk = R_SkinAvailable(cv_skin[0].string);
|
||||
bombcolor = K_GetEffectiveFollowerColor(followers[skin].defaultcolor, &followers[skin], cv_playercolor[0].value, (psk != -1) ? &skins[psk] : &skins[0]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,8 @@
|
|||
#include "../s_sound.h"
|
||||
#include "../k_grandprix.h" // K_CanChangeRules
|
||||
#include "../m_cond.h" // Condition Sets
|
||||
#include "../k_color.h"
|
||||
#include "../z_zone.h"
|
||||
|
||||
menuitem_t PLAY_CharSelect[] =
|
||||
{
|
||||
|
|
@ -36,8 +38,6 @@ static void Splitplayers_OnChange(void);
|
|||
CV_PossibleValue_t splitplayers_cons_t[] = {{1, "One"}, {2, "Two"}, {3, "Three"}, {4, "Four"}, {0, NULL}};
|
||||
consvar_t cv_splitplayers = CVAR_INIT ("splitplayers", "One", CV_CALL, splitplayers_cons_t, Splitplayers_OnChange);
|
||||
|
||||
UINT16 nummenucolors = 0;
|
||||
|
||||
// Character Select!
|
||||
// @TODO: Splitscreen handling when profiles are added into the game. ...I probably won't be the one to handle this however. -Lat'
|
||||
|
||||
|
|
@ -53,261 +53,116 @@ tic_t setup_animcounter = 0;
|
|||
UINT8 setup_page = 0;
|
||||
UINT8 setup_maxpage = 0; // For charsel page to identify alts easier...
|
||||
|
||||
void M_AddMenuColor(UINT16 color) {
|
||||
menucolor_t *c;
|
||||
|
||||
if (color >= numskincolors) {
|
||||
CONS_Printf("M_AddMenuColor: color %d does not exist.",color);
|
||||
return;
|
||||
}
|
||||
|
||||
// SRB2Kart: I do not understand vanilla doesn't need this but WE do???!?!??!
|
||||
if (!skincolors[color].accessible) {
|
||||
return;
|
||||
}
|
||||
|
||||
c = (menucolor_t *)malloc(sizeof(menucolor_t));
|
||||
c->color = color;
|
||||
if (menucolorhead == NULL) {
|
||||
c->next = c;
|
||||
c->prev = c;
|
||||
menucolorhead = c;
|
||||
menucolortail = c;
|
||||
} else {
|
||||
c->next = menucolorhead;
|
||||
c->prev = menucolortail;
|
||||
menucolortail->next = c;
|
||||
menucolorhead->prev = c;
|
||||
menucolortail = c;
|
||||
}
|
||||
|
||||
nummenucolors++;
|
||||
}
|
||||
|
||||
void M_MoveColorBefore(UINT16 color, UINT16 targ) {
|
||||
menucolor_t *look, *c = NULL, *t = NULL;
|
||||
|
||||
if (color == targ)
|
||||
return;
|
||||
if (color >= numskincolors) {
|
||||
CONS_Printf("M_MoveColorBefore: color %d does not exist.",color);
|
||||
return;
|
||||
}
|
||||
if (targ >= numskincolors) {
|
||||
CONS_Printf("M_MoveColorBefore: target color %d does not exist.",targ);
|
||||
return;
|
||||
}
|
||||
|
||||
for (look=menucolorhead;;look=look->next) {
|
||||
if (look->color == color)
|
||||
c = look;
|
||||
else if (look->color == targ)
|
||||
t = look;
|
||||
if (c != NULL && t != NULL)
|
||||
break;
|
||||
if (look==menucolortail)
|
||||
return;
|
||||
}
|
||||
|
||||
if (c == t->prev)
|
||||
return;
|
||||
|
||||
if (t==menucolorhead)
|
||||
menucolorhead = c;
|
||||
if (c==menucolortail)
|
||||
menucolortail = c->prev;
|
||||
|
||||
c->prev->next = c->next;
|
||||
c->next->prev = c->prev;
|
||||
|
||||
c->prev = t->prev;
|
||||
c->next = t;
|
||||
t->prev->next = c;
|
||||
t->prev = c;
|
||||
}
|
||||
|
||||
void M_MoveColorAfter(UINT16 color, UINT16 targ) {
|
||||
menucolor_t *look, *c = NULL, *t = NULL;
|
||||
|
||||
if (color == targ)
|
||||
return;
|
||||
if (color >= numskincolors) {
|
||||
CONS_Printf("M_MoveColorAfter: color %d does not exist.\n",color);
|
||||
return;
|
||||
}
|
||||
if (targ >= numskincolors) {
|
||||
CONS_Printf("M_MoveColorAfter: target color %d does not exist.\n",targ);
|
||||
return;
|
||||
}
|
||||
|
||||
for (look=menucolorhead;;look=look->next) {
|
||||
if (look->color == color)
|
||||
c = look;
|
||||
else if (look->color == targ)
|
||||
t = look;
|
||||
if (c != NULL && t != NULL)
|
||||
break;
|
||||
if (look==menucolortail)
|
||||
return;
|
||||
}
|
||||
|
||||
if (t == c->prev)
|
||||
return;
|
||||
|
||||
if (t==menucolortail)
|
||||
menucolortail = c;
|
||||
else if (c==menucolortail)
|
||||
menucolortail = c->prev;
|
||||
|
||||
c->prev->next = c->next;
|
||||
c->next->prev = c->prev;
|
||||
|
||||
c->next = t->next;
|
||||
c->prev = t;
|
||||
t->next->prev = c;
|
||||
t->next = c;
|
||||
}
|
||||
|
||||
UINT16 M_GetColorBefore(UINT16 color, UINT16 amount, boolean follower)
|
||||
static void M_PushMenuColor(setup_player_colors_t *colors, UINT16 newColor)
|
||||
{
|
||||
menucolor_t *look = NULL;
|
||||
|
||||
for (; amount > 0; amount--)
|
||||
if (colors->listLen >= colors->listCap)
|
||||
{
|
||||
if (follower == true)
|
||||
if (colors->listCap == 0)
|
||||
{
|
||||
if (color == FOLLOWERCOLOR_OPPOSITE)
|
||||
{
|
||||
look = menucolortail;
|
||||
color = menucolortail->color;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (color == FOLLOWERCOLOR_MATCH)
|
||||
{
|
||||
look = NULL;
|
||||
color = FOLLOWERCOLOR_OPPOSITE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (color == menucolorhead->color)
|
||||
{
|
||||
look = NULL;
|
||||
color = FOLLOWERCOLOR_MATCH;
|
||||
continue;
|
||||
}
|
||||
colors->listCap = 64;
|
||||
}
|
||||
else
|
||||
{
|
||||
colors->listCap *= 2;
|
||||
}
|
||||
|
||||
if (color == 0 || color >= numskincolors)
|
||||
{
|
||||
CONS_Printf("M_GetColorBefore: color %d does not exist.\n",color);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (look == NULL)
|
||||
{
|
||||
for (look = menucolorhead;; look = look->next)
|
||||
{
|
||||
if (look->color == color)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (look == menucolortail)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
look = look->prev;
|
||||
color = look->color;
|
||||
colors->list = Z_ReallocAlign(
|
||||
colors->list,
|
||||
sizeof(UINT16) * colors->listCap,
|
||||
PU_STATIC,
|
||||
NULL,
|
||||
sizeof(UINT16) * 8
|
||||
);
|
||||
}
|
||||
return color;
|
||||
|
||||
colors->list[colors->listLen] = newColor;
|
||||
colors->listLen++;
|
||||
}
|
||||
|
||||
UINT16 M_GetColorAfter(UINT16 color, UINT16 amount, boolean follower)
|
||||
static void M_ClearMenuColors(setup_player_colors_t *colors)
|
||||
{
|
||||
menucolor_t *look = NULL;
|
||||
|
||||
for (; amount > 0; amount--)
|
||||
if (colors->list != NULL)
|
||||
{
|
||||
if (follower == true)
|
||||
{
|
||||
if (color == menucolortail->color)
|
||||
{
|
||||
look = NULL;
|
||||
color = FOLLOWERCOLOR_OPPOSITE;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (color == FOLLOWERCOLOR_OPPOSITE)
|
||||
{
|
||||
look = NULL;
|
||||
color = FOLLOWERCOLOR_MATCH;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (color == FOLLOWERCOLOR_MATCH)
|
||||
{
|
||||
look = menucolorhead;
|
||||
color = menucolorhead->color;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (color == 0 || color >= numskincolors)
|
||||
{
|
||||
CONS_Printf("M_GetColorAfter: color %d does not exist.\n",color);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (look == NULL)
|
||||
{
|
||||
for (look = menucolorhead;; look = look->next)
|
||||
{
|
||||
if (look->color == color)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (look == menucolortail)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
look = look->next;
|
||||
color = look->color;
|
||||
Z_Free(colors->list);
|
||||
colors->list = NULL;
|
||||
}
|
||||
return color;
|
||||
|
||||
colors->listLen = colors->listCap = 0;
|
||||
}
|
||||
|
||||
void M_InitPlayerSetupColors(void) {
|
||||
UINT8 i;
|
||||
numskincolors = SKINCOLOR_FIRSTFREESLOT;
|
||||
menucolorhead = menucolortail = NULL;
|
||||
for (i=0; i<numskincolors; i++)
|
||||
M_AddMenuColor(i);
|
||||
}
|
||||
UINT16 M_GetColorAfter(setup_player_colors_t *colors, UINT16 value, INT32 amount)
|
||||
{
|
||||
const INT32 sign = (amount < 0) ? -1 : 1;
|
||||
INT32 index = -1;
|
||||
size_t i = SIZE_MAX;
|
||||
|
||||
void M_FreePlayerSetupColors(void) {
|
||||
menucolor_t *look = menucolorhead, *tmp;
|
||||
if (amount == 0 || colors->listLen == 0)
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
if (menucolorhead==NULL)
|
||||
return;
|
||||
|
||||
while (true) {
|
||||
if (look != menucolortail) {
|
||||
tmp = look;
|
||||
look = look->next;
|
||||
free(tmp);
|
||||
} else {
|
||||
free(look);
|
||||
return;
|
||||
for (i = 0; i < colors->listLen; i++)
|
||||
{
|
||||
if (colors->list[i] == value)
|
||||
{
|
||||
index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
menucolorhead = menucolortail = NULL;
|
||||
if (index == -1)
|
||||
{
|
||||
// Not in list, so no real correct behavior here.
|
||||
// Just try to get back to the list.
|
||||
return colors->list[0];
|
||||
}
|
||||
|
||||
amount = abs(amount);
|
||||
|
||||
while (amount > 0)
|
||||
{
|
||||
index += sign;
|
||||
|
||||
if (index < 0)
|
||||
{
|
||||
index = colors->listLen - 1;
|
||||
}
|
||||
else if (index >= (INT32)colors->listLen)
|
||||
{
|
||||
index = 0;
|
||||
}
|
||||
|
||||
amount--;
|
||||
}
|
||||
|
||||
return colors->list[index];
|
||||
}
|
||||
|
||||
static void M_NewPlayerColors(setup_player_t *p)
|
||||
{
|
||||
const boolean follower = (p->mdepth >= CSSTEP_FOLLOWER);
|
||||
INT32 i = INT32_MAX;
|
||||
|
||||
M_ClearMenuColors(&p->colors);
|
||||
|
||||
// Add all unlocked colors
|
||||
for (i = SKINCOLOR_NONE+1; i < numskincolors; i++)
|
||||
{
|
||||
if (K_ColorUsable(i, follower) == true)
|
||||
{
|
||||
M_PushMenuColor(&p->colors, i);
|
||||
}
|
||||
}
|
||||
|
||||
// Add special colors
|
||||
M_PushMenuColor(&p->colors, SKINCOLOR_NONE);
|
||||
|
||||
if (follower == true)
|
||||
{
|
||||
// Add special follower colors
|
||||
M_PushMenuColor(&p->colors, FOLLOWERCOLOR_MATCH);
|
||||
M_PushMenuColor(&p->colors, FOLLOWERCOLOR_OPPOSITE);
|
||||
}
|
||||
}
|
||||
|
||||
// sets up the grid pos for the skin used by the profile.
|
||||
|
|
@ -409,7 +264,7 @@ void M_CharacterSelectInit(void)
|
|||
// Default to no follower / match colour.
|
||||
setup_player[i].followern = -1;
|
||||
setup_player[i].followercategory = -1;
|
||||
setup_player[i].followercolor = FOLLOWERCOLOR_MATCH;
|
||||
setup_player[i].followercolor = SKINCOLOR_NONE;
|
||||
|
||||
// Set default selected profile to the last used profile for each player:
|
||||
// (Make sure we don't overshoot it somehow if we deleted profiles or whatnot)
|
||||
|
|
@ -878,6 +733,7 @@ static boolean M_HandleCharacterGrid(setup_player_t *p, UINT8 num)
|
|||
else
|
||||
{
|
||||
p->mdepth = CSSTEP_COLORS;
|
||||
M_NewPlayerColors(p);
|
||||
S_StartSound(NULL, sfx_s3k63);
|
||||
}
|
||||
}
|
||||
|
|
@ -891,9 +747,14 @@ static boolean M_HandleCharacterGrid(setup_player_t *p, UINT8 num)
|
|||
else
|
||||
{
|
||||
if (setup_page+1 == setup_chargrid[p->gridx][p->gridy].numskins)
|
||||
{
|
||||
p->mdepth = CSSTEP_COLORS; // Skip clones menu if there are none on this page.
|
||||
M_NewPlayerColors(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
p->mdepth = CSSTEP_ALTS;
|
||||
}
|
||||
|
||||
S_StartSound(NULL, sfx_s3k63);
|
||||
}
|
||||
|
|
@ -966,6 +827,7 @@ static void M_HandleCharRotate(setup_player_t *p, UINT8 num)
|
|||
if (M_MenuConfirmPressed(num) /*|| M_MenuButtonPressed(num, MBT_START)*/)
|
||||
{
|
||||
p->mdepth = CSSTEP_COLORS;
|
||||
M_NewPlayerColors(p);
|
||||
S_StartSound(NULL, sfx_s3k63);
|
||||
M_SetMenuDelay(num);
|
||||
}
|
||||
|
|
@ -994,14 +856,14 @@ static void M_HandleColorRotate(setup_player_t *p, UINT8 num)
|
|||
|
||||
if (menucmd[num].dpad_lr > 0)
|
||||
{
|
||||
p->color = M_GetColorAfter(p->color, 1, false);
|
||||
p->color = M_GetColorAfter(&p->colors, p->color, 1);
|
||||
p->rotate = CSROTATETICS;
|
||||
M_SetMenuDelay(num); //CSROTATETICS
|
||||
S_StartSound(NULL, sfx_s3k5b); //sfx_s3kc3s
|
||||
}
|
||||
else if (menucmd[num].dpad_lr < 0)
|
||||
{
|
||||
p->color = M_GetColorBefore(p->color, 1, false);
|
||||
p->color = M_GetColorBefore(&p->colors, p->color, 1);
|
||||
p->rotate = -CSROTATETICS;
|
||||
M_SetMenuDelay(num); //CSROTATETICS
|
||||
S_StartSound(NULL, sfx_s3k5b); //sfx_s3kc3s
|
||||
|
|
@ -1031,7 +893,7 @@ static void M_HandleColorRotate(setup_player_t *p, UINT8 num)
|
|||
{
|
||||
if (p->skin >= 0)
|
||||
{
|
||||
p->color = skins[p->skin].prefcolor;
|
||||
p->color = SKINCOLOR_NONE;
|
||||
p->rotate = CSROTATETICS;
|
||||
p->hitlag = true;
|
||||
S_StartSound(NULL, sfx_s3k7b); //sfx_s3kc3s
|
||||
|
|
@ -1133,6 +995,7 @@ static void M_HandleFollowerCategoryRotate(setup_player_t *p, UINT8 num)
|
|||
else if (M_MenuBackPressed(num))
|
||||
{
|
||||
p->mdepth = CSSTEP_COLORS;
|
||||
M_NewPlayerColors(p);
|
||||
S_StartSound(NULL, sfx_s3k5b);
|
||||
M_SetMenuDelay(num);
|
||||
}
|
||||
|
|
@ -1236,14 +1099,14 @@ static void M_HandleFollowerColorRotate(setup_player_t *p, UINT8 num)
|
|||
|
||||
if (menucmd[num].dpad_lr > 0)
|
||||
{
|
||||
p->followercolor = M_GetColorAfter(p->followercolor, 1, true);
|
||||
p->followercolor = M_GetColorAfter(&p->colors, p->followercolor, 1);
|
||||
p->rotate = CSROTATETICS;
|
||||
M_SetMenuDelay(num); //CSROTATETICS
|
||||
S_StartSound(NULL, sfx_s3k5b); //sfx_s3kc3s
|
||||
}
|
||||
else if (menucmd[num].dpad_lr < 0)
|
||||
{
|
||||
p->followercolor = M_GetColorBefore(p->followercolor, 1, true);
|
||||
p->followercolor = M_GetColorBefore(&p->colors, p->followercolor, 1);
|
||||
p->rotate = -CSROTATETICS;
|
||||
M_SetMenuDelay(num); //CSROTATETICS
|
||||
S_StartSound(NULL, sfx_s3k5b); //sfx_s3kc3s
|
||||
|
|
@ -1268,10 +1131,10 @@ static void M_HandleFollowerColorRotate(setup_player_t *p, UINT8 num)
|
|||
{
|
||||
if (p->followercolor == FOLLOWERCOLOR_MATCH)
|
||||
p->followercolor = FOLLOWERCOLOR_OPPOSITE;
|
||||
else if (p->followercolor == followers[p->followern].defaultcolor)
|
||||
else if (p->followercolor == SKINCOLOR_NONE)
|
||||
p->followercolor = FOLLOWERCOLOR_MATCH;
|
||||
else
|
||||
p->followercolor = followers[p->followern].defaultcolor;
|
||||
p->followercolor = SKINCOLOR_NONE;
|
||||
p->rotate = CSROTATETICS;
|
||||
p->hitlag = true;
|
||||
S_StartSound(NULL, sfx_s3k7b); //sfx_s3kc3s
|
||||
|
|
@ -1345,6 +1208,7 @@ boolean M_CharacterSelectHandler(INT32 choice)
|
|||
if (M_MenuBackPressed(i))
|
||||
{
|
||||
p->mdepth = CSSTEP_COLORS;
|
||||
M_NewPlayerColors(p);
|
||||
S_StartSound(NULL, sfx_s3k5b);
|
||||
M_SetMenuDelay(i);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1675,7 +1675,6 @@ void I_Quit(void)
|
|||
|
||||
D_QuitNetGame();
|
||||
CL_AbortDownloadResume();
|
||||
M_FreePlayerSetupColors();
|
||||
I_ShutdownMusic();
|
||||
I_ShutdownSound();
|
||||
// use this for 1.28 19990220 by Kin
|
||||
|
|
@ -1801,7 +1800,6 @@ void I_Error(const char *error, ...)
|
|||
|
||||
D_QuitNetGame();
|
||||
CL_AbortDownloadResume();
|
||||
M_FreePlayerSetupColors();
|
||||
|
||||
I_ShutdownMusic();
|
||||
I_ShutdownGraphics();
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@ TYPEDEF (menucolor_t);
|
|||
TYPEDEF (menuitem_t);
|
||||
TYPEDEF (menu_t);
|
||||
TYPEDEF (menucmd_t);
|
||||
TYPEDEF (setup_player_colors_t);
|
||||
TYPEDEF (setup_player_t);
|
||||
TYPEDEF (modedesc_t);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue