Skip to content

J21 Updates for get(0) to getFirst()#8897

Merged
rjhancock merged 2 commits into
MegaMek:mainfrom
rjhancock:language-updates
Apr 21, 2026
Merged

J21 Updates for get(0) to getFirst()#8897
rjhancock merged 2 commits into
MegaMek:mainfrom
rjhancock:language-updates

Conversation

@rjhancock

Copy link
Copy Markdown
Collaborator

J21 Updates for MHQ through gui.dialog

J21 Updates for MHQ through gui.dialog
Copilot AI review requested due to automatic review settings April 21, 2026 22:01
@rjhancock rjhancock requested a review from a team as a code owner April 21, 2026 22:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

This PR updates MekHQ code (including GUI dialogs and tests) to use Java 21 collection conveniences (e.g., getFirst(), addFirst(), getLast()), and replaces custom scrolling components with FastJScrollPane. It also removes a number of deprecated/unused dialog classes and makes several AtB-related logic changes in GUI flows.

Changes:

  • Replace list.get(0) / index-based first-element access with Java 21 getFirst() (and similar addFirst() / getLast() updates).
  • Replace JScrollPaneWithSpeed usage with megamek.common.ui.FastJScrollPane across multiple dialogs/views.
  • Remove multiple deprecated/unused dialogs and trim AtB-related branches in some UI logic (nag dialogs, personnel “sack”, contract market behaviors, etc.).

Reviewed changes

