- Added support for the original games' player translations, including Hexen's table-based ones.

SVN r2193 (trunk)
This commit is contained in:
Randy Heit 2010-03-06 02:51:23 +00:00
parent dfd963ba1a
commit e78fd195d8
15 changed files with 406 additions and 40 deletions

View file

@ -1850,7 +1850,7 @@ void AM_drawPlayers ()
{ {
float h, s, v, r, g, b; float h, s, v, r, g, b;
D_GetPlayerColor (i, &h, &s, &v); D_GetPlayerColor (i, &h, &s, &v, NULL);
HSVtoRGB (&r, &g, &b, h, s, v); HSVtoRGB (&r, &g, &b, h, s, v);
color.FromRGB(clamp (int(r*255.f),0,255), clamp (int(g*255.f),0,255), clamp (int(b*255.f),0,255)); color.FromRGB(clamp (int(r*255.f),0,255), clamp (int(g*255.f),0,255), clamp (int(b*255.f),0,255));

View file

@ -54,7 +54,8 @@ void D_DoServerInfoChange (BYTE **stream, bool singlebit);
void D_WriteUserInfoStrings (int player, BYTE **stream, bool compact=false); void D_WriteUserInfoStrings (int player, BYTE **stream, bool compact=false);
void D_ReadUserInfoStrings (int player, BYTE **stream, bool update); void D_ReadUserInfoStrings (int player, BYTE **stream, bool update);
void D_GetPlayerColor (int player, float *h, float *s, float *v); struct FPlayerColorSet;
void D_GetPlayerColor (int player, float *h, float *s, float *v, FPlayerColorSet **colorset);
void D_PickRandomTeam (int player); void D_PickRandomTeam (int player);
int D_PickRandomTeam (); int D_PickRandomTeam ();
class player_t; class player_t;

View file

@ -65,6 +65,7 @@ EXTERN_CVAR (Bool, teamplay)
CVAR (Float, autoaim, 5000.f, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (Float, autoaim, 5000.f, CVAR_USERINFO | CVAR_ARCHIVE);
CVAR (String, name, "Player", CVAR_USERINFO | CVAR_ARCHIVE); CVAR (String, name, "Player", CVAR_USERINFO | CVAR_ARCHIVE);
CVAR (Color, color, 0x40cf00, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (Color, color, 0x40cf00, CVAR_USERINFO | CVAR_ARCHIVE);
CVAR (Int, colorset, 0, CVAR_USERINFO | CVAR_ARCHIVE);
CVAR (String, skin, "base", CVAR_USERINFO | CVAR_ARCHIVE); CVAR (String, skin, "base", CVAR_USERINFO | CVAR_ARCHIVE);
CVAR (Int, team, TEAM_NONE, CVAR_USERINFO | CVAR_ARCHIVE); CVAR (Int, team, TEAM_NONE, CVAR_USERINFO | CVAR_ARCHIVE);
CVAR (String, gender, "male", CVAR_USERINFO | CVAR_ARCHIVE); CVAR (String, gender, "male", CVAR_USERINFO | CVAR_ARCHIVE);
@ -85,6 +86,7 @@ enum
INFO_MoveBob, INFO_MoveBob,
INFO_StillBob, INFO_StillBob,
INFO_PlayerClass, INFO_PlayerClass,
INFO_ColorSet,
}; };
const char *GenderNames[3] = { "male", "female", "other" }; const char *GenderNames[3] = { "male", "female", "other" };
@ -101,6 +103,7 @@ static const char *UserInfoStrings[] =
"movebob", "movebob",
"stillbob", "stillbob",
"playerclass", "playerclass",
"colorset",
NULL NULL
}; };
@ -184,10 +187,24 @@ int D_PlayerClassToInt (const char *classname)
} }
} }
void D_GetPlayerColor (int player, float *h, float *s, float *v) void D_GetPlayerColor (int player, float *h, float *s, float *v, FPlayerColorSet **set)
{ {
userinfo_t *info = &players[player].userinfo; userinfo_t *info = &players[player].userinfo;
int color = info->color; FPlayerColorSet *colorset = NULL;
int color;
if (players[player].mo != NULL)
{
colorset = P_GetPlayerColorSet(players[player].mo->GetClass()->TypeName, info->colorset);
}
if (colorset != NULL)
{
color = GPalette.BaseColors[GPalette.Remap[colorset->RepresentativeColor]];
}
else
{
color = info->color;
}
RGBtoHSV (RPART(color)/255.f, GPART(color)/255.f, BPART(color)/255.f, RGBtoHSV (RPART(color)/255.f, GPART(color)/255.f, BPART(color)/255.f,
h, s, v); h, s, v);
@ -206,6 +223,10 @@ void D_GetPlayerColor (int player, float *h, float *s, float *v)
*s = clamp(ts + *s * 0.15f - 0.075f, 0.f, 1.f); *s = clamp(ts + *s * 0.15f - 0.075f, 0.f, 1.f);
*v = clamp(tv + *v * 0.5f - 0.25f, 0.f, 1.f); *v = clamp(tv + *v * 0.5f - 0.25f, 0.f, 1.f);
} }
if (set != NULL)
{
*set = colorset;
}
} }
// Find out which teams are present. If there is only one, // Find out which teams are present. If there is only one,
@ -379,6 +400,7 @@ void D_SetupUserInfo ()
coninfo->aimdist = abs ((int)(autoaim * (float)ANGLE_1)); coninfo->aimdist = abs ((int)(autoaim * (float)ANGLE_1));
} }
coninfo->color = color; coninfo->color = color;
coninfo->colorset = colorset;
coninfo->skin = R_FindSkin (skin, 0); coninfo->skin = R_FindSkin (skin, 0);
coninfo->gender = D_GenderToInt (gender); coninfo->gender = D_GenderToInt (gender);
coninfo->neverswitch = neverswitchonpickup; coninfo->neverswitch = neverswitchonpickup;
@ -564,6 +586,7 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact)
"\\name\\%s" "\\name\\%s"
"\\autoaim\\%g" "\\autoaim\\%g"
"\\color\\%x %x %x" "\\color\\%x %x %x"
"\\colorset\\%d"
"\\skin\\%s" "\\skin\\%s"
"\\team\\%d" "\\team\\%d"
"\\gender\\%s" "\\gender\\%s"
@ -574,6 +597,7 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact)
, ,
D_EscapeUserInfo(info->netname).GetChars(), D_EscapeUserInfo(info->netname).GetChars(),
(double)info->aimdist / (float)ANGLE_1, (double)info->aimdist / (float)ANGLE_1,
info->colorset,
RPART(info->color), GPART(info->color), BPART(info->color), RPART(info->color), GPART(info->color), BPART(info->color),
D_EscapeUserInfo(skins[info->skin].name).GetChars(), D_EscapeUserInfo(skins[info->skin].name).GetChars(),
info->team, info->team,
@ -600,6 +624,7 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact)
"\\%g" // movebob "\\%g" // movebob
"\\%g" // stillbob "\\%g" // stillbob
"\\%s" // playerclass "\\%s" // playerclass
"\\%d" // colorset
, ,
D_EscapeUserInfo(info->netname).GetChars(), D_EscapeUserInfo(info->netname).GetChars(),
(double)info->aimdist / (float)ANGLE_1, (double)info->aimdist / (float)ANGLE_1,
@ -612,7 +637,8 @@ void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact)
(float)(info->MoveBob) / 65536.f, (float)(info->MoveBob) / 65536.f,
(float)(info->StillBob) / 65536.f, (float)(info->StillBob) / 65536.f,
info->PlayerClass == -1 ? "Random" : info->PlayerClass == -1 ? "Random" :
D_EscapeUserInfo(type->Meta.GetMetaString (APMETA_DisplayName)).GetChars() D_EscapeUserInfo(type->Meta.GetMetaString (APMETA_DisplayName)).GetChars(),
info->colorset
); );
} }
} }
@ -716,7 +742,15 @@ void D_ReadUserInfoStrings (int i, BYTE **stream, bool update)
break; break;
case INFO_Color: case INFO_Color:
case INFO_ColorSet:
if (infotype == INFO_Color)
{
info->color = V_GetColorFromString (NULL, value); info->color = V_GetColorFromString (NULL, value);
}
else
{
info->colorset = atoi(value);
}
R_BuildPlayerTranslation (i); R_BuildPlayerTranslation (i);
if (StatusBar != NULL && i == StatusBar->GetPlayer()) if (StatusBar != NULL && i == StatusBar->GetPlayer())
{ {
@ -806,6 +840,10 @@ FArchive &operator<< (FArchive &arc, userinfo_t &info)
arc.Read (&info.netname, sizeof(info.netname)); arc.Read (&info.netname, sizeof(info.netname));
} }
arc << info.team << info.aimdist << info.color << info.skin << info.gender << info.neverswitch; arc << info.team << info.aimdist << info.color << info.skin << info.gender << info.neverswitch;
if (SaveVersion >= 2193)
{
arc << info.colorset;
}
return arc; return arc;
} }
@ -831,6 +869,7 @@ CCMD (playerinfo)
Printf ("Team: %s (%d)\n", ui->team == TEAM_NONE ? "None" : Teams[ui->team].GetName (), ui->team); Printf ("Team: %s (%d)\n", ui->team == TEAM_NONE ? "None" : Teams[ui->team].GetName (), ui->team);
Printf ("Aimdist: %d\n", ui->aimdist); Printf ("Aimdist: %d\n", ui->aimdist);
Printf ("Color: %06x\n", ui->color); Printf ("Color: %06x\n", ui->color);
Printf ("ColorSet: %d\n", ui->colorset);
Printf ("Skin: %s (%d)\n", skins[ui->skin].name, ui->skin); Printf ("Skin: %s (%d)\n", skins[ui->skin].name, ui->skin);
Printf ("Gender: %s (%d)\n", GenderNames[ui->gender], ui->gender); Printf ("Gender: %s (%d)\n", GenderNames[ui->gender], ui->gender);
Printf ("NeverSwitch: %d\n", ui->neverswitch); Printf ("NeverSwitch: %d\n", ui->neverswitch);

