Skip to content

Commit 9856187

Browse files
authored
Merge pull request #6572 from IllianiBird/randomizeTraits
Added Randomize Traits Option For Character Creation
2 parents ecec7a4 + ecbfe75 commit 9856187

File tree

9 files changed

+156
-15
lines changed

9 files changed

+156
-15
lines changed

MekHQ/resources/mekhq/resources/CampaignOptionsDialog.properties

+11
Original file line numberDiff line numberDiff line change
@@ -1808,6 +1808,17 @@ lblExtraRandomness.tooltip=If checked, an additional 1d6 will be rolled per skil
18081808
<br>\
18091809
<br><b>Warning:</b> Due to the way experience levels are calculated, enabling this option will\
18101810
\ more frequently have characters created with slightly lower than normal experience levels.
1811+
lblRandomizeTraits.text=Randomize Traits \u26A0 \uD83C\uDF1F
1812+
lblRandomizeTraits.tooltip=If checked, a newly created character's Connections, Wealth, Reputation, and Unlucky scores\
1813+
\ are randomized.\
1814+
<br>\
1815+
<br>For <b>Connections</b> a d6 is rolled, on a roll of 6 the character's Connections score becomes 1.\
1816+
<br>\
1817+
<br>For <b>Wealth</b> and <b>Reputation</b> a d6 is rolled (for each), on a roll of 6 the character's score becomes 1.\
1818+
\ While a roll of 1 causes their score to become -1.\
1819+
<br>\
1820+
<br>For <b>Unlucky</b> a d20 is rolled, on a roll of 1 the character's score becomes 1. A high Unlucky score is a bad\
1821+
\ thing.
18111822
lblPhenotypesPanel.text=Clan Trueborn Percentages
18121823
lblMekWarrior.text=MekWarrior
18131824
lblMekWarrior.tooltip=What percentage of Clan MekWarriors should have a Trueborn phenotype?

MekHQ/resources/mekhq/resources/GUI.properties

+1
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,7 @@ regenerateLoyalty.text=Regenerate Loyalty
285285
regeneratePersonality.text=Regenerate Personality
286286
addRandomSPA.text=Add Random SPA
287287
generateRoleplaySkills.text=Generate Roleplay Skills
288+
generateRoleplayTraits.text=Reset Roleplay Traits
288289
addMinimumComplement.text=Add minimum complement
289290
addMinimumComplementRandom.text=Random
290291
addMinimumComplementElite.text=Elite

MekHQ/src/mekhq/campaign/RandomSkillPreferences.java