Copilot reviewed 126 out of 126 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
MekHQ/unittests/mekhq/io/idReferenceClasses/PersonIdReferenceTest.java Use getFirst() in assertions.
MekHQ/unittests/mekhq/campaign/universe/RegionPerimeterTest.java Use getFirst() for first element checks.
MekHQ/unittests/mekhq/campaign/randomEvents/prisoners/PrisonerEventManagerTest.java Use getFirst() for first boolean result.
MekHQ/unittests/mekhq/campaign/personnel/medical/advancedMedical/InjuryTypesTest.java Use getFirst() and reflow long Javadoc lines.
MekHQ/unittests/mekhq/campaign/personnel/familyTree/GenealogyTest.java Use getFirst() for first former spouse/child checks.
MekHQ/unittests/mekhq/campaign/personnel/BloodmarkTest.java Use getFirst() for first scheduled date assertion; reflow formatting.
MekHQ/unittests/mekhq/campaign/ResolveScenarioTrackerTest.java Use getFirst() and reflow Javadoc formatting.
MekHQ/unittests/mekhq/campaign/C3NetworkTest.java Use getFirst() for first network row; align Javadoc params.
MekHQ/src/mekhq/utilities/MHQXMLUtility.java Use getFirst() when exactly one entity is present.
MekHQ/src/mekhq/service/mrms/MRMSService.java Use getFirst() for first valid tech; reflow Javadoc formatting.
MekHQ/src/mekhq/service/PartsAcquisitionService.java Use getFirst() for first acquisition work entry.
MekHQ/src/mekhq/io/FileType.java Use getFirst() for recommended extension.
MekHQ/src/mekhq/gui/view/PaperDoll.java Use getFirst() to start path generation.
MekHQ/src/mekhq/gui/view/LanceAssignmentView.java Use getFirst() for default contract.
MekHQ/src/mekhq/gui/utilities/StaticChecks.java Use getFirst() for first unit/entity checks in Vector<Unit>.
MekHQ/src/mekhq/gui/stratCon/ScenarioWizardLanceRenderer.java Use getFirst() for first operational status element; re-indent signature.
MekHQ/src/mekhq/gui/panels/StartupScreenPanel.java Use getFirst() for first skin font color.
MekHQ/src/mekhq/gui/model/RetirementTableModel.java Use getFirst() for single tech-unit handling.
MekHQ/src/mekhq/gui/model/PersonnelTableModel.java Use getFirst() for tech-units fallback.
MekHQ/src/mekhq/gui/model/AutoAwardsTableModel.java Use getFirst() for first row value extraction.
MekHQ/src/mekhq/gui/enums/PersonnelTableModelColumn.java Use getFirst() for single tech-unit display.
MekHQ/src/mekhq/gui/dialog/resupplyAndCaches/DialogRoleplayEvent.java Deleted deprecated/unused dialog.
MekHQ/src/mekhq/gui/dialog/resupplyAndCaches/DialogInterception.java Deleted deprecated/unused dialog.
MekHQ/src/mekhq/gui/dialog/resupplyAndCaches/DialogAbandonedConvoy.java Deleted deprecated/unused dialog.
MekHQ/src/mekhq/gui/dialog/reportDialogs/UnitRatingReportDialog.java Deleted deprecated report dialog.
MekHQ/src/mekhq/gui/dialog/reportDialogs/PartQualityReportDialog.java Use addFirst() instead of indexed insert.
MekHQ/src/mekhq/gui/dialog/reportDialogs/NewsReportDialog.java Mark dialog deprecated.
MekHQ/src/mekhq/gui/dialog/reportDialogs/AbstractReportDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/randomEvents/prisonerDialogs/PrisonerWarningResultsDialog.java Deleted deprecated/unused dialog.
MekHQ/src/mekhq/gui/dialog/randomEvents/prisonerDialogs/PrisonerWarningDialog.java Deleted deprecated/unused dialog.
MekHQ/src/mekhq/gui/dialog/randomEvents/prisonerDialogs/PrisonerRansomEventDialog.java Deleted deprecated/unused dialog.
MekHQ/src/mekhq/gui/dialog/randomEvents/prisonerDialogs/PrisonerEventResultsDialog.java Deleted deprecated/unused dialog.
MekHQ/src/mekhq/gui/dialog/randomEvents/prisonerDialogs/PrisonerEventDialog.java Deleted deprecated/unused dialog.
MekHQ/src/mekhq/gui/dialog/randomEvents/prisonerDialogs/PrisonerEscapeeScenarioDialog.java Deleted deprecated/unused dialog.
MekHQ/src/mekhq/gui/dialog/randomEvents/GrayMondayDialog.java Deleted deprecated/unused dialog.
MekHQ/src/mekhq/gui/dialog/nagDialogs/OutstandingScenariosNagDialog.java Remove unused imports + remove checkNag helper.
MekHQ/src/mekhq/gui/dialog/nagDialogs/NagController.java Remove outstanding-scenarios & deployment-shortfall nag triggers.
MekHQ/src/mekhq/gui/dialog/nagDialogs/DeploymentShortfallNagDialog.java Deleted nag dialog implementation.
MekHQ/src/mekhq/gui/dialog/markets/personnelMarket/PersonnelTablePanel.java Use getFirst() for default selection.
MekHQ/src/mekhq/gui/dialog/markets/personnelMarket/PersonnelMarketDialog.java Use getFirst() for selection handling.
MekHQ/src/mekhq/gui/dialog/glossary/NewDocumentationEntryDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/factionStanding/gmToolsDialog/CensureSelectionDialog.java Use addFirst() instead of index insert.
MekHQ/src/mekhq/gui/dialog/factionStanding/gmToolsDialog/AccoladeSelectionDialog.java Use addFirst() instead of index insert.
MekHQ/src/mekhq/gui/dialog/VocationalExperienceAwardDialog.java Simplify active-contract XP doubling logic.
MekHQ/src/mekhq/gui/dialog/StoryNarrativeDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/StoryChoiceDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/StoryArcSelectionDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/SkillCheckDialog.java Switch from regex replaceAll to literal replace.
MekHQ/src/mekhq/gui/dialog/SelectUnusedAbilityDialog.java Deleted deprecated/unused dialog.
MekHQ/src/mekhq/gui/dialog/ScenarioTemplateEditorDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/RetirementDefectionDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/QuirksDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/PayCollateralDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/PartsReportDialog.java Use getFirst() for spare part name in prompt.
MekHQ/src/mekhq/gui/dialog/ObjectiveEditPanel.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/NewsDialog.java Use getLast() for final network selection.
MekHQ/src/mekhq/gui/dialog/NewRecruitDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/NewContractDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/MissionEndPrisonerDialog.java Deleted deprecated/unused dialog.
MekHQ/src/mekhq/gui/dialog/MissionEndPrisonerDefectorDialog.java Deleted deprecated/unused dialog.
MekHQ/src/mekhq/gui/dialog/MekViewDialog.java Deleted deprecated/unused dialog.
MekHQ/src/mekhq/gui/dialog/MedicalViewDialog.java Replace scrollpane; use getFirst() for first history entry.
MekHQ/src/mekhq/gui/dialog/MassMothballDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane; use getFirst() for first unit entity.
MekHQ/src/mekhq/gui/dialog/ManageAssetsDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/MRMSDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/LootDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/LargeCraftAmmoSwapDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/GlossaryDialog.java Deleted deprecated/unused dialog.
MekHQ/src/mekhq/gui/dialog/GMToolsDialog.java Replace scrollpane; add several deprecations; remove personnel module tab; use getFirst()/getLast().
MekHQ/src/mekhq/gui/dialog/FullGlossaryDialog.java Deleted deprecated/unused dialog.
MekHQ/src/mekhq/gui/dialog/ForceTemplateAssignmentDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane; use getFirst().
MekHQ/src/mekhq/gui/dialog/FamilyTreeDialog.java Use Math.clamp; use getFirst() for parent selection.
MekHQ/src/mekhq/gui/dialog/EditSkillPreRequisiteDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/EditPersonnelInjuriesDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/EditMapSettingsDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/DefectionOffer.java Deleted deprecated/unused dialog.
MekHQ/src/mekhq/gui/dialog/DataLoadingDialog.java Remove AtB initialization during new-campaign creation.
MekHQ/src/mekhq/gui/dialog/CustomizeScenarioObjectiveDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/CustomizeScenarioDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane; simplify OK handling branch.
MekHQ/src/mekhq/gui/dialog/CustomizePersonDialog.java Use Math.clamp; remove some aging-related locals/unused vars.
MekHQ/src/mekhq/gui/dialog/CustomizeBotForceDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/CustomizeAtBContractDialog.java Mark dialog deprecated.
MekHQ/src/mekhq/gui/dialog/CreateCharacterDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane; use Math.clamp.
MekHQ/src/mekhq/gui/dialog/ContractMarketDialog.java Remove AtB-specific share recalculation and reroll enabling; other UI updates.
MekHQ/src/mekhq/gui/dialog/ContractAutomationDialog.java Deleted deprecated/unused dialog.
MekHQ/src/mekhq/gui/dialog/CompanyGenerationDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/ChooseRefitDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/ChooseFactionsDialog.java Deleted deprecated/unused dialog.
MekHQ/src/mekhq/gui/dialog/CampaignExportWizard.java Replace JScrollPaneWithSpeed with FastJScrollPane; reflow signature formatting.
MekHQ/src/mekhq/gui/dialog/BombsDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/dialog/BatchXPDialog.java Replace scrollpane; use Math.clamp for spinner value.
MekHQ/src/mekhq/gui/dialog/AutoAwardsDialog.java Replace scrollpane; use getFirst() in data extraction.
MekHQ/src/mekhq/gui/dialog/AttributeCheckDialog.java Replace regex replaceAll with literal replace; use getFirst() for attributes.
MekHQ/src/mekhq/gui/dialog/AcquisitionsDialog.java Replace JScrollPaneWithSpeed with FastJScrollPane; use getFirst() for work selection.
MekHQ/src/mekhq/gui/control/EditScenarioLogControl.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/control/EditLogControl.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/control/EditKillLogControl.java Replace JScrollPaneWithSpeed with FastJScrollPane.
MekHQ/src/mekhq/gui/campaignOptions/contents/SalariesTab.java Use addFirst(); replace regex replaceAll(" ", "") with replace(" ", "").
MekHQ/src/mekhq/gui/campaignOptions/contents/RulesetsTab.java Import ordering + wrapping; deprecate legacy tab creator.
MekHQ/src/mekhq/gui/campaignOptions/contents/AbilitiesTab.java Adjust brace-stripping logic in descriptions.
MekHQ/src/mekhq/gui/campaignOptions/CampaignOptionsUtilities.java Import ordering; use addFirst(); reflow docs/indentation.
MekHQ/src/mekhq/gui/campaignOptions/CampaignOptionsPresetPicker.java Deprecate wasCustomized().
MekHQ/src/mekhq/gui/campaignOptions/CampaignOptionsDialog.java Deprecate older constructor overload.
MekHQ/src/mekhq/gui/baseComponents/SortedComboBoxModel.java Deprecate convenience constructors.
MekHQ/src/mekhq/gui/baseComponents/JScrollablePopupMenu.java Deprecate constructors.
MekHQ/src/mekhq/gui/baseComponents/JScrollableMenu.java Deprecate constructors.
MekHQ/src/mekhq/gui/baseComponents/AbstractMHQValidationButtonDialog.java Deprecate constructor overload.
MekHQ/src/mekhq/gui/baseComponents/AbstractMHQTabbedPane.java Deprecate constructor overload.
MekHQ/src/mekhq/gui/baseComponents/AbstractMHQButtonDialog.java Deprecate constructor overload.
MekHQ/src/mekhq/gui/adapter/UnitTableMouseAdapter.java Use getFirst(); minor logic simplification; avoid size()>0 check.
MekHQ/src/mekhq/gui/adapter/TOEMouseAdapter.java Use getFirst(); remove AtB-only combat-team override menu items; formatting.
MekHQ/src/mekhq/gui/adapter/PersonnelTableMouseAdapter.java Simplify “sack” flow; use Math.clamp; use getFirst() in education menus.
MekHQ/src/mekhq/gui/DailyReportLogPanel.java Use getFirst() when list size is 1.
MekHQ/src/mekhq/gui/CampaignGUI.java Use getFirst() for default selection; wrap long lines.
MekHQ/src/mekhq/gui/BriefingTab.java Use getFirst(); use addFirst(); use getFirst() for faction code.
MekHQ/src/mekhq/campaign/randomEvents/prisoners/CapturePrisoners.java Use getFirst() in loyalty roll sum.
MekHQ/src/mekhq/campaign/personnel/Person.java Use getFirst() for first skill name.
MekHQ/src/mekhq/campaign/force/CombatTeam.java Import reorder + Javadoc wrapping.
MekHQ/src/mekhq/campaign/campaignOptions/CampaignOptions.java Removed several @Deprecated annotations on personnel market accessors.
MekHQ/src/mekhq/campaign/camOpsReputation/ReputationController.java Use getFirst() for first element access.
MekHQ/src/mekhq/Utilities.java Use getFirst() in sorted roll sum.
MekHQ/src/mekhq/AtBGameThread.java Use getFirst(); formatting fixes.
MekHQ/resources/mekhq/resources/CampaignOptionsDialog.properties Remove preset dialog strings; whitespace tweaks.
Comments suppressed due to low confidence (2)

