- Switched to a genericly extensible representation for userinfo.

- Fixed: The playerinfo CCMD did not range check the player number.

SVN r4253 (trunk)
This commit is contained in:
Randy Heit 2013-05-12 18:27:03 +00:00
parent 404df07629
commit 2668988870
37 changed files with 756 additions and 441 deletions

View file

@ -51,15 +51,16 @@ void FCajunMaster::ClearPlayer (int i, bool keepTeam)
players[i].mo = NULL; players[i].mo = NULL;
} }
botinfo_t *bot = botinfo; botinfo_t *bot = botinfo;
while (bot && stricmp (players[i].userinfo.netname, bot->name)) while (bot && stricmp (players[i].userinfo.GetName(), bot->name))
bot = bot->next; bot = bot->next;
if (bot) if (bot)
{ {
bot->inuse = false; bot->inuse = false;
bot->lastteam = keepTeam ? players[i].userinfo.team : TEAM_NONE; bot->lastteam = keepTeam ? players[i].userinfo.GetTeam() : TEAM_NONE;
} }
players[i].~player_t(); players[i].~player_t();
::new(&players[i]) player_t; ::new(&players[i]) player_t;
players[i].userinfo.Reset();
playeringame[i] = false; playeringame[i] = false;
} }

View file

@ -140,7 +140,7 @@ void FCajunMaster::Main (int buf)
//Check if player should go observer. Or un observe //Check if player should go observer. Or un observe
if (bot_observer && !observer && !netgame) if (bot_observer && !observer && !netgame)
{ {
Printf ("%s is now observer\n", players[consoleplayer].userinfo.netname); Printf ("%s is now observer\n", players[consoleplayer].userinfo.GetName());
observer = true; observer = true;
players[consoleplayer].mo->UnlinkFromWorld (); players[consoleplayer].mo->UnlinkFromWorld ();
players[consoleplayer].mo->flags = MF_DROPOFF|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOTDMATCH|MF_NOGRAVITY|MF_FRIENDLY; players[consoleplayer].mo->flags = MF_DROPOFF|MF_NOBLOCKMAP|MF_NOCLIP|MF_NOTDMATCH|MF_NOGRAVITY|MF_FRIENDLY;
@ -149,7 +149,7 @@ void FCajunMaster::Main (int buf)
} }
else if (!bot_observer && observer && !netgame) //Go back else if (!bot_observer && observer && !netgame) //Go back
{ {
Printf ("%s returned to the fray\n", players[consoleplayer].userinfo.netname); Printf ("%s returned to the fray\n", players[consoleplayer].userinfo.GetName());
observer = false; observer = false;
players[consoleplayer].mo->UnlinkFromWorld (); players[consoleplayer].mo->UnlinkFromWorld ();
players[consoleplayer].mo->flags = MF_SOLID|MF_SHOOTABLE|MF_DROPOFF|MF_PICKUP|MF_NOTDMATCH|MF_FRIENDLY; players[consoleplayer].mo->flags = MF_SOLID|MF_SHOOTABLE|MF_DROPOFF|MF_PICKUP|MF_NOTDMATCH|MF_FRIENDLY;
@ -218,7 +218,7 @@ void FCajunMaster::End ()
{ {
if (deathmatch) if (deathmatch)
{ {
getspawned.Push(players[i].userinfo.netname); getspawned.Push(players[i].userinfo.GetName());
} }
CleanBotstuff (&players[i]); CleanBotstuff (&players[i]);
} }
@ -353,7 +353,7 @@ void FCajunMaster::DoAddBot (int bnum, char *info)
if (!deathmatch && playerstarts[bnum].type == 0) if (!deathmatch && playerstarts[bnum].type == 0)
{ {
Printf ("%s tried to join, but there was no player %d start\n", Printf ("%s tried to join, but there was no player %d start\n",
players[bnum].userinfo.netname, bnum+1); players[bnum].userinfo.GetName(), bnum+1);
ClearPlayer (bnum, false); // Make the bot inactive again ClearPlayer (bnum, false); // Make the bot inactive again
if (botnum > 0) if (botnum > 0)
{ {
@ -370,9 +370,9 @@ void FCajunMaster::DoAddBot (int bnum, char *info)
botingame[bnum] = true; botingame[bnum] = true;
if (teamplay) if (teamplay)
Printf ("%s joined the %s team\n", players[bnum].userinfo.netname,Teams[players[bnum].userinfo.team].GetName ()); Printf ("%s joined the %s team\n", players[bnum].userinfo.GetName(), Teams[players[bnum].userinfo.GetTeam()].GetName());
else else
Printf ("%s joined the game\n", players[bnum].userinfo.netname); Printf ("%s joined the game\n", players[bnum].userinfo.GetName());
G_DoReborn (bnum, true); G_DoReborn (bnum, true);
if (StatusBar != NULL) if (StatusBar != NULL)

View file

@ -231,7 +231,7 @@ bool AnnounceKill (AActor *killer, AActor *killee)
if (killer == NULL) if (killer == NULL)
{ // The world killed the player { // The world killed the player
if (killee->player->userinfo.gender == GENDER_MALE) if (killee->player->userinfo.GetGender() == GENDER_MALE)
{ // Only males have scrotums to separate { // Only males have scrotums to separate
choice = &WorldKillSounds[rannum % 3]; choice = &WorldKillSounds[rannum % 3];
} }
@ -244,11 +244,11 @@ bool AnnounceKill (AActor *killer, AActor *killee)
else if (killer == killee) else if (killer == killee)
{ // The player killed self { // The player killed self
choice = &SuicideSounds[rannum & 3]; choice = &SuicideSounds[rannum & 3];
killerName = killer->player->userinfo.netname; killerName = killer->player->userinfo.GetName();
} }
else else
{ // Another player did the killing { // Another player did the killing
if (killee->player->userinfo.gender == GENDER_MALE) if (killee->player->userinfo.GetGender() == GENDER_MALE)
{ // Only males can be castrated { // Only males can be castrated
choice = &KillSounds[rannum % countof(KillSounds)]; choice = &KillSounds[rannum % countof(KillSounds)];
} }
@ -256,7 +256,7 @@ bool AnnounceKill (AActor *killer, AActor *killee)
{ {
choice = &KillSounds[rannum % (countof(KillSounds) - 1)]; choice = &KillSounds[rannum % (countof(KillSounds) - 1)];
} }
killerName = killer->player->userinfo.netname; killerName = killer->player->userinfo.GetName();
// Blood only plays the announcement sound on the killer's // Blood only plays the announcement sound on the killer's
// computer. I think it sounds neater to also hear it on // computer. I think it sounds neater to also hear it on
@ -269,8 +269,8 @@ bool AnnounceKill (AActor *killer, AActor *killee)
{ {
char assembled[1024]; char assembled[1024];
SexMessage (message, assembled, killee->player->userinfo.gender, SexMessage (message, assembled, killee->player->userinfo.GetGender(),
killee->player->userinfo.netname, killerName); killee->player->userinfo.GetName(), killerName);
Printf (PRINT_MEDIUM, "%s\n", assembled); Printf (PRINT_MEDIUM, "%s\n", assembled);
} }
if (playSound) if (playSound)
@ -301,8 +301,8 @@ bool AnnounceTelefrag (AActor *killer, AActor *killee)
{ {
char assembled[1024]; char assembled[1024];
SexMessage (message, assembled, killee->player->userinfo.gender, SexMessage (message, assembled, killee->player->userinfo.GetGender(),
killee->player->userinfo.netname, killer->player->userinfo.netname); killee->player->userinfo.GetName(), killer->player->userinfo.GetName());
Printf (PRINT_MEDIUM, "%s\n", assembled); Printf (PRINT_MEDIUM, "%s\n", assembled);
} }
if (killee->CheckLocalView (consoleplayer) || if (killee->CheckLocalView (consoleplayer) ||

View file

@ -1477,6 +1477,29 @@ FBaseCVar *FindCVarSub (const char *var_name, int namelen)
return var; return var;
} }
//===========================================================================
//
// C_CreateCVar
//
// Create a new cvar with the specified name and type. It should not already
// exist.
//
//===========================================================================
FBaseCVar *C_CreateCVar(const char *var_name, ECVarType var_type, DWORD flags)
{
assert(FindCVar(var_name, NULL) == NULL);
switch (var_type)
{
case CVAR_Bool: return new FBoolCVar(var_name, 0, flags);
case CVAR_Int: return new FIntCVar(var_name, 0, flags);
case CVAR_Float: return new FFloatCVar(var_name, 0, flags);
case CVAR_String: return new FStringCVar(var_name, NULL, flags);
case CVAR_Color: return new FColorCVar(var_name, 0, flags);
default: return NULL;
}
}
void UnlatchCVars (void) void UnlatchCVars (void)
{ {
FLatchedValue var; FLatchedValue var;

View file

@ -96,6 +96,7 @@ public:
inline const char *GetName () const { return Name; } inline const char *GetName () const { return Name; }
inline uint32 GetFlags () const { return Flags; } inline uint32 GetFlags () const { return Flags; }
inline FBaseCVar *GetNext() const { return m_Next; }
void CmdSet (const char *newval); void CmdSet (const char *newval);
void ForceSet (UCVarValue value, ECVarType type); void ForceSet (UCVarValue value, ECVarType type);
@ -181,6 +182,9 @@ void C_BackupCVars (void);
FBaseCVar *FindCVar (const char *var_name, FBaseCVar **prev); FBaseCVar *FindCVar (const char *var_name, FBaseCVar **prev);
FBaseCVar *FindCVarSub (const char *var_name, int namelen); FBaseCVar *FindCVarSub (const char *var_name, int namelen);
// Create a new cvar with the specified name and type
FBaseCVar *C_CreateCVar(const char *var_name, ECVarType var_type, DWORD flags);
// Called from G_InitNew() // Called from G_InitNew()
void UnlatchCVars (void); void UnlatchCVars (void);
@ -425,5 +429,6 @@ void C_ForgetCVars (void);
#define EXTERN_CVAR(type,name) extern F##type##CVar name; #define EXTERN_CVAR(type,name) extern F##type##CVar name;
extern FBaseCVar *CVars;
#endif //__C_CVARS_H__ #endif //__C_CVARS_H__

View file

@ -755,7 +755,7 @@ FString strbin1 (const char *start)
// //
//========================================================================== //==========================================================================
void CleanseString(char *str) char *CleanseString(char *str)
{ {
char *escape = strrchr(str, TEXTCOLOR_ESCAPE); char *escape = strrchr(str, TEXTCOLOR_ESCAPE);
if (escape != NULL) if (escape != NULL)
@ -773,6 +773,7 @@ void CleanseString(char *str)
} }
} }
} }
return str;
} }
//========================================================================== //==========================================================================

View file

@ -47,7 +47,7 @@ const char *myasctime ();
int strbin (char *str); int strbin (char *str);
FString strbin1 (const char *start); FString strbin1 (const char *start);
void CleanseString (char *str); char *CleanseString (char *str);
void CreatePath(const char * fn); void CreatePath(const char * fn);

View file

@ -596,12 +596,12 @@ void PlayerIsGone (int netnode, int netconsole)
if (deathmatch) if (deathmatch)
{ {
Printf ("%s left the game with %d frags\n", Printf ("%s left the game with %d frags\n",
players[netconsole].userinfo.netname, players[netconsole].userinfo.GetName(),
players[netconsole].fragcount); players[netconsole].fragcount);
} }
else else
{ {
Printf ("%s left the game\n", players[netconsole].userinfo.netname); Printf ("%s left the game\n", players[netconsole].userinfo.GetName());
} }
// [RH] Revert each player to their own view if spying through the player who left // [RH] Revert each player to their own view if spying through the player who left
@ -646,7 +646,7 @@ void PlayerIsGone (int netnode, int netconsole)
{ {
Net_Arbitrator = i; Net_Arbitrator = i;
players[i].settings_controller = true; players[i].settings_controller = true;
Printf ("%s is the new arbitrator\n", players[i].userinfo.netname); Printf ("%s is the new arbitrator\n", players[i].userinfo.GetName());
break; break;
} }
} }
@ -1361,7 +1361,7 @@ bool DoArbitrate (void *userdata)
data->playersdetected[0] |= 1 << netbuffer[1]; data->playersdetected[0] |= 1 << netbuffer[1];
StartScreen->NetMessage ("Found %s (node %d, player %d)", StartScreen->NetMessage ("Found %s (node %d, player %d)",
players[netbuffer[1]].userinfo.netname, players[netbuffer[1]].userinfo.GetName(),
node, netbuffer[1]+1); node, netbuffer[1]+1);
} }
} }
@ -1968,12 +1968,12 @@ void Net_DoCommand (int type, BYTE **stream, int player)
{ {
case DEM_SAY: case DEM_SAY:
{ {
const char *name = players[player].userinfo.netname; const char *name = players[player].userinfo.GetName();
BYTE who = ReadByte (stream); BYTE who = ReadByte (stream);
s = ReadString (stream); s = ReadString (stream);
CleanseString (s); CleanseString (s);
if (((who & 1) == 0) || players[player].userinfo.team == TEAM_NONE) if (((who & 1) == 0) || players[player].userinfo.GetTeam() == TEAM_NONE)
{ // Said to everyone { // Said to everyone
if (who & 2) if (who & 2)
{ {
@ -1985,7 +1985,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
} }
S_Sound (CHAN_VOICE | CHAN_UI, gameinfo.chatSound, 1, ATTN_NONE); S_Sound (CHAN_VOICE | CHAN_UI, gameinfo.chatSound, 1, ATTN_NONE);
} }
else if (players[player].userinfo.team == players[consoleplayer].userinfo.team) else if (players[player].userinfo.GetTeam() == players[consoleplayer].userinfo.GetTeam())
{ // Said only to members of the player's team { // Said only to members of the player's team
if (who & 2) if (who & 2)
{ {
@ -2392,7 +2392,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
players[playernum].settings_controller = true; players[playernum].settings_controller = true;
if (consoleplayer == playernum || consoleplayer == Net_Arbitrator) if (consoleplayer == playernum || consoleplayer == Net_Arbitrator)
Printf ("%s has been added to the controller list.\n", players[playernum].userinfo.netname); Printf ("%s has been added to the controller list.\n", players[playernum].userinfo.GetName());
} }
break; break;
@ -2402,7 +2402,7 @@ void Net_DoCommand (int type, BYTE **stream, int player)
players[playernum].settings_controller = false; players[playernum].settings_controller = false;
if (consoleplayer == playernum || consoleplayer == Net_Arbitrator) if (consoleplayer == playernum || consoleplayer == Net_Arbitrator)
Printf ("%s has been removed from the controller list.\n", players[playernum].userinfo.netname); Printf ("%s has been removed from the controller list.\n", players[playernum].userinfo.GetName());
} }
break; break;
@ -2653,7 +2653,7 @@ CCMD (pings)
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
if (playeringame[i]) if (playeringame[i])
Printf ("% 4d %s\n", currrecvtime[i] - lastrecvtime[i], Printf ("% 4d %s\n", currrecvtime[i] - lastrecvtime[i],
players[i].userinfo.netname); players[i].userinfo.GetName());
} }
//========================================================================== //==========================================================================
@ -2675,13 +2675,13 @@ static void Network_Controller (int playernum, bool add)
if (players[playernum].settings_controller && add) if (players[playernum].settings_controller && add)
{ {
Printf ("%s is already on the setting controller list.\n", players[playernum].userinfo.netname); Printf ("%s is already on the setting controller list.\n", players[playernum].userinfo.GetName());
return; return;
} }
if (!players[playernum].settings_controller && !add) if (!players[playernum].settings_controller && !add)
{ {
Printf ("%s is not on the setting controller list.\n", players[playernum].userinfo.netname); Printf ("%s is not on the setting controller list.\n", players[playernum].userinfo.GetName());
return; return;
} }
@ -2780,7 +2780,7 @@ CCMD (net_listcontrollers)
if (players[i].settings_controller) if (players[i].settings_controller)
{ {
Printf ("- %s\n", players[i].userinfo.netname); Printf ("- %s\n", players[i].userinfo.GetName());
} }
} }
} }

