Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GENDER: Enable the user to select the gender #199

Merged
merged 1 commit into from
Nov 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 21 additions & 22 deletions code/cgame/cg_event.c
Original file line number Diff line number Diff line change
Expand Up @@ -156,40 +156,39 @@ static void CG_Obituary(entityState_t *ent) {
gender = ci->gender;
switch (mod) {
case MOD_BALLOONY_SPLASH:
if (gender == GENDER_FEMALE)
if (gender == GENDER_MALE)
message = "tripped on his own water bomb";
else if (gender == GENDER_FEMALE)
message = "tripped on her own water bomb";
else if (gender == GENDER_NEUTER)
message = "tripped on its own water bomb";
else
message = "tripped on his own water bomb";
message = "tripped on their own water bomb";
break;
case MOD_BETTY_SPLASH:
if (gender == GENDER_FEMALE)
if (gender == GENDER_MALE)
message = "blew himself up";
else if (gender == GENDER_FEMALE)
message = "blew herself up";
else if (gender == GENDER_NEUTER)
message = "blew itself up";
else
message = "blew himself up";
message = "blew themselves up";
break;
case MOD_BUBBLEG_SPLASH:
if (gender == GENDER_FEMALE)
if (gender == GENDER_MALE)
message = "melted himself";
else if (gender == GENDER_FEMALE)
message = "melted herself";
else if (gender == GENDER_NEUTER)
message = "melted itself";
else
message = "melted himself";
message = "melted themselves";
break;
case MOD_IMPERIUS_SPLASH:
message = "should have used a smaller gun";
break;
default: /*
if ( gender == GENDER_FEMALE )
message = "killed herself";
else if ( gender == GENDER_NEUTER )
message = "killed itself";
else
message = "killed himself";
break;*/
default:
message = "did the lemming thing";
break;
}
Expand All @@ -206,19 +205,19 @@ static void CG_Obituary(entityState_t *ent) {

if (cgs.gametype < GT_TEAM) {
if (cgs.gametype == GT_LPS) {
const char *gender_strings[] = {"he", "she", "it", 0};
const char *gender_strings[] = {"they have", "he has", "she has", "it has", NULL};
CASSERT(ARRAY_LEN(gender_strings) == GENDER_MAX + 1);

gender = ci->gender;
if (gender > 2 || gender < 0)
gender = 2;
if (gender >= GENDER_MAX || gender < GENDER_NONE)
gender = GENDER_NONE;

if (ent->generic1 == 0)
s = va("You fragged %s\n%s has no lives left.", targetName, gender_strings[gender]);
s = va("You fragged %s,\n%s no lives left.", targetName, gender_strings[gender]);
else if (ent->generic1 == 1)
s = va("You fragged %s\n%s has 1 live left.", targetName, gender_strings[gender]);
s = va("You fragged %s,\n%s 1 life left.", targetName, gender_strings[gender]);
else
s = va("You fragged %s\n%s has %i lives left.", targetName, gender_strings[gender], ent->generic1);
s = va("You fragged %s,\n%s %i lives left.", targetName, gender_strings[gender], ent->generic1);
} else
s = va("You fragged %s\n%s place with %i", targetName,
CG_PlaceString(cg.snap->ps.persistant[PERS_RANK] + 1), cg.snap->ps.persistant[PERS_SCORE]);
Expand Down Expand Up @@ -282,7 +281,7 @@ static void CG_Obituary(entityState_t *ent) {
break;
case MOD_SPLASHER:
message = "was splashed by";
message2 = "'s splasher";
message2 = "'s Splasher";
break;
case MOD_BOASTER:
message = "was showered by";
Expand All @@ -294,7 +293,7 @@ static void CG_Obituary(entityState_t *ent) {
break;
case MOD_KILLERDUCKS:
message = "was hunted & bitten to death by";
message2 = "'s KillerDuck";
message2 = "'s Killerduck";
break;
case MOD_TELEFRAG:
message = "tried to invade";
Expand Down
3 changes: 2 additions & 1 deletion code/cgame/cg_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -369,7 +369,8 @@ typedef struct {
float headScale;

footstep_t footsteps;
gender_t gender; // from model
gender_t gender; // user settings (can also be from model)
gender_t genderModel; // cached value from model (animation.cfg)

qhandle_t legsModel;
qhandle_t legsSkin;
Expand Down
56 changes: 34 additions & 22 deletions code/cgame/cg_players.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,6 @@ static qboolean CG_ParseAnimationFile(const char *filename, clientInfo_t *ci) {
ci->footsteps = FOOTSTEP_NORMAL;
VectorClear(ci->headOffset);
ci->headScale = 1.0f;
ci->gender = GENDER_MALE;
ci->fixedlegs = qfalse;
ci->fixedtorso = qfalse;

Expand Down Expand Up @@ -167,14 +166,15 @@ static qboolean CG_ParseAnimationFile(const char *filename, clientInfo_t *ci) {
} else if (!Q_stricmp(token, "sex")) {
token = COM_Parse(&text_p);
if (!token[0]) {
ci->genderModel = GENDER_NONE;
break;
}
if (token[0] == 'f' || token[0] == 'F') {
ci->gender = GENDER_FEMALE;
if (token[0] == 'm' || token[0] == 'M') {
ci->genderModel = GENDER_MALE;
} else if (token[0] == 'f' || token[0] == 'F') {
ci->genderModel = GENDER_FEMALE;
} else if (token[0] == 'n' || token[0] == 'N') {
ci->gender = GENDER_NEUTER;
} else {
ci->gender = GENDER_MALE;
ci->genderModel = GENDER_NEUTER;
}
continue;
} else if (!Q_stricmp(token, "fixedlegs")) {
Expand All @@ -195,7 +195,6 @@ static qboolean CG_ParseAnimationFile(const char *filename, clientInfo_t *ci) {

// read information for each frame
for (i = 0; i < MAX_ANIMATIONS; i++) {

token = COM_Parse(&text_p);
if (!token[0]) {
if (i >= TORSO_GETFLAG && i <= TORSO_NEGATIVE) {
Expand Down Expand Up @@ -261,8 +260,8 @@ static qboolean CG_ParseAnimationFile(const char *filename, clientInfo_t *ci) {
if (fps == 0) {
fps = 1;
}
animations[i].frameLerp = 1000 / fps;
animations[i].initialLerp = 1000 / fps;
animations[i].frameLerp = 1000.0f / fps;
animations[i].initialLerp = 1000.0f / fps;
}

if (i != MAX_ANIMATIONS) {
Expand Down Expand Up @@ -668,18 +667,21 @@ static void CG_LoadClientInfo(int clientNum, clientInfo_t *ci) {
CG_ResetPlayerEntity(&cg_entities[i]);
}
}

if (ci->gender == GENDER_MAX) {
ci->gender = ci->genderModel;
}
}

/*
======================
CG_CopyClientInfoModel
======================
*/
static void CG_CopyClientInfoModel(clientInfo_t *from, clientInfo_t *to) {
/**
* @brief Copies the attributes of a model from its @c animation.cfg properties to the new @c clientInfo_t
* @sa CG_ParseAnimationFile()
*/
static void CG_CopyClientInfoModel(const clientInfo_t *from, clientInfo_t *to) {
VectorCopy(from->headOffset, to->headOffset);
to->headScale = from->headScale;
to->footsteps = from->footsteps;
to->gender = from->gender;
to->genderModel = from->genderModel;

to->legsModel = from->legsModel;
to->legsSkin = from->legsSkin;
Expand All @@ -700,7 +702,7 @@ CG_ScanForExistingClientInfo
*/
static qboolean CG_ScanForExistingClientInfo(clientInfo_t *ci) {
int i;
clientInfo_t *match;
const clientInfo_t *match;

for (i = 0; i < cgs.maxclients; i++) {
match = &cgs.clientinfo[i];
Expand Down Expand Up @@ -801,11 +803,9 @@ static void CG_SetDeferredClientInfo(int clientNum, clientInfo_t *ci) {
CG_LoadClientInfo(clientNum, ci);
}

/*
======================
CG_NewClientInfo
======================
*/
/**
* @sa ClientUserinfoChanged()
*/
void CG_NewClientInfo(int clientNum) {
clientInfo_t *ci;
clientInfo_t newInfo;
Expand Down Expand Up @@ -879,6 +879,17 @@ void CG_NewClientInfo(int clientNum) {
// team leader
v = Info_ValueForKey(configstring, "tl");
newInfo.teamLeader = atoi(v);

// sex
// if a sex option is set in the userinfo string we take this,
// otherwise we check for GENDER_MAX in CG_ParseAnimationFile() to use the
// setting from animation.cfg
newInfo.gender = GENDER_MAX;
v = Info_ValueForKey(configstring, "s");
if (v[0] != '\0') {
newInfo.gender = atoi(v);
}

oldTeam = ci->team;

// this may be run before the first snapshot arrives
Expand Down Expand Up @@ -987,6 +998,7 @@ void CG_NewClientInfo(int clientNum) {

// replace whatever was there with the new one
newInfo.infoValid = qtrue;

*ci = newInfo;

// if the local client changed teams in a team gametype, adjust team- and enemymodels
Expand Down
2 changes: 1 addition & 1 deletion code/client/cl_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -3394,7 +3394,7 @@ void CL_Init(void) {
Cvar_Get("team_model", "padman", CVAR_USERINFO | CVAR_ARCHIVE);
Cvar_Get("team_headmodel", "padman", CVAR_USERINFO | CVAR_ARCHIVE);
Cvar_Get("handicap", "100", CVAR_USERINFO | CVAR_ARCHIVE);
Cvar_Get("sex", "male", CVAR_USERINFO | CVAR_ARCHIVE);
Cvar_Get("sex", "model", CVAR_USERINFO | CVAR_ARCHIVE);
Cvar_Get("cl_anonymous", "0", CVAR_USERINFO | CVAR_ARCHIVE);

Cvar_Get("password", "", CVAR_USERINFO);
Expand Down
2 changes: 1 addition & 1 deletion code/game/bg_public.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ typedef enum {

int convertGTStringToGTNumber(const char *argStr);

typedef enum { GENDER_MALE, GENDER_FEMALE, GENDER_NEUTER, GENDER_MAX } gender_t;
typedef enum { GENDER_NONE, GENDER_MALE, GENDER_FEMALE, GENDER_NEUTER, GENDER_MAX } gender_t;

/*
===================================================================================
Expand Down
2 changes: 1 addition & 1 deletion code/game/g_bot.c
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ static void G_AddBot(const char *name, float skill, const char *team, int delay,
// have the server allocate a client slot
clientNum = trap_BotAllocateClient();
if (clientNum == -1) {
G_Printf(S_COLOR_RED "Unable to add bot. All player slots are in use.\n");
G_Printf(S_COLOR_RED "Unable to add bot. All player slots are in use.\n");
G_Printf(S_COLOR_RED "Start server with more 'open' slots (or check setting of sv_maxclients cvar).\n");
return;
}
Expand Down
46 changes: 29 additions & 17 deletions code/game/g_client.c
Original file line number Diff line number Diff line change
Expand Up @@ -741,17 +741,15 @@ static void ClientCleanName(const char *in, char *out, int outSize) {
Q_strncpyz(out, "UnnamedPlayer", outSize);
}

/*
===========
ClientUserInfoChanged

Called from ClientConnect when the player first connects and
directly by the server system when the player updates a userinfo variable.

The game can override any of the settings and call trap_SetUserinfo
if desired.
============
*/
/**
* Called from ClientConnect when the player first connects and
* directly by the server system when the player updates a userinfo variable.
*
* The game can override any of the settings and call trap_SetUserinfo
* if desired.
*
* @see CG_NewClientInfo()
*/
void ClientUserinfoChanged(int clientNum) {
gentity_t *ent;
int teamLeader, team, health;
Expand All @@ -763,6 +761,7 @@ void ClientUserinfoChanged(int clientNum) {
char c1[MAX_INFO_STRING];
char c2[MAX_INFO_STRING];
char userinfo[MAX_INFO_STRING];
gender_t gender;

ent = g_entities + clientNum;
client = ent->client;
Expand Down Expand Up @@ -815,6 +814,20 @@ void ClientUserinfoChanged(int clientNum) {
}
client->ps.stats[STAT_MAX_HEALTH] = client->pers.maxHealth;

// set gender
s = Info_ValueForKey(userinfo, "sex");
if (!Q_stricmp(s, "neuter")) {
gender = GENDER_NEUTER;
} else if (!Q_stricmp(s, "female")) {
gender = GENDER_FEMALE;
} else if (!Q_stricmp(s, "male")) {
gender = GENDER_MALE;
} else if (!Q_stricmp(s, "none")) {
gender = GENDER_NONE;
} else {
gender = GENDER_MAX;
}

// set model
if (g_gametype.integer >= GT_TEAM) {
Q_strncpyz(model, Info_ValueForKey(userinfo, "team_model"), sizeof(model));
Expand Down Expand Up @@ -849,16 +862,15 @@ void ClientUserinfoChanged(int clientNum) {
int rnd;
rnd = random() * 5.9;
rnd_str = va("%d", rnd);
s = va("n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\skill\\%s\\tl\\%"
"d\\sl\\%s",
s = va("n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\skill\\%s\\tl\\%d"
"\\sl\\%s",
client->pers.netname, team, model, headModel, c1, rnd_str, client->pers.maxHealth, client->sess.wins,
client->sess.losses, Info_ValueForKey(userinfo, "skill"), teamLeader,
client->sess.selectedlogo);
client->sess.losses, Info_ValueForKey(userinfo, "skill"), teamLeader, client->sess.selectedlogo);
// cyr}
} else {
s = va("n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\tl\\%d\\sl\\%s",
s = va("n\\%s\\t\\%i\\model\\%s\\hmodel\\%s\\c1\\%s\\c2\\%s\\hc\\%i\\w\\%i\\l\\%i\\tl\\%d\\sl\\%s\\s\\%i",
client->pers.netname, client->sess.sessionTeam, model, headModel, c1, c2, client->pers.maxHealth,
client->sess.wins, client->sess.losses, teamLeader, client->sess.selectedlogo);
client->sess.wins, client->sess.losses, teamLeader, client->sess.selectedlogo, (int)gender);
}

trap_SetConfigstring(CS_PLAYERS + clientNum, s);
Expand Down
Loading
Loading