+13
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ public class RandomSkillPreferences {
5252
private int overallRecruitBonus;
5353
Map<PersonnelRole, Integer> recruitmentBonuses;
5454
private boolean randomizeSkill;
55+
private boolean randomizeTraits;
5556
private boolean useClanBonuses;
5657
private int antiMekProb;
5758
private int[] specialAbilityBonus;
@@ -68,6 +69,7 @@ public RandomSkillPreferences() {
6869
overallRecruitBonus = 0;
6970
recruitmentBonuses = new HashMap<>();
7071
randomizeSkill = true;
72+
randomizeTraits = false;
7173
useClanBonuses = true;
7274
antiMekProb = 10;
7375
combatSmallArmsBonus = -3;
@@ -173,6 +175,14 @@ public boolean randomizeSkill() {
173175
return randomizeSkill;
174176
}
175177

178+
public boolean isRandomizeTraits() {
179+
return randomizeTraits;
180+
}
181+
182+
public void setRandomizeTraits(boolean randomizeTraits) {
183+
this.randomizeTraits = randomizeTraits;
184+
}
185+
176186
public void setUseClanBonuses(boolean b) {
177187
this.useClanBonuses = b;
178188
}
@@ -269,6 +279,7 @@ public void writeToXML(final PrintWriter pw, int indent) {
269279
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "commandSkillsModifier", commandSkillsModifier);
270280
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "roleplaySkillsModifier", roleplaySkillsModifier);
271281
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "randomizeSkill", randomizeSkill);
282+
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "randomizeTraits", randomizeTraits);
272283
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "useClanBonuses", useClanBonuses);
273284
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "antiMekProb", antiMekProb);
274285
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "combatSmallArmsBonus", combatSmallArmsBonus);
@@ -303,6 +314,8 @@ public static RandomSkillPreferences generateRandomSkillPreferencesFromXml(Node
303314
retVal.overallRecruitBonus = Integer.parseInt(wn2.getTextContent().trim());
304315
} else if (wn2.getNodeName().equalsIgnoreCase("randomizeSkill")) {
305316
retVal.randomizeSkill = wn2.getTextContent().equalsIgnoreCase("true");
317+
} else if (wn2.getNodeName().equalsIgnoreCase("randomizeTraits")) {
318+
retVal.randomizeTraits = wn2.getTextContent().equalsIgnoreCase("true");
306319
} else if (wn2.getNodeName().equalsIgnoreCase("useClanBonuses")) {
307320
retVal.useClanBonuses = wn2.getTextContent().equalsIgnoreCase("true");
308321
} else if (wn2.getNodeName().equalsIgnoreCase("antiMekProb")) {

MekHQ/src/mekhq/campaign/personnel/Person.java

+48-4
Original file line numberDiff line numberDiff line change
@@ -4924,15 +4924,41 @@ public int getConnections() {
49244924
}
49254925

49264926
public void setConnections(final int connections) {
4927-
this.connections = connections;
4927+
this.connections = clamp(connections, MINIMUM_CONNECTIONS, MAXIMUM_CONNECTIONS);
4928+
}
4929+
4930+
/**
4931+
* Adjusts the person's Connections score by the specified amount.
4932+
*
4933+
* <p>The change in connections can be positive or negative, depending on the provided delta value.</p>
4934+
*
4935+
* @param delta The amount by which to adjust the number of connections. A positive value increases the connections,
4936+
* while a negative value decreases them.
4937+
*/
4938+
public void changeConnections(final int delta) {
4939+
int newValue = connections + delta;
4940+
connections = clamp(newValue, MINIMUM_CONNECTIONS, MAXIMUM_CONNECTIONS);
49284941
}
49294942

49304943
public int getWealth() {
49314944
return wealth;
49324945
}
49334946

49344947
public void setWealth(final int wealth) {
4935-
this.wealth = wealth;
4948+
this.wealth = clamp(wealth, MINIMUM_REPUTATION, MAXIMUM_REPUTATION);
4949+
}
4950+
4951+
/**
4952+
* Adjusts the person's wealth by the specified amount.
4953+
*
4954+
* <p>The change in wealth can be positive or negative, depending on the provided delta value.</p>
4955+
*
4956+
* @param delta The amount by which to adjust the wealth. A positive value increases the wealth, while a negative
4957+
* value decreases it.
4958+
*/
4959+
public void changeWealth(final int delta) {
4960+
int newValue = wealth + delta;
4961+
wealth = clamp(newValue, MINIMUM_WEALTH, MAXIMUM_WEALTH);
49364962
}
49374963

49384964
/**
@@ -4960,15 +4986,33 @@ public int getReputation() {
49604986
}
49614987

49624988
public void setReputation(final int reputation) {
4963-
this.reputation = reputation;
4989+
this.reputation = clamp(reputation, MINIMUM_REPUTATION, MAXIMUM_REPUTATION);
4990+
}
4991+
4992+
/**
4993+
* Adjusts the person's reputation by the specified amount.
4994+
*
4995+
* <p>The change in reputation can be positive or negative, depending on the provided delta value.</p>
4996+
*
4997+
* @param delta The amount by which to adjust the reputation. A positive value increases the reputation, while a
4998+
* negative value decreases it.
4999+
*/
5000+
public void changeReputation(final int delta) {
5001+
int newValue = reputation + delta;
5002+
reputation = clamp(newValue, MINIMUM_REPUTATION, MAXIMUM_REPUTATION);
49645003
}
49655004

49665005
public int getUnlucky() {
49675006
return unlucky;
49685007
}
49695008

49705009
public void setUnlucky(final int unlucky) {
4971-
this.unlucky = unlucky;
5010+
this.unlucky = clamp(unlucky, MINIMUM_UNLUCKY, MAXIMUM_UNLUCKY);
5011+
}
5012+
5013+
public void changeUnlucky(final int delta) {
5014+
int newValue = unlucky + delta;
5015+
unlucky = clamp(newValue, MINIMUM_UNLUCKY, MAXIMUM_UNLUCKY);
49725016
}
49735017

49745018
/**

MekHQ/src/mekhq/campaign/personnel/generator/AbstractSkillGenerator.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@
3535
import mekhq.campaign.Campaign;
3636
import mekhq.campaign.RandomSkillPreferences;
3737
import mekhq.campaign.personnel.Person;
38-
import mekhq.campaign.personnel.skills.Skill;
39-
import mekhq.campaign.personnel.skills.SkillType;
4038
import mekhq.campaign.personnel.enums.PersonnelRole;
4139
import mekhq.campaign.personnel.skills.Skill;
4240
import mekhq.campaign.personnel.skills.SkillType;
@@ -78,6 +76,8 @@ public void setSkillPreferences(RandomSkillPreferences skillPreferences) {
7876
*/
7977
public abstract void generateSkills(Campaign campaign, Person person, int expLvl);
8078

79+
public abstract void generateTraits(Person person);
80+
8181
/**
8282
* Generates the default skills for a {@link Person} based on their primary role.
8383
*
@@ -88,7 +88,7 @@ public void setSkillPreferences(RandomSkillPreferences skillPreferences) {
8888
* @param rollModifier A roll modifier to apply to any randomizations.
8989
*/
9090
protected void generateDefaultSkills(Person person, PersonnelRole primaryRole, int expLvl, int bonus,
91-
int rollModifier) {
91+
int rollModifier) {
9292
switch (primaryRole) {
9393
case MEKWARRIOR:
9494
addSkill(person, SkillType.S_PILOT_MEK, expLvl, rskillPrefs.randomizeSkill(), bonus, rollModifier);
@@ -209,12 +209,12 @@ public static void addSkill(Person person, String skillName, int level, int bonu
209209
}
210210

211211
protected static void addSkill(Person person, String skillName, int experienceLevel, boolean randomizeLevel,
212-
int bonus) {
212+
int bonus) {
213213
addSkill(person, skillName, experienceLevel, randomizeLevel, bonus, 0);
214214
}
215215

216216
protected static void addSkill(Person person, String skillName, int experienceLevel, boolean randomizeLevel,
217-
int bonus, int rollMod) {
217+
int bonus, int rollMod) {
218218
if (randomizeLevel) {
219219
person.addSkill(skillName, Skill.randomizeLevel(skillName, experienceLevel, bonus, rollMod));
220220
} else {

MekHQ/src/mekhq/campaign/personnel/generator/DefaultPersonnelGenerator.java

+1
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,7 @@ public Person generate(Campaign campaign, PersonnelRole primaryRole, PersonnelRo
103103

104104
AbstractSkillGenerator skillGenerator = new DefaultSkillGenerator(getSkillPreferences());
105105
skillGenerator.generateSkills(campaign, person, expLvl);
106+
skillGenerator.generateTraits(person);
106107

107108
// Limit skills by age for children and adolescents
108109
int age = person.getAge(campaign.getLocalDate());

MekHQ/src/mekhq/campaign/personnel/generator/DefaultSkillGenerator.java

+50-3
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,19 @@
2727
*/
2828
package mekhq.campaign.personnel.generator;
2929

30+
import static megamek.common.Compute.d6;
31+
import static megamek.common.Compute.randomInt;
3032
import static mekhq.campaign.personnel.skills.SkillDeprecationTool.DEPRECATED_SKILLS;
3133
import static mekhq.campaign.personnel.skills.enums.SkillSubType.SUPPORT_COMMAND;
3234

3335
import java.util.ArrayList;
3436
import java.util.List;
3537

36-
import megamek.common.Compute;
3738
import mekhq.Utilities;
3839
import mekhq.campaign.Campaign;
3940
import mekhq.campaign.CampaignOptions;
4041
import mekhq.campaign.RandomSkillPreferences;
4142
import mekhq.campaign.personnel.Person;
42-
import mekhq.campaign.personnel.skills.SkillType;
4343
import mekhq.campaign.personnel.enums.PersonnelRole;
4444
import mekhq.campaign.personnel.skills.SkillType;
4545

@@ -147,9 +147,56 @@ public void generateSkills(final Campaign campaign, final Person person, final i
147147
}
148148
}
149149

150-
String selSkill = possibleSkills.get(Compute.randomInt(possibleSkills.size()));
150+
String selSkill = possibleSkills.get(randomInt(possibleSkills.size()));
151151
int secondLvl = Utilities.generateExpLevel(rskillPrefs.getSecondSkillBonus());
152152
addSkill(person, selSkill, secondLvl, rskillPrefs.randomizeSkill(), 0);
153153
}
154154
}
155+
156+
/**
157+
* Generates traits for the specified person based on random or pre-determined criteria.
158+
*
159+
* <p>When randomization is enabled, this method calculates and assigns specific traits such as connections,
160+
* reputation, wealth, and bad luck using random rolls. Each trait has its own set of rules for adjustment.</p>
161+
*
162+
* @param person The person whose traits will be updated. Traits are adjusted based on random rolls when
163+
* randomization is enabled.
164+
*/
165+
@Override
166+
public void generateTraits(Person person) {
167+
if (!getSkillPreferences().isRandomizeTraits()) {
168+
return;
169+
}
170+
171+
// Connections
172+
if (d6() == 6) {
173+
person.setConnections(1);
174+
} else {
175+
person.setConnections(0);
176+
}
177+
178+
// Reputation
179+
int roll = d6();
180+
if (roll == 6 || roll == 1) {
181+
person.setReputation(roll == 6 ? 1 : -1);
182+
} else {
183+
person.setReputation(0);
184+
}
185+
186+
// Wealth
187+
roll = d6();
188+
if (roll == 6 || roll == 1) {
189+
person.setWealth(roll == 6 ? 1 : -1);
190+
} else {
191+
person.setWealth(0);
192+
}
193+
194+
// Unlucky
195+
roll = randomInt(20);
196+
if (roll == 0) {
197+
person.setUnlucky(1);
198+
} else {
199+
person.setUnlucky(0);
200+
}
201+
}
155202
}

MekHQ/src/mekhq/gui/adapter/PersonnelTableMouseAdapter.java

+17
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ public class PersonnelTableMouseAdapter extends JPopupMenuAdapter {
218218
private static final String CMD_PERSONALITY = "PERSONALITY";
219219
private static final String CMD_ADD_RANDOM_ABILITY = "ADD_RANDOM_ABILITY";
220220
private static final String CMD_GENERATE_ROLEPLAY_SKILLS = "GENERATE_ROLEPLAY_SKILLS";
221+
private static final String CMD_GENERATE_ROLEPLAY_TRAITS = "GENERATE_ROLEPLAY_TRAITS";
221222

222223
private static final String CMD_FREE = "FREE";
223224
private static final String CMD_EXECUTE = "EXECUTE";
@@ -1395,6 +1396,15 @@ public void actionPerformed(ActionEvent action) {
13951396
}
13961397
break;
13971398
}
1399+
case CMD_GENERATE_ROLEPLAY_TRAITS: {
1400+
RandomSkillPreferences skillPreferences = getCampaign().getRandomSkillPreferences();
1401+
AbstractSkillGenerator skillGenerator = new DefaultSkillGenerator(skillPreferences);
1402+
for (Person person : people) {
1403+
skillGenerator.generateTraits(person);
1404+
MekHQ.triggerEvent(new PersonChangedEvent(person));
1405+
}
1406+
break;
1407+
}
13981408

13991409
// region Randomization Menu
14001410
case CMD_RANDOM_NAME: {
@@ -3673,6 +3683,13 @@ protected Optional<JPopupMenu> createPopupMenu() {
36733683
menuItem.addActionListener(this);
36743684
menu.add(menuItem);
36753685

3686+
if (getCampaign().getRandomSkillPreferences().isRandomizeTraits()) {
3687+
menuItem = new JMenuItem(resources.getString("generateRoleplayTraits.text"));
3688+
menuItem.setActionCommand(CMD_GENERATE_ROLEPLAY_TRAITS);
3689+
menuItem.addActionListener(this);
3690+
menu.add(menuItem);
3691+
}
3692+
36763693
JMenu attributesMenu = new JMenu(resources.getString("spendOnAttributes.set"));
36773694

36783695
for (SkillAttribute attribute : SkillAttribute.values()) {

MekHQ/src/mekhq/gui/campaignOptions/contents/AdvancementTab.java

+10-3
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
import mekhq.campaign.Campaign;
4444
import mekhq.campaign.CampaignOptions;
4545
import mekhq.campaign.RandomSkillPreferences;
46-
import mekhq.campaign.personnel.skills.SkillType;
4746
import mekhq.campaign.personnel.enums.PersonnelRole;
4847
import mekhq.campaign.personnel.enums.Phenotype;
4948
import mekhq.campaign.personnel.skills.SkillType;
@@ -114,6 +113,7 @@ public class AdvancementTab {
114113

115114
//start Skill Randomization Tab
116115
private JCheckBox chkExtraRandomness;
116+
private JCheckBox chkRandomizeTraits;
117117

118118
private JPanel pnlPhenotype;
119119
private JLabel[] phenotypeLabels;
@@ -520,6 +520,7 @@ private JPanel createAdministratorsPanel() {
520520
*/
521521
private void initializeSkillRandomizationTab() {
522522
chkExtraRandomness = new JCheckBox();
523+
chkRandomizeTraits = new JCheckBox();
523524

524525
pnlPhenotype = new JPanel();
525526
phenotypeLabels = new JLabel[] {}; // This will be initialized properly later
@@ -604,6 +605,7 @@ public JPanel skillRandomizationTab() {
604605

605606
// Contents
606607
chkExtraRandomness = new CampaignOptionsCheckBox("ExtraRandomness");
608+
chkRandomizeTraits = new CampaignOptionsCheckBox("RandomizeTraits");
607609

608610
pnlPhenotype = createPhenotypePanel();
609611
pnlRandomAbilities = createAbilityPanel();
@@ -621,6 +623,9 @@ public JPanel skillRandomizationTab() {
621623
layout.gridwidth = 1;
622624
panel.add(chkExtraRandomness, layout);
623625

626+
layout.gridy++;
627+
panel.add(chkRandomizeTraits, layout);
628+
624629
layout.gridx = 0;
625630
layout.gridy++;
626631
panel.add(pnlPhenotype, layout);
@@ -1100,7 +1105,7 @@ public void loadValuesFromCampaignOptions() {
11001105
* {@code null}, values are loaded from the current skill preferences.
11011106
*/
11021107
public void loadValuesFromCampaignOptions(@Nullable CampaignOptions presetCampaignOptions,
1103-
@Nullable RandomSkillPreferences presetRandomSkillPreferences) {
1108+
@Nullable RandomSkillPreferences presetRandomSkillPreferences) {
11041109
CampaignOptions options = presetCampaignOptions;
11051110
if (presetCampaignOptions == null) {
11061111
options = this.campaignOptions;
@@ -1132,6 +1137,7 @@ public void loadValuesFromCampaignOptions(@Nullable CampaignOptions presetCampai
11321137

11331138
//start Skill Randomization Tab
11341139
chkExtraRandomness.setSelected(skillPreferences.randomizeSkill());
1140+
chkRandomizeTraits.setSelected(skillPreferences.isRandomizeTraits());
11351141
final int[] phenotypeProbabilities = options.getPhenotypeProbabilities();
11361142
for (int i = 0; i < phenotypeSpinners.length; i++) {
11371143
phenotypeSpinners[i].setValue(phenotypeProbabilities[i]);
@@ -1184,7 +1190,7 @@ public void loadValuesFromCampaignOptions(@Nullable CampaignOptions presetCampai
11841190
* {@code null}, values are applied to the current skill preferences.
11851191
*/
11861192
public void applyCampaignOptionsToCampaign(@Nullable CampaignOptions presetCampaignOptions,
1187-
@Nullable RandomSkillPreferences presetRandomSkillPreferences) {
1193+
@Nullable RandomSkillPreferences presetRandomSkillPreferences) {
11881194
CampaignOptions options = presetCampaignOptions;
11891195
if (presetCampaignOptions == null) {
11901196
options = this.campaignOptions;
@@ -1216,6 +1222,7 @@ public void applyCampaignOptionsToCampaign(@Nullable CampaignOptions presetCampa
12161222

12171223
//start Skill Randomization Tab
12181224
skillPreferences.setRandomizeSkill(chkExtraRandomness.isSelected());
1225+
skillPreferences.setRandomizeTraits(chkRandomizeTraits.isSelected());
12191226
for (int i = 0; i < phenotypeSpinners.length; i++) {
12201227
options.setPhenotypeProbability(i, (int) phenotypeSpinners[i].getValue());
12211228
}

0 commit comments

Comments
 (0)