MekHQ/src/mekhq/gui/dialog/nagDialogs/NagController.java:220

  • triggerDailyNags() no longer checks or displays the Outstanding Scenarios and Deployment Shortfall nags. OutstandingScenariosNagDialog still exists but is now unreachable, and DeploymentShortfallNagDialog was removed entirely. If this was intended, it likely needs a replacement nag path; otherwise, reintroduce equivalent checks here so users still get warned before advancing the day.
    MekHQ/src/mekhq/gui/dialog/ContractMarketDialog.java:253
  • The share percentage spinner no longer propagates the updated sharePct into AtBContract instances or recalculates contract values. This can leave the contract list/view showing stale financials after the user changes sharePct. Consider restoring the loop that updates AtB shares percent (when using the share system) and calls calculateContract(), then refreshing the view.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 3908 to 3938
@@ -3923,23 +3921,19 @@ public void setPersonnelMarketReportRefresh(final boolean personnelMarketReportR
this.personnelMarketReportRefresh = personnelMarketReportRefresh;
}

@Deprecated(since = "0.51.0", forRemoval = true)
public Map<SkillLevel, Integer> getPersonnelMarketRandomRemovalTargets() {
return personnelMarketRandomRemovalTargets;
}

@Deprecated(since = "0.51.0", forRemoval = true)
public void setPersonnelMarketRandomRemovalTargets(
final Map<SkillLevel, Integer> personnelMarketRandomRemovalTargets) {
this.personnelMarketRandomRemovalTargets = personnelMarketRandomRemovalTargets;
}