View file

@ -71,6 +71,21 @@ enum
APMETA_Slot9, APMETA_Slot9,
}; };
// Standard pre-defined skin colors
struct FPlayerColorSet
{
FName Name; // Name of this color
int Lump; // Lump to read the translation from, otherwise use next 2 fields
BYTE FirstColor, LastColor; // Describes the range of colors to use for the translation
BYTE RepresentativeColor; // A palette entry representative of this translation,
// for map arrows and status bar backgrounds and such
};
void P_AddPlayerColorSet(FName classname, int setnum, const FPlayerColorSet *colorset);
FPlayerColorSet *P_GetPlayerColorSet(FName classname, int setnum);
void P_EnumPlayerColorSets(FName classname, TArray<int> *out);
class player_t; class player_t;
class APlayerPawn : public AActor class APlayerPawn : public AActor
@ -223,6 +238,7 @@ struct userinfo_t
BYTE team; BYTE team;
int aimdist; int aimdist;
int color; int color;
int colorset;
int skin; int skin;
int gender; int gender;
bool neverswitch; bool neverswitch;

View file

@ -418,7 +418,7 @@ void HU_DrawColorBar(int x, int y, int height, int playernum)
{ {
float h, s, v, r, g, b; float h, s, v, r, g, b;
D_GetPlayerColor (playernum, &h, &s, &v); D_GetPlayerColor (playernum, &h, &s, &v, NULL);
HSVtoRGB (&r, &g, &b, h, s, v); HSVtoRGB (&r, &g, &b, h, s, v);
screen->Clear (x, y, x + 24*CleanXfac, y + height, -1, screen->Clear (x, y, x + 24*CleanXfac, y + height, -1,

View file

@ -118,7 +118,7 @@ protected:
// EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
void R_GetPlayerTranslation (int color, FPlayerSkin *skin, FRemapTable *table); void R_GetPlayerTranslation (int color, const FPlayerColorSet *colorset, FPlayerSkin *skin, FRemapTable *table);
// PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- // PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
@ -188,6 +188,7 @@ static void M_EditPlayerName (int choice);
static void M_ChangePlayerTeam (int choice); static void M_ChangePlayerTeam (int choice);
static void M_PlayerNameChanged (FSaveGameNode *dummy); static void M_PlayerNameChanged (FSaveGameNode *dummy);
static void M_PlayerNameNotChanged (); static void M_PlayerNameNotChanged ();
static void M_ChangeColorSet (int choice);
static void M_SlidePlayerRed (int choice); static void M_SlidePlayerRed (int choice);
static void M_SlidePlayerGreen (int choice); static void M_SlidePlayerGreen (int choice);
static void M_SlidePlayerBlue (int choice); static void M_SlidePlayerBlue (int choice);
@ -269,6 +270,7 @@ static int PlayerSkin;
static FState *PlayerState; static FState *PlayerState;
static int PlayerTics; static int PlayerTics;
static int PlayerRotation; static int PlayerRotation;
static TArray<int> PlayerColorSets;
static FTexture *SavePic; static FTexture *SavePic;
static FBrokenLines *SaveComment; static FBrokenLines *SaveComment;
@ -536,10 +538,11 @@ static oldmenuitem_t PlayerSetupMenu[] =
{ {
{ 1,0,'n',NULL,M_EditPlayerName, CR_UNTRANSLATED}, { 1,0,'n',NULL,M_EditPlayerName, CR_UNTRANSLATED},
{ 2,0,'t',NULL,M_ChangePlayerTeam, CR_UNTRANSLATED}, { 2,0,'t',NULL,M_ChangePlayerTeam, CR_UNTRANSLATED},
{ 2,0,'c',NULL,M_ChangeColorSet, CR_UNTRANSLATED},
{ 2,0,'r',NULL,M_SlidePlayerRed, CR_UNTRANSLATED}, { 2,0,'r',NULL,M_SlidePlayerRed, CR_UNTRANSLATED},
{ 2,0,'g',NULL,M_SlidePlayerGreen, CR_UNTRANSLATED}, { 2,0,'g',NULL,M_SlidePlayerGreen, CR_UNTRANSLATED},
{ 2,0,'b',NULL,M_SlidePlayerBlue, CR_UNTRANSLATED}, { 2,0,'b',NULL,M_SlidePlayerBlue, CR_UNTRANSLATED},
{ 2,0,'c',NULL,M_ChangeClass, CR_UNTRANSLATED}, { 2,0,'t',NULL,M_ChangeClass, CR_UNTRANSLATED},
{ 2,0,'s',NULL,M_ChangeSkin, CR_UNTRANSLATED}, { 2,0,'s',NULL,M_ChangeSkin, CR_UNTRANSLATED},
{ 2,0,'e',NULL,M_ChangeGender, CR_UNTRANSLATED}, { 2,0,'e',NULL,M_ChangeGender, CR_UNTRANSLATED},
{ 2,0,'a',NULL,M_ChangeAutoAim, CR_UNTRANSLATED} { 2,0,'a',NULL,M_ChangeAutoAim, CR_UNTRANSLATED}
@ -2088,13 +2091,16 @@ void M_PlayerSetup (void)
PlayerClass = &PlayerClasses[players[consoleplayer].CurrentPlayerClass]; PlayerClass = &PlayerClasses[players[consoleplayer].CurrentPlayerClass];
} }
PlayerSkin = players[consoleplayer].userinfo.skin; PlayerSkin = players[consoleplayer].userinfo.skin;
R_GetPlayerTranslation (players[consoleplayer].userinfo.color, &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); R_GetPlayerTranslation (players[consoleplayer].userinfo.color,
P_GetPlayerColorSet(PlayerClass->Type->TypeName, players[consoleplayer].userinfo.colorset),
&skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]);
PlayerState = GetDefaultByType (PlayerClass->Type)->SeeState; PlayerState = GetDefaultByType (PlayerClass->Type)->SeeState;
PlayerTics = PlayerState->GetTics(); PlayerTics = PlayerState->GetTics();
if (FireTexture == NULL) if (FireTexture == NULL)
{ {
FireTexture = new FBackdropTexture; FireTexture = new FBackdropTexture;
} }
P_EnumPlayerColorSets(PlayerClass->Type->TypeName, &PlayerColorSets);
} }
static void M_PlayerSetupTicker (void) static void M_PlayerSetupTicker (void)
@ -2112,6 +2118,7 @@ static void M_PlayerSetupTicker (void)
item = (MenuTime>>2) % (ClassMenuDef.numitems-1); item = (MenuTime>>2) % (ClassMenuDef.numitems-1);
PlayerClass = &PlayerClasses[D_PlayerClassToInt (ClassMenuItems[item].name)]; PlayerClass = &PlayerClasses[D_PlayerClassToInt (ClassMenuItems[item].name)];
P_EnumPlayerColorSets(PlayerClass->Type->TypeName, &PlayerColorSets);
} }
else else
{ {
@ -2125,6 +2132,7 @@ static void M_PlayerSetupTicker (void)
PlayerSkin = R_FindSkin (skins[PlayerSkin].name, int(PlayerClass - &PlayerClasses[0])); PlayerSkin = R_FindSkin (skins[PlayerSkin].name, int(PlayerClass - &PlayerClasses[0]));
R_GetPlayerTranslation (players[consoleplayer].userinfo.color, R_GetPlayerTranslation (players[consoleplayer].userinfo.color,
P_GetPlayerColorSet(PlayerClass->Type->TypeName, players[consoleplayer].userinfo.colorset),
&skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]);
} }
@ -2280,19 +2288,27 @@ static void M_PlayerSetupDrawer ()
DTA_Clean, true, TAG_DONE); DTA_Clean, true, TAG_DONE);
} }
// Draw player color sliders // Draw player color selection and sliders
//V_DrawTextCleanMove (CR_GREY, PSetupDef.x, PSetupDef.y + LINEHEIGHT, "Color"); FPlayerColorSet *colorset = P_GetPlayerColorSet(PlayerClass->Type->TypeName, players[consoleplayer].userinfo.colorset);
x = SmallFont->StringWidth("Color") + 8 + PSetupDef.x;
screen->DrawText(SmallFont, label, PSetupDef.x, PSetupDef.y + LINEHEIGHT*2+yo, "Color", DTA_Clean, true, TAG_DONE);
screen->DrawText(SmallFont, value, x, PSetupDef.y + LINEHEIGHT*2+yo,
colorset != NULL ? colorset->Name.GetChars() : "Custom", DTA_Clean, true, TAG_DONE);
screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + LINEHEIGHT*2+yo, "Red", DTA_Clean, true, TAG_DONE); // Only show the sliders for a custom color set.
screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + LINEHEIGHT*3+yo, "Green", DTA_Clean, true, TAG_DONE); if (colorset == NULL)
screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + LINEHEIGHT*4+yo, "Blue", DTA_Clean, true, TAG_DONE); {
screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + int(LINEHEIGHT*2.875)+yo, "Red", DTA_Clean, true, TAG_DONE);
screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + int(LINEHEIGHT*3.5)+yo, "Green", DTA_Clean, true, TAG_DONE);
screen->DrawText (SmallFont, label, PSetupDef.x, PSetupDef.y + int(LINEHEIGHT*4.125)+yo, "Blue", DTA_Clean, true, TAG_DONE);
x = SmallFont->StringWidth ("Green") + 8 + PSetupDef.x; x = SmallFont->StringWidth ("Green") + 8 + PSetupDef.x;
color = players[consoleplayer].userinfo.color; color = players[consoleplayer].userinfo.color;
M_DrawPlayerSlider (x, PSetupDef.y + LINEHEIGHT*2+yo, RPART(color)); M_DrawPlayerSlider (x, PSetupDef.y + int(LINEHEIGHT*2.875)+yo, RPART(color));
M_DrawPlayerSlider (x, PSetupDef.y + LINEHEIGHT*3+yo, GPART(color)); M_DrawPlayerSlider (x, PSetupDef.y + int(LINEHEIGHT*3.5)+yo, GPART(color));
M_DrawPlayerSlider (x, PSetupDef.y + LINEHEIGHT*4+yo, BPART(color)); M_DrawPlayerSlider (x, PSetupDef.y + int(LINEHEIGHT*4.125)+yo, BPART(color));
}
// [GRB] Draw class setting // [GRB] Draw class setting
int pclass = players[consoleplayer].userinfo.PlayerClass; int pclass = players[consoleplayer].userinfo.PlayerClass;
@ -2587,7 +2603,9 @@ static void M_ChangeSkin (int choice)
PlayerSkin = (PlayerSkin < (int)numskins - 1) ? PlayerSkin + 1 : 0; PlayerSkin = (PlayerSkin < (int)numskins - 1) ? PlayerSkin + 1 : 0;
} while (!PlayerClass->CheckSkin (PlayerSkin)); } while (!PlayerClass->CheckSkin (PlayerSkin));
R_GetPlayerTranslation (players[consoleplayer].userinfo.color, &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); R_GetPlayerTranslation (players[consoleplayer].userinfo.color,
P_GetPlayerColorSet(PlayerClass->Type->TypeName, players[consoleplayer].userinfo.colorset),
&skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]);
cvar_set ("skin", skins[PlayerSkin].name); cvar_set ("skin", skins[PlayerSkin].name);
} }
@ -2708,13 +2726,50 @@ static void M_ChangePlayerTeam (int choice)
} }
} }
static void M_ChangeColorSet (int choice)
{
int curpos = (int)PlayerColorSets.Size();
int mycolorset = players[consoleplayer].userinfo.colorset;
while (--curpos >= 0)
{
if (PlayerColorSets[curpos] == mycolorset)
break;
}
if (choice == 0)
{
curpos--;
}
else
{
curpos++;
}
if (curpos < -1)
{
curpos = (int)PlayerColorSets.Size() - 1;
}
else if (curpos >= (int)PlayerColorSets.Size())
{
curpos = -1;
}
mycolorset = (curpos >= 0) ? PlayerColorSets[curpos] : -1;
char command[24];
mysnprintf(command, countof(command), "colorset %d", mycolorset);
C_DoCommand(command);
R_GetPlayerTranslation(players[consoleplayer].userinfo.color,
P_GetPlayerColorSet(PlayerClass->Type->TypeName, mycolorset),
&skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]);
}
static void SendNewColor (int red, int green, int blue) static void SendNewColor (int red, int green, int blue)
{ {
char command[24]; char command[24];
mysnprintf (command, countof(command), "color \"%02x %02x %02x\"", red, green, blue); mysnprintf (command, countof(command), "color \"%02x %02x %02x\"", red, green, blue);
C_DoCommand (command); C_DoCommand (command);
R_GetPlayerTranslation (MAKERGB (red, green, blue), &skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]); R_GetPlayerTranslation(MAKERGB (red, green, blue),
P_GetPlayerColorSet(PlayerClass->Type->TypeName, players[consoleplayer].userinfo.colorset),
&skins[PlayerSkin], translationtables[TRANSLATION_Players][MAXPLAYERS]);
} }
static void M_SlidePlayerRed (int choice) static void M_SlidePlayerRed (int choice)
@ -3646,8 +3701,31 @@ void M_Drawer ()
// [RH] Use options menu cursor for the player setup menu. // [RH] Use options menu cursor for the player setup menu.
if (skullAnimCounter < 6) if (skullAnimCounter < 6)
{ {
double item;
// The green slider is halfway between lines, and the red and
// blue ones are offset slightly to make room for it.
if (itemOn < 3)
{
item = itemOn;
}
else if (itemOn > 5)
{
item = itemOn - 1;
}
else if (itemOn == 3)
{
item = 2.875;
}
else if (itemOn == 4)
{
item = 3.5;
}
else
{
item = 4.125;
}
screen->DrawText (ConFont, CR_RED, x - 16, screen->DrawText (ConFont, CR_RED, x - 16,
currentMenu->y + itemOn*PLAYERSETUP_LINEHEIGHT + currentMenu->y + int(item*PLAYERSETUP_LINEHEIGHT) +
(!(gameinfo.gametype & (GAME_DoomStrifeChex)) ? 6 : -1), "\xd", (!(gameinfo.gametype & (GAME_DoomStrifeChex)) ? 6 : -1), "\xd",
DTA_Clean, true, TAG_DONE); DTA_Clean, true, TAG_DONE);
} }
@ -4037,4 +4115,5 @@ static void PickPlayerClass ()
} }
PlayerClass = &PlayerClasses[pclass]; PlayerClass = &PlayerClasses[pclass];
P_EnumPlayerColorSets(PlayerClass->Type->TypeName, &PlayerColorSets);
} }

