Skip to content

Commit

Permalink
Merge pull request #5690 from IllianiCBT/garrison_routed
Browse files Browse the repository at this point in the history
Added Potential Difficulty Spikes to Garrison-Type Contracts
Sleet01 authored Jan 9, 2025
2 parents 38ab0a8 + 09ec58a commit ff53b77
Showing 4 changed files with 55 additions and 17 deletions.
Original file line number Diff line number Diff line change
@@ -25,4 +25,4 @@ lblSharePct.text=<html><nobr><b>Shares:</b></nobr></html>
lblCargoRequirement.text=<html><nobr><b>Estimated Cargo Requirement:</b></nobr></html>

txtGarrisonMoraleRouted.text=Peaceful
txtGarrisonMoraleRouted.tooltip=It's quiet, too quiet...
txtGarrisonMoraleRouted.tooltip=There is no enemy activity in the Area of Operations.
66 changes: 52 additions & 14 deletions MekHQ/src/mekhq/campaign/mission/AtBContract.java
Original file line number Diff line number Diff line change
@@ -27,7 +27,6 @@
import megamek.client.ratgenerator.RATGenerator;
import megamek.client.ratgenerator.UnitTable;
import megamek.client.ui.swing.util.PlayerColour;
import megamek.common.Compute;
import megamek.common.Entity;
import megamek.common.TargetRoll;
import megamek.common.UnitType;
@@ -54,6 +53,7 @@
import mekhq.campaign.stratcon.StratconCampaignState;
import mekhq.campaign.stratcon.StratconContractDefinition;
import mekhq.campaign.stratcon.StratconContractInitializer;
import mekhq.campaign.stratcon.StratconTrackState;
import mekhq.campaign.unit.Unit;
import mekhq.campaign.universe.Faction;
import mekhq.campaign.universe.Factions;
@@ -81,7 +81,9 @@
import static java.lang.Math.round;
import static megamek.client.ratgenerator.ModelRecord.NETWORK_NONE;
import static megamek.client.ratgenerator.UnitTable.findTable;
import static megamek.codeUtilities.ObjectUtility.getRandomItem;
import static megamek.common.Compute.d6;
import static megamek.common.Compute.randomInt;
import static megamek.common.UnitType.MEK;
import static megamek.common.enums.SkillLevel.ELITE;
import static megamek.common.enums.SkillLevel.REGULAR;
@@ -93,6 +95,7 @@
import static mekhq.campaign.mission.AtBDynamicScenarioFactory.getEntity;
import static mekhq.campaign.mission.BotForceRandomizer.UNIT_WEIGHT_UNSPECIFIED;
import static mekhq.campaign.rating.IUnitRating.*;
import static mekhq.campaign.stratcon.StratconContractDefinition.getContractDefinition;
import static mekhq.campaign.universe.Factions.getFactionLogo;
import static mekhq.campaign.universe.fameAndInfamy.BatchallFactions.BATCHALL_FACTIONS;
import static mekhq.gui.dialog.HireBulkPersonnelDialog.overrideSkills;
@@ -458,18 +461,53 @@ public static boolean isMinorPower(final String factionCode) {
public void checkMorale(Campaign campaign, LocalDate today) {
// Check whether enemy forces have been reinforced, and whether any current rout continues
// beyond its expected date
boolean routContinue = Compute.randomInt(4) == 0;
boolean routContinue = randomInt(4) == 0;

// If there is a rout end date, and it's past today, update morale and enemy state accordingly
if (routEnd != null && !routContinue) {
if (routEnd != null) {
if (routContinue) {
return;
}

if (today.isAfter(routEnd)) {
setMoraleLevel(AtBMoraleLevel.STALEMATE);
int roll = randomInt(8);

// We use variable morale levels to spike morale up to a value above Stalemate.
// This works with the regenerated Scenario Odds to crease very high intensity
// spikes in otherwise low-key Garrison-type contracts.
AtBMoraleLevel newMoraleLevel = switch (roll) {
case 0,1 -> AtBMoraleLevel.STALEMATE;
case 2,3,4,5 -> AtBMoraleLevel.ADVANCING;
case 6,7 -> AtBMoraleLevel.DOMINATING;
case 8 -> AtBMoraleLevel.OVERWHELMING;
default -> AtBMoraleLevel.STALEMATE;
};

// If we have a StratCon enabled contract, regenerate Scenario Odds
if (stratconCampaignState != null) {
StratconContractDefinition contractDefinition = getContractDefinition(getContractType());

if (contractDefinition != null) {
List<Integer> definedScenarioOdds = contractDefinition.getScenarioOdds();

int scenarioOddsMultiplier = randomInt(20) == 0 ? 2 : 1;

for (StratconTrackState trackState : stratconCampaignState.getTracks()) {
int baseScenarioOdds = getRandomItem(definedScenarioOdds);

trackState.setScenarioOdds(baseScenarioOdds * scenarioOddsMultiplier);
}
}
}

moraleLevel = newMoraleLevel;
routEnd = null;

updateEnemy(campaign, today); // mix it up a little
} else {
setMoraleLevel(AtBMoraleLevel.ROUTED);
if (contractType.isGarrisonType() && !contractType.isRiotDuty()) {
updateEnemy(campaign, today); // mix it up a little
}
}

return;
}

@@ -567,18 +605,18 @@ public void checkMorale(Campaign campaign, LocalDate today) {
final AtBMoraleLevel[] moraleLevels = AtBMoraleLevel.values();

if (roll < 5) {
setMoraleLevel(moraleLevels[max(getMoraleLevel().ordinal() - 1, 0)]);
moraleLevel = moraleLevels[max(getMoraleLevel().ordinal() - 1, 0)];
logger.info("Result: Morale Level -1");
} else if ((roll > 9)) {
setMoraleLevel(moraleLevels[Math.min(getMoraleLevel().ordinal() + 1, moraleLevels.length - 1)]);
moraleLevel = moraleLevels[Math.min(getMoraleLevel().ordinal() + 1, moraleLevels.length - 1)];
logger.info("Result: Morale Level +1");
} else {
logger.info("Result: Morale Unchanged");
}

// Additional morale updates if morale level is set to 'Routed' and contract type is a garrison type
if (getMoraleLevel().isRouted()) {
if (getContractType().isGarrisonType()) {
if (moraleLevel.isRouted()) {
if (contractType.isGarrisonType() && !contractType.isRiotDuty()) {
routEnd = today.plusMonths(max(1, d6() - 3)).minusDays(1);
} else {
campaign.addReport("With the enemy routed, any remaining objectives have been successfully completed." +
@@ -818,7 +856,7 @@ private void addBonusUnit(Campaign campaign, int unitType) {
String faction = employerCode;
int quality = allyQuality;

if (Compute.randomInt(2) > 0) {
if (randomInt(2) > 0) {
faction = enemyCode;
quality = enemyQuality;
}
@@ -1007,7 +1045,7 @@ UnitMarketType.EMPLOYER, MEK, getEmployerFaction(),

public LocalDate getRandomDayOfMonth(LocalDate today) {
return LocalDate.of(today.getYear(), today.getMonth(),
Compute.randomInt(today.getMonth().length(today.isLeapYear())) + 1);
randomInt(today.getMonth().length(today.isLeapYear())) + 1);
}

public boolean contractExtended(final Campaign campaign) {
@@ -1481,7 +1519,7 @@ public void setStratconCampaignState(StratconCampaignState state) {
public void acceptContract(Campaign campaign) {
if (campaign.getCampaignOptions().isUseStratCon()) {
StratconContractInitializer.initializeCampaignState(this, campaign,
StratconContractDefinition.getContractDefinition(getContractType()));
getContractDefinition(getContractType()));
}
}

Original file line number Diff line number Diff line change
@@ -203,7 +203,7 @@ public static void initializeCampaignState(AtBContract contract, Campaign campai
}

// Determine starting morale
if (contract.getContractType().isGarrisonType()) {
if (contract.getContractType().isGarrisonDuty()) {
contract.setMoraleLevel(AtBMoraleLevel.ROUTED);

LocalDate routEnd = contract.getStartDate().plusMonths(Math.max(1, Compute.d6() - 3)).minusDays(1);
2 changes: 1 addition & 1 deletion MekHQ/src/mekhq/gui/view/MissionViewPanel.java
Original file line number Diff line number Diff line change
@@ -949,7 +949,7 @@ public void mouseClicked(MouseEvent e) {

txtMorale.setName("txtMorale");

if (contract.getContractType().isGarrisonType() && contract.getMoraleLevel().isRouted()) {
if (contract.getContractType().isGarrisonDuty() && contract.getMoraleLevel().isRouted()) {
txtMorale.setText(resourceMap.getString("txtGarrisonMoraleRouted.text"));
txtMorale.setToolTipText(wordWrap(resourceMap.getString("txtGarrisonMoraleRouted.tooltip")));
} else {

0 comments on commit ff53b77

Please sign in to comment.