@Deprecated(since = "0.51.0", forRemoval = true)
public double getPersonnelMarketDylansWeight() {
return personnelMarketDylansWeight;
}

@Deprecated(since = "0.51.0", forRemoval = true)
public void setPersonnelMarketDylansWeight(final double personnelMarketDylansWeight) {
this.personnelMarketDylansWeight = personnelMarketDylansWeight;

Copilot AI Apr 21, 2026

Copy link

Choose a reason for hiding this comment

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

These personnel market accessor methods had their @Deprecated annotations removed, but related code (e.g., OptionsChangedEvent handlers and XML marshalling) still treats this market-name path as legacy/for-removal. If these APIs are still intended to be phased out, consider restoring the deprecation annotations to keep the migration signal consistent.

Copilot uses AI. Check for mistakes.
Comment on lines 423 to 432
// News
campaign.reloadNews();
campaign.readNews();

// GM Mode
campaign.setGMMode((preset == null) || preset.isGM());

// AtB
if (campaignOptions.isUseAtB()) {
campaign.initAtB(true);
}

// Turnover
campaign.initTurnover();
// endregion Progress 7

Copilot AI Apr 21, 2026

Copy link

Choose a reason for hiding this comment

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

New campaign initialization no longer calls Campaign.initAtB(true) when the campaign options enable AtB. Campaign.initAtB() sets up AtB configuration, RandomFactionGenerator startup, contract offers, and the AtB event processor; without it, newly-created AtB campaigns may be missing core AtB state. Consider restoring the initAtB(true) call (guarded by campaignOptions.isUseAtB()) or moving equivalent initialization into a guaranteed code path for new campaigns.

Copilot uses AI. Check for mistakes.
Comment on lines 1196 to 1213
case CMD_SACK: {
boolean showDialog = false;
List<Person> toRemove = new ArrayList<>();
if (getCampaignOptions().isUseAtB()) {
for (Person person : people) {
if (!person.getPrimaryRole().isCivilian()) {
if (getCampaign().getRetirementDefectionTracker()
.removeFromCampaign(person, false, true, getCampaign(), null)) {
showDialog = true;
} else {
toRemove.add(person);
}
} else {
toRemove.add(person);
}
}
}

if (showDialog) {
RetirementDefectionDialog rdd = new RetirementDefectionDialog(gui, null, false);
String question;

if (rdd.wasAborted() ||
!getCampaign().applyRetirement(rdd.totalPayout(), rdd.getUnitAssignments())) {
for (Person person : people) {
getCampaign().getRetirementDefectionTracker().removePayout(person);
}
} else {
for (final Person person : toRemove) {
getCampaign().removePerson(person);
}
}
if (people.length > 1) {
question = resources.getString("confirmRemoveMultiple.text");
} else {
String question;
if (people.length > 1) {
question = resources.getString("confirmRemoveMultiple.text");
} else {
question = String.format(resources.getString("confirmRemove.format"), people[0].getFullTitle());
}
if (JOptionPane.YES_OPTION ==
JOptionPane.showConfirmDialog(null,
question,
resources.getString("removeQ.text"),
JOptionPane.YES_NO_OPTION)) {
for (Person person : people) {
getCampaign().removePerson(person);
}
question = String.format(resources.getString("confirmRemove.format"), people[0].getFullTitle());
}

if (JOptionPane.YES_OPTION ==
JOptionPane.showConfirmDialog(null,
question,
resources.getString("removeQ.text"),
JOptionPane.YES_NO_OPTION)) {
for (Person person : people) {
getCampaign().removePerson(person);
}
}

Copilot AI Apr 21, 2026

Copy link

Choose a reason for hiding this comment

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

CMD_SACK previously routed AtB campaigns through the retirement/defection tracker and (when needed) RetirementDefectionDialog to handle payouts and unit assignment cleanup. The new implementation directly removes personnel after confirmation, which changes AtB behavior and may bypass required retirement payout bookkeeping. If AtB retirement logic is still required, restore the tracker-based flow (or ensure equivalent processing happens before removal).

Copilot uses AI. Check for mistakes.
Comment on lines 738 to 742
scrollContractView.setViewportView(null);
return;
}
contractView = new ContractSummaryPanel(selectedContract,
campaign,
campaign.getCampaignOptions().isUseAtB() &&
selectedContract instanceof AtBContract &&
!((AtBContract) selectedContract).isSubcontract() &&
!campaign.isPirateCampaign());
contractView = new ContractSummaryPanel(selectedContract, campaign, false);
scrollContractView.setViewportView(contractView);

Copilot AI Apr 21, 2026

Copy link

Choose a reason for hiding this comment

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

refreshContractView() now always constructs ContractSummaryPanel with allowRerolls=false. Previously this flag was computed based on AtB/share-system/subcontract/pirate conditions, and disabling it unconditionally removes reroll/negotiation functionality in the contract view. If rerolls are still supported, restore the prior allowRerolls logic (or document why rerolls are being removed).

Copilot uses AI. Check for mistakes.
Comment on lines 117 to 148
/**
* Constructs an out-of-character (OOC) message to provide context for XP advancements based on the campaign's
* settings and current state.
*
* <p>The generated message includes details about the idle XP gained, as determined by
* the campaign's configuration and active contracts. If the campaign has an active contract that is not a garrison
* type (when using AtB settings), or simply has an active contract otherwise, the default XP advancement rate is
* doubled.</p>
*
* <p>This method integrates campaign options such as:</p>
* <ul>
* <li>The default vocational XP advancement rate ({@code VocationalXP})</li>
* <li>The status of whether the campaign is using the AtB (Against the Bot)
* system ({@code isUseAtB})</li>
* <li>The type of active employment contracts (e.g., garrison or non-garrison)</li>
* </ul>
*
* <p>This information is formatted into a predefined message string using localized
* resource strings.</p>
*
* @param campaign the {@link Campaign} containing the current campaign state, settings, and active contracts
*
* @return a string representing the out-of-character (OOC) message to be displayed
*/
private static String createOutOfCharacterMessage(Campaign campaign) {
final CampaignOptions campaignOptions = campaign.getCampaignOptions();

int advancement = campaignOptions.getVocationalXP();

if (campaign.hasActiveContract()) {
if (campaignOptions.isUseAtB()) {
for (AtBContract contract : campaign.getActiveAtBContracts()) {
if (!contract.getContractType().isGarrisonType()) {
advancement *= 2;
break;
}
}
} else {
advancement *= 2;
}
advancement *= 2;
}

Copilot AI Apr 21, 2026

Copy link

Choose a reason for hiding this comment

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

The OOC text logic no longer matches the method’s javadoc: the comment states XP is doubled only for non-garrison AtB contracts (or any active contract outside AtB), but the implementation now doubles advancement for any active contract, including AtB garrison/retainer types. Either restore the previous conditional (so garrison contracts don’t double XP) or update the documentation and any gameplay expectations accordingly.

Copilot uses AI. Check for mistakes.
@codecov

codecov Bot commented Apr 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 2.31481% with 211 lines in your changes missing coverage. Please review.
✅ Project coverage is 13.79%. Comparing base (93ca050) to head (468c109).
⚠️ Report is 4 commits behind head on main.

Files with missing lines Patch % Lines
MekHQ/src/mekhq/gui/CampaignGUI.java 0.00% 23 Missing ⚠️
.../mekhq/gui/adapter/PersonnelTableMouseAdapter.java 0.00% 13 Missing ⚠️
MekHQ/src/mekhq/gui/adapter/TOEMouseAdapter.java 0.00% 10 Missing ⚠️
...HQ/src/mekhq/gui/dialog/CreateCharacterDialog.java 0.00% 10 Missing ⚠️
...HQ/src/mekhq/gui/dialog/CustomizePersonDialog.java 0.00% 9 Missing ⚠️
...mekhq/gui/dialog/ScenarioTemplateEditorDialog.java 0.00% 7 Missing ⚠️
MekHQ/src/mekhq/gui/utilities/StaticChecks.java 25.00% 6 Missing ⚠️
MekHQ/src/mekhq/AtBGameThread.java 0.00% 5 Missing ⚠️
MekHQ/src/mekhq/gui/BriefingTab.java 0.00% 5 Missing ⚠️
...Q/src/mekhq/gui/adapter/UnitTableMouseAdapter.java 0.00% 5 Missing ⚠️
... and 66 more
Additional details and impacted files
@@             Coverage Diff              @@
##               main    #8897      +/-   ##
============================================
+ Coverage     13.70%   13.79%   +0.09%     
  Complexity     8179     8179              
============================================
  Files          1309     1285      -24     
  Lines        168872   167606    -1266     
  Branches      25403    25279     -124     
============================================
- Hits          23140    23126      -14     
+ Misses       143403   142152    -1251     
+ Partials       2329     2328       -1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@rjhancock rjhancock merged commit 7209655 into MegaMek:main Apr 21, 2026
8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants