Skip to content

Commit cd86472

Browse files
authored
Merge pull request #6202 from IllianiCBT/personalitiesTheyThemSupport
Fixed Non-Binary Pronoun Support for Personality Generator; Added Additional Quirks; Expanded Characteristic Variants; Fixed Personality Generator
2 parents 73feeaf + 5bb3dee commit cd86472

File tree

19 files changed

+7739
-5274
lines changed

19 files changed

+7739
-5274
lines changed

MekHQ/resources/mekhq/resources/Aggression.properties

Lines changed: 502 additions & 200 deletions
Large diffs are not rendered by default.

MekHQ/resources/mekhq/resources/Ambition.properties

Lines changed: 540 additions & 214 deletions
Large diffs are not rendered by default.

MekHQ/resources/mekhq/resources/Greed.properties

Lines changed: 535 additions & 197 deletions
Large diffs are not rendered by default.

MekHQ/resources/mekhq/resources/Intelligence.properties

Lines changed: 613 additions & 485 deletions
Large diffs are not rendered by default.

MekHQ/resources/mekhq/resources/PersonalityQuirk.properties

Lines changed: 4730 additions & 3837 deletions
Large diffs are not rendered by default.

MekHQ/resources/mekhq/resources/Social.properties

Lines changed: 525 additions & 187 deletions
Large diffs are not rendered by default.

MekHQ/src/mekhq/campaign/randomEvents/personalities/PersonalityController.java

Lines changed: 110 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,9 @@
3737

3838
import static megamek.common.Compute.d6;
3939
import static megamek.common.Compute.randomInt;
40+
import static mekhq.campaign.personnel.enums.GenderDescriptors.HE_SHE_THEY;
41+
import static mekhq.campaign.personnel.enums.GenderDescriptors.HIM_HER_THEM;
42+
import static mekhq.campaign.personnel.enums.GenderDescriptors.HIS_HER_THEIR;
4043
import static mekhq.campaign.randomEvents.personalities.enums.Intelligence.*;
4144

