Skip to content

Commit

Permalink
Merge pull request #4931 from IllianiCBT/atb_bonusRolls
Browse files Browse the repository at this point in the history
Reworked AtB Bonus Rolls, Fixed Bug in Bulk Hire
  • Loading branch information
IllianiCBT authored Oct 2, 2024
2 parents 014fd07 + b3b6c2a commit 50fdd64
Show file tree
Hide file tree
Showing 3 changed files with 107 additions and 91 deletions.
114 changes: 64 additions & 50 deletions MekHQ/src/mekhq/campaign/mission/AtBContract.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,18 @@
*/
package mekhq.campaign.mission;

import megamek.client.generator.RandomCallsignGenerator;
import megamek.client.generator.RandomNameGenerator;
import megamek.client.generator.RandomUnitGenerator;
import megamek.client.ratgenerator.FactionRecord;
import megamek.client.ratgenerator.RATGenerator;
import megamek.client.ratgenerator.UnitTable;
import megamek.client.ui.swing.util.PlayerColour;
import megamek.common.*;
import megamek.common.Compute;
import megamek.common.Entity;
import megamek.common.UnitType;
import megamek.common.enums.Gender;
import megamek.common.enums.SkillLevel;
import megamek.common.icons.Camouflage;
import megamek.common.loaders.EntityLoadingException;
import megamek.logging.MMLogger;
import mekhq.MekHQ;
import mekhq.campaign.Campaign;
Expand All @@ -45,6 +46,7 @@
import mekhq.campaign.personnel.Bloodname;
import mekhq.campaign.personnel.Person;
import mekhq.campaign.personnel.backgrounds.BackgroundsController;
import mekhq.campaign.personnel.enums.PersonnelRole;
import mekhq.campaign.personnel.enums.Phenotype;
import mekhq.campaign.rating.IUnitRating;
import mekhq.campaign.stratcon.StratconCampaignState;
Expand Down Expand Up @@ -77,8 +79,13 @@
import static megamek.common.enums.SkillLevel.REGULAR;
import static megamek.common.enums.SkillLevel.parseFromInteger;
import static megamek.common.enums.SkillLevel.parseFromString;
import static mekhq.campaign.mission.AtBDynamicScenarioFactory.getEntity;
import static mekhq.campaign.mission.BotForceRandomizer.UNIT_WEIGHT_UNSPECIFIED;
import static mekhq.campaign.universe.Factions.getFactionLogo;
import static mekhq.campaign.universe.fameAndInfamy.BatchallFactions.BATCHALL_FACTIONS;
import static mekhq.gui.dialog.HireBulkPersonnelDialog.overrideSkills;
import static mekhq.gui.dialog.HireBulkPersonnelDialog.reRollAdvantages;
import static mekhq.gui.dialog.HireBulkPersonnelDialog.reRollLoyalty;

/**
* Contract class for use with Against the Bot rules
Expand Down Expand Up @@ -643,77 +650,84 @@ public int getContractScoreArbitraryModifier() {
return contractScoreArbitraryModifier;
}

public void doBonusRoll(Campaign c) {
public void doBonusRoll(Campaign campaign) {
int number;
String rat = null;
int roll = Compute.d6();

switch (roll) {
case 1: /* 1d6 dependents */
if (c.getCampaignOptions().isUseRandomDependentAddition()) {
if (campaign.getCampaignOptions().isUseRandomDependentAddition()) {
number = Compute.d6();
c.addReport("Bonus: " + number + " dependent" + ((number > 1) ? "s" : ""));
campaign.addReport("Bonus: " + number + " dependent" + ((number > 1) ? "s" : ""));

for (int i = 0; i < number; i++) {
Person p = c.newDependent(false, Gender.RANDOMIZE);
c.recruitPerson(p);
Person p = campaign.newDependent(false, Gender.RANDOMIZE);
campaign.recruitPerson(p);
}
}
break;
case 2: /* Recruit (choose) */
c.addReport("Bonus: hire one recruit of your choice.");
case 2:
campaign.addReport("Bonus: Ronin");
recruitRonin(campaign);
break;
case 3: /* 1d6 parts */
number = Compute.d6();
numBonusParts += number;
c.addReport("Bonus: " + number + " part" + ((number > 1) ? "s" : ""));
case 3:
numBonusParts++;
campaign.addReport("Bonus: Part");
break;
case 4: /* civilian vehicle */
rat = "CivilianUnits_CivVeh";
c.addReport("Bonus: civilian vehicle");
case 4:
campaign.addReport("Bonus: Unit");
addBonusUnit(campaign, UnitType.TANK);
break;
case 5: /* APC */
rat = "CivilianUnits_APC";
c.addReport("Bonus: civilian APC");
case 5:
campaign.addReport("Bonus: Unit");
addBonusUnit(campaign, UnitType.AEROSPACEFIGHTER);
break;
case 6: /* civilian 'Mek */
rat = "CivilianUnits_PrimMek";
c.addReport("Bonus: civilian Mek");
case 6:
campaign.addReport("Bonus: Unit");
addBonusUnit(campaign, MEK);
break;
default:
throw new IllegalStateException(
"Unexpected value in mekhq/campaign/mission/AtBContract.java/doBonusRoll: " + roll);
"Unexpected value in mekhq/campaign/mission/AtBContract.java/doBonusRoll: " + roll);
}
}

