void D_SetupUserInfo () { int i; userinfo_t *coninfo = &players[consoleplayer].userinfo; for (i = 0; i < MAXPLAYERS; i++) memset (&players[i].userinfo, 0, sizeof(userinfo_t)); strncpy (coninfo->netname, name, MAXPLAYERNAME); if (teamplay && !TeamLibrary.IsValidTeam (team)) { coninfo->team = D_PickRandomTeam (); } else { coninfo->team = team; } if (autoaim > 35.f || autoaim < 0.f) { coninfo->aimdist = ANGLE_1*35; } else { coninfo->aimdist = abs ((int)(autoaim * (float)ANGLE_1)); } coninfo->color = color; coninfo->skin = R_FindSkin (skin, 0); coninfo->gender = D_GenderToInt (gender); coninfo->neverswitch = neverswitchonpickup; coninfo->MoveBob = (fixed_t)(65536.f * movebob); coninfo->StillBob = (fixed_t)(65536.f * stillbob); coninfo->PlayerClass = D_PlayerClassToInt (playerclass); R_BuildPlayerTranslation (consoleplayer); }
DEFINE_ACTION_FUNCTION(_Translation, SetPlayerTranslation) { PARAM_PROLOGUE; PARAM_UINT(tgroup); PARAM_UINT(tnum); PARAM_UINT(pnum); PARAM_POINTER(cls, FPlayerClass); if (pnum >= MAXPLAYERS || tgroup >= NUM_TRANSLATION_TABLES || tnum >= translationtables[tgroup].Size()) { ACTION_RETURN_BOOL(false); } auto self = &players[pnum]; int PlayerColor = self->userinfo.GetColor(); int PlayerSkin = self->userinfo.GetSkin(); int PlayerColorset = self->userinfo.GetColorSet(); if (cls != nullptr) { PlayerSkin = R_FindSkin(Skins[PlayerSkin].Name, int(cls - &PlayerClasses[0])); R_GetPlayerTranslation(PlayerColor, GetColorSet(cls->Type, PlayerColorset), &Skins[PlayerSkin], translationtables[tgroup][tnum]); } ACTION_RETURN_BOOL(true); }
static void CopyPlayer (player_t *dst, player_t *src, const char *name) { // The userinfo needs to be saved for real players, but it // needs to come from the save for bots. userinfo_t uibackup; userinfo_t uibackup2; uibackup.TransferFrom(dst->userinfo); uibackup2.TransferFrom(src->userinfo); int chasecam = dst->cheats & CF_CHASECAM; // Remember the chasecam setting bool attackdown = dst->attackdown; bool usedown = dst->usedown; *dst = *src; // To avoid memory leaks at this point the userinfo in src must be empty which is taken care of by the TransferFrom call above. dst->cheats |= chasecam; if (dst->isbot) { botinfo_t *thebot = bglobal.botinfo; while (thebot && stricmp (name, thebot->name)) { thebot = thebot->next; } if (thebot) { thebot->inuse = true; } bglobal.botnum++; bglobal.botingame[dst - players] = true; dst->userinfo.TransferFrom(uibackup2); } else { dst->userinfo.TransferFrom(uibackup); } // Validate the skin dst->userinfo.SkinNumChanged(R_FindSkin(skins[dst->userinfo.GetSkin()].name, dst->CurrentPlayerClass)); // Make sure the player pawn points to the proper player struct. if (dst->mo != NULL) { dst->mo->player = dst; } // These 2 variables may not be overwritten. dst->attackdown = attackdown; dst->usedown = usedown; }
void D_SetupUserInfo(void) { userinfo_t *coninfo = &consoleplayer().userinfo; // Save the previous weapon preferences weapontype_t backup_weapon_prefs[NUMWEAPONS]; memcpy(backup_weapon_prefs, coninfo->weapon_prefs, sizeof(backup_weapon_prefs)); memset (&consoleplayer().userinfo, 0, sizeof(userinfo_t)); strncpy (coninfo->netname, cl_name.cstring(), MAXPLAYERNAME); coninfo->team = D_TeamByName (cl_team.cstring()); // [Toke - Teams] coninfo->color = V_GetColorFromString (NULL, cl_color.cstring()); coninfo->skin = R_FindSkin (cl_skin.cstring()); coninfo->gender = D_GenderByName (cl_gender.cstring()); coninfo->aimdist = (fixed_t)(cl_autoaim * 16384.0); coninfo->unlag = cl_unlag; coninfo->update_rate = cl_updaterate; coninfo->switchweapon = (weaponswitch_t)cl_switchweapon.asInt(); // Copies the updated cl_weaponpref* cvars to coninfo->weapon_prefs[] CL_PrepareWeaponPreferenceUserInfo(); // Find which weapon preference slot was changed for (size_t i = 0; i < NUMWEAPONS; i++) { if (backup_weapon_prefs[i] != coninfo->weapon_prefs[i]) { // slot i was changed weapontype_t oldweapon = backup_weapon_prefs[i]; weapontype_t newweapon = coninfo->weapon_prefs[i]; // swap the weapon in slot i with whatever slot already has newweapon for (size_t j = 0; j < NUMWEAPONS; j++) { if (coninfo->weapon_prefs[j] == newweapon && j != i) { coninfo->weapon_prefs[j] = oldweapon; CL_SetWeaponPreferenceCvar(j, oldweapon); break; } } break; } } }
int userinfo_t::SkinChanged(const char *skinname) { int skinnum = R_FindSkin(skinname, 0); *static_cast<FIntCVar *>((*this)[NAME_Skin]) = skinnum; return skinnum; }
void D_ReadUserInfoStrings (int i, BYTE **stream, bool update) { userinfo_t *info = &players[i].userinfo; const char *ptr = *((const char **)stream); const char *breakpt; FString value; bool compact; int infotype = -1; if (*ptr++ != '\\') return; compact = (*ptr == '\\') ? ptr++, true : false; if (i < MAXPLAYERS) { for (;;) { int j; breakpt = strchr (ptr, '\\'); if (compact) { value = D_UnescapeUserInfo(ptr, breakpt != NULL ? breakpt - ptr : strlen(ptr)); infotype++; } else { assert(breakpt != NULL); // A malicious remote machine could invalidate the above assert. if (breakpt == NULL) { break; } const char *valstart = breakpt + 1; if ( (breakpt = strchr (valstart, '\\')) != NULL ) { value = D_UnescapeUserInfo(valstart, breakpt - valstart); } else { value = D_UnescapeUserInfo(valstart, strlen(valstart)); } for (j = 0; UserInfoStrings[j] && strnicmp (UserInfoStrings[j], ptr, valstart - ptr - 1) != 0; ++j) { } if (UserInfoStrings[j] == NULL) { infotype = -1; } 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; case INFO_Name: { 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; case INFO_Team: UpdateTeam (i, atoi(value), update); break; case INFO_Color: info->color = V_GetColorFromString (NULL, 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->state->sprite == GetDefaultByType (players[i].cls)->SpawnState->sprite) { // Only change the sprite if the player is using a standard one players[i].mo->sprite = skins[info->skin].sprite; players[i].mo->scaleX = skins[info->skin].ScaleX; players[i].mo->scaleY = skins[info->skin].ScaleY; } } // Rebuild translation in case the new skin uses a different range // than the old one. R_BuildPlayerTranslation (i); if (StatusBar != NULL && i == StatusBar->GetPlayer()) { StatusBar->SetFace (&skins[info->skin]); } break; case INFO_Gender: info->gender = D_GenderToInt (value); break; case INFO_NeverSwitchOnPickup: if (value[0] >= '0' && value[0] <= '9') { 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; default: break; } if (breakpt) { ptr = breakpt + 1; } else { break; } } } *stream += strlen (*((char **)stream)) + 1; }