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

Added Randomize Traits Option For Character Creation #6572

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
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
11 changes: 11 additions & 0 deletions MekHQ/resources/mekhq/resources/CampaignOptionsDialog.properties
Original file line number Diff line number Diff line change
Expand Up @@ -1796,6 +1796,17 @@ lblExtraRandomness.tooltip=If checked, an additional 1d6 will be rolled per skil
<br>\
<br><b>Warning:</b> Due to the way experience levels are calculated, enabling this option will\
\ more frequently have characters created with slightly lower than normal experience levels.
lblRandomizeTraits.text=Randomize Traits \u26A0 \uD83C\uDF1F
lblRandomizeTraits.tooltip=If checked, a newly created character's Connections, Wealth, Reputation, and Unlucky scores\
\ are randomized.\
<br>\
<br>For <b>Connections</b> a d6 is rolled, on a roll of 6 the character's Connections score becomes 1.\
<br>\
<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.\
\ While a roll of 1 causes their score to become -1.\
<br>\
<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\
\ thing.
lblPhenotypesPanel.text=Clan Trueborn Percentages
lblMekWarrior.text=MekWarrior
lblMekWarrior.tooltip=What percentage of Clan MekWarriors should have a Trueborn phenotype?
Expand Down
1 change: 1 addition & 0 deletions MekHQ/resources/mekhq/resources/GUI.properties
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ regenerateLoyalty.text=Regenerate Loyalty
regeneratePersonality.text=Regenerate Personality
addRandomSPA.text=Add Random SPA
generateRoleplaySkills.text=Generate Roleplay Skills
generateRoleplayTraits.text=Reset Roleplay Traits
addMinimumComplement.text=Add minimum complement
addMinimumComplementRandom.text=Random
addMinimumComplementElite.text=Elite
Expand Down
13 changes: 13 additions & 0 deletions MekHQ/src/mekhq/campaign/RandomSkillPreferences.java
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ public class RandomSkillPreferences {
private int overallRecruitBonus;
Map<PersonnelRole, Integer> recruitmentBonuses;
private boolean randomizeSkill;
private boolean randomizeTraits;
private boolean useClanBonuses;
private int antiMekProb;
private int[] specialAbilityBonus;
Expand All @@ -68,6 +69,7 @@ public RandomSkillPreferences() {
overallRecruitBonus = 0;
recruitmentBonuses = new HashMap<>();
randomizeSkill = true;
randomizeTraits = false;
useClanBonuses = true;
antiMekProb = 10;
combatSmallArmsBonus = -3;
Expand Down Expand Up @@ -173,6 +175,14 @@ public boolean randomizeSkill() {
return randomizeSkill;
}

public boolean isRandomizeTraits() {
return randomizeTraits;
}

public void setRandomizeTraits(boolean randomizeTraits) {
this.randomizeTraits = randomizeTraits;
}

public void setUseClanBonuses(boolean b) {
this.useClanBonuses = b;
}
Expand Down Expand Up @@ -269,6 +279,7 @@ public void writeToXML(final PrintWriter pw, int indent) {
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "commandSkillsModifier", commandSkillsModifier);
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "roleplaySkillsModifier", roleplaySkillsModifier);
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "randomizeSkill", randomizeSkill);
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "randomizeTraits", randomizeTraits);
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "useClanBonuses", useClanBonuses);
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "antiMekProb", antiMekProb);
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "combatSmallArmsBonus", combatSmallArmsBonus);
Expand Down Expand Up @@ -303,6 +314,8 @@ public static RandomSkillPreferences generateRandomSkillPreferencesFromXml(Node
retVal.overallRecruitBonus = Integer.parseInt(wn2.getTextContent().trim());
} else if (wn2.getNodeName().equalsIgnoreCase("randomizeSkill")) {
retVal.randomizeSkill = wn2.getTextContent().equalsIgnoreCase("true");
} else if (wn2.getNodeName().equalsIgnoreCase("randomizeTraits")) {
retVal.randomizeTraits = wn2.getTextContent().equalsIgnoreCase("true");
} else if (wn2.getNodeName().equalsIgnoreCase("useClanBonuses")) {
retVal.useClanBonuses = wn2.getTextContent().equalsIgnoreCase("true");
} else if (wn2.getNodeName().equalsIgnoreCase("antiMekProb")) {
Expand Down
52 changes: 48 additions & 4 deletions MekHQ/src/mekhq/campaign/personnel/Person.java
Original file line number Diff line number Diff line change
Expand Up @@ -4916,31 +4916,75 @@ public int getConnections() {
}

public void setConnections(final int connections) {
this.connections = connections;
this.connections = clamp(connections, MINIMUM_CONNECTIONS, MAXIMUM_CONNECTIONS);
}

/**
* Adjusts the person's Connections score by the specified amount.
*
* <p>The change in connections can be positive or negative, depending on the provided delta value.</p>
*
* @param delta The amount by which to adjust the number of connections. A positive value increases the connections,
* while a negative value decreases them.
*/
public void changeConnections(final int delta) {
int newValue = connections + delta;
connections = clamp(newValue, MINIMUM_CONNECTIONS, MAXIMUM_CONNECTIONS);
}

public int getWealth() {
return wealth;
}

public void setWealth(final int wealth) {
this.wealth = wealth;
this.wealth = clamp(wealth, MINIMUM_REPUTATION, MAXIMUM_REPUTATION);
}

/**
* Adjusts the person's wealth by the specified amount.
*
* <p>The change in wealth can be positive or negative, depending on the provided delta value.</p>
*
* @param delta The amount by which to adjust the wealth. A positive value increases the wealth, while a negative
* value decreases it.
*/
public void changeWealth(final int delta) {
int newValue = wealth + delta;
wealth = clamp(newValue, MINIMUM_WEALTH, MAXIMUM_WEALTH);
}

public int getReputation() {
return reputation;
}

public void setReputation(final int reputation) {
this.reputation = reputation;
this.reputation = clamp(reputation, MINIMUM_REPUTATION, MAXIMUM_REPUTATION);
}

/**
* Adjusts the person's reputation by the specified amount.
*
* <p>The change in reputation can be positive or negative, depending on the provided delta value.</p>
*
* @param delta The amount by which to adjust the reputation. A positive value increases the reputation, while a
* negative value decreases it.
*/
public void changeReputation(final int delta) {
int newValue = reputation + delta;
reputation = clamp(newValue, MINIMUM_REPUTATION, MAXIMUM_REPUTATION);
}

public int getUnlucky() {
return unlucky;
}

public void setUnlucky(final int unlucky) {
this.unlucky = unlucky;
this.unlucky = clamp(unlucky, MINIMUM_UNLUCKY, MAXIMUM_UNLUCKY);
}

public void changeUnlucky(final int delta) {
int newValue = unlucky + delta;
unlucky = clamp(newValue, MINIMUM_UNLUCKY, MAXIMUM_UNLUCKY);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@
import mekhq.campaign.Campaign;
import mekhq.campaign.RandomSkillPreferences;
import mekhq.campaign.personnel.Person;
import mekhq.campaign.personnel.skills.Skill;
import mekhq.campaign.personnel.skills.SkillType;
import mekhq.campaign.personnel.enums.PersonnelRole;
import mekhq.campaign.personnel.skills.Skill;
import mekhq.campaign.personnel.skills.SkillType;
Expand Down Expand Up @@ -78,6 +76,8 @@ public void setSkillPreferences(RandomSkillPreferences skillPreferences) {
*/
public abstract void generateSkills(Campaign campaign, Person person, int expLvl);

public abstract void generateTraits(Person person);

/**
* Generates the default skills for a {@link Person} based on their primary role.
*
Expand All @@ -88,7 +88,7 @@ public void setSkillPreferences(RandomSkillPreferences skillPreferences) {
* @param rollModifier A roll modifier to apply to any randomizations.
*/
protected void generateDefaultSkills(Person person, PersonnelRole primaryRole, int expLvl, int bonus,
int rollModifier) {
int rollModifier) {
switch (primaryRole) {
case MEKWARRIOR:
addSkill(person, SkillType.S_PILOT_MEK, expLvl, rskillPrefs.randomizeSkill(), bonus, rollModifier);
Expand Down Expand Up @@ -209,12 +209,12 @@ public static void addSkill(Person person, String skillName, int level, int bonu
}

protected static void addSkill(Person person, String skillName, int experienceLevel, boolean randomizeLevel,
int bonus) {
int bonus) {
addSkill(person, skillName, experienceLevel, randomizeLevel, bonus, 0);
}

protected static void addSkill(Person person, String skillName, int experienceLevel, boolean randomizeLevel,
int bonus, int rollMod) {
int bonus, int rollMod) {
if (randomizeLevel) {
person.addSkill(skillName, Skill.randomizeLevel(skillName, experienceLevel, bonus, rollMod));
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ public Person generate(Campaign campaign, PersonnelRole primaryRole, PersonnelRo

AbstractSkillGenerator skillGenerator = new DefaultSkillGenerator(getSkillPreferences());
skillGenerator.generateSkills(campaign, person, expLvl);
skillGenerator.generateTraits(person);

// Limit skills by age for children and adolescents
int age = person.getAge(campaign.getLocalDate());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,19 @@
*/
package mekhq.campaign.personnel.generator;

import static megamek.common.Compute.d6;
import static megamek.common.Compute.randomInt;
import static mekhq.campaign.personnel.skills.SkillDeprecationTool.DEPRECATED_SKILLS;
import static mekhq.campaign.personnel.skills.enums.SkillSubType.SUPPORT_COMMAND;

import java.util.ArrayList;
import java.util.List;

import megamek.common.Compute;
import mekhq.Utilities;
import mekhq.campaign.Campaign;
import mekhq.campaign.CampaignOptions;
import mekhq.campaign.RandomSkillPreferences;
import mekhq.campaign.personnel.Person;
import mekhq.campaign.personnel.skills.SkillType;
import mekhq.campaign.personnel.enums.PersonnelRole;
import mekhq.campaign.personnel.skills.SkillType;

Expand Down Expand Up @@ -147,9 +147,56 @@ public void generateSkills(final Campaign campaign, final Person person, final i
}
}

String selSkill = possibleSkills.get(Compute.randomInt(possibleSkills.size()));
String selSkill = possibleSkills.get(randomInt(possibleSkills.size()));
int secondLvl = Utilities.generateExpLevel(rskillPrefs.getSecondSkillBonus());
addSkill(person, selSkill, secondLvl, rskillPrefs.randomizeSkill(), 0);
}
}

/**
* Generates traits for the specified person based on random or pre-determined criteria.
*
* <p>When randomization is enabled, this method calculates and assigns specific traits such as connections,
* reputation, wealth, and bad luck using random rolls. Each trait has its own set of rules for adjustment.</p>
*
* @param person The person whose traits will be updated. Traits are adjusted based on random rolls when
* randomization is enabled.
*/
@Override
public void generateTraits(Person person) {
if (!getSkillPreferences().isRandomizeTraits()) {
return;
}

// Connections
if (d6() == 6) {
person.setConnections(1);
} else {
person.setConnections(0);
}

// Reputation
int roll = d6();
if (roll == 6 || roll == 1) {
person.setReputation(roll == 6 ? 1 : -1);
} else {
person.setReputation(0);
}

// Wealth
roll = d6();
if (roll == 6 || roll == 1) {
person.setWealth(roll == 6 ? 1 : -1);
} else {
person.setWealth(0);
}

// Unlucky
roll = randomInt(20);
if (roll == 0) {
person.setUnlucky(1);
} else {
person.setUnlucky(0);
}
}
}
17 changes: 17 additions & 0 deletions MekHQ/src/mekhq/gui/adapter/PersonnelTableMouseAdapter.java
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ public class PersonnelTableMouseAdapter extends JPopupMenuAdapter {
private static final String CMD_PERSONALITY = "PERSONALITY";
private static final String CMD_ADD_RANDOM_ABILITY = "ADD_RANDOM_ABILITY";
private static final String CMD_GENERATE_ROLEPLAY_SKILLS = "GENERATE_ROLEPLAY_SKILLS";
private static final String CMD_GENERATE_ROLEPLAY_TRAITS = "GENERATE_ROLEPLAY_TRAITS";

private static final String CMD_FREE = "FREE";
private static final String CMD_EXECUTE = "EXECUTE";
Expand Down Expand Up @@ -1367,6 +1368,15 @@ public void actionPerformed(ActionEvent action) {
}
break;
}
case CMD_GENERATE_ROLEPLAY_TRAITS: {
RandomSkillPreferences skillPreferences = getCampaign().getRandomSkillPreferences();
AbstractSkillGenerator skillGenerator = new DefaultSkillGenerator(skillPreferences);
for (Person person : people) {
skillGenerator.generateTraits(person);
MekHQ.triggerEvent(new PersonChangedEvent(person));
}
break;
}

// region Randomization Menu
case CMD_RANDOM_NAME: {
Expand Down Expand Up @@ -3631,6 +3641,13 @@ protected Optional<JPopupMenu> createPopupMenu() {
menuItem.addActionListener(this);
menu.add(menuItem);

if (getCampaign().getRandomSkillPreferences().isRandomizeTraits()) {
menuItem = new JMenuItem(resources.getString("generateRoleplayTraits.text"));
menuItem.setActionCommand(CMD_GENERATE_ROLEPLAY_TRAITS);
menuItem.addActionListener(this);
menu.add(menuItem);
}

JMenu attributesMenu = new JMenu(resources.getString("spendOnAttributes.set"));

for (SkillAttribute attribute : SkillAttribute.values()) {
Expand Down
13 changes: 10 additions & 3 deletions MekHQ/src/mekhq/gui/campaignOptions/contents/AdvancementTab.java
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@
import mekhq.campaign.Campaign;
import mekhq.campaign.CampaignOptions;
import mekhq.campaign.RandomSkillPreferences;
import mekhq.campaign.personnel.skills.SkillType;
import mekhq.campaign.personnel.enums.PersonnelRole;
import mekhq.campaign.personnel.enums.Phenotype;
import mekhq.campaign.personnel.skills.SkillType;
Expand Down Expand Up @@ -114,6 +113,7 @@ public class AdvancementTab {

//start Skill Randomization Tab
private JCheckBox chkExtraRandomness;
private JCheckBox chkRandomizeTraits;

private JPanel pnlPhenotype;
private JLabel[] phenotypeLabels;
Expand Down Expand Up @@ -520,6 +520,7 @@ private JPanel createAdministratorsPanel() {
*/
private void initializeSkillRandomizationTab() {
chkExtraRandomness = new JCheckBox();
chkRandomizeTraits = new JCheckBox();

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

// Contents
chkExtraRandomness = new CampaignOptionsCheckBox("ExtraRandomness");
chkRandomizeTraits = new CampaignOptionsCheckBox("RandomizeTraits");

pnlPhenotype = createPhenotypePanel();
pnlRandomAbilities = createAbilityPanel();
Expand All @@ -621,6 +623,9 @@ public JPanel skillRandomizationTab() {
layout.gridwidth = 1;
panel.add(chkExtraRandomness, layout);

layout.gridy++;
panel.add(chkRandomizeTraits, layout);

layout.gridx = 0;
layout.gridy++;
panel.add(pnlPhenotype, layout);
Expand Down Expand Up @@ -1100,7 +1105,7 @@ public void loadValuesFromCampaignOptions() {
* {@code null}, values are loaded from the current skill preferences.
*/
public void loadValuesFromCampaignOptions(@Nullable CampaignOptions presetCampaignOptions,
@Nullable RandomSkillPreferences presetRandomSkillPreferences) {
@Nullable RandomSkillPreferences presetRandomSkillPreferences) {
CampaignOptions options = presetCampaignOptions;
if (presetCampaignOptions == null) {
options = this.campaignOptions;
Expand Down Expand Up @@ -1132,6 +1137,7 @@ public void loadValuesFromCampaignOptions(@Nullable CampaignOptions presetCampai

//start Skill Randomization Tab
chkExtraRandomness.setSelected(skillPreferences.randomizeSkill());
chkRandomizeTraits.setSelected(skillPreferences.isRandomizeTraits());
final int[] phenotypeProbabilities = options.getPhenotypeProbabilities();
for (int i = 0; i < phenotypeSpinners.length; i++) {
phenotypeSpinners[i].setValue(phenotypeProbabilities[i]);
Expand Down Expand Up @@ -1184,7 +1190,7 @@ public void loadValuesFromCampaignOptions(@Nullable CampaignOptions presetCampai
* {@code null}, values are applied to the current skill preferences.
*/
public void applyCampaignOptionsToCampaign(@Nullable CampaignOptions presetCampaignOptions,
@Nullable RandomSkillPreferences presetRandomSkillPreferences) {
@Nullable RandomSkillPreferences presetRandomSkillPreferences) {
CampaignOptions options = presetCampaignOptions;
if (presetCampaignOptions == null) {
options = this.campaignOptions;
Expand Down Expand Up @@ -1216,6 +1222,7 @@ public void applyCampaignOptionsToCampaign(@Nullable CampaignOptions presetCampa

//start Skill Randomization Tab
skillPreferences.setRandomizeSkill(chkExtraRandomness.isSelected());
skillPreferences.setRandomizeTraits(chkRandomizeTraits.isSelected());
for (int i = 0; i < phenotypeSpinners.length; i++) {
options.setPhenotypeProbability(i, (int) phenotypeSpinners[i].getValue());
}
Expand Down
Loading