View file

@ -55,6 +55,9 @@
static FRandom pr_skullpop ("SkullPop"); static FRandom pr_skullpop ("SkullPop");
// Color set class name -> mapping table
typedef TMap<int, FPlayerColorSet> FPlayerColorSetMap;
TMap<FName, FPlayerColorSetMap *> PlayerToColorsMap;
// [RH] # of ticks to complete a turn180 // [RH] # of ticks to complete a turn180
#define TURN180_TICKS ((TICRATE / 4) + 1) #define TURN180_TICKS ((TICRATE / 4) + 1)
@ -2631,3 +2634,66 @@ void player_t::Serialize (FArchive &arc)
} }
} }
static FPlayerColorSetMap *GetPlayerColors(FName classname, bool create)
{
FPlayerColorSetMap *map, **value;
value = PlayerToColorsMap.CheckKey(classname);
if (value == NULL)
{
if (create)
{
map = new FPlayerColorSetMap;
PlayerToColorsMap.Insert(classname, map);
}
else
{
map = NULL;
}
}
else
{
map = *value;
}
return map;
}
void P_AddPlayerColorSet(FName classname, int setnum, const FPlayerColorSet *colorset)
{
FPlayerColorSetMap *map = GetPlayerColors(classname, true);
(*map)[setnum] = *colorset;
}
FPlayerColorSet *P_GetPlayerColorSet(FName classname, int setnum)
{
FPlayerColorSetMap *map = GetPlayerColors(classname, false);
if (map == NULL)
{
return NULL;
}
return map->CheckKey(setnum);
}
static int STACK_ARGS intcmp(const void *a, const void *b)
{
return *(const int *)a - *(const int *)b;
}
void P_EnumPlayerColorSets(FName classname, TArray<int> *out)
{
out->Clear();
FPlayerColorSetMap *map = GetPlayerColors(classname, false);
if (map != NULL)
{
FPlayerColorSetMap::Iterator it(*map);
FPlayerColorSetMap::Pair *pair;
while (it.NextPair(pair))
{
out->Push(pair->Key);
}
qsort(&(*out)[0], out->Size(), sizeof(int), intcmp);
}
}

