Skip to content

Commit

Permalink
GENDER: Enable the user to ignore the gender of all players
Browse files Browse the repository at this point in the history
- inspired by PadWorld-Entertainment/worldofpadman-fork#41
- add "none" as a new default gender which will force "they/them" to be used instead of "male" with "he/him"
- also "none" is the new default gender for a model if undefined in animations.cfg
- add an "ignore gender" option in game settings menu; if enabled, the gender normally set by the player model (male/female/neuter) via animations.cfg is ignored and set to (none)
- add gender neutral event messages
- fix minor typos in event messages
- TODO: Make the user selected option also work without model change, right now it only works if animation.cfg is reloaded.
  • Loading branch information
kai-li-wop committed Sep 8, 2023
1 parent 03a80a2 commit 45b548b
Show file tree
Hide file tree
Showing 9 changed files with 61 additions and 33 deletions.
45 changes: 22 additions & 23 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};
CASSERT(ARRAY_LEN(gender_strings) == GENDER_MAX + 1);
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
1 change: 1 addition & 0 deletions code/cgame/cg_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -1317,6 +1317,7 @@ extern vmCvar_t cg_cineDrawLetterBox;

extern vmCvar_t cg_glowModel;
extern vmCvar_t cg_glowModelTeam;
extern vmCvar_t cg_ignoreGender;

extern vmCvar_t cg_warmupReady;
extern vmCvar_t cg_curWarmupReady;
Expand Down
2 changes: 2 additions & 0 deletions code/cgame/cg_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -186,6 +186,7 @@ vmCvar_t cg_glowModelTeam;

vmCvar_t cg_warmupReady;
vmCvar_t cg_curWarmupReady;
vmCvar_t cg_ignoreGender;

