static sfx_t *GetPlayerSound(clEntityState_t *ent, const char *base) { clientInfo_t &ci = cl.clientInfo[ent->number - 1]; // may use ent->skinnum & 0xFF too ... bool isFemale = ci.modelGender == 'f'; // see if we already know of the model specific sound TString<MAX_QPATH> LocalFilename; LocalFilename.sprintf("#players/%s/%s", *ci.ModelName, base+1); sfx_t *sfx = S_FindName(LocalFilename, false); if (sfx) return sfx; // try sound in Quake2 model directory ("players/[model_name]/[sound]") if (GFileSystem->FileExists(LocalFilename + 1)) { sfx = S_RegisterSound(LocalFilename); if (sfx) return sfx; } // try sound in Quake3 model directory ("sound/player/[model_name]/[sound]") static const struct { const char *q2name, *q3name; } convert[] = { {"death4.wav", "death1.wav"}, {"fall2.wav", "fall1.wav"}, {"pain25_2.wav", "pain25_1.wav"}, {"pain50_2.wav", "pain50_1.wav"}, {"pain75_2.wav", "pain75_1.wav"}, {"pain100_2.wav","pain100_1.wav"} }; // Quake3 models have no some Quake2 sounds const char *newName = base + 1; for (int i = 0; i < ARRAY_COUNT(convert); i++) if (!stricmp(newName, convert[i].q2name)) { newName = convert[i].q3name; break; } TString<MAX_QPATH> FileName2; FileName2.sprintf("sound/player/%s/%s", *ci.ModelName, newName); // NOTE: used below as filename2+6 too if (GFileSystem->FileExists(FileName2)) { sfx = S_AliasName(LocalFilename, FileName2 + 6 /* skip "sound/" */); if (sfx) return sfx; } // setup as default sound return S_AliasName(LocalFilename, va("player/%smale/%s", isFemale ? "fe" : "", base+1)); }
struct sfx_s *S_RegisterSexedSound (entity_state_t *ent, char *base) { int n; char *p; struct sfx_s *sfx; FILE *f; char model[MAX_QPATH]; char sexedFilename[MAX_QPATH]; char maleFilename[MAX_QPATH]; // determine what model the client is using model[0] = 0; n = CS_PLAYERSKINS + ent->number - 1; if (cl.configstrings[n][0]) { p = strchr(cl.configstrings[n], '\\'); if (p) { p += 1; strcpy(model, p); p = strchr(model, '/'); if (p) *p = 0; } } // if we can't figure it out, they're male if (!model[0]) strcpy(model, "male"); // see if we already know of the model specific sound Com_sprintf (sexedFilename, sizeof(sexedFilename), "#players/%s/%s", model, base+1); sfx = S_FindName (sexedFilename, false); if (!sfx) { // no, so see if it exists FS_FOpenFile (&sexedFilename[1], &f); if (f) { // yes, close the file and register it FS_FCloseFile (f); sfx = S_RegisterSound (sexedFilename); } else { // no, revert to the male sound in the pak0.pak Com_sprintf (maleFilename, sizeof(maleFilename), "player/%s/%s", "male", base+1); sfx = S_AliasName (sexedFilename, maleFilename); } } return sfx; }
static struct sfx_s *S_RegisterSexedSound (int entnum, const char *base) { int n; char *p; struct sfx_s *sfx; char model[MAX_QPATH]; char sexedFilename[MAX_QPATH]; char maleFilename[MAX_QPATH]; // determine what model the client is using model[0] = 0; n = CS_PLAYERSKINS + entnum - 1; if (cl.configstrings[n][0]) { p = strchr(cl.configstrings[n], '\\'); if (p) { Q_strncpyz(model, p + 1, sizeof(model)); p = strchr(model, '/'); if (p) *p = 0; } } // if we can't figure it out, they're male if (!model[0]) strcpy(model, "male"); // see if we already know of the model specific sound Com_sprintf (sexedFilename, sizeof(sexedFilename), "#players/%s/%s", model, base+1); sfx = S_FindName (sexedFilename, false); if (!sfx) { // no, so see if it exists if (FS_LoadFile(sexedFilename + 1, NULL) > 0) { // yes, close the file and register it sfx = S_RegisterSound(sexedFilename); } else { // no, revert to the male sound in the pak0.pak Com_sprintf(maleFilename, sizeof(maleFilename), "player/%s/%s", "male", base+1); sfx = S_AliasName(sexedFilename, maleFilename); } } return sfx; }