View file

@ -46,6 +46,7 @@
#include "sc_man.h" #include "sc_man.h"
#include "doomerrors.h" #include "doomerrors.h"
#include "i_system.h" #include "i_system.h"
#include "w_wad.h"
#include "gi.h" #include "gi.h"
#include "stats.h" #include "stats.h"
@ -892,7 +893,8 @@ static void SetRemap(FRemapTable *table, int i, float r, float g, float b)
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *skin, FRemapTable *table, FRemapTable *alttable) static void R_CreatePlayerTranslation (float h, float s, float v, const FPlayerColorSet *colorset,
FPlayerSkin *skin, FRemapTable *table, FRemapTable *alttable)
{ {
int i; int i;
BYTE start = skin->range0start; BYTE start = skin->range0start;
@ -936,7 +938,46 @@ static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *s
bases = s; bases = s;
basev = v; basev = v;
if (gameinfo.gametype & GAME_DoomStrifeChex) if (colorset != NULL && colorset->Lump >= 0 && Wads.LumpLength(colorset->Lump) < 256)
{ // Bad table length. Ignore it.
colorset = NULL;
}
if (colorset != NULL)
{
// Use the pre-defined range instead of a custom one.
if (colorset->Lump < 0)
{
int first = colorset->FirstColor;
if (start == end)
{
table->Remap[i] = (first + colorset->LastColor) / 2;
}
else
{
int palrange = colorset->LastColor - first;
for (i = start; i <= end; ++i)
{
table->Remap[i] = GPalette.Remap[first + palrange * (i - start) / (end - start)];
}
}
}
else
{
FMemLump translump = Wads.ReadLump(colorset->Lump);
const BYTE *trans = (const BYTE *)translump.GetMem();
for (i = start; i <= end; ++i)
{
table->Remap[i] = GPalette.Remap[trans[i]];
}
}
for (i = start; i <= end; ++i)
{
table->Palette[i] = GPalette.BaseColors[table->Remap[i]];
table->Palette[i].a = 255;
}
}
else if (gameinfo.gametype & GAME_DoomStrifeChex)
{ {
// Build player sprite translation // Build player sprite translation
s -= 0.23f; s -= 0.23f;
@ -1014,9 +1055,19 @@ static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *s
SetRemap(table, i, r, g, b); SetRemap(table, i, r, g, b);
} }
} }
}
if (gameinfo.gametype == GAME_Hexen && alttable != NULL)
{
// Build Hexen's lifegem translation.
// Build lifegem translation // Is the player's translation range the same as the gem's and we are using a
if (alttable) // predefined translation? If so, then use the same one for the gem. Otherwise,
// build one as per usual.
if (colorset != NULL && start == 164 && end == 185)
{
*alttable = *table;
}
else
{ {
for (i = 164; i <= 185; ++i) for (i = 164; i <= 185; ++i)
{ {
@ -1027,8 +1078,8 @@ static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *s
HSVtoRGB (&r, &g, &b, h, s*bases, v*basev); HSVtoRGB (&r, &g, &b, h, s*bases, v*basev);
SetRemap(alttable, i, r, g, b); SetRemap(alttable, i, r, g, b);
} }
alttable->UpdateNative();
} }
alttable->UpdateNative();
} }
table->UpdateNative(); table->UpdateNative();
} }
@ -1042,10 +1093,11 @@ static void R_CreatePlayerTranslation (float h, float s, float v, FPlayerSkin *s
void R_BuildPlayerTranslation (int player) void R_BuildPlayerTranslation (int player)
{ {
float h, s, v; float h, s, v;
FPlayerColorSet *colorset;
D_GetPlayerColor (player, &h, &s, &v); D_GetPlayerColor (player, &h, &s, &v, &colorset);
R_CreatePlayerTranslation (h, s, v, R_CreatePlayerTranslation (h, s, v, colorset,
&skins[players[player].userinfo.skin], &skins[players[player].userinfo.skin],
translationtables[TRANSLATION_Players][player], translationtables[TRANSLATION_Players][player],
translationtables[TRANSLATION_PlayersExtra][player]); translationtables[TRANSLATION_PlayersExtra][player]);
@ -1057,13 +1109,17 @@ void R_BuildPlayerTranslation (int player)
// //
//---------------------------------------------------------------------------- //----------------------------------------------------------------------------
void R_GetPlayerTranslation (int color, FPlayerSkin *skin, FRemapTable *table) void R_GetPlayerTranslation (int color, const FPlayerColorSet *colorset, FPlayerSkin *skin, FRemapTable *table)
{ {
float h, s, v; float h, s, v;
if (colorset != NULL)
{
color = colorset->RepresentativeColor;
}
RGBtoHSV (RPART(color)/255.f, GPART(color)/255.f, BPART(color)/255.f, RGBtoHSV (RPART(color)/255.f, GPART(color)/255.f, BPART(color)/255.f,
&h, &s, &v); &h, &s, &v);
R_CreatePlayerTranslation (h, s, v, skin, table, NULL); R_CreatePlayerTranslation (h, s, v, colorset, skin, table, NULL);
} }

View file

@ -1860,6 +1860,57 @@ DEFINE_CLASS_PROPERTY_PREFIX(player, colorrange, I_I, PlayerPawn)
info->Class->Meta.SetMetaInt (APMETA_ColorRange, (start & 255) | ((end & 255) << 8)); info->Class->Meta.SetMetaInt (APMETA_ColorRange, (start & 255) | ((end & 255) << 8));
} }
//==========================================================================
//
//==========================================================================
DEFINE_CLASS_PROPERTY_PREFIX(player, colorset, ISIII, PlayerPawn)
{
PROP_INT_PARM(setnum, 0);
PROP_STRING_PARM(setname, 1);
PROP_INT_PARM(rangestart, 2);
PROP_INT_PARM(rangeend, 3);
PROP_INT_PARM(representative_color, 4);
FPlayerColorSet color;
color.Name = setname;
color.Lump = -1;
color.FirstColor = rangestart;
color.LastColor = rangeend;
color.RepresentativeColor = representative_color;
if (setnum < 0)
{
bag.ScriptPosition.Message(MSG_WARNING, "Color set number must not be negative.\n");
}
else
{
P_AddPlayerColorSet(info->Class->TypeName, setnum, &color);
}
}
//==========================================================================
//
//==========================================================================
DEFINE_CLASS_PROPERTY_PREFIX(player, colorsetfile, ISSI, PlayerPawn)
{
PROP_INT_PARM(setnum, 0);
PROP_STRING_PARM(setname, 1);
PROP_STRING_PARM(rangefile, 2);
PROP_INT_PARM(representative_color, 3);
FPlayerColorSet color;
color.Name = setname;
color.Lump = Wads.CheckNumForName(rangefile);
color.RepresentativeColor = representative_color;
if (setnum < 0)
{
bag.ScriptPosition.Message(MSG_WARNING, "Color set number must not be negative.\n");
}
else if (color.Lump >= 0)
{
P_AddPlayerColorSet(info->Class->TypeName, setnum, &color);
}
}
//========================================================================== //==========================================================================
// //
//========================================================================== //==========================================================================

View file

@ -11,7 +11,6 @@ ACTOR DoomPlayer : PlayerPawn
Height 56 Height 56
Mass 100 Mass 100
PainChance 255 PainChance 255
Player.ColorRange 112, 127
Player.DisplayName "Marine" Player.DisplayName "Marine"
Player.CrouchSprite "PLYC" Player.CrouchSprite "PLYC"
Player.StartItem "Pistol" Player.StartItem "Pistol"
@ -25,6 +24,17 @@ ACTOR DoomPlayer : PlayerPawn
Player.WeaponSlot 6, PlasmaRifle Player.WeaponSlot 6, PlasmaRifle
Player.WeaponSlot 7, BFG9000 Player.WeaponSlot 7, BFG9000
Player.ColorRange 112, 127
Player.Colorset 0, "Green", 0x70, 0x7F, 0x72
Player.Colorset 1, "Gray", 0x60, 0x6F, 0x62
Player.Colorset 2, "Brown", 0x40, 0x4F, 0x42
Player.Colorset 3, "Red", 0x20, 0x2F, 0x22
// Doom Legacy additions
Player.Colorset 4, "Light Gray", 0x58, 0x67, 0x5A
Player.Colorset 5, "Light Brown", 0x38, 0x47, 0x3A
Player.Colorset 6, "Light Red", 0xB0, 0xBF, 0xB2
Player.Colorset 7, "Light Blue", 0xC0, 0xCF, 0xC2
States States
{ {
Spawn: Spawn:

View file

@ -6,7 +6,6 @@ ACTOR HereticPlayer : PlayerPawn
Mass 100 Mass 100
Painchance 255 Painchance 255
Speed 1 Speed 1
Player.ColorRange 225, 240
Player.DisplayName "Corvus" Player.DisplayName "Corvus"
Player.StartItem "GoldWand" Player.StartItem "GoldWand"
Player.StartItem "Staff" Player.StartItem "Staff"
@ -19,6 +18,19 @@ ACTOR HereticPlayer : PlayerPawn
Player.WeaponSlot 6, PhoenixRod Player.WeaponSlot 6, PhoenixRod
Player.WeaponSlot 7, Mace Player.WeaponSlot 7, Mace
Player.ColorRange 225, 240
Player.Colorset 0, "Green", 225, 240, 238
Player.Colorset 1, "Yellow", 114, 129, 127
Player.Colorset 2, "Red", 145, 160, 158
Player.Colorset 3, "Blue", 190, 205, 203
// Doom Legacy additions
Player.Colorset 4, "Brown", 67, 82, 80
Player.Colorset 5, "Light Gray", 9, 24, 22
Player.Colorset 6, "Light Brown", 74, 89, 87
Player.Colorset 7, "Light Red", 150, 165, 163
Player.Colorset 8, "Light Blue", 192, 207, 205
Player.Colorset 9, "Beige", 95, 110, 108
States States
{ {
Spawn: Spawn:

View file

@ -15,7 +15,6 @@ ACTOR ClericPlayer : PlayerPawn
RadiusDamageFactor 0.25 RadiusDamageFactor 0.25
Player.JumpZ 9 Player.JumpZ 9
Player.Viewheight 48 Player.Viewheight 48
Player.ColorRange 146, 163
Player.SpawnClass "Cleric" Player.SpawnClass "Cleric"
Player.DisplayName "Cleric" Player.DisplayName "Cleric"
Player.SoundClass "cleric" Player.SoundClass "cleric"
@ -29,6 +28,16 @@ ACTOR ClericPlayer : PlayerPawn
Player.WeaponSlot 3, CWeapFlame Player.WeaponSlot 3, CWeapFlame
Player.WeaponSlot 4, CWeapWraithverge Player.WeaponSlot 4, CWeapWraithverge
Player.ColorRange 146, 163
Player.Colorset 0, "Blue", 146, 163, 161
Player.ColorsetFile 1, "Red", "TRANTBL7", 0xB3
Player.ColorsetFile 2, "Gold", "TRANTBL8", 0x8C
Player.ColorsetFile 3, "Dull Green", "TRANTBL9", 0x41
Player.ColorsetFile 4, "Green", "TRANTBLA", 0xC9
Player.ColorsetFile 5, "Gray", "TRANTBLB", 0x30
Player.ColorsetFile 6, "Brown", "TRANTBLC", 0x72
Player.ColorsetFile 7, "Purple", "TRANTBLD", 0xEE
States States
{ {
Spawn: Spawn:

View file

@ -14,7 +14,6 @@ ACTOR FighterPlayer : PlayerPawn
RadiusDamageFactor 0.25 RadiusDamageFactor 0.25
Player.JumpZ 9 Player.JumpZ 9
Player.Viewheight 48 Player.Viewheight 48
Player.ColorRange 246, 254
Player.SpawnClass "Fighter" Player.SpawnClass "Fighter"
Player.DisplayName "Fighter" Player.DisplayName "Fighter"
Player.SoundClass "fighter" Player.SoundClass "fighter"
@ -29,6 +28,16 @@ ACTOR FighterPlayer : PlayerPawn
Player.WeaponSlot 3, FWeapHammer Player.WeaponSlot 3, FWeapHammer
Player.WeaponSlot 4, FWeapQuietus Player.WeaponSlot 4, FWeapQuietus
Player.ColorRange 246, 254
Player.Colorset 0, "Gold", 246, 254, 253
Player.ColorsetFile 1, "Red", "TRANTBL0", 0xAC
Player.ColorsetFile 2, "Blue", "TRANTBL1", 0x9D
Player.ColorsetFile 3, "Dull Green", "TRANTBL2", 0x3E
Player.ColorsetFile 4, "Green", "TRANTBL3", 0xC8
Player.ColorsetFile 5, "Gray", "TRANTBL4", 0x2D
Player.ColorsetFile 6, "Brown", "TRANTBL5", 0x6F
Player.ColorsetFile 7, "Purple", "TRANTBL6", 0xEE
States States
{ {
Spawn: Spawn:

View file

@ -15,7 +15,6 @@ ACTOR MagePlayer : PlayerPawn
RadiusDamageFactor 0.25 RadiusDamageFactor 0.25
Player.JumpZ 9 Player.JumpZ 9
Player.Viewheight 48 Player.Viewheight 48
Player.ColorRange 146, 163
Player.SpawnClass "Mage" Player.SpawnClass "Mage"
Player.DisplayName "Mage" Player.DisplayName "Mage"
Player.SoundClass "mage" Player.SoundClass "mage"
@ -31,6 +30,16 @@ ACTOR MagePlayer : PlayerPawn
Player.WeaponSlot 3, MWeapLightning Player.WeaponSlot 3, MWeapLightning
Player.WeaponSlot 4, MWeapBloodscourge Player.WeaponSlot 4, MWeapBloodscourge
Player.ColorRange 146, 163
Player.Colorset 0, "Blue", 146, 163, 161
Player.ColorsetFile 1, "Red", "TRANTBL7", 0xB3
Player.ColorsetFile 2, "Gold", "TRANTBL8", 0x8C
Player.ColorsetFile 3, "Dull Green", "TRANTBL9", 0x41
Player.ColorsetFile 4, "Green", "TRANTBLA", 0xC9
Player.ColorsetFile 5, "Gray", "TRANTBLB", 0x30
Player.ColorsetFile 6, "Brown", "TRANTBLC", 0x72
Player.ColorsetFile 7, "Purple", "TRANTBLD", 0xEE
States States
{ {
Spawn: Spawn:

View file

@ -9,7 +9,6 @@ ACTOR StrifePlayer : PlayerPawn
PainChance 255 PainChance 255
Speed 1 Speed 1
MaxStepHeight 16 MaxStepHeight 16
Player.ColorRange 128, 143
Player.DisplayName "Rebel" Player.DisplayName "Rebel"
Player.StartItem "PunchDagger" Player.StartItem "PunchDagger"
Player.RunHealth 15 Player.RunHealth 15
@ -22,6 +21,16 @@ ACTOR StrifePlayer : PlayerPawn
Player.WeaponSlot 7, Mauler2, Mauler Player.WeaponSlot 7, Mauler2, Mauler
Player.WeaponSlot 8, Sigil Player.WeaponSlot 8, Sigil
Player.ColorRange 128, 143
Player.Colorset 0, "Brown", 0x80, 0x8F, 0x82
Player.Colorset 1, "Red", 0x40, 0x4F, 0x42
Player.Colorset 2, "Rust", 0xB0, 0xBF, 0xB2
Player.Colorset 3, "Gray", 0x10, 0x1F, 0x12
Player.Colorset 4, "Dark Green", 0x30, 0x3F, 0x32
Player.Colorset 5, "Gold", 0x50, 0x5F, 0x52
Player.Colorset 6, "Bright Green", 0x60, 0x6F, 0x62
Player.Colorset 7, "Blue", 0x90, 0x9F, 0x92
action native A_ItBurnsItBurns(); action native A_ItBurnsItBurns();
action native A_CrispyPlayer(); action native A_CrispyPlayer();
action native A_HandLower(); action native A_HandLower();