vmCvar_t cg_sky;
vmCvar_t cg_skyLensflare;
Expand Down Expand Up @@ -320,6 +321,7 @@ static cvarTable_t cvarTable[] = { // bk001129

{&cg_glowModel, "cg_glowModel", "", CVAR_ARCHIVE},
{&cg_glowModelTeam, "cg_glowModelTeam", "", CVAR_ARCHIVE},
{&cg_ignoreGender, "cg_ignoreGender", "0", CVAR_ARCHIVE},

/* NOTE: We can't easily extend CS_WARMUP as SV_MapRestart_f() directly sets it */
{&cg_warmupReady, "g_warmupReady", "", CVAR_SYSTEMINFO},
Expand Down
16 changes: 9 additions & 7 deletions code/cgame/cg_players.c
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ 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->gender = GENDER_NONE;
ci->fixedlegs = qfalse;
ci->fixedtorso = qfalse;

Expand Down Expand Up @@ -169,12 +169,14 @@ static qboolean CG_ParseAnimationFile(const char *filename, clientInfo_t *ci) {
if (!token[0]) {
break;
}
if (token[0] == 'f' || token[0] == 'F') {
ci->gender = GENDER_FEMALE;
} else if (token[0] == 'n' || token[0] == 'N') {
ci->gender = GENDER_NEUTER;
} else {
ci->gender = GENDER_MALE;
if (!cg_ignoreGender.integer) {
if (token[0] == 'm' || token[0] == 'M') {
ci->gender = GENDER_MALE;
} else if (token[0] == 'f' || token[0] == 'F') {
ci->gender = GENDER_FEMALE;
} else if (token[0] == 'n' || token[0] == 'N') {
ci->gender = GENDER_NEUTER;
}
}
continue;
} else if (!Q_stricmp(token, "fixedlegs")) {
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", "none", 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 @@ -549,7 +549,7 @@ static void G_AddBot(const char *name, float skill, const char *team, int delay,
key = "gender";
s = Info_ValueForKey(botinfo, key);
if (!*s) {
s = "male";
s = "none";
}
Info_SetValueForKey(userinfo, "sex", s);

Expand Down
2 changes: 2 additions & 0 deletions code/ui/ui_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ vmCvar_t wop_AutoBindUnusedKeys;
vmCvar_t cg_drawChatIcon;
vmCvar_t cg_chatBeep;
vmCvar_t cg_glowModel;
vmCvar_t cg_ignoreGender;
vmCvar_t cl_renderer;

// bk001129 - made static to avoid aliasing.
Expand Down Expand Up @@ -230,6 +231,7 @@ static cvarTable_t cvarTable[] = {{&ui_ffa_fraglimit, "ui_ffa_fraglimit", "20",
{&cg_drawChatIcon, "cg_drawChatIcon", "1", CVAR_ARCHIVE},
{&cg_chatBeep, "cg_chatBeep", "7", CVAR_ARCHIVE},
{&cg_glowModel, "cg_glowModel", "", CVAR_ARCHIVE},
{&cg_ignoreGender, "cg_ignoreGender", "0", CVAR_ARCHIVE},
{&wop_AutoswitchSongByNextMap, "wop_AutoswitchSongByNextMap", "0", CVAR_ARCHIVE},
{&wop_AutoBindUnusedKeys, "wop_AutoBindUnusedKeys", "1", CVAR_ARCHIVE},
{&cl_renderer, "cl_renderer", "opengl1", CVAR_ARCHIVE}};
Expand Down
22 changes: 22 additions & 0 deletions code/ui/ui_preferences.c
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ PREFERENCES MENU
#define ID_SYNCEVERYFRAME 37
#define ID_FORCEMODEL 38
#define ID_GLOWMODEL 39
#define ID_IGNOREGENDER 40

#define ID_CONNOTIFY 50
#define ID_CHATHEIGHT 51
Expand Down Expand Up @@ -133,6 +134,7 @@ typedef struct {
menuradiobutton_s synceveryframe;
menuradiobutton_s forcemodel;
menulist_s glowmodel;
menuradiobutton_s ignoregender;

menulist_s connotify;
menulist_s chatheight;
Expand Down Expand Up @@ -190,6 +192,7 @@ static menucommon_s *g_game_options[] = {
(menucommon_s *)&s_preferences.synceveryframe,
(menucommon_s *)&s_preferences.forcemodel,
(menucommon_s *)&s_preferences.glowmodel,
(menucommon_s *)&s_preferences.ignoregender,
NULL
};

Expand Down Expand Up @@ -279,6 +282,8 @@ static void UI_Preferences_SetMenuItems(void) {
s_preferences.glowmodel.curvalue = (trap_Cvar_VariableValue("cg_glowModel") + 1);
}

s_preferences.ignoregender.curvalue = trap_Cvar_VariableValue("cg_ignoreGender") != 0;

notify = UI_GetCvarInt("con_notifytime");
if (notify < 0) {
notify *= -1;
Expand Down Expand Up @@ -523,6 +528,10 @@ static void UI_Preferences_Event(void *ptr, int notification) {
UI_Preferences_UpdateMenuItems();
break;

case ID_IGNOREGENDER:
trap_Cvar_SetValue("cg_ignoreGender", s_preferences.ignoregender.curvalue);
break;

case ID_CONNOTIFY:
switch (s_preferences.connotify.curvalue) {
case 0:
Expand Down Expand Up @@ -1028,6 +1037,18 @@ static void UI_Preferences_MenuInit(void) {
"Enable to force all players to be displayed with glowing player models in the desired skin color. "
"Default is none. NOTE: In team gametypes, the glowing color is always set to red or blue.";

y += (BIGCHAR_HEIGHT + 2);
s_preferences.ignoregender.generic.type = MTYPE_RADIOBUTTON;
s_preferences.ignoregender.generic.name = "Ignore Gender:";
s_preferences.ignoregender.generic.flags = QMF_SMALLFONT;
s_preferences.ignoregender.generic.id = ID_IGNOREGENDER;
s_preferences.ignoregender.generic.callback = UI_Preferences_Event;
s_preferences.ignoregender.generic.x = XPOSITION;
s_preferences.ignoregender.generic.y = y;
s_preferences.ignoregender.generic.toolTip =
"Enable to ignore the gender of all players, which is normally set by the selected player model. "
"This forces the game to replace he/him, she/her and it/its with they/them. Default is off.";

// chat options
y = YPOSITION;
s_preferences.connotify.generic.type = MTYPE_SPINCONTROL;
Expand Down Expand Up @@ -1287,6 +1308,7 @@ static void UI_Preferences_MenuInit(void) {
Menu_AddItem(&s_preferences.menu, &s_preferences.synceveryframe);
Menu_AddItem(&s_preferences.menu, &s_preferences.forcemodel);
Menu_AddItem(&s_preferences.menu, &s_preferences.glowmodel);
Menu_AddItem(&s_preferences.menu, &s_preferences.ignoregender);

Menu_AddItem(&s_preferences.menu, &s_preferences.connotify);
Menu_AddItem(&s_preferences.menu, &s_preferences.chatheight);
Expand Down

0 comments on commit 45b548b

Please sign in to comment.