8000 Refactor StratCon Reinforcement Logic and Improve Skill Checks by IllianiBird · Pull Request #6709 · MegaMek/mekhq · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Refactor StratCon Reinforcement Logic and Improve Skill Checks #6709

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

Merged
merged 4 commits into from
Apr 26, 2025
Merged
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
10 changes: 4 additions & 6 deletions MekHQ/resources/mekhq/resources/AtBStratCon.properties
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ reinforcementsCriticalFailure.text=%s<b>Critical Command Failure</b>%s. Reinforc
\ fails and Support Points are lost.
reinforcementsSuccess.text=%s<b>Reinforcement Success</b>%s.
reinforcementsAutomaticSuccess.text=%s<b>Automatic Success</b>%s.
reinforcementsSuccessRouted.text=%s<b>Reinforcement Success</b>%s. The enemy has routed\
\ and is unable to intercept your reinforcements.
reinforcementsCommandFailure.text=%s<b>Command Failure</b>%s. Reinforcements will arrive, but have\
\ been delayed.
reinforcementsInterceptionAttempt.text=Due to a %s<b>Command Failure</b>%s your reinforcements are\
Expand All @@ -44,13 +42,13 @@ reinforcementsErrorNoCommander.text=%s<b>Error</b>%s. There is no commander assi
reinforcementsErrorUnableToFetchCommander.text= %s<b>Error</b>%s. We were unable to fetch the\
\ commander using the commander ID logged for this force. You should report this bug.\
\ Reinforcement attempt fails and Support Point is lost.
reinforcementEvasionSuccessful.text=%s<b>Evasion Success</b>%s (%s vs. %s). The commander of the\
reinforcementEvasionSuccessful.text=%s<b>Evasion Success</b>%s. The commander of the\
\ reinforcements was able to use their <i>Tactics</i> skill to evade the enemy long enough to\
\ reach safety. Reinforcements were delayed, but successful.
reinforcementEvasionSuccessful.noSkill=%s<b>Evasion Success</b>%s (%s vs. %s). The commander of the\
reinforcementEvasionSuccessful.noSkill=%s<b>Evasion Success</b>%s. The commander of the\
\ reinforcements does not possess the <i>Tactics</i> skill. Despite this they were still able to\
\ evade the enemy long enough to reach safety. Reinforcements were delayed, but successful.
reinforcementEvasionUnsuccessful.text=%s<b>Evasion Unsuccessful</b>%s (%s vs. %s). The commander\
reinforcementEvasionUnsuccessful.text=%s<b>Evasion Unsuccessful</b>%s. The commander\
\ of the reinforcements attempted to use their <i>Tactics</i> skill to evade the enemy\
\ interception, but was unsuccessful. An interception scenario has occurred. The reinforcing\
\ force has already been assigned to this new scenario.
Expand Down Expand Up @@ -105,4 +103,4 @@ supportPoints.initial.noAdministrators=Your unit has no Admin/Transport personne
supportPoints.weekly.noAdministrators=Your unit has no Admin/Transport personnel. Therefore,\
\ you will not gain %s<b>any</b>%s additional Support Points this week.
supportPoints.weekly=The skill of your Admin/Transport personnel has created %s<b>%s</b>%s\
\ additional Support Point%s for contract %s.
\ additional Support Point%s for contract %s.
74 changes: 22 additions & 52 deletions MekHQ/src/mekhq/campaign/stratcon/StratconRulesManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
import static megamek.common.UnitType.DROPSHIP;
import static megamek.common.UnitType.JUMPSHIP;
import static megamek.common.UnitType.MEK;
import static megamek.common.enums.SkillLevel.REGULAR;
import static mekhq.campaign.force.Force.FORCE_NONE;
import static mekhq.campaign.icons.enums.OperationalStatus.determineLayeredForceIconOperationalStatus;
import static mekhq.campaign.mission.AtBDynamicScenarioFactory.finalizeScenario;
Expand All @@ -50,7 +51,6 @@
import static mekhq.campaign.mission.ScenarioMapParameters.MapLocation.SpecificGroundTerrain;
import static mekhq.campaign.personnel.skills.SkillType.S_ADMIN;
import static mekhq.campaign.personnel.skills.SkillType.S_TACTICS;
import static mekhq.campaign.personnel.skills.SkillType.getSkillHash;
import static mekhq.campaign.stratcon.StratconContractInitializer.getUnoccupiedCoords;
import static mekhq.campaign.stratcon.StratconRulesManager.ReinforcementEligibilityType.AUXILIARY;
import static mekhq.campaign.stratcon.StratconRulesManager.ReinforcementResultsType.DELAYED;
Expand All @@ -72,7 +72,6 @@
import megamek.common.Minefield;
import megamek.common.TargetRoll;
import megamek.common.annotations.Nullable;
import megamek.common.enums.SkillLevel;
import megamek.common.event.Subscribe;
import megamek.logging.MMLogger;
import mekhq.MHQConstants;
Expand Down Expand Up @@ -106,7 +105,7 @@
import mekhq.campaign.mission.resupplyAndCaches.StarLeagueCache.CacheType;
import mekhq.campaign.personnel.Person;
import mekhq.campaign.personnel.skills.Skill;
import mekhq.campaign.personnel.skills.SkillType;
import mekhq.campaign.personnel.skills.SkillCheckUtility;
import mekhq.campaign.personnel.turnoverAndRetention.Fatigue;
import mekhq.campaign.stratcon.StratconContractDefinition.StrategicObjectiveType;
import mekhq.campaign.stratcon.StratconScenario.ScenarioState;
Expand Down Expand Up @@ -1687,7 +1686,7 @@ public static ReinforcementResultsType processReinforcementDeployment(Force forc
int interceptionRoll = randomInt(100);

// Check passed
if (interceptionRoll >= interceptionOdds) {
if (interceptionRoll >= interceptionOdds || contract.getMoraleLevel().isRouted()) {
reportStatus.append(' ');
Comment on lines 1688 to 1690
Copy link
Preview
Copilot AI Apr 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verify that combining the interception roll check with the enemy morale routed condition is intentional, as this change may bypass some reporting or handling scenarios previously managed separately.

Copilot uses AI. Check for mistakes.

reportStatus.append(String.format(resources.getString("reinforcementsCommandFailure.text"),
spanOpeningWithCustomColor(MekHQ.getMHQOptions().getFontColorWarningHexColor()),
Expand All @@ -1696,16 +1695,6 @@ public static ReinforcementResultsType processReinforcementDeployment(Force forc
return DELAYED;
}

// Check failed, but enemy is routed
if (contract.getMoraleLevel().isRouted()) {
reportStatus.append(' ');
reportStatus.append(String.format(resources.getString("reinforcementsSuccessRouted.text"),
spanOpeningWithCustomColor(MekHQ.getMHQOptions().getFontColorPositiveHexColor()),
CLOSING_SPAN_TAG));
campaign.addReport(reportStatus.toString());
return SUCCESS;
}

// Check failed, enemy attempt interception
reportStatus.append(' ');
reportStatus.append(String.format(resources.getString("reinforcementsInterceptionAttempt.text"),
Expand Down Expand Up @@ -1738,31 +1727,23 @@ public static ReinforcementResultsType processReinforcementDeployment(Force forc
return FAILED;
}

campaign.addReport(reportStatus.toString());


roll = d6(2);
int targetNumber = 9;
Skill tactics = commander.getSkill(S_TACTICS);

if (tactics != null) {
targetNumber -= tactics.getFinalSkillValue(commander.getOptions());
} else {
// Effectively a -1 penalty for being unskilled
targetNumber++;
}
SkillCheckUtility skillCheckUtility = new SkillCheckUtility(commander, S_TACTICS, null, 0, true, false);
campaign.addReport(skillCheckUtility.getResultsText());

if (roll >= targetNumber) {
reportStatus.append(' ');
if (skillCheckUtility.isSuccess()) {
String reportString = tactics != null ?
resources.getString("reinforcementEvasionSuccessful.text") :
resources.getString("reinforcementEvasionSuccessful.noSkill");
reportStatus.append(String.format(reportString,
campaign.addReport(String.format(reportString,
spanOpeningWithCustomColor(MekHQ.getMHQOptions().getFontColorPositiveHexColor()),
Comment on lines +1738 to 1745
Copy link
Preview
Copilot AI Apr 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nitpick] Consider standardizing the reporting approach by either accumulating messages in reportStatus or using campaign.addReport consistently, to ensure clarity in the report output.

Copilot uses AI. Check for mistakes.

CLOSING_SPAN_TAG,
roll,
targetNumber));


campaign.addReport(reportStatus.toString());
CLOSING_SPAN_TAG));

if (campaign.getCampaignOptions().isUseFatigue()) {
increaseFatigue(force.getId(), campaign);
Expand All @@ -1771,13 +1752,11 @@ public static ReinforcementResultsType processReinforcementDeployment(Force forc
return DELAYED;
}

reportStatus.append(' ');
reportStatus.append(String.format(resources.getString("reinforcementEvasionUnsuccessful.text"),
campaign.addReport(String.format(resources.getString("reinforcementEvasionUnsuccessful.text"),
spanOpeningWithCustomColor(MekHQ.getMHQOptions().getFontColorNegativeHexColor()),
CLOSING_SPAN_TAG,
roll,
targetNumber));
campaign.addReport(reportStatus.toString());

ScenarioTemplate scenarioTemplate = getInterceptionScenarioTemplate(force, campaign.getHangar());

Expand Down Expand Up @@ -1869,35 +1848,26 @@ private static ScenarioTemplate getInterceptionScenarioTemplate(Force force, Han
*/
public static TargetRoll calculateReinforcementTargetNumber(@Nullable Person commandLiaison, AtBContract contract) {
// Create Target Roll
TargetRoll reinforcementTargetNumber = new TargetRoll();
TargetRoll reinforcementTargetNumber = new TargetRoll(7, "Base Target Number");

// Base Target Number
int skillTargetNumber = 12;
SkillType skillType = getSkillHash().get(S_ADMIN);
if (skillType != null) {
skillTargetNumber = getSkillHash().get(S_ADMIN).getTarget();
}

if (commandLiaison != null) {
Skill skill = commandLiaison.getSkill(S_ADMIN);

if (skill != null) {
skillTargetNumber = skill.getFinalSkillValue(commandLiaison.getOptions());
}

reinforcementTargetNumber.addModifier(skillTargetNumber,
"Administration (" + commandLiaison.getFullTitle() + ')');
Skill skill = commandLiaison != null ? commandLiaison.getSkill(S_ADMIN) : null;
int skillModifier;
if (skill == null) {
skillModifier = -REGULAR.getExperienceLevel();
} else {
reinforcementTargetNumber.addModifier(skillTargetNumber, "Administration (Unskilled)");
skillModifier = skill.getExperienceLevel() - REGULAR.getExperienceLevel();
}

// Admin Skill Modifier
reinforcementTargetNumber.addModifier(skillModifier, "Administration Skill");

// Enemy Morale Modifier
reinforcementTargetNumber.addModifier(contract.getMoraleLevel().ordinal(), "Enemy Morale");

// Skill Modifier
int skillModifier = contract.getEnemySkill().getAdjustedValue() - SkillLevel.REGULAR.getAdjustedValue();

reinforcementTargetNumber.addModifier(skillModifier, "Enemy Skill Modifier");
int enemySkillModifier = contract.getEnemySkill().getAdjustedValue() - REGULAR.getAdjustedValue();
reinforcementTargetNumber.addModifier(enemySkillModifier, "Enemy Skill Modifier");

// Liaison Modifier
ContractCommandRights commandRights = contract.getCommandRights();
Expand Down
Loading
0