4245
/**
@@ -126,7 +129,7 @@ public static void generatePersonality(Person person) {
126129
*/
127130
public static void generateAndApplyPersonalityQuirk(Person person) {
128131
// This ensures we're rolling a value between 1 and the maximum index in the enum
129-
int traitRoll = 1 + randomInt(PersonalityQuirk.values().length - 1);
132+
int traitRoll = randomInt(PersonalityQuirk.values().length) + 1;
130133
String traitIndex = String.valueOf(traitRoll);
131134

132135
person.setPersonalityQuirk(PersonalityQuirk.fromString(traitIndex));
@@ -175,7 +178,7 @@ private static void performPersonalityGenerationFallback(Person person) {
175178
*/
176179
private static String getTraitIndex(final int majorTraitsStartIndex) {
177180
// This gives us a random number between 1 and the start of the major traits
178-
int traitRoll = randomInt(majorTraitsStartIndex + 1);
181+
int traitRoll = randomInt(majorTraitsStartIndex) + 1;
179182

180183
if (traitRoll == majorTraitsStartIndex) {
181184
// We're deliberately not using d6() here as we want 0 to be a possibility
@@ -193,8 +196,35 @@ private static String getTraitIndex(final int majorTraitsStartIndex) {
193196
* @param person the person whose personality description will be generated and updated
194197
*/
195198
public static void writePersonalityDescription(Person person) {
196-
List<String> traitDescriptions = getTraitDescriptions(person);
199+
Gender gender = person.getGender();
200+
String givenName = person.getGivenName();
197201

202+
List<String> traitDescriptions = getTraitDescriptions(
203+
gender, givenName, person.getAggression(), person.getAggressionDescriptionIndex(),
204+
person.getAmbition(), person.getAmbitionDescriptionIndex(), person.getGreed(),
205+
person.getGreedDescriptionIndex(), person.getSocial(), person.getSocialDescriptionIndex()
206+
);
207+
208+
// Intelligence and personality quirk are handled differently to general personality traits.
209+
// INTELLIGENCE
210+
Intelligence intelligence = person.getIntelligence();
211+
String intelligenceDescription = "";
212+
if (!intelligence.isAverageType()) {
213+
intelligenceDescription = intelligence.getDescription(person.getIntelligenceDescriptionIndex(),
214+
gender, givenName);
215+
}
216+
217+
// PERSONALITY QUIRK
218+
PersonalityQuirk personalityQuirk = person.getPersonalityQuirk();
219+
String quirkDescription = "";
220+
if (!personalityQuirk.isNone()) {
221+
quirkDescription = personalityQuirk.getDescription(
222+
person.getPrimaryRole(), person.getPersonalityQuirkDescriptionIndex(), gender,
223+
person.getOriginFaction(), givenName
224+
);
225+
}
226+
227+
// Build the description proper
198228
StringBuilder personalityDescription = new StringBuilder();
199229

200230
// Append the first trait description, if exists, without wrapping in <p>
@@ -218,86 +248,92 @@ public static void writePersonalityDescription(Person person) {
218248
}
219249
}
220250

251+
if (!intelligenceDescription.isBlank()) {
252+
if (!personalityDescription.toString().isBlank()) {
253+
personalityDescription.append("<p>").append(intelligenceDescription).append("</p>");
254+
} else {
255+
personalityDescription.append(intelligenceDescription);
256+
}
257+
}
258+
259+
if (!quirkDescription.isBlank()) {
260+
if (!personalityDescription.toString().isBlank()) {
261+
personalityDescription.append("<p>").append(quirkDescription).append("</p>");
262+
} else {
263+
personalityDescription.append(quirkDescription);
264+
}
265+
}
266+
221267
person.setPersonalityDescription(personalityDescription.toString());
222268
}
223269

224270
/**
225-
* Retrieves the descriptions of all assigned personality traits for the given person. Each
226-
* trait is processed to generate a detailed description, which is then collated into a list of
227-
* strings.
271+
* Retrieves the descriptions of all personality traits (other than Intelligence and Quirks) for
272+
* the given person. This method processes various personality traits such as aggression, ambition,
273+
* greed, and social behavior, generating descriptions based on the specified indices, gender,
274+
* and given name of the person.
275+
*
276+
* <p>Descriptions for traits that are not assigned or are empty will be excluded from the
277+
* returned list. This ensures only meaningful and applicable descriptions are included.
228278
*
229-
* @param person the person whose personality traits will be described
230-
* @return a list of strings representing the descriptions of the person's traits, excluding
231-
* default values
279+
* @param gender the gender of the person, used for generating gender-specific pronouns in trait
280+
* descriptions
281+
* @param givenName the given name of the person, used to personalize the descriptions
282+
* @param aggression the {@link Aggression} trait assigned to the person; omitted if the trait
283+
* is set to "none"
284+
* @param aggressionDescriptionIndex the index used to determine the specific {@link Aggression}
285+
* description
286+
* @param ambition the {@link Ambition} trait assigned to the person; omitted if the trait is set
287+
* to "none"
288+
* @param ambitionDescriptionIndex the index used to determine the specific {@link Ambition}
289+
* description
290+
* @param greed the {@link Greed} trait assigned to the person; omitted if the trait is set to
291+
* "none"
292+
* @param greedDescriptionIndex the index used to determine the specific {@link Greed} description
293+
* @param social the {@link Social} behavior trait assigned to the person; omitted if the trait
294+
* is set to "none"
295+
* @param socialDescriptionIndex the index used to determine the specific {@link Social} description
296+
* @return a list of strings, where each string represents a detailed description of a personality
297+
* trait assigned to the given person; traits without meaningful descriptions are excluded
232298
*/
233-
private static List<String> getTraitDescriptions(Person person) {
299+
private static List<String> getTraitDescriptions(Gender gender, String givenName,
300+
Aggression aggression, int aggressionDescriptionIndex,
301+
Ambition ambition, int ambitionDescriptionIndex,
302+
Greed greed, int greedDescriptionIndex,
303+
Social social, int socialDescriptionIndex) {
234304
List<String> traitDescriptions = new ArrayList<>();
235305

236-
final Gender gender = person.getGender();
237-
final String givenName = person.getGivenName();
238-
239306
// AGGRESSION
240-
Aggression aggression = person.getAggression();
241307
if (!aggression.isNone()) {
242-
String traitDescription = aggression.getDescription(
243-
person.getAggressionDescriptionIndex(), gender, givenName);
308+
String traitDescription = aggression.getDescription(aggressionDescriptionIndex, gender,
309+
givenName);
244310

245311
if (!traitDescription.isBlank()) {
246312
traitDescriptions.add(traitDescription);
247313
}
248314
}
249315

250316
// AMBITION
251-
Ambition ambition = person.getAmbition();
252317
if (!ambition.isNone()) {
253-
String traitDescription = ambition.getDescription(
254-
person.getAmbitionDescriptionIndex(), gender, givenName);
318+
String traitDescription = ambition.getDescription(ambitionDescriptionIndex, gender, givenName);
255319

256320
if (!traitDescription.isBlank()) {
257321
traitDescriptions.add(traitDescription);
258322
}
259323
}
260324

261325
// GREED
262-
Greed greed = person.getGreed();
263326
if (!greed.isNone()) {
264-
String traitDescription = greed.getDescription(
265-
person.getGreedDescriptionIndex(), gender, givenName);
327+
String traitDescription = greed.getDescription(greedDescriptionIndex, gender, givenName);
266328

267329
if (!traitDescription.isBlank()) {
268330
traitDescriptions.add(traitDescription);
269331
}
270332
}
271333

272334
// SOCIAL
273-
Social social = person.getSocial();
274335
if (!social.isNone()) {
275-
String traitDescription = social.getDescription(
276-
person.getSocialDescriptionIndex(), gender, givenName);
277-
278-
if (!traitDescription.isBlank()) {
279-
traitDescriptions.add(traitDescription);
280-
}
281-
}
282-
283-
// INTELLIGENCE
284-
Intelligence intelligence = person.getIntelligence();
285-
if (!intelligence.isAverageType()) {
286-
String traitDescription = intelligence.getDescription(
287-
person.getIntelligenceDescriptionIndex(), gender, givenName);
288-
289-
if (!traitDescription.isBlank()) {
290-
traitDescriptions.add(traitDescription);
291-
}
292-
}
293-
294-
// PERSONALITY QUIRK
295-
PersonalityQuirk personalityQuirk = person.getPersonalityQuirk();
296-
if (!personalityQuirk.isNone()) {
297-
String traitDescription = personalityQuirk.getDescription(
298-
person.getPrimaryRole(), person.getPersonalityQuirkDescriptionIndex(), gender,
299-
person.getOriginFaction(), givenName
300-
);
336+
String traitDescription = social.getDescription(socialDescriptionIndex, gender, givenName);
301337

302338
if (!traitDescription.isBlank()) {
303339
traitDescriptions.add(traitDescription);
@@ -424,4 +460,29 @@ public static int getPersonalityValue(final boolean isUseRandomPersonalities,
424460

425461
return personalityValue;
426462
}
463+
464+
/**
465+
* A record to encapsulate pronoun information and associated data based on a given gender.
466+
*/
467+
public record PronounData(String subjectPronoun, String subjectPronounLowerCase, String objectPronoun,
468+
String objectPronounLowerCase, String possessivePronoun, String possessivePronounLowerCase,
469+
int pluralizer) {
470+
471+
/**
472+
* Constructs a new {@code PronounData} record based on the specified gender.
473+
*
474+
* @param gender The gender used to determine the pronouns and pluralizer.
475+
*/
476+
public PronounData(Gender gender) {
477+
this(
478+
HE_SHE_THEY.getDescriptorCapitalized(gender),
479+
HE_SHE_THEY.getDescriptorCapitalized(gender).toLowerCase(),
480+
HIM_HER_THEM.getDescriptorCapitalized(gender),
481+
HIM_HER_THEM.getDescriptorCapitalized(gender).toLowerCase(),
482+
HIS_HER_THEIR.getDescriptorCapitalized(gender),
483+
HIS_HER_THEIR.getDescriptorCapitalized(gender).toLowerCase(),
484+
gender.isGenderNeutral() ? 0 : 1 // Used to determine whether to use a plural case
485+
);
486+
}
487+
}
427488
}

MekHQ/src/mekhq/campaign/randomEvents/personalities/enums/Aggression.java

Lines changed: 17 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,9 @@
2929

3030
import megamek.common.enums.Gender;
3131
import megamek.logging.MMLogger;
32+
import mekhq.campaign.randomEvents.personalities.PersonalityController.PronounData;
3233

3334
import static megamek.codeUtilities.MathUtility.clamp;
34-
import static mekhq.campaign.personnel.enums.GenderDescriptors.HE_SHE_THEY;
35-
import static mekhq.campaign.personnel.enums.GenderDescriptors.HIM_HER_THEM;
36-
import static mekhq.campaign.personnel.enums.GenderDescriptors.HIS_HER_THEIR;
3735
import static mekhq.utilities.MHQInternationalization.getFormattedTextAt;
3836

3937
/**
@@ -102,7 +100,7 @@ public enum Aggression {
102100
/**
103101
* Defines the number of individual description variants available for each trait.
104102
*/
105-
public final static int MAXIMUM_VARIATIONS = 3;
103+
public final static int MAXIMUM_VARIATIONS = 6;
106104

107105
/**
108106
* The index at which major traits begin within the enumeration.
@@ -150,17 +148,20 @@ public String getDescription(int aggressionDescriptionIndex, final Gender gender
150148
aggressionDescriptionIndex = clamp(aggressionDescriptionIndex, 0, MAXIMUM_VARIATIONS - 1);
151149

152150
final String RESOURCE_KEY = name() + ".description." + aggressionDescriptionIndex;
153-
154-
String subjectPronoun = HE_SHE_THEY.getDescriptorCapitalized(gender);
155-
String subjectPronounLowerCase = HE_SHE_THEY.getDescriptor(gender);
156-
String objectPronoun = HIM_HER_THEM.getDescriptorCapitalized(gender);
157-
String objectPronounLowerCase = HIM_HER_THEM.getDescriptor(gender);
158-
String possessivePronoun = HIS_HER_THEIR.getDescriptorCapitalized(gender);
159-
String possessivePronounLowerCase = HIS_HER_THEIR.getDescriptor(gender);
160-
161-
return getFormattedTextAt(RESOURCE_BUNDLE, RESOURCE_KEY, givenName, subjectPronoun,
162-
subjectPronounLowerCase, objectPronoun, objectPronounLowerCase, possessivePronoun,
163-
possessivePronounLowerCase);
151+
final PronounData pronounData = new PronounData(gender);
152+
153+
// {0} = givenName
154+
// {1} = He/She/They
155+
// {2} = he/she/they
156+
// {3} = Him/Her/Them
157+
// {4} = him/her/them
158+
// {5} = His/Her/Their
159+
// {6} = his/her/their
160+
// {7} = Gender Neutral = 0, Otherwise 1 (used to determine whether to use plural case)
161+
162+
return getFormattedTextAt(RESOURCE_BUNDLE, RESOURCE_KEY, givenName, pronounData.subjectPronoun(),
163+
pronounData.subjectPronounLowerCase(), pronounData.objectPronoun(), pronounData.objectPronounLowerCase(),
164+
pronounData.possessivePronoun(), pronounData.possessivePronounLowerCase(), pronounData.pluralizer());
164165
}
165166

166167
/**
@@ -201,7 +202,7 @@ public boolean isNone() {
201202
*/
202203
public static Aggression fromString(String text) {
203204
try {
204-
return Aggression.valueOf(text);
205+
return Aggression.valueOf(text.toUpperCase().replace(" ", "_"));
205206
} catch (Exception ignored) {}
206207

207208
try {

MekHQ/src/mekhq/campaign/randomEvents/personalities/enums/Ambition.java

Lines changed: 19 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,9 @@
2929

3030
import megamek.common.enums.Gender;
3131
import megamek.logging.MMLogger;
32+
import mekhq.campaign.randomEvents.personalities.PersonalityController.PronounData;
3233

3334
import static megamek.codeUtilities.MathUtility.clamp;
34-
import static mekhq.campaign.personnel.enums.GenderDescriptors.HE_SHE_THEY;
35-
import static mekhq.campaign.personnel.enums.GenderDescriptors.HIM_HER_THEM;
36-
import static mekhq.campaign.personnel.enums.GenderDescriptors.HIS_HER_THEIR;
3735
import static mekhq.utilities.MHQInternationalization.getFormattedTextAt;
3836

3937
/**
@@ -101,7 +99,7 @@ public enum Ambition {
10199
/**
102100
* Defines the number of individual description variants available for each trait.
103101
*/
104-
public final static int MAXIMUM_VARIATIONS = 3;
102+
public final static int MAXIMUM_VARIATIONS = 6;
105103

106104
/**
107105
* The index at which major traits begin within the enumeration.
@@ -142,21 +140,25 @@ public String getLabel() {
142140
* @return a formatted description string based on the enum,
143141
* the individual's gender, name, and aggression description index.
144142
*/
145-
public String getDescription(int ambitionDescriptionIndex, final Gender gender, final String givenName) {
143+
public String getDescription(int ambitionDescriptionIndex, final Gender gender,
144+
final String givenName) {
146145
ambitionDescriptionIndex = clamp(ambitionDescriptionIndex, 0, MAXIMUM_VARIATIONS - 1);
147146

148147
final String RESOURCE_KEY = name() + ".description." + ambitionDescriptionIndex;
149-
150-
String subjectPronoun = HE_SHE_THEY.getDescriptorCapitalized(gender);
151-
String subjectPronounLowerCase = HE_SHE_THEY.getDescriptor(gender);
152-
String objectPronoun = HIM_HER_THEM.getDescriptorCapitalized(gender);
153-
String objectPronounLowerCase = HIM_HER_THEM.getDescriptor(gender);
154-
String possessivePronoun = HIS_HER_THEIR.getDescriptorCapitalized(gender);
155-
String possessivePronounLowerCase = HIS_HER_THEIR.getDescriptor(gender);
156-
157-
return getFormattedTextAt(RESOURCE_BUNDLE, RESOURCE_KEY, givenName, subjectPronoun,
158-
subjectPronounLowerCase, objectPronoun, objectPronounLowerCase, possessivePronoun,
159-
possessivePronounLowerCase);
148+
final PronounData pronounData = new PronounData(gender);
149+
150+
// {0} = givenName
151+
// {1} = He/She/They
152+
// {2} = he/she/they
153+
// {3} = Him/Her/Them
154+
// {4} = him/her/them
155+
// {5} = His/Her/Their
156+
// {6} = his/her/their
157+
// {7} = Gender Neutral = 0, Otherwise 1 (used to determine whether to use plural case)
158+
159+
return getFormattedTextAt(RESOURCE_BUNDLE, RESOURCE_KEY, givenName, pronounData.subjectPronoun(),
160+
pronounData.subjectPronounLowerCase(), pronounData.objectPronoun(), pronounData.objectPronounLowerCase(),
161+
pronounData.possessivePronoun(), pronounData.possessivePronounLowerCase(), pronounData.pluralizer());
160162
}
161163

162164
/**
@@ -196,7 +198,7 @@ public boolean isNone() {
196198
// region File I/O
197199
public static Ambition fromString(String text) {
198200
try {
199-
return Ambition.valueOf(text);
201+
return Ambition.valueOf(text.toUpperCase().replace(" ", "_"));
200202
} catch (Exception ignored) {}
201203

202204
try {

0 commit comments

Comments
 (0)