View file

@ -192,11 +192,12 @@ void D_GetPlayerColor (int player, float *h, float *s, float *v, FPlayerColorSet
{ {
userinfo_t *info = &players[player].userinfo; userinfo_t *info = &players[player].userinfo;
FPlayerColorSet *colorset = NULL; FPlayerColorSet *colorset = NULL;
int color; uint32 color;
int team;
if (players[player].mo != NULL) if (players[player].mo != NULL)
{ {
colorset = P_GetPlayerColorSet(players[player].mo->GetClass()->TypeName, info->colorset); colorset = P_GetPlayerColorSet(players[player].mo->GetClass()->TypeName, info->GetColorSet());
} }
if (colorset != NULL) if (colorset != NULL)
{ {
@ -204,19 +205,19 @@ void D_GetPlayerColor (int player, float *h, float *s, float *v, FPlayerColorSet
} }
else else
{ {
color = info->color; color = info->GetColor();
} }
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);
if (teamplay && TeamLibrary.IsValidTeam(info->team) && !Teams[info->team].GetAllowCustomPlayerColor ()) if (teamplay && TeamLibrary.IsValidTeam((team = info->GetTeam())) && !Teams[team].GetAllowCustomPlayerColor())
{ {
// In team play, force the player to use the team's hue // In team play, force the player to use the team's hue
// and adjust the saturation and value so that the team // and adjust the saturation and value so that the team
// hue is visible in the final color. // hue is visible in the final color.
float ts, tv; float ts, tv;
int tcolor = Teams[info->team].GetPlayerColor (); int tcolor = Teams[team].GetPlayerColor ();
RGBtoHSV (RPART(tcolor)/255.f, GPART(tcolor)/255.f, BPART(tcolor)/255.f, RGBtoHSV (RPART(tcolor)/255.f, GPART(tcolor)/255.f, BPART(tcolor)/255.f,
h, &ts, &tv); h, &ts, &tv);
@ -264,9 +265,10 @@ int D_PickRandomTeam ()
{ {
if (playeringame[i]) if (playeringame[i])
{ {
if (TeamLibrary.IsValidTeam (players[i].userinfo.team)) team = players[i].userinfo.GetTeam();
if (TeamLibrary.IsValidTeam(team))
{ {
if (Teams[players[i].userinfo.team].m_iPresent++ == 0) if (Teams[team].m_iPresent++ == 0)
{ {
numTeams++; numTeams++;
} }
@ -278,7 +280,7 @@ int D_PickRandomTeam ()
{ {
do do
{ {
team = pr_pickteam() % Teams.Size (); team = pr_pickteam() % Teams.Size();
} while (Teams[team].m_iPresent != 0); } while (Teams[team].m_iPresent != 0);
} }
else else
@ -319,7 +321,7 @@ static void UpdateTeam (int pnum, int team, bool update)
{ {
userinfo_t *info = &players[pnum].userinfo; userinfo_t *info = &players[pnum].userinfo;
if ((dmflags2 & DF2_NO_TEAM_SWITCH) && (alwaysapplydmflags || deathmatch) && TeamLibrary.IsValidTeam (info->team)) if ((dmflags2 & DF2_NO_TEAM_SWITCH) && (alwaysapplydmflags || deathmatch) && TeamLibrary.IsValidTeam (info->GetTeam()))
{ {
Printf ("Team changing has been disabled!\n"); Printf ("Team changing has been disabled!\n");
return; return;
@ -331,19 +333,15 @@ static void UpdateTeam (int pnum, int team, bool update)
{ {
team = TEAM_NONE; team = TEAM_NONE;
} }
oldteam = info->team; oldteam = info->GetTeam();
info->team = team; team = info->TeamChanged(team);
if (teamplay && !TeamLibrary.IsValidTeam (info->team)) if (update && oldteam != team)
{ // Force players onto teams in teamplay mode
info->team = D_PickRandomTeam ();
}
if (update && oldteam != info->team)
{ {
if (TeamLibrary.IsValidTeam (info->team)) if (TeamLibrary.IsValidTeam (team))
Printf ("%s joined the %s team\n", info->netname, Teams[info->team].GetName ()); Printf ("%s joined the %s team\n", info->GetName(), Teams[team].GetName ());
else else
Printf ("%s is now a loner\n", info->netname); Printf ("%s is now a loner\n", info->GetName());
} }
// Let the player take on the team's color // Let the player take on the team's color
R_BuildPlayerTranslation (pnum); R_BuildPlayerTranslation (pnum);
@ -351,25 +349,28 @@ static void UpdateTeam (int pnum, int team, bool update)
{ {
StatusBar->AttachToPlayer (&players[pnum]); StatusBar->AttachToPlayer (&players[pnum]);
} }
if (!TeamLibrary.IsValidTeam (info->team)) // Double-check
info->team = TEAM_NONE; if (!TeamLibrary.IsValidTeam (team))
{
*static_cast<FIntCVar *>((*info)[NAME_Team]) = TEAM_NONE;
}
} }
int D_GetFragCount (player_t *player) int D_GetFragCount (player_t *player)
{ {
if (!teamplay || !TeamLibrary.IsValidTeam (player->userinfo.team)) const int team = player->userinfo.GetTeam();
if (!teamplay || !TeamLibrary.IsValidTeam(team))
{ {
return player->fragcount; return player->fragcount;
} }
else else
{ {
// Count total frags for this player's team // Count total frags for this player's team
const int team = player->userinfo.team;
int count = 0; int count = 0;
for (int i = 0; i < MAXPLAYERS; ++i) for (int i = 0; i < MAXPLAYERS; ++i)
{ {
if (playeringame[i] && players[i].userinfo.team == team) if (playeringame[i] && players[i].userinfo.GetTeam() == team)
{ {
count += players[i].fragcount; count += players[i].fragcount;
} }
@ -381,37 +382,147 @@ int D_GetFragCount (player_t *player)
void D_SetupUserInfo () void D_SetupUserInfo ()
{ {
int i; int i;
userinfo_t *coninfo = &players[consoleplayer].userinfo; userinfo_t *coninfo;
// Reset everybody's userinfo to a default state.
for (i = 0; i < MAXPLAYERS; i++) for (i = 0; i < MAXPLAYERS; i++)
memset (&players[i].userinfo, 0, sizeof(userinfo_t)); {
players[i].userinfo.Reset();
}
// Initialize the console player's user info
coninfo = &players[consoleplayer].userinfo;
strncpy (coninfo->netname, name, MAXPLAYERNAME); for (FBaseCVar *cvar = CVars; cvar != NULL; cvar = cvar->GetNext())
if (teamplay && !TeamLibrary.IsValidTeam (team))
{ {
coninfo->team = D_PickRandomTeam (); if (cvar->GetFlags() & CVAR_USERINFO)
}
else
{ {
coninfo->team = team; FBaseCVar **newcvar;
} FName cvarname(cvar->GetName());
if (autoaim > 35.f || autoaim < 0.f) ECVarType type;
switch (cvarname.GetIndex())
{ {
coninfo->aimdist = ANGLE_1*35; // Some cvars don't copy their original value directly.
case NAME_Team: coninfo->TeamChanged(team); break;
case NAME_Skin: coninfo->SkinChanged(skin); break;
case NAME_Gender: coninfo->GenderChanged(gender); break;
case NAME_PlayerClass: coninfo->PlayerClassChanged(playerclass); break;
// The rest do.
default:
newcvar = coninfo->CheckKey(cvarname);
(*newcvar)->SetGenericRep(cvar->GetGenericRep(CVAR_String), CVAR_String);
break;
} }
else }
}
R_BuildPlayerTranslation(consoleplayer);
}
void userinfo_t::Reset()
{
// Clear this player's userinfo.
TMapIterator<FName, FBaseCVar *> it(*this);
TMap<FName, FBaseCVar *>::Pair *pair;
while (it.NextPair(pair))
{ {
coninfo->aimdist = abs ((int)(autoaim * (float)ANGLE_1)); delete pair->Value;
} }
coninfo->color = color; Clear();
coninfo->colorset = colorset;
coninfo->skin = R_FindSkin (skin, 0); // Create userinfo vars for this player, initialized to their defaults.
coninfo->gender = D_GenderToInt (gender); for (FBaseCVar *cvar = CVars; cvar != NULL; cvar = cvar->GetNext())
coninfo->neverswitch = neverswitchonpickup; {
coninfo->MoveBob = (fixed_t)(65536.f * movebob); if (cvar->GetFlags() & CVAR_USERINFO)
coninfo->StillBob = (fixed_t)(65536.f * stillbob); {
coninfo->PlayerClass = D_PlayerClassToInt (playerclass); ECVarType type;
R_BuildPlayerTranslation (consoleplayer); FName cvarname(cvar->GetName());
FBaseCVar *newcvar;
// Some cvars have different types for their shadow copies.
switch (cvarname.GetIndex())
{
case NAME_Skin: type = CVAR_Int; break;
case NAME_Gender: type = CVAR_Int; break;
case NAME_PlayerClass: type = CVAR_Int; break;
default: type = cvar->GetRealType(); break;
}
newcvar = C_CreateCVar(NULL, type, 0);
newcvar->SetGenericRepDefault(cvar->GetGenericRepDefault(CVAR_String), CVAR_String);
Insert(cvarname, newcvar);
}
}
}
int userinfo_t::TeamChanged(int team)
{
if (teamplay && !TeamLibrary.IsValidTeam(team))
{ // Force players onto teams in teamplay mode
team = D_PickRandomTeam();
}
*static_cast<FIntCVar *>((*this)[NAME_Team]) = team;
return team;
}
int userinfo_t::SkinChanged(const char *skinname)
{
int skinnum = R_FindSkin(skinname, 0);
*static_cast<FIntCVar *>((*this)[NAME_Skin]) = skinnum;
return skinnum;
}
int userinfo_t::SkinNumChanged(int skinnum)
{
*static_cast<FIntCVar *>((*this)[NAME_Skin]) = skinnum;
return skinnum;
}
int userinfo_t::GenderChanged(const char *gendername)
{
int gendernum = D_GenderToInt(gendername);
*static_cast<FIntCVar *>((*this)[NAME_Gender]) = gendernum;
return gendernum;
}
int userinfo_t::PlayerClassChanged(const char *classname)
{
int classnum = D_PlayerClassToInt(classname);
*static_cast<FIntCVar *>((*this)[NAME_PlayerClass]) = classnum;
return classnum;
}
int userinfo_t::PlayerClassNumChanged(int classnum)
{
*static_cast<FIntCVar *>((*this)[NAME_PlayerClass]) = classnum;
return classnum;
}
int userinfo_t::ColorSetChanged(int setnum)
{
*static_cast<FIntCVar *>((*this)[NAME_ColorSet]) = setnum;
return setnum;
}
uint32 userinfo_t::ColorChanged(const char *colorname)
{
FColorCVar *color = static_cast<FColorCVar *>((*this)[NAME_Color]);
assert(color != NULL);
UCVarValue val;
val.String = const_cast<char *>(colorname);
color->SetGenericRep(val, CVAR_String);
*static_cast<FIntCVar *>((*this)[NAME_ColorSet]) = -1;
return *color;
}
uint32 userinfo_t::ColorChanged(uint32 colorval)
{
FColorCVar *color = static_cast<FColorCVar *>((*this)[NAME_Color]);
assert(color != NULL);
UCVarValue val;
val.Int = colorval;
color->SetGenericRep(val, CVAR_Int);
// This version is called by the menu code. Do not implicitly set colorset.
return colorval;
} }
void D_UserInfoChanged (FBaseCVar *cvar) void D_UserInfoChanged (FBaseCVar *cvar)
@ -503,7 +614,7 @@ static const char *SetServerVar (char *name, ECVarType type, BYTE **stream, bool
{ {
if (playeringame[i]) if (playeringame[i])
{ {
UpdateTeam (i, players[i].userinfo.team, true); UpdateTeam (i, players[i].userinfo.GetTeam(), true);
} }
} }
} }
@ -572,113 +683,131 @@ void D_DoServerInfoChange (BYTE **stream, bool singlebit)
} }
} }
void D_WriteUserInfoStrings (int i, BYTE **stream, bool compact) static int STACK_ARGS userinfosortfunc(const void *a, const void *b)
{ {
if (i >= MAXPLAYERS) TMap<FName, FBaseCVar *>::ConstPair *pair1 = *(TMap<FName, FBaseCVar *>::ConstPair **)a;
{ TMap<FName, FBaseCVar *>::ConstPair *pair2 = *(TMap<FName, FBaseCVar *>::ConstPair **)b;
WriteByte (0, stream); return stricmp(pair1->Key.GetChars(), pair2->Key.GetChars());
}
else
{
userinfo_t *info = &players[i].userinfo;
const PClass *type = PlayerClasses[info->PlayerClass].Type;
if (!compact)
{
sprintf (*((char **)stream),
"\\name\\%s"
"\\autoaim\\%g"
"\\color\\%x %x %x"
"\\colorset\\%d"
"\\skin\\%s"
"\\team\\%d"
"\\gender\\%s"
"\\neverswitchonpickup\\%d"
"\\movebob\\%g"
"\\stillbob\\%g"
"\\playerclass\\%s"
,
D_EscapeUserInfo(info->netname).GetChars(),
(double)info->aimdist / (float)ANGLE_1,
RPART(info->color), GPART(info->color), BPART(info->color),
info->colorset,
D_EscapeUserInfo(skins[info->skin].name).GetChars(),
info->team,
info->gender == GENDER_FEMALE ? "female" :
info->gender == GENDER_NEUTER ? "other" : "male",
info->neverswitch,
(float)(info->MoveBob) / 65536.f,
(float)(info->StillBob) / 65536.f,
info->PlayerClass == -1 ? "Random" :
D_EscapeUserInfo(type->Meta.GetMetaString (APMETA_DisplayName)).GetChars()
);
}
else
{
sprintf (*((char **)stream),
"\\"
"\\%s" // name
"\\%g" // autoaim
"\\%x %x %x" // color
"\\%s" // skin
"\\%d" // team
"\\%s" // gender
"\\%d" // neverswitchonpickup
"\\%g" // movebob
"\\%g" // stillbob
"\\%s" // playerclass
"\\%d" // colorset
,
D_EscapeUserInfo(info->netname).GetChars(),
(double)info->aimdist / (float)ANGLE_1,
RPART(info->color), GPART(info->color), BPART(info->color),
D_EscapeUserInfo(skins[info->skin].name).GetChars(),
info->team,
info->gender == GENDER_FEMALE ? "female" :
info->gender == GENDER_NEUTER ? "other" : "male",
info->neverswitch,
(float)(info->MoveBob) / 65536.f,
(float)(info->StillBob) / 65536.f,
info->PlayerClass == -1 ? "Random" :
D_EscapeUserInfo(type->Meta.GetMetaString (APMETA_DisplayName)).GetChars(),
info->colorset
);
}
}
*stream += strlen (*((char **)stream)) + 1;
} }
void D_ReadUserInfoStrings (int i, BYTE **stream, bool update) static int STACK_ARGS namesortfunc(const void *a, const void *b)
{ {
userinfo_t *info = &players[i].userinfo; FName *name1 = (FName *)a;
FName *name2 = (FName *)b;
return stricmp(name1->GetChars(), name2->GetChars());
}
void D_WriteUserInfoStrings (int pnum, BYTE **stream, bool compact)
{
if (pnum >= MAXPLAYERS)
{
WriteByte (0, stream);
return;
}
userinfo_t *info = &players[pnum].userinfo;
TArray<TMap<FName, FBaseCVar *>::Pair *> userinfo_pairs(info->CountUsed());
TMap<FName, FBaseCVar *>::Iterator it(*info);
TMap<FName, FBaseCVar *>::Pair *pair;
UCVarValue cval;
// Create a simple array of all userinfo cvars
while (it.NextPair(pair))
{
userinfo_pairs.Push(pair);
}
// For compact mode, these need to be sorted. Verbose mode doesn't matter.
if (compact)
{
qsort(&userinfo_pairs[0], userinfo_pairs.Size(), sizeof(pair), userinfosortfunc);
// Compact mode is signified by starting the string with two backslash characters.
// We output one now. The second will be output as part of the first value.
*(*stream)++ = '\\';
}
for (unsigned int i = 0; i < userinfo_pairs.Size(); ++i)
{
pair = userinfo_pairs[i];
if (!compact)
{ // In verbose mode, prepend the cvar's name
*stream += sprintf(*((char **)stream), "\\%s\\", pair->Key.GetChars());
}
// A few of these need special handling for compatibility reasons.
switch (pair->Key.GetIndex())
{
case NAME_Gender:
*stream += sprintf(*((char **)stream), "\\%s",
*static_cast<FIntCVar *>(pair->Value) == GENDER_FEMALE ? "female" :
*static_cast<FIntCVar *>(pair->Value) == GENDER_NEUTER ? "other" : "male");
break;
case NAME_PlayerClass:
*stream += sprintf(*((char **)stream), "\\%s", info->GetPlayerClassNum() == -1 ? "Random" :
D_EscapeUserInfo(info->GetPlayerClassType()->Meta.GetMetaString(APMETA_DisplayName)).GetChars());
break;
case NAME_Skin:
*stream += sprintf(*((char **)stream), "\\%s", D_EscapeUserInfo(skins[info->GetSkin()].name).GetChars());
break;
default:
cval = pair->Value->GetGenericRep(CVAR_String);
*stream += sprintf(*((char **)stream), "\\%s", cval.String);
break;
}
}
*(*stream)++ = '\0';
}
void D_ReadUserInfoStrings (int pnum, BYTE **stream, bool update)
{
userinfo_t *info = &players[pnum].userinfo;
TArray<FName> compact_names(info->CountUsed());
FBaseCVar **cvar_ptr;
const char *ptr = *((const char **)stream); const char *ptr = *((const char **)stream);
const char *breakpt; const char *breakpt;
FString value; FString value;
bool compact; bool compact;
int infotype = -1; FName keyname;
unsigned int infotype = 0;
if (*ptr++ != '\\') if (*ptr++ != '\\')
return; return;
compact = (*ptr == '\\') ? ptr++, true : false; compact = (*ptr == '\\') ? ptr++, true : false;
if (i < MAXPLAYERS) // We need the cvar names in sorted order for compact mode
if (compact)
{ {
for (;;) TMap<FName, FBaseCVar *>::Iterator it(*info);
{ TMap<FName, FBaseCVar *>::Pair *pair;
int j;
breakpt = strchr (ptr, '\\'); while (it.NextPair(pair))
{
compact_names.Push(pair->Key);
}
qsort(&compact_names[0], compact_names.Size(), sizeof(FName), namesortfunc);
}
if (pnum < MAXPLAYERS)
{
for (breakpt = ptr; breakpt != NULL; ptr = breakpt + 1)
{
breakpt = strchr(ptr, '\\');
if (compact) if (compact)
{ {
// Compact has just the value.
if (infotype >= compact_names.Size())
{ // Too many entries! OMG!
break;
}
keyname = compact_names[infotype++];
value = D_UnescapeUserInfo(ptr, breakpt != NULL ? breakpt - ptr : strlen(ptr)); value = D_UnescapeUserInfo(ptr, breakpt != NULL ? breakpt - ptr : strlen(ptr));
infotype++;
} }
else else
{ {
// Verbose has both the key name and its value.
assert(breakpt != NULL); assert(breakpt != NULL);
// A malicious remote machine could invalidate the above assert. // A malicious remote machine could invalidate the above assert.
if (breakpt == NULL) if (breakpt == NULL)
@ -694,154 +823,187 @@ void D_ReadUserInfoStrings (int i, BYTE **stream, bool update)
{ {
value = D_UnescapeUserInfo(valstart, strlen(valstart)); value = D_UnescapeUserInfo(valstart, strlen(valstart));
} }
keyname = FName(ptr, valstart - ptr - 1, true);
}
for (j = 0; // A few of these need special handling.
UserInfoStrings[j] && strnicmp (UserInfoStrings[j], ptr, valstart - ptr - 1) != 0; switch (keyname)
++j)
{ }
if (UserInfoStrings[j] == NULL)
{ {
infotype = -1; case NAME_Gender:
} info->GenderChanged(value);
else
{
infotype = j;
}
}
switch (infotype)
{
case INFO_Autoaim: {
double angles;
angles = atof (value);
if (angles > 35.f || angles < 0.f)
{
info->aimdist = ANGLE_1*35;
}
else
{
info->aimdist = abs ((int)(angles * (float)ANGLE_1));
}
}
break; break;
case INFO_Name: case NAME_PlayerClass:
{ info->PlayerClassChanged(value);
char oldname[MAXPLAYERNAME+1];
strcpy (oldname, info->netname);
strncpy (info->netname, value, MAXPLAYERNAME);
info->netname[MAXPLAYERNAME] = 0;
CleanseString(info->netname);
if (update && strcmp (oldname, info->netname) != 0)
{
Printf ("%s is now known as %s\n", oldname, info->netname);
}
}
break; break;
case INFO_Team: case NAME_Skin:
UpdateTeam (i, atoi(value), update); info->SkinChanged(value);
break; if (players[pnum].mo != NULL)
case INFO_Color:
case INFO_ColorSet:
if (infotype == INFO_Color)
{ {
info->color = V_GetColorFromString (NULL, value); if (players[pnum].cls != NULL &&
info->colorset = -1; !(players[pnum].mo->flags4 & MF4_NOSKIN) &&
} players[pnum].mo->state->sprite ==
else GetDefaultByType (players[pnum].cls)->SpawnState->sprite)
{
info->colorset = atoi(value);
}
R_BuildPlayerTranslation (i);
if (StatusBar != NULL && i == StatusBar->GetPlayer())
{
StatusBar->AttachToPlayer (&players[i]);
}
break;
case INFO_Skin:
info->skin = R_FindSkin (value, players[i].CurrentPlayerClass);
if (players[i].mo != NULL)
{
if (players[i].cls != NULL &&
!(players[i].mo->flags4 & MF4_NOSKIN) &&
players[i].mo->state->sprite ==
GetDefaultByType (players[i].cls)->SpawnState->sprite)
{ // Only change the sprite if the player is using a standard one { // Only change the sprite if the player is using a standard one
players[i].mo->sprite = skins[info->skin].sprite; players[pnum].mo->sprite = skins[info->GetSkin()].sprite;
} }
} }
// Rebuild translation in case the new skin uses a different range // Rebuild translation in case the new skin uses a different range
// than the old one. // than the old one.
R_BuildPlayerTranslation (i); R_BuildPlayerTranslation(pnum);
break; break;
case INFO_Gender: case NAME_Team:
info->gender = D_GenderToInt (value); UpdateTeam(pnum, atoi(value), update);
break; break;
case INFO_NeverSwitchOnPickup: case NAME_Color:
if (value[0] >= '0' && value[0] <= '9') info->ColorChanged(value);
{
info->neverswitch = atoi (value) ? true : false;
}
else if (stricmp (value, "true") == 0)
{
info->neverswitch = 1;
}
else
{
info->neverswitch = 0;
}
break;
case INFO_MoveBob:
info->MoveBob = (fixed_t)(atof (value) * 65536.f);
break;
case INFO_StillBob:
info->StillBob = (fixed_t)(atof (value) * 65536.f);
break;
case INFO_PlayerClass:
info->PlayerClass = D_PlayerClassToInt (value);
break; break;
default: default:
cvar_ptr = info->CheckKey(keyname);
if (cvar_ptr != NULL)
{
assert(*cvar_ptr != NULL);
UCVarValue val;
FString oldname;
if (keyname == NAME_Name)
{
val = (*cvar_ptr)->GetGenericRep(CVAR_String);
oldname = val.String;
}
val.String = CleanseString(value.LockBuffer());
(*cvar_ptr)->SetGenericRep(val, CVAR_String);
value.UnlockBuffer();
if (keyname == NAME_Name && update && oldname != value)
{
Printf("%s is now known as %s\n", oldname.GetChars(), value.GetChars());
}
}
break; break;
} }
if (keyname == NAME_Color || keyname == NAME_ColorSet)
if (breakpt)
{ {
ptr = breakpt + 1; R_BuildPlayerTranslation(pnum);
} if (StatusBar != NULL && pnum == StatusBar->GetPlayer())
else
{ {
break; StatusBar->AttachToPlayer(&players[pnum]);
}
} }
} }
} }
*stream += strlen (*((char **)stream)) + 1; *stream += strlen (*((char **)stream)) + 1;
} }
void ReadCompatibleUserInfo(FArchive &arc, userinfo_t &info)
{
char netname[MAXPLAYERNAME];
BYTE team;
int aimdist, color, colorset, skin, gender;
bool neverswitch;
//fixed_t movebob, stillbob; These were never serialized!
//int playerclass; "
info.Reset();
arc.Read(&netname, sizeof(netname));
arc << team << aimdist << color << skin << gender << neverswitch << colorset;
*static_cast<FStringCVar *>(info[NAME_Name]) = netname;
*static_cast<FIntCVar *>(info[NAME_Team]) = team;
*static_cast<FFloatCVar *>(info[NAME_AutoAim]) = (float)aimdist / ANGLE_1;
*static_cast<FIntCVar *>(info[NAME_Skin]) = skin;
*static_cast<FIntCVar *>(info[NAME_Gender]) = gender;
*static_cast<FBoolCVar *>(info[NAME_NeverSwitchOnPickup]) = neverswitch;
*static_cast<FIntCVar *>(info[NAME_ColorSet]) = colorset;
UCVarValue val;
val.Int = color;
static_cast<FColorCVar *>(info[NAME_Color])->SetGenericRep(val, CVAR_Int);
}
void WriteUserInfo(FArchive &arc, userinfo_t &info)
{
TMapIterator<FName, FBaseCVar *> it(info);
TMap<FName, FBaseCVar *>::Pair *pair;
FName name;
UCVarValue val;
int i;
while (it.NextPair(pair))
{
name = pair->Key;
arc << name;
switch (name.GetIndex())
{
case NAME_Skin:
arc.WriteString(skins[info.GetSkin()].name);
break;
case NAME_PlayerClass:
i = info.GetPlayerClassNum();
arc.WriteString(i == -1 ? "Random" : PlayerClasses[i].Type->Meta.GetMetaString(APMETA_DisplayName));
break;
default:
val = pair->Value->GetGenericRep(CVAR_String);
arc.WriteString(val.String);
break;
}
}
name = NAME_None;
arc << name;
}
void ReadUserInfo(FArchive &arc, userinfo_t &info)
{
FName name;
FBaseCVar **cvar;
char *str = NULL;
UCVarValue val;
info.Reset();
for (arc << name; name != NAME_None; arc << name)
{
cvar = info.CheckKey(name);
arc << str;
if (cvar != NULL && *cvar != NULL)
{
switch (name)
{
case NAME_Team: info.TeamChanged(atoi(str)); break;
case NAME_Skin: info.SkinChanged(str); break;
case NAME_PlayerClass: info.PlayerClassChanged(str); break;
default:
val.String = str;
(*cvar)->SetGenericRep(val, CVAR_String);
break;
}
}
}
if (str != NULL)
{
delete[] str;
}
}
FArchive &operator<< (FArchive &arc, userinfo_t &info) FArchive &operator<< (FArchive &arc, userinfo_t &info)
{ {
if (arc.IsStoring ()) if (SaveVersion < 4253)
{ {
arc.Write (&info.netname, sizeof(info.netname)); ReadCompatibleUserInfo(arc, info);
}
else if (arc.IsStoring())
{
WriteUserInfo(arc, info);
} }
else else
{ {
arc.Read (&info.netname, sizeof(info.netname)); ReadUserInfo(arc, info);
} }
arc << info.team << info.aimdist << info.color
<< info.skin << info.gender << info.neverswitch
<< info.colorset;
return arc; return arc;
} }
@ -855,27 +1017,51 @@ CCMD (playerinfo)
{ {
if (playeringame[i]) if (playeringame[i])
{ {
Printf ("%d. %s\n", i, players[i].userinfo.netname); Printf("%d. %s\n", i, players[i].userinfo.GetName());
} }
} }
} }
else else
{ {
int i = atoi (argv[1]); int i = atoi(argv[1]);
if (i < 0 || i >= MAXPLAYERS)
{
Printf("Bad player number\n");
return;
}
userinfo_t *ui = &players[i].userinfo; userinfo_t *ui = &players[i].userinfo;
Printf ("Name: %s\n", ui->netname);
Printf ("Team: %s (%d)\n", ui->team == TEAM_NONE ? "None" : Teams[ui->team].GetName (), ui->team); if (!playeringame[i])
Printf ("Aimdist: %d\n", ui->aimdist); {
Printf ("Color: %06x\n", ui->color); Printf(TEXTCOLOR_ORANGE "Player %d is not in the game\n", i);
Printf ("ColorSet: %d\n", ui->colorset); }
Printf ("Skin: %s (%d)\n", skins[ui->skin].name, ui->skin);
Printf ("Gender: %s (%d)\n", GenderNames[ui->gender], ui->gender); // Print special info
Printf ("NeverSwitch: %d\n", ui->neverswitch); Printf("%20s: %s\n", "Name", ui->GetName());
Printf ("MoveBob: %g\n", ui->MoveBob/65536.f); Printf("%20s: %s (%d)\n", "Team", ui->GetTeam() == TEAM_NONE ? "None" : Teams[ui->GetTeam()].GetName(), ui->GetTeam());
Printf ("StillBob: %g\n", ui->StillBob/65536.f); Printf("%20s: %s (%d)\n", "Skin", skins[ui->GetSkin()].name, ui->GetSkin());
Printf ("PlayerClass: %s (%d)\n", Printf("%20s: %s (%d)\n", "Gender", GenderNames[ui->GetGender()], ui->GetGender());
ui->PlayerClass == -1 ? "Random" : PlayerClasses[ui->PlayerClass].Type->Meta.GetMetaString (APMETA_DisplayName), Printf("%20s: %s (%d)\n", "PlayerClass",
ui->PlayerClass); ui->GetPlayerClassNum() == -1 ? "Random" : ui->GetPlayerClassType()->Meta.GetMetaString (APMETA_DisplayName),
if (argv.argc() > 2) PrintMiscActorInfo(players[i].mo); ui->GetPlayerClassNum());
// Print generic info
TMapIterator<FName, FBaseCVar *> it(*ui);
TMap<FName, FBaseCVar *>::Pair *pair;
while (it.NextPair(pair))
{
if (pair->Key != NAME_Name && pair->Key != NAME_Team && pair->Key != NAME_Skin &&
pair->Key != NAME_Gender && pair->Key != NAME_PlayerClass)
{
UCVarValue val = pair->Value->GetGenericRep(CVAR_String);
Printf("%20s: %s\n", pair->Key.GetChars(), val.String);
}
}
if (argv.argc() > 2)
{
PrintMiscActorInfo(players[i].mo);
}
} }
} }

View file

@ -228,6 +228,29 @@ enum
#define MAXPLAYERNAME 15 #define MAXPLAYERNAME 15
// [GRB] Custom player classes
enum
{
PCF_NOMENU = 1, // Hide in new game menu
};
class FPlayerClass
{
public:
FPlayerClass ();
FPlayerClass (const FPlayerClass &other);
~FPlayerClass ();
bool CheckSkin (int skin);
const PClass *Type;
DWORD Flags;
TArray<int> Skins;
};
extern TArray<FPlayerClass> PlayerClasses;
// User info (per-player copies of each CVAR_USERINFO cvar)
enum enum
{ {
GENDER_MALE, GENDER_MALE,
@ -235,20 +258,80 @@ enum
GENDER_NEUTER GENDER_NEUTER
}; };
struct userinfo_t struct userinfo_t : TMap<FName,FBaseCVar *>
{ {
char netname[MAXPLAYERNAME+1]; int GetAimDist() const
BYTE team; {
int aimdist; if (dmflags2 & DF2_NOAUTOAIM)
int color; {
int colorset; return 0;
int skin; }
int gender;
bool neverswitch;
fixed_t MoveBob, StillBob;
int PlayerClass;
int GetAimDist() const { return (dmflags2 & DF2_NOAUTOAIM)? 0 : aimdist; } float aim = *static_cast<FFloatCVar *>(*CheckKey(NAME_Autoaim));
if (aim > 35 || aim < 0)
{
return ANGLE_1*35;
}
else
{
return xs_RoundToInt(fabs(aim * ANGLE_1));
}
}
const char *GetName() const
{
return *static_cast<FStringCVar *>(*CheckKey(NAME_Name));
}
int GetTeam() const
{
return *static_cast<FIntCVar *>(*CheckKey(NAME_Team));
}
int GetColorSet() const
{
return *static_cast<FIntCVar *>(*CheckKey(NAME_ColorSet));
}
uint32 GetColor() const
{
return *static_cast<FColorCVar *>(*CheckKey(NAME_Color));
}
bool GetNeverSwitch() const
{
return *static_cast<FBoolCVar *>(*CheckKey(NAME_NeverSwitchOnPickup));
}
fixed_t GetMoveBob() const
{
return FLOAT2FIXED(*static_cast<FFloatCVar *>(*CheckKey(NAME_MoveBob)));
}
fixed_t GetStillBob() const
{
return FLOAT2FIXED(*static_cast<FFloatCVar *>(*CheckKey(NAME_StillBob)));
}
int GetPlayerClassNum() const
{
return *static_cast<FIntCVar *>(*CheckKey(NAME_PlayerClass));
}
const PClass *GetPlayerClassType() const
{
return PlayerClasses[GetPlayerClassNum()].Type;
}
int GetSkin() const
{
return *static_cast<FIntCVar *>(*CheckKey(NAME_Skin));
}
int GetGender() const
{
return *static_cast<FIntCVar *>(*CheckKey(NAME_Gender));
}
void Reset();
int TeamChanged(int team);
int SkinChanged(const char *skinname);
int SkinNumChanged(int skinnum);
int GenderChanged(const char *gendername);
int PlayerClassChanged(const char *classname);
int PlayerClassNumChanged(int classnum);
uint32 ColorChanged(const char *colorname);
uint32 ColorChanged(uint32 colorval);
int ColorSetChanged(int setnum);
}; };
FArchive &operator<< (FArchive &arc, userinfo_t &info); FArchive &operator<< (FArchive &arc, userinfo_t &info);
@ -467,26 +550,4 @@ inline bool AActor::IsNoClip2() const
bool P_IsPlayerTotallyFrozen(const player_t *player); bool P_IsPlayerTotallyFrozen(const player_t *player);
// [GRB] Custom player classes
enum
{
PCF_NOMENU = 1, // Hide in new game menu
};
class FPlayerClass
{
public:
FPlayerClass ();
FPlayerClass (const FPlayerClass &other);
~FPlayerClass ();
bool CheckSkin (int skin);
const PClass *Type;
DWORD Flags;
TArray<int> Skins;
};
extern TArray<FPlayerClass> PlayerClasses;
#endif // __D_PLAYER_H__ #endif // __D_PLAYER_H__

View file

@ -774,7 +774,7 @@ void FParser::SF_PlayerName(void)
if(plnum !=-1) if(plnum !=-1)
{ {
t_return.type = svt_string; t_return.type = svt_string;
t_return.string = players[plnum].userinfo.netname; t_return.string = players[plnum].userinfo.GetName();
} }
else else
{ {

View file

@ -1127,7 +1127,7 @@ void G_Ticker ()
if (cmd->ucmd.forwardmove > TURBOTHRESHOLD && if (cmd->ucmd.forwardmove > TURBOTHRESHOLD &&
!(gametic&31) && ((gametic>>5)&(MAXPLAYERS-1)) == i ) !(gametic&31) && ((gametic>>5)&(MAXPLAYERS-1)) == i )
{ {
Printf ("%s is turbo!\n", players[i].userinfo.netname); Printf ("%s is turbo!\n", players[i].userinfo.GetName());
} }
if (netgame && !players[i].isbot && !demoplayback && (gametic%ticdup) == 0) if (netgame && !players[i].isbot && !demoplayback && (gametic%ticdup) == 0)
@ -1312,7 +1312,7 @@ void G_PlayerReborn (int player)
int chasecam; int chasecam;
BYTE currclass; BYTE currclass;
userinfo_t userinfo; // [RH] Save userinfo userinfo_t userinfo; // [RH] Save userinfo
botskill_t b_skill;//Added by MC: botskill_t b_skill; //Added by MC:
APlayerPawn *actor; APlayerPawn *actor;
const PClass *cls; const PClass *cls;
FString log; FString log;
@ -1326,7 +1326,7 @@ void G_PlayerReborn (int player)
secretcount = p->secretcount; secretcount = p->secretcount;
currclass = p->CurrentPlayerClass; currclass = p->CurrentPlayerClass;
b_skill = p->skill; //Added by MC: b_skill = p->skill; //Added by MC:
memcpy (&userinfo, &p->userinfo, sizeof(userinfo)); userinfo.TransferFrom(p->userinfo);
actor = p->mo; actor = p->mo;
cls = p->cls; cls = p->cls;
log = p->LogText; log = p->LogText;
@ -1342,7 +1342,7 @@ void G_PlayerReborn (int player)
p->itemcount = itemcount; p->itemcount = itemcount;
p->secretcount = secretcount; p->secretcount = secretcount;
p->CurrentPlayerClass = currclass; p->CurrentPlayerClass = currclass;
memcpy (&p->userinfo, &userinfo, sizeof(userinfo)); p->userinfo.TransferFrom(userinfo);
p->mo = actor; p->mo = actor;
p->cls = cls; p->cls = cls;
p->LogText = log; p->LogText = log;

View file

@ -240,14 +240,15 @@ void G_NewInit ()
for (i = 0; i < MAXPLAYERS; ++i) for (i = 0; i < MAXPLAYERS; ++i)
{ {
player_t *p = &players[i]; player_t *p = &players[i];
userinfo_t saved_ui = players[i].userinfo; userinfo_t saved_ui;
saved_ui.TransferFrom(players[i].userinfo);
int chasecam = p->cheats & CF_CHASECAM; int chasecam = p->cheats & CF_CHASECAM;
p->~player_t(); p->~player_t();
::new(p) player_t; ::new(p) player_t;
players[i].cheats |= chasecam; players[i].cheats |= chasecam;
players[i].playerstate = PST_DEAD; players[i].playerstate = PST_DEAD;
playeringame[i] = 0; playeringame[i] = 0;
players[i].userinfo = saved_ui; players[i].userinfo.TransferFrom(saved_ui);
} }
BackupSaveName = ""; BackupSaveName = "";
consoleplayer = 0; consoleplayer = 0;
@ -287,7 +288,7 @@ static void InitPlayerClasses ()
{ {
for (int i = 0; i < MAXPLAYERS; ++i) for (int i = 0; i < MAXPLAYERS; ++i)
{ {
SinglePlayerClass[i] = players[i].userinfo.PlayerClass; SinglePlayerClass[i] = players[i].userinfo.GetPlayerClassNum();
if (SinglePlayerClass[i] < 0 || !playeringame[i]) if (SinglePlayerClass[i] < 0 || !playeringame[i])
{ {
SinglePlayerClass[i] = (pr_classchoice()) % PlayerClasses.Size (); SinglePlayerClass[i] = (pr_classchoice()) % PlayerClasses.Size ();

View file

@ -287,11 +287,11 @@ bool P_UndoPlayerMorph (player_t *activator, player_t *player, int unmorphflag,
size_t skinindex = 0; size_t skinindex = 0;
// If a custom skin was in use, then reload it // If a custom skin was in use, then reload it
// or else the base skin for the player class. // or else the base skin for the player class.
if ((unsigned int)player->userinfo.skin >= PlayerClasses.Size () && if ((unsigned int)player->userinfo.GetSkin() >= PlayerClasses.Size () &&
(size_t)player->userinfo.skin < numskins) (size_t)player->userinfo.GetSkin() < numskins)
{ {
skinindex = player->userinfo.skin; skinindex = player->userinfo.GetSkin();
} }
else if (PlayerClasses.Size () > 1) else if (PlayerClasses.Size () > 1)
{ {

View file

@ -314,7 +314,7 @@ void AWeapon::AttachToOwner (AActor *other)
SisterWeapon = AddWeapon (SisterWeaponType); SisterWeapon = AddWeapon (SisterWeaponType);
if (Owner->player != NULL) if (Owner->player != NULL)
{ {
if (!Owner->player->userinfo.neverswitch && !(WeaponFlags & WIF_NO_AUTO_SWITCH)) if (!Owner->player->userinfo.GetNeverSwitch() && !(WeaponFlags & WIF_NO_AUTO_SWITCH))
{ {
Owner->player->PendingWeapon = this; Owner->player->PendingWeapon = this;
} }

View file

@ -505,7 +505,7 @@ FTexture *FMugShot::GetFace(player_t *player, const char *default_face, int accu
} }
if (CurrentState != NULL) if (CurrentState != NULL)
{ {
const char *skin_face = player->morphTics ? player->MorphedPlayerClass->Meta.GetMetaString(APMETA_Face) : skins[player->userinfo.skin].face; const char *skin_face = player->morphTics ? player->MorphedPlayerClass->Meta.GetMetaString(APMETA_Face) : skins[player->userinfo.GetSkin()].face;
return CurrentState->GetCurrentFrameTexture(default_face, skin_face, level, angle); return CurrentState->GetCurrentFrameTexture(default_face, skin_face, level, angle);
} }
return NULL; return NULL;

View file

@ -736,9 +736,9 @@ class CommandDrawString : public SBarInfoCommand
} }
break; break;
case PLAYERCLASS: case PLAYERCLASS:
if(statusBar->CPlayer->userinfo.PlayerClass != cache) if(statusBar->CPlayer->userinfo.GetPlayerClassNum() != cache)
{ {
cache = statusBar->CPlayer->userinfo.PlayerClass; cache = statusBar->CPlayer->userinfo.GetPlayerClassNum();
str = GetPrintableDisplayName(statusBar->CPlayer->cls); str = GetPrintableDisplayName(statusBar->CPlayer->cls);
RealignString(); RealignString();
} }
@ -758,7 +758,7 @@ class CommandDrawString : public SBarInfoCommand
case PLAYERNAME: case PLAYERNAME:
// Can't think of a good way to detect changes to this, so // Can't think of a good way to detect changes to this, so
// I guess copying it every tick will have to do. // I guess copying it every tick will have to do.
str = statusBar->CPlayer->userinfo.netname; str = statusBar->CPlayer->userinfo.GetName();
RealignString(); RealignString();
break; break;
case GLOBALVAR: case GLOBALVAR:

View file

@ -520,7 +520,7 @@ void DBaseStatusBar::ShowPlayerName ()
EColorRange color; EColorRange color;
color = (CPlayer == &players[consoleplayer]) ? CR_GOLD : CR_GREEN; color = (CPlayer == &players[consoleplayer]) ? CR_GOLD : CR_GREEN;
AttachMessage (new DHUDMessageFadeOut (SmallFont, CPlayer->userinfo.netname, AttachMessage (new DHUDMessageFadeOut (SmallFont, CPlayer->userinfo.GetName(),
1.5f, 0.92f, 0, 0, color, 2.f, 0.35f), MAKE_ID('P','N','A','M')); 1.5f, 0.92f, 0, 0, color, 2.f, 0.35f), MAKE_ID('P','N','A','M'));
} }

View file

@ -94,7 +94,7 @@ static int STACK_ARGS comparepoints (const void *arg1, const void *arg2)
diff = deathmatch ? p2->fragcount - p1->fragcount : p2->killcount - p1->killcount; diff = deathmatch ? p2->fragcount - p1->fragcount : p2->killcount - p1->killcount;
if (diff == 0) if (diff == 0)
{ {
diff = stricmp (p1->userinfo.netname, p2->userinfo.netname); diff = stricmp(p1->userinfo.GetName(), p2->userinfo.GetName());
} }
return diff; return diff;
} }
@ -106,13 +106,13 @@ static int STACK_ARGS compareteams (const void *arg1, const void *arg2)
player_t *p2 = *(player_t **)arg2; player_t *p2 = *(player_t **)arg2;
int diff; int diff;
diff = p1->userinfo.team - p2->userinfo.team; diff = p1->userinfo.GetTeam() - p2->userinfo.GetTeam();
if (diff == 0) if (diff == 0)
{ {
diff = p2->fragcount - p1->fragcount; diff = p2->fragcount - p1->fragcount;
if (diff == 0) if (diff == 0)
{ {
diff = stricmp (p1->userinfo.netname, p2->userinfo.netname); diff = stricmp (p1->userinfo.GetName(), p2->userinfo.GetName());
} }
} }
return diff; return diff;
@ -189,7 +189,7 @@ void HU_GetPlayerWidths(int &maxnamewidth, int &maxscorewidth, int &maxiconheigh
{ {
if (playeringame[i]) if (playeringame[i])
{ {
int width = SmallFont->StringWidth(players[i].userinfo.netname); int width = SmallFont->StringWidth(players[i].userinfo.GetName());
if (width > maxnamewidth) if (width > maxnamewidth)
{ {
maxnamewidth = width; maxnamewidth = width;
@ -268,14 +268,14 @@ static void HU_DoDrawScores (player_t *player, player_t *sortedplayers[MAXPLAYER
for (i = 0; i < MAXPLAYERS; ++i) for (i = 0; i < MAXPLAYERS; ++i)
{ {
if (playeringame[sortedplayers[i]-players] && TeamLibrary.IsValidTeam (sortedplayers[i]->userinfo.team)) if (playeringame[sortedplayers[i]-players] && TeamLibrary.IsValidTeam (sortedplayers[i]->userinfo.GetTeam()))
{ {
if (Teams[sortedplayers[i]->userinfo.team].m_iPlayerCount++ == 0) if (Teams[sortedplayers[i]->userinfo.GetTeam()].m_iPlayerCount++ == 0)
{ {
numTeams++; numTeams++;
} }
Teams[sortedplayers[i]->userinfo.team].m_iScore += sortedplayers[i]->fragcount; Teams[sortedplayers[i]->userinfo.GetTeam()].m_iScore += sortedplayers[i]->fragcount;
} }
} }
@ -413,12 +413,12 @@ static void HU_DrawPlayer (player_t *player, bool highlight, int col1, int col2,
TAG_DONE); TAG_DONE);
} }
screen->DrawText (SmallFont, color, col4, y + ypadding, player->userinfo.netname, screen->DrawText (SmallFont, color, col4, y + ypadding, player->userinfo.GetName(),
DTA_CleanNoMove, true, TAG_DONE); DTA_CleanNoMove, true, TAG_DONE);
if (teamplay && Teams[player->userinfo.team].GetLogo ().IsNotEmpty ()) if (teamplay && Teams[player->userinfo.GetTeam()].GetLogo().IsNotEmpty ())
{ {
FTexture *pic = TexMan[Teams[player->userinfo.team].GetLogo ().GetChars ()]; FTexture *pic = TexMan[Teams[player->userinfo.GetTeam()].GetLogo().GetChars ()];
screen->DrawTexture (pic, col1 - (pic->GetScaledWidth() + 2) * CleanXfac, y, screen->DrawTexture (pic, col1 - (pic->GetScaledWidth() + 2) * CleanXfac, y,
DTA_CleanNoMove, true, TAG_DONE); DTA_CleanNoMove, true, TAG_DONE);
} }
@ -453,8 +453,8 @@ int HU_GetRowColor(player_t *player, bool highlight)
{ {
if (teamplay && deathmatch) if (teamplay && deathmatch)
{ {
if (TeamLibrary.IsValidTeam (player->userinfo.team)) if (TeamLibrary.IsValidTeam (player->userinfo.GetTeam()))
return Teams[player->userinfo.team].GetTextColor(); return Teams[player->userinfo.GetTeam()].GetTextColor();
else else
return CR_GREY; return CR_GREY;
} }

View file

@ -272,12 +272,12 @@ void PacketGet (void)
if (StartScreen != NULL) if (StartScreen != NULL)
{ {
StartScreen->NetMessage ("The connection from %s was dropped.\n", StartScreen->NetMessage ("The connection from %s was dropped.\n",
players[sendplayer[node]].userinfo.netname); players[sendplayer[node]].userinfo.GetName());
} }
else else
{ {
Printf("The connection from %s was dropped.\n", Printf("The connection from %s was dropped.\n",
players[sendplayer[node]].userinfo.netname); players[sendplayer[node]].userinfo.GetName());
} }
doomcom.data[0] = 0x80; // NCMD_EXIT doomcom.data[0] = 0x80; // NCMD_EXIT

View file

@ -602,7 +602,7 @@ void DIntermissionScreenCast::Drawer ()
{ {
if (PlayerClasses[i].Type == mClass) if (PlayerClasses[i].Type == mClass)
{ {
castsprite = skins[players[consoleplayer].userinfo.skin].sprite; castsprite = skins[players[consoleplayer].userinfo.GetSkin()].sprite;
} }
} }
} }

View file

@ -522,7 +522,7 @@ void cht_DoCheat (player_t *player, int cheat)
if (player == &players[consoleplayer]) if (player == &players[consoleplayer])
Printf ("%s\n", msg); Printf ("%s\n", msg);
else if (cheat != CHT_CHASECAM) else if (cheat != CHT_CHASECAM)
Printf ("%s cheats: %s\n", player->userinfo.netname, msg); Printf ("%s cheats: %s\n", player->userinfo.GetName(), msg);
} }
const char *cht_Morph (player_t *player, const PClass *morphclass, bool quickundo) const char *cht_Morph (player_t *player, const PClass *morphclass, bool quickundo)
@ -603,7 +603,7 @@ void cht_Give (player_t *player, const char *name, int amount)
const PClass *type; const PClass *type;
if (player != &players[consoleplayer]) if (player != &players[consoleplayer])
Printf ("%s is a cheater: give %s\n", player->userinfo.netname, name); Printf ("%s is a cheater: give %s\n", player->userinfo.GetName(), name);
if (player->mo == NULL || player->health <= 0) if (player->mo == NULL || player->health <= 0)
{ {

View file

@ -406,9 +406,9 @@ void FListMenuItemPlayerDisplay::UpdateRandomClass()
void FListMenuItemPlayerDisplay::UpdateTranslation() void FListMenuItemPlayerDisplay::UpdateTranslation()
{ {
int PlayerColor = players[consoleplayer].userinfo.color; int PlayerColor = players[consoleplayer].userinfo.GetColor();
int PlayerSkin = players[consoleplayer].userinfo.skin; int PlayerSkin = players[consoleplayer].userinfo.GetSkin();
int PlayerColorset = players[consoleplayer].userinfo.colorset; int PlayerColorset = players[consoleplayer].userinfo.GetColorSet();
if (mPlayerClass != NULL) if (mPlayerClass != NULL)
{ {

View file

@ -545,11 +545,11 @@ void DPlayerMenu::Init(DMenu *parent, FListMenuDescriptor *desc)
li->SetValue(FListMenuItemPlayerDisplay::PDF_ROTATION, 0); li->SetValue(FListMenuItemPlayerDisplay::PDF_ROTATION, 0);
li->SetValue(FListMenuItemPlayerDisplay::PDF_MODE, 1); li->SetValue(FListMenuItemPlayerDisplay::PDF_MODE, 1);
li->SetValue(FListMenuItemPlayerDisplay::PDF_TRANSLATE, 1); li->SetValue(FListMenuItemPlayerDisplay::PDF_TRANSLATE, 1);
li->SetValue(FListMenuItemPlayerDisplay::PDF_CLASS, players[consoleplayer].userinfo.PlayerClass); li->SetValue(FListMenuItemPlayerDisplay::PDF_CLASS, players[consoleplayer].userinfo.GetPlayerClassNum());
if (PlayerClass != NULL && !(GetDefaultByType (PlayerClass->Type)->flags4 & MF4_NOSKIN) && if (PlayerClass != NULL && !(GetDefaultByType (PlayerClass->Type)->flags4 & MF4_NOSKIN) &&
players[consoleplayer].userinfo.PlayerClass != -1) players[consoleplayer].userinfo.GetPlayerClassNum() != -1)
{ {
li->SetValue(FListMenuItemPlayerDisplay::PDF_SKIN, players[consoleplayer].userinfo.skin); li->SetValue(FListMenuItemPlayerDisplay::PDF_SKIN, players[consoleplayer].userinfo.GetSkin());
} }
} }
@ -570,8 +570,8 @@ void DPlayerMenu::Init(DMenu *parent, FListMenuDescriptor *desc)
li->SetValue(0, team == TEAM_NONE? 0 : team + 1); li->SetValue(0, team == TEAM_NONE? 0 : team + 1);
} }
int mycolorset = players[consoleplayer].userinfo.colorset; int mycolorset = players[consoleplayer].userinfo.GetColorSet();
int color = players[consoleplayer].userinfo.color; int color = players[consoleplayer].userinfo.GetColor();
UpdateColorsets(); UpdateColorsets();
@ -614,7 +614,7 @@ void DPlayerMenu::Init(DMenu *parent, FListMenuDescriptor *desc)
const char *cls = GetPrintableDisplayName(PlayerClasses[i].Type); const char *cls = GetPrintableDisplayName(PlayerClasses[i].Type);
li->SetString(gameinfo.norandomplayerclass ? i : i+1, cls); li->SetString(gameinfo.norandomplayerclass ? i : i+1, cls);
} }
int pclass = players[consoleplayer].userinfo.PlayerClass; int pclass = players[consoleplayer].userinfo.GetPlayerClassNum();
li->SetValue(0, gameinfo.norandomplayerclass && pclass >= 0 ? pclass : pclass + 1); li->SetValue(0, gameinfo.norandomplayerclass && pclass >= 0 ? pclass : pclass + 1);
} }
} }
@ -624,7 +624,7 @@ void DPlayerMenu::Init(DMenu *parent, FListMenuDescriptor *desc)
li = GetItem(NAME_Gender); li = GetItem(NAME_Gender);
if (li != NULL) if (li != NULL)
{ {
li->SetValue(0, players[consoleplayer].userinfo.gender); li->SetValue(0, players[consoleplayer].userinfo.GetGender());
} }
li = GetItem(NAME_Autoaim); li = GetItem(NAME_Autoaim);
@ -686,9 +686,9 @@ bool DPlayerMenu::Responder (event_t *ev)
void DPlayerMenu::UpdateTranslation() void DPlayerMenu::UpdateTranslation()
{ {
int PlayerColor = players[consoleplayer].userinfo.color; int PlayerColor = players[consoleplayer].userinfo.GetColor();
int PlayerSkin = players[consoleplayer].userinfo.skin; int PlayerSkin = players[consoleplayer].userinfo.GetSkin();
int PlayerColorset = players[consoleplayer].userinfo.colorset; int PlayerColorset = players[consoleplayer].userinfo.GetColorSet();
if (PlayerClass != NULL) if (PlayerClass != NULL)
{ {
@ -722,7 +722,7 @@ void DPlayerMenu::PickPlayerClass()
// [GRB] Pick a class from player class list // [GRB] Pick a class from player class list
if (PlayerClasses.Size () > 1) if (PlayerClasses.Size () > 1)
{ {
pclass = players[consoleplayer].userinfo.PlayerClass; pclass = players[consoleplayer].userinfo.GetPlayerClassNum();
if (pclass < 0) if (pclass < 0)
{ {
@ -745,7 +745,7 @@ void DPlayerMenu::SendNewColor (int red, int green, int blue)
{ {
char command[24]; char command[24];
players[consoleplayer].userinfo.color = MAKERGB(red, green, blue); players[consoleplayer].userinfo.ColorChanged(MAKERGB(red,green,blue));
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);
UpdateTranslation(); UpdateTranslation();
@ -770,7 +770,7 @@ void DPlayerMenu::UpdateColorsets()
FPlayerColorSet *colorset = P_GetPlayerColorSet(PlayerClass->Type->TypeName, PlayerColorSets[i]); FPlayerColorSet *colorset = P_GetPlayerColorSet(PlayerClass->Type->TypeName, PlayerColorSets[i]);
li->SetString(i+1, colorset->Name); li->SetString(i+1, colorset->Name);
} }
int mycolorset = players[consoleplayer].userinfo.colorset; int mycolorset = players[consoleplayer].userinfo.GetColorSet();
if (mycolorset != -1) if (mycolorset != -1)
{ {
for(unsigned i=0;i<PlayerColorSets.Size(); i++) for(unsigned i=0;i<PlayerColorSets.Size(); i++)
@ -799,7 +799,7 @@ void DPlayerMenu::UpdateSkins()
if (li != NULL) if (li != NULL)
{ {
if (GetDefaultByType (PlayerClass->Type)->flags4 & MF4_NOSKIN || if (GetDefaultByType (PlayerClass->Type)->flags4 & MF4_NOSKIN ||
players[consoleplayer].userinfo.PlayerClass == -1) players[consoleplayer].userinfo.GetPlayerClassNum() == -1)
{ {
li->SetString(0, "Base"); li->SetString(0, "Base");
li->SetValue(0, 0); li->SetValue(0, 0);
@ -814,7 +814,7 @@ void DPlayerMenu::UpdateSkins()
{ {
int j = PlayerSkins.Push(i); int j = PlayerSkins.Push(i);
li->SetString(j, skins[i].name); li->SetString(j, skins[i].name);
if (players[consoleplayer].userinfo.skin == i) if (players[consoleplayer].userinfo.GetSkin() == i)
{ {
sel = j; sel = j;
} }
@ -886,7 +886,7 @@ void DPlayerMenu::ColorSetChanged (FListMenuItem *li)
if (blue != NULL) blue->Enable(mycolorset == -1); if (blue != NULL) blue->Enable(mycolorset == -1);
char command[24]; char command[24];
players[consoleplayer].userinfo.colorset = mycolorset; players[consoleplayer].userinfo.ColorSetChanged(mycolorset);
mysnprintf(command, countof(command), "colorset %d", mycolorset); mysnprintf(command, countof(command), "colorset %d", mycolorset);
C_DoCommand(command); C_DoCommand(command);
UpdateTranslation(); UpdateTranslation();
@ -910,7 +910,7 @@ void DPlayerMenu::ClassChanged (FListMenuItem *li)
if (li->GetValue(0, &sel)) if (li->GetValue(0, &sel))
{ {
players[consoleplayer].userinfo.PlayerClass = gameinfo.norandomplayerclass ? sel : sel-1; players[consoleplayer].userinfo.PlayerClassNumChanged(gameinfo.norandomplayerclass ? sel : sel-1);
PickPlayerClass(); PickPlayerClass();
cvar_set ("playerclass", sel == 0 && !gameinfo.norandomplayerclass ? "Random" : PlayerClass->Type->Meta.GetMetaString (APMETA_DisplayName)); cvar_set ("playerclass", sel == 0 && !gameinfo.norandomplayerclass ? "Random" : PlayerClass->Type->Meta.GetMetaString (APMETA_DisplayName));
@ -922,7 +922,7 @@ void DPlayerMenu::ClassChanged (FListMenuItem *li)
li = GetItem(NAME_Playerdisplay); li = GetItem(NAME_Playerdisplay);
if (li != NULL) if (li != NULL)
{ {
li->SetValue(FListMenuItemPlayerDisplay::PDF_CLASS, players[consoleplayer].userinfo.PlayerClass); li->SetValue(FListMenuItemPlayerDisplay::PDF_CLASS, players[consoleplayer].userinfo.GetPlayerClassNum());
} }
} }
} }
@ -936,7 +936,7 @@ void DPlayerMenu::ClassChanged (FListMenuItem *li)
void DPlayerMenu::SkinChanged (FListMenuItem *li) void DPlayerMenu::SkinChanged (FListMenuItem *li)
{ {
if (GetDefaultByType (PlayerClass->Type)->flags4 & MF4_NOSKIN || if (GetDefaultByType (PlayerClass->Type)->flags4 & MF4_NOSKIN ||
players[consoleplayer].userinfo.PlayerClass == -1) players[consoleplayer].userinfo.GetPlayerClassNum() == -1)
{ {
return; return;
} }
@ -946,7 +946,7 @@ void DPlayerMenu::SkinChanged (FListMenuItem *li)
if (li->GetValue(0, &sel)) if (li->GetValue(0, &sel))
{ {
sel = PlayerSkins[sel]; sel = PlayerSkins[sel];
players[consoleplayer].userinfo.skin = sel; players[consoleplayer].userinfo.SkinNumChanged(sel);
UpdateTranslation(); UpdateTranslation();
cvar_set ("skin", skins[sel].name); cvar_set ("skin", skins[sel].name);
@ -1013,7 +1013,7 @@ bool DPlayerMenu::MenuEvent (int mkey, bool fromcontroller)
case NAME_Red: case NAME_Red:
if (li->GetValue(0, &v)) if (li->GetValue(0, &v))
{ {
int color = players[consoleplayer].userinfo.color; uint32 color = players[consoleplayer].userinfo.GetColor();
SendNewColor (v, GPART(color), BPART(color)); SendNewColor (v, GPART(color), BPART(color));
} }
break; break;
@ -1021,7 +1021,7 @@ bool DPlayerMenu::MenuEvent (int mkey, bool fromcontroller)
case NAME_Green: case NAME_Green:
if (li->GetValue(0, &v)) if (li->GetValue(0, &v))
{ {
int color = players[consoleplayer].userinfo.color; uint32 color = players[consoleplayer].userinfo.GetColor();
SendNewColor (RPART(color), v, BPART(color)); SendNewColor (RPART(color), v, BPART(color));
} }
break; break;
@ -1029,7 +1029,7 @@ bool DPlayerMenu::MenuEvent (int mkey, bool fromcontroller)
case NAME_Blue: case NAME_Blue:
if (li->GetValue(0, &v)) if (li->GetValue(0, &v))
{ {
int color = players[consoleplayer].userinfo.color; uint32 color = players[consoleplayer].userinfo.GetColor();
SendNewColor (RPART(color), GPART(color), v); SendNewColor (RPART(color), GPART(color), v);
} }
break; break;
@ -1092,7 +1092,7 @@ bool DPlayerMenu::MouseEvent(int type, int x, int y)
case NAME_Red: case NAME_Red:
if (li->GetValue(0, &v)) if (li->GetValue(0, &v))
{ {
int color = players[consoleplayer].userinfo.color; uint32 color = players[consoleplayer].userinfo.GetColor();
SendNewColor (v, GPART(color), BPART(color)); SendNewColor (v, GPART(color), BPART(color));
} }
break; break;
@ -1100,7 +1100,7 @@ bool DPlayerMenu::MouseEvent(int type, int x, int y)
case NAME_Green: case NAME_Green:
if (li->GetValue(0, &v)) if (li->GetValue(0, &v))
{ {
int color = players[consoleplayer].userinfo.color; uint32 color = players[consoleplayer].userinfo.GetColor();
SendNewColor (RPART(color), v, BPART(color)); SendNewColor (RPART(color), v, BPART(color));
} }
break; break;
@ -1108,7 +1108,7 @@ bool DPlayerMenu::MouseEvent(int type, int x, int y)
case NAME_Blue: case NAME_Blue:
if (li->GetValue(0, &v)) if (li->GetValue(0, &v))
{ {
int color = players[consoleplayer].userinfo.color; uint32 color = players[consoleplayer].userinfo.GetColor();
SendNewColor (RPART(color), GPART(color), v); SendNewColor (RPART(color), GPART(color), v);
} }
break; break;

View file

@ -559,3 +559,11 @@ xx(Inter_Strife_Lose)
xx(Inter_Strife_MAP03) xx(Inter_Strife_MAP03)
xx(Inter_Strife_MAP10) xx(Inter_Strife_MAP10)
xx(Multiplayer) xx(Multiplayer)
// more stuff
xx(ColorSet)
xx(NeverSwitchOnPickup)
xx(MoveBob)
xx(StillBob)
xx(PlayerClass)
xx(AutoAim)

View file

@ -5594,7 +5594,7 @@ scriptwait:
} }
if (player) if (player)
{ {
work += player->userinfo.netname; work += player->userinfo.GetName();
} }
else if (activator) else if (activator)
{ {
@ -7078,14 +7078,14 @@ scriptwait:
userinfo_t *userinfo = &pl->userinfo; userinfo_t *userinfo = &pl->userinfo;
switch (STACK(1)) switch (STACK(1))
{ {
case PLAYERINFO_TEAM: STACK(2) = userinfo->team; break; case PLAYERINFO_TEAM: STACK(2) = userinfo->GetTeam(); break;
case PLAYERINFO_AIMDIST: STACK(2) = userinfo->GetAimDist(); break; case PLAYERINFO_AIMDIST: STACK(2) = userinfo->GetAimDist(); break;
case PLAYERINFO_COLOR: STACK(2) = userinfo->color; break; case PLAYERINFO_COLOR: STACK(2) = userinfo->GetColor(); break;
case PLAYERINFO_GENDER: STACK(2) = userinfo->gender; break; case PLAYERINFO_GENDER: STACK(2) = userinfo->GetGender(); break;
case PLAYERINFO_NEVERSWITCH: STACK(2) = userinfo->neverswitch; break; case PLAYERINFO_NEVERSWITCH: STACK(2) = userinfo->GetNeverSwitch(); break;
case PLAYERINFO_MOVEBOB: STACK(2) = userinfo->MoveBob; break; case PLAYERINFO_MOVEBOB: STACK(2) = userinfo->GetMoveBob(); break;
case PLAYERINFO_STILLBOB: STACK(2) = userinfo->StillBob; break; case PLAYERINFO_STILLBOB: STACK(2) = userinfo->GetStillBob(); break;
case PLAYERINFO_PLAYERCLASS: STACK(2) = userinfo->PlayerClass; break; case PLAYERINFO_PLAYERCLASS: STACK(2) = userinfo->GetPlayerClassNum(); break;
case PLAYERINFO_DESIREDFOV: STACK(2) = (int)pl->DesiredFOV; break; case PLAYERINFO_DESIREDFOV: STACK(2) = (int)pl->DesiredFOV; break;
case PLAYERINFO_FOV: STACK(2) = (int)pl->FOV; break; case PLAYERINFO_FOV: STACK(2) = (int)pl->FOV; break;
default: STACK(2) = 0; break; default: STACK(2) = 0; break;
@ -7583,7 +7583,7 @@ int P_StartScript (AActor *who, line_t *where, int script, const char *map, cons
if (!(scriptdata->Flags & SCRIPTF_Net)) if (!(scriptdata->Flags & SCRIPTF_Net))
{ {
Printf(PRINT_BOLD, "%s tried to puke %s (\n", Printf(PRINT_BOLD, "%s tried to puke %s (\n",
who->player->userinfo.netname, ScriptPresentation(script).GetChars()); who->player->userinfo.GetName(), ScriptPresentation(script).GetChars());
for (int i = 0; i < argcount; ++i) for (int i = 0; i < argcount; ++i)
{ {
Printf(PRINT_BOLD, "%d%s", args[i], i == argcount-1 ? "" : ", "); Printf(PRINT_BOLD, "%d%s", args[i], i == argcount-1 ? "" : ", ");

View file

@ -192,7 +192,7 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf
if (self->player == NULL || self->player->mo != self || !show_obituaries) if (self->player == NULL || self->player->mo != self || !show_obituaries)
return; return;
gender = self->player->userinfo.gender; gender = self->player->userinfo.GetGender();
// Treat voodoo dolls as unknown deaths // Treat voodoo dolls as unknown deaths
if (inflictor && inflictor->player && inflictor->player->mo != inflictor) if (inflictor && inflictor->player && inflictor->player->mo != inflictor)
@ -274,7 +274,7 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf
attacker->player->fragcount -= 2; attacker->player->fragcount -= 2;
attacker->player->frags[attacker->player - players]++; attacker->player->frags[attacker->player - players]++;
self = attacker; self = attacker;
gender = self->player->userinfo.gender; gender = self->player->userinfo.GetGender();
mysnprintf (gendermessage, countof(gendermessage), "OB_FRIENDLY%c", '1' + (pr_obituary() & 3)); mysnprintf (gendermessage, countof(gendermessage), "OB_FRIENDLY%c", '1' + (pr_obituary() & 3));
message = GStrings(gendermessage); message = GStrings(gendermessage);
} }
@ -321,7 +321,7 @@ void ClientObituary (AActor *self, AActor *inflictor, AActor *attacker, int dmgf
} }
SexMessage (message, gendermessage, gender, SexMessage (message, gendermessage, gender,
self->player->userinfo.netname, attacker->player->userinfo.netname); self->player->userinfo.GetName(), attacker->player->userinfo.GetName());
Printf (PRINT_MEDIUM, "%s\n", gendermessage); Printf (PRINT_MEDIUM, "%s\n", gendermessage);
} }
@ -457,8 +457,8 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
if (deathmatch && player->spreecount >= 5 && cl_showsprees) if (deathmatch && player->spreecount >= 5 && cl_showsprees)
{ {
SexMessage (GStrings("SPREEKILLSELF"), buff, SexMessage (GStrings("SPREEKILLSELF"), buff,
player->userinfo.gender, player->userinfo.netname, player->userinfo.GetGender(), player->userinfo.GetName(),
player->userinfo.netname); player->userinfo.GetName());
StatusBar->AttachMessage (new DHUDMessageFadeOut (SmallFont, buff, StatusBar->AttachMessage (new DHUDMessageFadeOut (SmallFont, buff,
1.5f, 0.2f, 0, 0, CR_WHITE, 3.f, 0.5f), MAKE_ID('K','S','P','R')); 1.5f, 0.2f, 0, 0, CR_WHITE, 3.f, 0.5f), MAKE_ID('K','S','P','R'));
} }
@ -505,8 +505,8 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
{ {
if (!AnnounceSpreeLoss (this)) if (!AnnounceSpreeLoss (this))
{ {
SexMessage (GStrings("SPREEOVER"), buff, player->userinfo.gender, SexMessage (GStrings("SPREEOVER"), buff, player->userinfo.GetGender(),
player->userinfo.netname, source->player->userinfo.netname); player->userinfo.GetName(), source->player->userinfo.GetName());
StatusBar->AttachMessage (new DHUDMessageFadeOut (SmallFont, buff, StatusBar->AttachMessage (new DHUDMessageFadeOut (SmallFont, buff,
1.5f, 0.2f, 0, 0, CR_WHITE, 3.f, 0.5f), MAKE_ID('K','S','P','R')); 1.5f, 0.2f, 0, 0, CR_WHITE, 3.f, 0.5f), MAKE_ID('K','S','P','R'));
} }
@ -515,8 +515,8 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
{ {
if (!AnnounceSpree (source)) if (!AnnounceSpree (source))
{ {
SexMessage (spreemsg, buff, player->userinfo.gender, SexMessage (spreemsg, buff, player->userinfo.GetGender(),
player->userinfo.netname, source->player->userinfo.netname); player->userinfo.GetName(), source->player->userinfo.GetName());
StatusBar->AttachMessage (new DHUDMessageFadeOut (SmallFont, buff, StatusBar->AttachMessage (new DHUDMessageFadeOut (SmallFont, buff,
1.5f, 0.2f, 0, 0, CR_WHITE, 3.f, 0.5f), MAKE_ID('K','S','P','R')); 1.5f, 0.2f, 0, 0, CR_WHITE, 3.f, 0.5f), MAKE_ID('K','S','P','R'));
} }
@ -565,8 +565,8 @@ void AActor::Die (AActor *source, AActor *inflictor, int dmgflags)
if (!AnnounceMultikill (source)) if (!AnnounceMultikill (source))
{ {
SexMessage (multimsg, buff, player->userinfo.gender, SexMessage (multimsg, buff, player->userinfo.GetGender(),
player->userinfo.netname, source->player->userinfo.netname); player->userinfo.GetName(), source->player->userinfo.GetName());
StatusBar->AttachMessage (new DHUDMessageFadeOut (SmallFont, buff, StatusBar->AttachMessage (new DHUDMessageFadeOut (SmallFont, buff,
1.5f, 0.8f, 0, 0, CR_RED, 3.f, 0.5f), MAKE_ID('M','K','I','L')); 1.5f, 0.8f, 0, 0, CR_RED, 3.f, 0.5f), MAKE_ID('M','K','I','L'));
} }

View file

@ -3384,7 +3384,7 @@ fixed_t P_AimLineAttack (AActor *t1, angle_t angle, fixed_t distance, AActor **p
// vrange of 0 degrees, because then toppitch and bottompitch will // vrange of 0 degrees, because then toppitch and bottompitch will
// be equal, and PTR_AimTraverse will never find anything to shoot at // be equal, and PTR_AimTraverse will never find anything to shoot at
// if it crosses a line. // if it crosses a line.
vrange = clamp (t1->player->userinfo.aimdist, ANGLE_1/2, ANGLE_1*35); vrange = clamp (t1->player->userinfo.GetAimDist(), ANGLE_1/2, ANGLE_1*35);
} }
} }
} }

View file

@ -327,7 +327,7 @@ void AActor::Serialize (FArchive &arc)
!(flags4 & MF4_NOSKIN) && !(flags4 & MF4_NOSKIN) &&
state->sprite == GetDefaultByType (player->cls)->SpawnState->sprite) state->sprite == GetDefaultByType (player->cls)->SpawnState->sprite)
{ // Give player back the skin { // Give player back the skin
sprite = skins[player->userinfo.skin].sprite; sprite = skins[player->userinfo.GetSkin()].sprite;
} }
if (Speed == 0) if (Speed == 0)
{ {
@ -462,7 +462,7 @@ bool AActor::SetState (FState *newstate, bool nofunction)
// spawning. // spawning.
if (player != NULL && skins != NULL) if (player != NULL && skins != NULL)
{ {
sprite = skins[player->userinfo.skin].sprite; sprite = skins[player->userinfo.GetSkin()].sprite;
} }
else if (newsprite != prevsprite) else if (newsprite != prevsprite)
{ {
@ -910,8 +910,8 @@ bool AActor::IsVisibleToPlayer() const
if ( players[consoleplayer].camera == NULL ) if ( players[consoleplayer].camera == NULL )
return true; return true;
if ( VisibleToTeam != 0 && teamplay && if (VisibleToTeam != 0 && teamplay &&
VisibleToTeam-1 != players[consoleplayer].userinfo.team ) VisibleToTeam-1 != players[consoleplayer].userinfo.GetTeam())
return false; return false;
const player_t* pPlayer = players[consoleplayer].camera->player; const player_t* pPlayer = players[consoleplayer].camera->player;
@ -4185,7 +4185,7 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
} }
else else
{ {
type = p->userinfo.PlayerClass; type = p->userinfo.GetPlayerClassNum();
if (type < 0) if (type < 0)
{ {
type = pr_multiclasschoice() % PlayerClasses.Size (); type = pr_multiclasschoice() % PlayerClasses.Size ();
@ -4267,8 +4267,7 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
} }
// [GRB] Reset skin // [GRB] Reset skin
p->userinfo.skin = R_FindSkin (skins[p->userinfo.skin].name, p->CurrentPlayerClass); p->userinfo.SkinNumChanged(R_FindSkin (skins[p->userinfo.GetSkin()].name, p->CurrentPlayerClass));
if (!(mobj->flags2 & MF2_DONTTRANSLATE)) if (!(mobj->flags2 & MF2_DONTTRANSLATE))
{ {
@ -4289,7 +4288,7 @@ APlayerPawn *P_SpawnPlayer (FPlayerStart *mthing, int playernum, int flags)
// [RH] Set player sprite based on skin // [RH] Set player sprite based on skin
if (!(mobj->flags4 & MF4_NOSKIN)) if (!(mobj->flags4 & MF4_NOSKIN))
{ {
mobj->sprite = skins[p->userinfo.skin].sprite; mobj->sprite = skins[p->userinfo.GetSkin()].sprite;
} }
p->DesiredFOV = p->FOV = 90.f; p->DesiredFOV = p->FOV = 90.f;
@ -5736,11 +5735,10 @@ bool AActor::IsTeammate (AActor *other)
int myTeam = DesignatedTeam; int myTeam = DesignatedTeam;
int otherTeam = other->DesignatedTeam; int otherTeam = other->DesignatedTeam;
if (player) if (player)
myTeam = player->userinfo.team; myTeam = player->userinfo.GetTeam();
if (other->player) if (other->player)
otherTeam = other->player->userinfo.team; otherTeam = other->player->userinfo.GetTeam();
if (teamplay && myTeam != TEAM_NONE && if (teamplay && myTeam != TEAM_NONE && myTeam == otherTeam)
myTeam == otherTeam)
{ {
return true; return true;
} }

View file

@ -91,7 +91,7 @@ void P_SerializePlayers (FArchive &arc, bool skipload)
{ {
if (playeringame[i]) if (playeringame[i])
{ {
arc.WriteString (players[i].userinfo.netname); arc.WriteString (players[i].userinfo.GetName());
players[i].Serialize (arc); players[i].Serialize (arc);
} }
} }
@ -185,7 +185,7 @@ static void ReadMultiplePlayers (FArchive &arc, int numPlayers, int numPlayersNo
{ {
for (j = 0; j < MAXPLAYERS; ++j) for (j = 0; j < MAXPLAYERS; ++j)
{ {
if (playerUsed[j] == 0 && stricmp(players[j].userinfo.netname, nametemp[i]) == 0) if (playerUsed[j] == 0 && stricmp(players[j].userinfo.GetName(), nametemp[i]) == 0)
{ // Found a match, so copy our temp player to the real player { // Found a match, so copy our temp player to the real player
Printf ("Found player %d (%s) at %d\n", i, nametemp[i], j); Printf ("Found player %d (%s) at %d\n", i, nametemp[i], j);
CopyPlayer (&players[j], &playertemp[i], nametemp[i]); CopyPlayer (&players[j], &playertemp[i], nametemp[i]);
@ -206,7 +206,7 @@ static void ReadMultiplePlayers (FArchive &arc, int numPlayers, int numPlayersNo
{ {
if (playerUsed[j] == 0) if (playerUsed[j] == 0)
{ {
Printf ("Assigned player %d (%s) to %d (%s)\n", i, nametemp[i], j, players[j].userinfo.netname); Printf ("Assigned player %d (%s) to %d (%s)\n", i, nametemp[i], j, players[j].userinfo.GetName());
CopyPlayer (&players[j], &playertemp[i], nametemp[i]); CopyPlayer (&players[j], &playertemp[i], nametemp[i]);
playerUsed[j] = 1; playerUsed[j] = 1;
tempPlayerUsed[i] = 1; tempPlayerUsed[i] = 1;
@ -282,7 +282,7 @@ static void CopyPlayer (player_t *dst, player_t *src, const char *name)
dst->userinfo = uibackup; dst->userinfo = uibackup;
} }
// Validate the skin // Validate the skin
dst->userinfo.skin = R_FindSkin(skins[dst->userinfo.skin].name, dst->CurrentPlayerClass); dst->userinfo.SkinNumChanged(R_FindSkin(skins[dst->userinfo.GetSkin()].name, dst->CurrentPlayerClass));
// Make sure the player pawn points to the proper player struct. // Make sure the player pawn points to the proper player struct.
if (dst->mo != NULL) if (dst->mo != NULL)

View file

@ -177,7 +177,7 @@ bool CheckIfExitIsGood (AActor *self, level_info_t *info)
} }
if (deathmatch) if (deathmatch)
{ {
Printf ("%s exited the level.\n", self->player->userinfo.netname); Printf ("%s exited the level.\n", self->player->userinfo.GetName());
} }
return true; return true;
} }

View file

@ -819,7 +819,7 @@ AWeapon *APlayerPawn::PickNewWeapon (const PClass *ammotype)
void APlayerPawn::CheckWeaponSwitch(const PClass *ammotype) void APlayerPawn::CheckWeaponSwitch(const PClass *ammotype)
{ {
if (!player->userinfo.neverswitch && if (!player->userinfo.GetNeverSwitch() &&
player->PendingWeapon == WP_NOCHANGE && player->PendingWeapon == WP_NOCHANGE &&
(player->ReadyWeapon == NULL || (player->ReadyWeapon == NULL ||
(player->ReadyWeapon->WeaponFlags & WIF_WIMPY_WEAPON))) (player->ReadyWeapon->WeaponFlags & WIF_WIMPY_WEAPON)))
@ -991,10 +991,10 @@ const char *APlayerPawn::GetSoundClass() const
{ {
if (player != NULL && if (player != NULL &&
(player->mo == NULL || !(player->mo->flags4 &MF4_NOSKIN)) && (player->mo == NULL || !(player->mo->flags4 &MF4_NOSKIN)) &&
(unsigned int)player->userinfo.skin >= PlayerClasses.Size () && (unsigned int)player->userinfo.GetSkin() >= PlayerClasses.Size () &&
(size_t)player->userinfo.skin < numskins) (size_t)player->userinfo.GetSkin() < numskins)
{ {
return skins[player->userinfo.skin].name; return skins[player->userinfo.GetSkin()].name;
} }
// [GRB] // [GRB]
@ -1500,13 +1500,13 @@ void P_CheckPlayerSprite(AActor *actor, int &spritenum, fixed_t &scalex, fixed_t
player_t *player = actor->player; player_t *player = actor->player;
int crouchspriteno; int crouchspriteno;
if (player->userinfo.skin != 0 && !(actor->flags4 & MF4_NOSKIN)) if (player->userinfo.GetSkin() != 0 && !(actor->flags4 & MF4_NOSKIN))
{ {
// Convert from default scale to skin scale. // Convert from default scale to skin scale.
fixed_t defscaleY = actor->GetDefault()->scaleY; fixed_t defscaleY = actor->GetDefault()->scaleY;
fixed_t defscaleX = actor->GetDefault()->scaleX; fixed_t defscaleX = actor->GetDefault()->scaleX;
scaley = Scale(scaley, skins[player->userinfo.skin].ScaleY, defscaleY); scaley = Scale(scaley, skins[player->userinfo.GetSkin()].ScaleY, defscaleY);
scalex = Scale(scalex, skins[player->userinfo.skin].ScaleX, defscaleX); scalex = Scale(scalex, skins[player->userinfo.GetSkin()].ScaleX, defscaleX);
} }
// Set the crouch sprite? // Set the crouch sprite?
@ -1517,10 +1517,10 @@ void P_CheckPlayerSprite(AActor *actor, int &spritenum, fixed_t &scalex, fixed_t
crouchspriteno = player->mo->crouchsprite; crouchspriteno = player->mo->crouchsprite;
} }
else if (!(actor->flags4 & MF4_NOSKIN) && else if (!(actor->flags4 & MF4_NOSKIN) &&
(spritenum == skins[player->userinfo.skin].sprite || (spritenum == skins[player->userinfo.GetSkin()].sprite ||
spritenum == skins[player->userinfo.skin].crouchsprite)) spritenum == skins[player->userinfo.GetSkin()].crouchsprite))
{ {
crouchspriteno = skins[player->userinfo.skin].crouchsprite; crouchspriteno = skins[player->userinfo.GetSkin()].crouchsprite;
} }
else else
{ // no sprite -> squash the existing one { // no sprite -> squash the existing one
@ -1644,7 +1644,7 @@ void P_CalcHeight (player_t *player)
} }
else else
{ {
player->bob = FixedMul (player->bob, player->userinfo.MoveBob); player->bob = FixedMul (player->bob, player->userinfo.GetMoveBob());
if (player->bob > MAXBOB) if (player->bob > MAXBOB)
player->bob = MAXBOB; player->bob = MAXBOB;
@ -1668,7 +1668,7 @@ void P_CalcHeight (player_t *player)
if (player->health > 0) if (player->health > 0)
{ {
angle = DivScale13 (level.time, 120*TICRATE/35) & FINEMASK; angle = DivScale13 (level.time, 120*TICRATE/35) & FINEMASK;
bob = FixedMul (player->userinfo.StillBob, finesine[angle]); bob = FixedMul (player->userinfo.GetStillBob(), finesine[angle]);
} }
else else
{ {

View file

@ -1101,7 +1101,7 @@ void R_BuildPlayerTranslation (int player)
D_GetPlayerColor (player, &h, &s, &v, &colorset); D_GetPlayerColor (player, &h, &s, &v, &colorset);
R_CreatePlayerTranslation (h, s, v, colorset, R_CreatePlayerTranslation (h, s, v, colorset,
&skins[players[player].userinfo.skin], &skins[players[player].userinfo.GetSkin()],
translationtables[TRANSLATION_Players][player], translationtables[TRANSLATION_Players][player],
translationtables[TRANSLATION_PlayersExtra][player]); translationtables[TRANSLATION_PlayersExtra][player]);
} }

View file

@ -1797,7 +1797,7 @@ int S_FindSkinnedSound (AActor *actor, FSoundID refid)
if (actor != NULL && actor->IsKindOf(RUNTIME_CLASS(APlayerPawn))) if (actor != NULL && actor->IsKindOf(RUNTIME_CLASS(APlayerPawn)))
{ {
pclass = static_cast<APlayerPawn*>(actor)->GetSoundClass (); pclass = static_cast<APlayerPawn*>(actor)->GetSoundClass ();
if (actor->player != NULL) gender = actor->player->userinfo.gender; if (actor->player != NULL) gender = actor->player->userinfo.GetGender();
} }
else else
{ {

View file

@ -468,6 +468,37 @@ public:
return *this; return *this;
} }
//=======================================================================
//
// TransferFrom
//
// Moves the contents from one TMap to another, leaving the TMap moved
// from empty.
//
//=======================================================================
void TransferFrom(TMap &o)
{
// Clear all our nodes.
NumUsed = 0;
ClearNodeVector();
// Copy all of o's nodes.
Nodes = o.Nodes;
LastFree = o.LastFree;
Size = o.Size;
NumUsed = o.NumUsed;
// Tell o it doesn't have any nodes.
o.Nodes = NULL;
o.Size = 0;
o.LastFree = NULL;
o.NumUsed = 0;
// Leave o functional with one empty node.
o.SetNodeVector(1);
}
//======================================================================= //=======================================================================
// //
// Clear // Clear

View file

@ -2877,7 +2877,7 @@ DEFINE_ACTION_FUNCTION_PARAMS(AActor, A_PlayerSkinCheck)
ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains! ACTION_SET_RESULT(false); // Jumps should never set the result for inventory state chains!
if (self->player != NULL && if (self->player != NULL &&
skins[self->player->userinfo.skin].othergame) skins[self->player->userinfo.GetSkin()].othergame)
{ {
ACTION_JUMP(jump); ACTION_JUMP(jump);
} }

View file

@ -1655,7 +1655,7 @@ void WI_drawNetgameStats ()
FTexture *pic = TexMan[player->mo->ScoreIcon]; FTexture *pic = TexMan[player->mo->ScoreIcon];
screen->DrawTexture(pic, icon_x, y, DTA_CleanNoMove, true, TAG_DONE); screen->DrawTexture(pic, icon_x, y, DTA_CleanNoMove, true, TAG_DONE);
} }
screen->DrawText(SmallFont, color, name_x, y + ypadding, player->userinfo.netname, DTA_CleanNoMove, true, TAG_DONE); screen->DrawText(SmallFont, color, name_x, y + ypadding, player->userinfo.GetName(), DTA_CleanNoMove, true, TAG_DONE);
WI_drawPercent(SmallFont, kills_x, y + ypadding, cnt_kills[i], wbs->maxkills, false, color); WI_drawPercent(SmallFont, kills_x, y + ypadding, cnt_kills[i], wbs->maxkills, false, color);
missed_kills -= cnt_kills[i]; missed_kills -= cnt_kills[i];
if (ng_state >= 4) if (ng_state >= 4)