if (null != rat) {
Entity en = null;
RandomUnitGenerator.getInstance().setChosenRAT(rat);
ArrayList<MekSummary> msl = RandomUnitGenerator.getInstance().generate(1);
/**
* Generates a Ronin and adds them to the personnel roster.
*
* @param campaign the current campaign.
*/
private static void recruitRonin(Campaign campaign) {
Person ronin = campaign.newPerson(PersonnelRole.MEKWARRIOR);

int quality = 3;
overrideSkills(campaign, ronin, PersonnelRole.MEKWARRIOR,
Objects.requireNonNull(SkillLevel.VETERAN).ordinal());

if (c.getCampaignOptions().isUseRandomUnitQualities()) {
quality = Unit.getRandomUnitQuality(0);
}
reRollLoyalty(ronin, ronin.getExperienceLevel(campaign, false));
reRollAdvantages(campaign, ronin, ronin.getExperienceLevel(campaign, false));
ronin.setCallsign(RandomCallsignGenerator.getInstance().generate());

if (!msl.isEmpty() && (msl.get(0) != null)) {
try {
en = new MekFileParser(msl.get(0).getSourceFile(), msl.get(0).getEntryName()).getEntity();
} catch (EntityLoadingException ex) {
logger.error("Unable to load entity: {}: {}: {}",
msl.get(0).getSourceFile(),
msl.get(0).getEntryName(),
ex.getMessage(),
ex);
}
}
campaign.recruitPerson(ronin, true);
}

if (null != en) {
c.addNewUnit(en, false, 0, quality);
} else {
c.addReport("<html><font color='" + MekHQ.getMHQOptions().getFontColorNegativeHexColor()
+ "'>Could not load unit</font></html>");
}
/**
* Generates a bonus unit for a given campaign and unit type.
*
* @param campaign the campaign object to add the bonus unit to
* @param unitType the type of unit for the bonus
*/
private void addBonusUnit(Campaign campaign, int unitType) {
String faction = employerCode;
int quality = allyQuality;

if (Compute.randomInt(2) > 0) {
faction = enemyCode;
quality = enemyQuality;
}

Entity newUnit = getEntity(faction, REGULAR, quality, unitType,
UNIT_WEIGHT_UNSPECIFIED, null, campaign);
campaign.addNewUnit(newUnit, false, 0);
}

public boolean isSubcontract() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -494,7 +494,7 @@ public static int generateForce(AtBDynamicScenario scenario, AtBContract contrac
} else if (forceTemplate.getAllowedUnitType() == ScenarioForceTemplate.SPECIAL_UNIT_TYPE_ATB_AERO_MIX) {
requiredRoles.put(UnitType.CONV_FIGHTER, new ArrayList<>(baseRoles));
requiredRoles.put(UnitType.AEROSPACEFIGHTER, new ArrayList<>(baseRoles));
} else if (forceTemplate.getAllowedUnitType() == ScenarioForceTemplate.SPECIAL_UNIT_TYPE_ATB_CIVILIANS) {
} else if (forceTemplate.getAllowedUnitType() == SPECIAL_UNIT_TYPE_ATB_CIVILIANS) {
// TODO: this will need to be adjusted to cover SUPPORT and CIVILIAN separately
for (int i = 0; i <= UnitType.AERO; i++) {
if (CIVILIAN.fitsUnitType(i)) {
Expand Down
82 changes: 42 additions & 40 deletions MekHQ/src/mekhq/gui/dialog/HireBulkPersonnelDialog.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,14 @@
import mekhq.campaign.Campaign;
import mekhq.campaign.RandomSkillPreferences;
import mekhq.campaign.personnel.Person;
import mekhq.campaign.personnel.SkillType;
import mekhq.campaign.personnel.PersonnelOptions;
import mekhq.campaign.personnel.education.EducationController;
import mekhq.campaign.personnel.SkillType;
import mekhq.campaign.personnel.enums.PersonnelRole;
import mekhq.campaign.personnel.enums.Profession;
import mekhq.campaign.personnel.generator.AbstractSpecialAbilityGenerator;
import mekhq.campaign.personnel.generator.DefaultSpecialAbilityGenerator;
import mekhq.gui.CampaignGUI;
import mekhq.gui.displayWrappers.RankDisplay;
import org.apache.logging.log4j.LogManager;

import javax.swing.*;
import javax.swing.JSpinner.DefaultEditor;
Expand All @@ -57,20 +55,6 @@
import static mekhq.campaign.personnel.SkillType.*;
import static mekhq.campaign.personnel.generator.AbstractSkillGenerator.addSkill;

import javax.swing.*;
import javax.swing.JSpinner.DefaultEditor;
import javax.swing.JSpinner.NumberEditor;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Objects;
import java.util.ResourceBundle;

import static mekhq.campaign.personnel.SkillType.*;
import static mekhq.campaign.personnel.generator.AbstractSkillGenerator.addSkill;

/**
* @author Jay Lawson
*/
Expand Down Expand Up @@ -379,31 +363,12 @@ private void hire(boolean isGmHire) {
} else if (age < 18) {
person.limitSkills(0);
}

// re-roll SPAs to include in any age and skill adjustments
Enumeration<IOption> options = new PersonnelOptions().getOptions(PersonnelOptions.LVL3_ADVANTAGES);

for (IOption option : Collections.list(options)) {
person.getOptions().getOption(option.getName()).clearValue();
}

int experienceLevel = person.getExperienceLevel(campaign, false);

if (experienceLevel <= 0) {
person.setLoyalty(Compute.d6(3) + 2);
} else if (experienceLevel == 1) {
person.setLoyalty(Compute.d6(3) + 1);
} else {
person.setLoyalty(Compute.d6(3));
}

if (experienceLevel > 0) {
AbstractSpecialAbilityGenerator specialAbilityGenerator = new DefaultSpecialAbilityGenerator();
specialAbilityGenerator.setSkillPreferences(new RandomSkillPreferences());
specialAbilityGenerator.generateSpecialAbilities(campaign, person, experienceLevel);
}
}

int experienceLevel = person.getExperienceLevel(campaign, false);

reRollLoyalty(person, experienceLevel);
reRollAdvantages(campaign, person, experienceLevel);

if (!campaign.recruitPerson(person, isGmHire)) {
number = 0;
Expand All @@ -413,6 +378,43 @@ private void hire(boolean isGmHire) {
}
}

/**
* Re-rolls the SPAs of a person based on their experience level.
*
* @param campaign The current campaign.
* @param person The person whose advantages are being re-rolled.
* @param experienceLevel The experience level of the person.
*/
public static void reRollAdvantages(Campaign campaign, Person person, int experienceLevel) {
Enumeration<IOption> options = new PersonnelOptions().getOptions(PersonnelOptions.LVL3_ADVANTAGES);

for (IOption option : Collections.list(options)) {
person.getOptions().getOption(option.getName()).clearValue();
}

if (experienceLevel > 0) {
AbstractSpecialAbilityGenerator specialAbilityGenerator = new DefaultSpecialAbilityGenerator();
specialAbilityGenerator.setSkillPreferences(new RandomSkillPreferences());
specialAbilityGenerator.generateSpecialAbilities(campaign, person, experienceLevel);
}
}

/**
* Re-rolls the loyalty of a person based on their experience level.
*
* @param person The person whose loyalty is being re-rolled.
* @param experienceLevel The experience level of the person.
*/
public static void reRollLoyalty(Person person, int experienceLevel) {
if (experienceLevel <= 0) {
person.setLoyalty(Compute.d6(3) + 2);
} else if (experienceLevel == 1) {
person.setLoyalty(Compute.d6(3) + 1);
} else {
person.setLoyalty(Compute.d6(3));
}
}

/**
* Replaces the skills for a {@link Person} based on their primary role and desired experience level.
*
Expand Down

0 comments on commit 50fdd64

Please sign in to comment.