From e5343704a15be633d51d84e4baf2da2e2a1f1849 Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Mon, 17 Jun 2024 09:12:09 -0500 Subject: [PATCH 01/33] fix: Corrected condition for enabling Prestigious Academies in PersonnelTableMouseAdapter --- MekHQ/src/mekhq/gui/adapter/PersonnelTableMouseAdapter.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MekHQ/src/mekhq/gui/adapter/PersonnelTableMouseAdapter.java b/MekHQ/src/mekhq/gui/adapter/PersonnelTableMouseAdapter.java index ef98e52a03..e808dfa737 100644 --- a/MekHQ/src/mekhq/gui/adapter/PersonnelTableMouseAdapter.java +++ b/MekHQ/src/mekhq/gui/adapter/PersonnelTableMouseAdapter.java @@ -1518,7 +1518,7 @@ protected Optional createPopupMenu() { } if (academySetNames.contains("Prestigious Academies")) { - if ((!campaign.getCampaignOptions().isEnableLocalAcademies()) || (campaignIsClan)) { + if ((!campaign.getCampaignOptions().isEnablePrestigiousAcademies()) || (campaignIsClan)) { academySetNames.remove("Prestigious Academies"); } } From 0c7179cf001c4af396e834de7b69f6f731c98720 Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Mon, 17 Jun 2024 09:16:38 -0500 Subject: [PATCH 02/33] fix: adjusted condition for setting campaign start date in CampaignOptionsPane --- MekHQ/src/mekhq/gui/panes/CampaignOptionsPane.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MekHQ/src/mekhq/gui/panes/CampaignOptionsPane.java b/MekHQ/src/mekhq/gui/panes/CampaignOptionsPane.java index cfa9441365..31b42cf129 100644 --- a/MekHQ/src/mekhq/gui/panes/CampaignOptionsPane.java +++ b/MekHQ/src/mekhq/gui/panes/CampaignOptionsPane.java @@ -8491,7 +8491,7 @@ public void updateOptions() { } campaign.setLocalDate(date); - if (campaign.getCampaignStartDate() == null) { + if ((campaign.getCampaignStartDate() == null) || (campaign.getCampaignStartDate().isAfter(campaign.getLocalDate()))) { campaign.setCampaignStartDate(date); } // Ensure that the MegaMek year GameOption matches the campaign year From c709270b5e9bd572001470fb37ef1b48e207ab11 Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Mon, 17 Jun 2024 09:40:29 -0500 Subject: [PATCH 03/33] feat: Updated color codes in StratconTab and StratconPanel files - Replaced hard coded color codes with calls to get color from MekHQ options - Updated formatting of string builders for cleaner code --- MekHQ/src/mekhq/gui/StratconPanel.java | 11 +++++++---- MekHQ/src/mekhq/gui/StratconTab.java | 22 +++++++++++----------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/MekHQ/src/mekhq/gui/StratconPanel.java b/MekHQ/src/mekhq/gui/StratconPanel.java index 4103132604..708a76a70d 100644 --- a/MekHQ/src/mekhq/gui/StratconPanel.java +++ b/MekHQ/src/mekhq/gui/StratconPanel.java @@ -528,7 +528,7 @@ private void drawScenarios(Graphics2D g2D) { ((scenario.getDeploymentDate() != null) || (scenario.isStrategicObjective() && currentTrack.getRevealedCoords().contains(currentCoords)) || currentTrack.isGmRevealed() || trackRevealed)) { - g2D.setColor(Color.RED); + g2D.setColor(MekHQ.getMHQOptions().getFontColorNegative()); BufferedImage scenarioImage = getImage(StratconBiomeManifest.FORCE_HOSTILE, ImageType.TerrainTile); if (scenarioImage != null) { @@ -836,16 +836,19 @@ private String buildSelectedHexInfo() { if ((facility != null) && (facility.getFacilityType() != null)) { if (facility.isStrategicObjective()) { infoBuilder.append(String.format("
Contract objective located", - facility.getOwner() == ForceAlignment.Allied ? "green" : "red")); + facility.getOwner() == ForceAlignment.Allied ? MekHQ.getMHQOptions().getFontColorPositiveHexColor() : MekHQ.getMHQOptions().getFontColorNegativeHexColor())); } - infoBuilder.append((facility.getOwner() == ForceAlignment.Allied) ? "" : "") + infoBuilder.append("") .append("
") .append(facility.getFormattedDisplayableName()) .append(""); } } else { - infoBuilder.append("Recon incomplete"); + infoBuilder.append("Recon incomplete"); } infoBuilder.append("
"); diff --git a/MekHQ/src/mekhq/gui/StratconTab.java b/MekHQ/src/mekhq/gui/StratconTab.java index c94791c388..89b10adb81 100644 --- a/MekHQ/src/mekhq/gui/StratconTab.java +++ b/MekHQ/src/mekhq/gui/StratconTab.java @@ -271,9 +271,9 @@ private String buildShortStrategicObjectiveText(StratconCampaignState campaignSt StringBuilder sb = new StringBuilder(); if (completedObjectives >= desiredObjectives) { - sb.append(""); + sb.append(""); } else { - sb.append(""); + sb.append(""); } // special logic for non-independent command clauses @@ -285,7 +285,7 @@ private String buildShortStrategicObjectiveText(StratconCampaignState campaignSt } } - sb.append("Strategic objectives: " + completedObjectives + "/" + desiredObjectives + " completed"); + sb.append("Strategic objectives: ").append(completedObjectives).append('/').append(desiredObjectives).append(" completed"); return sb.toString(); } @@ -313,16 +313,16 @@ private String buildStrategicObjectiveText(StratconCampaignState campaignState) // special case: allied facilities can get lost at any point in time if ((objective.getObjectiveType() == StrategicObjectiveType.AlliedFacilityControl) && !campaignState.allowEarlyVictory()) { - sb.append("").append(OBJECTIVE_IN_PROGRESS); + sb.append("").append(OBJECTIVE_IN_PROGRESS); } else if (objectiveCompleted) { - sb.append("").append(OBJECTIVE_COMPLETED); + sb.append("").append(OBJECTIVE_COMPLETED); } else if (objectiveFailed) { - sb.append("").append(OBJECTIVE_FAILED); + sb.append("").append(OBJECTIVE_FAILED); } else { - sb.append("").append(OBJECTIVE_IN_PROGRESS); + sb.append("").append(OBJECTIVE_IN_PROGRESS); } - sb.append(" "); + sb.append(' '); if (!coordsRevealed && displayCoordinateData) { sb.append("Locate and "); @@ -368,11 +368,11 @@ private String buildStrategicObjectiveText(StratconCampaignState campaignState) boolean contractIsActive = campaignState.getContract().isActiveOn(getCampaignGui().getCampaign().getLocalDate()); if (contractIsActive) { - sb.append("").append(OBJECTIVE_IN_PROGRESS); + sb.append("").append(OBJECTIVE_IN_PROGRESS); } else if (campaignState.getVictoryPoints() > 0) { - sb.append("").append(OBJECTIVE_COMPLETED); + sb.append("").append(OBJECTIVE_COMPLETED); } else { - sb.append("").append(OBJECTIVE_FAILED); + sb.append("").append(OBJECTIVE_FAILED); } sb.append(" Maintain Campaign Victory Point count above 0 by completing required scenarios") From e01248b985604f2e74815afc8ff722fbd0c7d41a Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Mon, 17 Jun 2024 09:54:33 -0500 Subject: [PATCH 04/33] feat: Updated market panel descriptions - Renamed `lblBlackMarketWarning` to `lblMarketDescriptions` - Updated market descriptions content in `GUI.properties` --- MekHQ/resources/mekhq/resources/GUI.properties | 5 +++-- MekHQ/src/mekhq/gui/panes/UnitMarketPane.java | 6 +++--- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/MekHQ/resources/mekhq/resources/GUI.properties b/MekHQ/resources/mekhq/resources/GUI.properties index 0838bd8f9e..d4bc23c5bb 100644 --- a/MekHQ/resources/mekhq/resources/GUI.properties +++ b/MekHQ/resources/mekhq/resources/GUI.properties @@ -1287,8 +1287,9 @@ chkFilterByPercentageOfCost.text=Show only units at chkFilterByPercentageOfCost.toolTipText=Filter out units above the specified percentage of market value. spnFilterByPercentageOfCost.toolTipText=Filter out units with market value above this percentage when the filter is enabled. lblCostPercentageThreshold.text=% of market value or lower -### Black Market Panel -lblBlackMarketWarning.text=Open Market & Mercenary Auction: The public sale of units available to your campaign faction\ +### Market Description Panel +lblMarketDescriptions.text=Open Market: The public sale of units available to your campaign faction\ +
Mercenary Auction: The sale of unwanted units sold through the MRBC (or the era-appropriate equivalent)\
Employer Market: Units or salvage no longer wanted by your employer\
Factory Line: Brand-new units fresh off the production line\
Black Market: Potentially brand-new units which come with the risk of being swindled diff --git a/MekHQ/src/mekhq/gui/panes/UnitMarketPane.java b/MekHQ/src/mekhq/gui/panes/UnitMarketPane.java index 1aba6005de..8ce7d9eb40 100644 --- a/MekHQ/src/mekhq/gui/panes/UnitMarketPane.java +++ b/MekHQ/src/mekhq/gui/panes/UnitMarketPane.java @@ -198,7 +198,7 @@ protected Component createLeftComponent() { final JScrollPane marketTableScrollPane = createMarketTablePane(); - final JLabel lblBlackMarketWarning = new JLabel(resources.getString("lblBlackMarketWarning.text")); + final JLabel lblMarketDescriptions = new JLabel(resources.getString("lblMarketDescriptions.text")); // Layout the UI JPanel panel = new JPanel(); @@ -215,7 +215,7 @@ protected Component createLeftComponent() { .addComponent(filtersPanel) .addComponent(getEntityImagePanel(), Alignment.LEADING)) .addComponent(marketTableScrollPane) - .addComponent(lblBlackMarketWarning) + .addComponent(lblMarketDescriptions) ); layout.setHorizontalGroup( @@ -224,7 +224,7 @@ protected Component createLeftComponent() { .addComponent(filtersPanel) .addComponent(getEntityImagePanel())) .addComponent(marketTableScrollPane) - .addComponent(lblBlackMarketWarning, Alignment.TRAILING) + .addComponent(lblMarketDescriptions, Alignment.TRAILING) ); return panel; } From d3cdd974bfcdabbb73ee45d43a2ccf11bcacd1d5 Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Mon, 17 Jun 2024 10:48:25 -0500 Subject: [PATCH 05/33] feat: Modified unit price computation in AtBMonthlyUnitMarket * Added getPricePercentage function to UnitMarketType class * Adjusted price modifier and percentage calculation for different unit and market types * Refactored addOffers method to use new pricing approach * Replaced static price target with a dynamic price modifier --- .../campaign/market/enums/UnitMarketType.java | 41 +++++++++++++ .../unitMarket/AtBMonthlyUnitMarket.java | 61 ++++++++++--------- 2 files changed, 72 insertions(+), 30 deletions(-) diff --git a/MekHQ/src/mekhq/campaign/market/enums/UnitMarketType.java b/MekHQ/src/mekhq/campaign/market/enums/UnitMarketType.java index 8081ca259a..563ee2cdde 100644 --- a/MekHQ/src/mekhq/campaign/market/enums/UnitMarketType.java +++ b/MekHQ/src/mekhq/campaign/market/enums/UnitMarketType.java @@ -108,7 +108,48 @@ public String toString() { return name; } + /** + * Calculates the price percentage based on a given modifier and d6 roll. + * + * @param modifier the modifier to adjust the price (a positive modifier decreases price, negative decreases price) + * @return the calculated price + * @throws IllegalStateException if the roll value is unexpected + */ + public static int getPricePercentage(int modifier) { + int roll = Compute.d6(2); + int value = 0; + switch (roll) { + case 2: + value = 3 + modifier; + break; + case 3: + value = 2 + modifier; + break; + case 4: + case 5: + value = 1 + modifier; + break; + case 6: + case 7: + case 8: + break; + case 9: + case 10: + value = -1 + modifier; + break; + case 11: + value = -2 + modifier; + break; + case 12: + value = -3 + modifier; + break; + default: + throw new IllegalStateException("Unexpected value in mekhq/campaign/market/unitMarket/AtBMonthlyUnitMarket.java/getPrice: " + roll); + } + + return 100 + (value * 5); + } /** * Returns the quality of a unit based on the given market type. diff --git a/MekHQ/src/mekhq/campaign/market/unitMarket/AtBMonthlyUnitMarket.java b/MekHQ/src/mekhq/campaign/market/unitMarket/AtBMonthlyUnitMarket.java index 1f20e06489..79d9597c87 100644 --- a/MekHQ/src/mekhq/campaign/market/unitMarket/AtBMonthlyUnitMarket.java +++ b/MekHQ/src/mekhq/campaign/market/unitMarket/AtBMonthlyUnitMarket.java @@ -39,6 +39,8 @@ import java.util.Collection; import java.util.List; +import static mekhq.campaign.market.enums.UnitMarketType.getPricePercentage; + public class AtBMonthlyUnitMarket extends AbstractUnitMarket { //region Constructors public AtBMonthlyUnitMarket() { @@ -76,47 +78,47 @@ public void generateUnitOffers(final Campaign campaign) { Faction faction = campaign.getFaction(); addOffers(campaign, getMarketItemCount("uncommon"), UnitMarketType.OPEN, UnitType.MEK, - faction, IUnitRating.DRAGOON_F, 6); + faction, IUnitRating.DRAGOON_F, -1); addOffers(campaign, getMarketItemCount("uncommon"), UnitMarketType.OPEN, UnitType.AEROSPACEFIGHTER, - faction, IUnitRating.DRAGOON_F, 6); + faction, IUnitRating.DRAGOON_F, -1); addOffers(campaign, getMarketItemCount("very common"), UnitMarketType.OPEN, UnitType.TANK, - faction, IUnitRating.DRAGOON_F, 6); + faction, IUnitRating.DRAGOON_F, -1); addOffers(campaign, getMarketItemCount("common"), UnitMarketType.OPEN, UnitType.CONV_FIGHTER, - faction, IUnitRating.DRAGOON_F, 6); + faction, IUnitRating.DRAGOON_F, -1); if ((contract != null) && (campaign.getLocalDate().isAfter(contract.getStartDate().minusDays(1)))) { // Employer Market faction = contract.getEmployerFaction(); addOffers(campaign, getMarketItemCount("rare"), UnitMarketType.EMPLOYER, UnitType.MEK, - faction, IUnitRating.DRAGOON_D, 8); + faction, IUnitRating.DRAGOON_D, 1); addOffers(campaign, getMarketItemCount("rare"), UnitMarketType.EMPLOYER, UnitType.AEROSPACEFIGHTER, - faction, IUnitRating.DRAGOON_D, 8); + faction, IUnitRating.DRAGOON_D, 1); addOffers(campaign, getMarketItemCount("common"), UnitMarketType.EMPLOYER, UnitType.TANK, - faction, IUnitRating.DRAGOON_D, 8); + faction, IUnitRating.DRAGOON_D, 1); addOffers(campaign, getMarketItemCount("uncommon"), UnitMarketType.EMPLOYER, UnitType.CONV_FIGHTER, - faction, IUnitRating.DRAGOON_D, 8); + faction, IUnitRating.DRAGOON_D, 1); // Unwanted Salvage Market faction = contract.getEnemy(); addOffers(campaign, getMarketItemCount("rare"), UnitMarketType.EMPLOYER, UnitType.MEK, - faction, IUnitRating.DRAGOON_F, 5); + faction, IUnitRating.DRAGOON_F, -2); addOffers(campaign, getMarketItemCount("rare"), UnitMarketType.EMPLOYER, UnitType.AEROSPACEFIGHTER, - faction, IUnitRating.DRAGOON_F, 5); + faction, IUnitRating.DRAGOON_F, -2); addOffers(campaign, getMarketItemCount("common"), UnitMarketType.EMPLOYER, UnitType.TANK, - faction, IUnitRating.DRAGOON_F, 5); + faction, IUnitRating.DRAGOON_F, -2); addOffers(campaign, getMarketItemCount("uncommon"), UnitMarketType.EMPLOYER, UnitType.CONV_FIGHTER, - faction, IUnitRating.DRAGOON_F, 5); + faction, IUnitRating.DRAGOON_F, -2); } // Mercenary Market @@ -130,16 +132,16 @@ public void generateUnitOffers(final Campaign campaign) { } addOffers(campaign, getMarketItemCount("uncommon"), UnitMarketType.MERCENARY, UnitType.MEK, - faction, IUnitRating.DRAGOON_C, 7 + modifier); + faction, IUnitRating.DRAGOON_C, modifier); addOffers(campaign, getMarketItemCount("uncommon"), UnitMarketType.MERCENARY, UnitType.AEROSPACEFIGHTER, - faction, IUnitRating.DRAGOON_C, 7 + modifier); + faction, IUnitRating.DRAGOON_C, modifier); addOffers(campaign, getMarketItemCount("very common"), UnitMarketType.MERCENARY, UnitType.TANK, - faction, IUnitRating.DRAGOON_C, 7 + modifier); + faction, IUnitRating.DRAGOON_C, modifier); addOffers(campaign, getMarketItemCount("common"), UnitMarketType.MERCENARY, UnitType.CONV_FIGHTER, - faction, IUnitRating.DRAGOON_C, 7 + modifier); + faction, IUnitRating.DRAGOON_C, modifier); } // Factory Market @@ -149,16 +151,16 @@ public void generateUnitOffers(final Campaign campaign) { if ((!campaign.getFaction().isClan()) && (faction != null) && (!faction.isClan())) { addOffers(campaign, getMarketItemCount("rare"), UnitMarketType.FACTORY, UnitType.MEK, - faction, IUnitRating.DRAGOON_A, 6); + faction, IUnitRating.DRAGOON_A, -2); addOffers(campaign, getMarketItemCount("rare"), UnitMarketType.FACTORY, UnitType.AEROSPACEFIGHTER, - faction, IUnitRating.DRAGOON_A, 6); + faction, IUnitRating.DRAGOON_A, -2); addOffers(campaign, getMarketItemCount("common"), UnitMarketType.FACTORY, UnitType.TANK, - faction, IUnitRating.DRAGOON_A, 6); + faction, IUnitRating.DRAGOON_A, -2); addOffers(campaign, getMarketItemCount("uncommon"), UnitMarketType.FACTORY, UnitType.CONV_FIGHTER, - faction, IUnitRating.DRAGOON_A, 6); + faction, IUnitRating.DRAGOON_A, -2); } } @@ -167,13 +169,13 @@ public void generateUnitOffers(final Campaign campaign) { // Clan Factory Market if ((faction.isClan()) && (campaign.getCurrentSystem().getFactionSet(campaign.getLocalDate()).contains(faction))) { addOffers(campaign, getMarketItemCount("very common"), UnitMarketType.FACTORY, UnitType.MEK, - faction, IUnitRating.DRAGOON_A, 9); + faction, IUnitRating.DRAGOON_A, 4); addOffers(campaign, getMarketItemCount("common"), UnitMarketType.FACTORY, UnitType.AEROSPACEFIGHTER, - faction, IUnitRating.DRAGOON_A, 9); + faction, IUnitRating.DRAGOON_A, 4); addOffers(campaign, getMarketItemCount("uncommon"), UnitMarketType.FACTORY, UnitType.TANK, - faction, IUnitRating.DRAGOON_A, 9); + faction, IUnitRating.DRAGOON_A, 4); } // Black Market @@ -182,16 +184,16 @@ public void generateUnitOffers(final Campaign campaign) { .getFactionSet(campaign.getLocalDate())); addOffers(campaign, getMarketItemCount("very rare"), UnitMarketType.BLACK_MARKET, UnitType.MEK, - faction, IUnitRating.DRAGOON_A, 9); + faction, IUnitRating.DRAGOON_A, 4); addOffers(campaign, getMarketItemCount("very rare"), UnitMarketType.BLACK_MARKET, UnitType.AEROSPACEFIGHTER, - faction, IUnitRating.DRAGOON_A, 9); + faction, IUnitRating.DRAGOON_A, 4); addOffers(campaign, getMarketItemCount("uncommon"), UnitMarketType.BLACK_MARKET, UnitType.TANK, - faction, IUnitRating.DRAGOON_A, 9); + faction, IUnitRating.DRAGOON_A, 4); addOffers(campaign, getMarketItemCount("rare"), UnitMarketType.BLACK_MARKET, UnitType.CONV_FIGHTER, - faction, IUnitRating.DRAGOON_A, 9); + faction, IUnitRating.DRAGOON_A, 4); } writeRefreshReport(campaign); @@ -224,7 +226,7 @@ private int getMarketItemCount(String rarity) { @Override public void addOffers(final Campaign campaign, final int num, UnitMarketType market, final int unitType, @Nullable Faction faction, final int quality, - final int priceTarget) { + final int priceModifier) { if (faction == null) { faction = RandomFactionGenerator.getInstance().getEmployerFaction(); } @@ -268,8 +270,7 @@ public void addOffers(final Campaign campaign, final int num, UnitMarketType mar } } - final int percent = 100 - (Compute.d6(2) - priceTarget) * 5; - addSingleUnit(campaign, market, unitType, faction, quality, movementModes, missionRoles, percent); + addSingleUnit(campaign, market, unitType, faction, quality, movementModes, missionRoles, getPricePercentage(priceModifier)); } } From 8bb6f12c35a4f56a1d97e2e46869465a3bed4fee Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Mon, 17 Jun 2024 11:45:38 -0500 Subject: [PATCH 06/33] feat: Adjusted unit market price modifier in AtBMonthlyUnitMarket - Changed price modifier in various market types; positive values now increase price, negative decrease - Fixed inaccurate comment in UnitMarketType regarding price modifier adjustment --- .../campaign/market/enums/UnitMarketType.java | 2 +- .../unitMarket/AtBMonthlyUnitMarket.java | 50 +++++++++---------- 2 files changed, 26 insertions(+), 26 deletions(-) diff --git a/MekHQ/src/mekhq/campaign/market/enums/UnitMarketType.java b/MekHQ/src/mekhq/campaign/market/enums/UnitMarketType.java index 563ee2cdde..a529ca5099 100644 --- a/MekHQ/src/mekhq/campaign/market/enums/UnitMarketType.java +++ b/MekHQ/src/mekhq/campaign/market/enums/UnitMarketType.java @@ -111,7 +111,7 @@ public String toString() { /** * Calculates the price percentage based on a given modifier and d6 roll. * - * @param modifier the modifier to adjust the price (a positive modifier decreases price, negative decreases price) + * @param modifier the modifier to adjust the price (a negative modifier decreases price, positive increases price) * @return the calculated price * @throws IllegalStateException if the roll value is unexpected */ diff --git a/MekHQ/src/mekhq/campaign/market/unitMarket/AtBMonthlyUnitMarket.java b/MekHQ/src/mekhq/campaign/market/unitMarket/AtBMonthlyUnitMarket.java index 79d9597c87..057aac33dd 100644 --- a/MekHQ/src/mekhq/campaign/market/unitMarket/AtBMonthlyUnitMarket.java +++ b/MekHQ/src/mekhq/campaign/market/unitMarket/AtBMonthlyUnitMarket.java @@ -78,57 +78,57 @@ public void generateUnitOffers(final Campaign campaign) { Faction faction = campaign.getFaction(); addOffers(campaign, getMarketItemCount("uncommon"), UnitMarketType.OPEN, UnitType.MEK, - faction, IUnitRating.DRAGOON_F, -1); + faction, IUnitRating.DRAGOON_F, 1); addOffers(campaign, getMarketItemCount("uncommon"), UnitMarketType.OPEN, UnitType.AEROSPACEFIGHTER, - faction, IUnitRating.DRAGOON_F, -1); + faction, IUnitRating.DRAGOON_F, 1); addOffers(campaign, getMarketItemCount("very common"), UnitMarketType.OPEN, UnitType.TANK, - faction, IUnitRating.DRAGOON_F, -1); + faction, IUnitRating.DRAGOON_F, 1); addOffers(campaign, getMarketItemCount("common"), UnitMarketType.OPEN, UnitType.CONV_FIGHTER, - faction, IUnitRating.DRAGOON_F, -1); + faction, IUnitRating.DRAGOON_F, 1); if ((contract != null) && (campaign.getLocalDate().isAfter(contract.getStartDate().minusDays(1)))) { // Employer Market faction = contract.getEmployerFaction(); addOffers(campaign, getMarketItemCount("rare"), UnitMarketType.EMPLOYER, UnitType.MEK, - faction, IUnitRating.DRAGOON_D, 1); + faction, IUnitRating.DRAGOON_D, -1); addOffers(campaign, getMarketItemCount("rare"), UnitMarketType.EMPLOYER, UnitType.AEROSPACEFIGHTER, - faction, IUnitRating.DRAGOON_D, 1); + faction, IUnitRating.DRAGOON_D, -1); addOffers(campaign, getMarketItemCount("common"), UnitMarketType.EMPLOYER, UnitType.TANK, - faction, IUnitRating.DRAGOON_D, 1); + faction, IUnitRating.DRAGOON_D, -1); addOffers(campaign, getMarketItemCount("uncommon"), UnitMarketType.EMPLOYER, UnitType.CONV_FIGHTER, - faction, IUnitRating.DRAGOON_D, 1); + faction, IUnitRating.DRAGOON_D, -1); // Unwanted Salvage Market faction = contract.getEnemy(); addOffers(campaign, getMarketItemCount("rare"), UnitMarketType.EMPLOYER, UnitType.MEK, - faction, IUnitRating.DRAGOON_F, -2); + faction, IUnitRating.DRAGOON_F, 2); addOffers(campaign, getMarketItemCount("rare"), UnitMarketType.EMPLOYER, UnitType.AEROSPACEFIGHTER, - faction, IUnitRating.DRAGOON_F, -2); + faction, IUnitRating.DRAGOON_F, 2); addOffers(campaign, getMarketItemCount("common"), UnitMarketType.EMPLOYER, UnitType.TANK, - faction, IUnitRating.DRAGOON_F, -2); + faction, IUnitRating.DRAGOON_F, 2); addOffers(campaign, getMarketItemCount("uncommon"), UnitMarketType.EMPLOYER, UnitType.CONV_FIGHTER, - faction, IUnitRating.DRAGOON_F, -2); + faction, IUnitRating.DRAGOON_F, 2); } // Mercenary Market if (!campaign.getFaction().isClan()) { faction = Factions.getInstance().getFaction("MERC"); - int modifier = -1; + int modifier = 1; if (campaign.getFaction().isMercenary()) { - modifier = 1; + modifier = -1; } addOffers(campaign, getMarketItemCount("uncommon"), UnitMarketType.MERCENARY, UnitType.MEK, @@ -151,16 +151,16 @@ public void generateUnitOffers(final Campaign campaign) { if ((!campaign.getFaction().isClan()) && (faction != null) && (!faction.isClan())) { addOffers(campaign, getMarketItemCount("rare"), UnitMarketType.FACTORY, UnitType.MEK, - faction, IUnitRating.DRAGOON_A, -2); + faction, IUnitRating.DRAGOON_A, 2); addOffers(campaign, getMarketItemCount("rare"), UnitMarketType.FACTORY, UnitType.AEROSPACEFIGHTER, - faction, IUnitRating.DRAGOON_A, -2); + faction, IUnitRating.DRAGOON_A, 2); addOffers(campaign, getMarketItemCount("common"), UnitMarketType.FACTORY, UnitType.TANK, - faction, IUnitRating.DRAGOON_A, -2); + faction, IUnitRating.DRAGOON_A, 2); addOffers(campaign, getMarketItemCount("uncommon"), UnitMarketType.FACTORY, UnitType.CONV_FIGHTER, - faction, IUnitRating.DRAGOON_A, -2); + faction, IUnitRating.DRAGOON_A, 2); } } @@ -169,13 +169,13 @@ public void generateUnitOffers(final Campaign campaign) { // Clan Factory Market if ((faction.isClan()) && (campaign.getCurrentSystem().getFactionSet(campaign.getLocalDate()).contains(faction))) { addOffers(campaign, getMarketItemCount("very common"), UnitMarketType.FACTORY, UnitType.MEK, - faction, IUnitRating.DRAGOON_A, 4); + faction, IUnitRating.DRAGOON_A, -4); addOffers(campaign, getMarketItemCount("common"), UnitMarketType.FACTORY, UnitType.AEROSPACEFIGHTER, - faction, IUnitRating.DRAGOON_A, 4); + faction, IUnitRating.DRAGOON_A, -4); addOffers(campaign, getMarketItemCount("uncommon"), UnitMarketType.FACTORY, UnitType.TANK, - faction, IUnitRating.DRAGOON_A, 4); + faction, IUnitRating.DRAGOON_A, -4); } // Black Market @@ -184,16 +184,16 @@ public void generateUnitOffers(final Campaign campaign) { .getFactionSet(campaign.getLocalDate())); addOffers(campaign, getMarketItemCount("very rare"), UnitMarketType.BLACK_MARKET, UnitType.MEK, - faction, IUnitRating.DRAGOON_A, 4); + faction, IUnitRating.DRAGOON_A, -4); addOffers(campaign, getMarketItemCount("very rare"), UnitMarketType.BLACK_MARKET, UnitType.AEROSPACEFIGHTER, - faction, IUnitRating.DRAGOON_A, 4); + faction, IUnitRating.DRAGOON_A, -4); addOffers(campaign, getMarketItemCount("uncommon"), UnitMarketType.BLACK_MARKET, UnitType.TANK, - faction, IUnitRating.DRAGOON_A, 4); + faction, IUnitRating.DRAGOON_A, -4); addOffers(campaign, getMarketItemCount("rare"), UnitMarketType.BLACK_MARKET, UnitType.CONV_FIGHTER, - faction, IUnitRating.DRAGOON_A, 4); + faction, IUnitRating.DRAGOON_A, -4); } writeRefreshReport(campaign); From df68d7040e987d02439fa8c73698dfc9debadc55 Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Mon, 17 Jun 2024 15:40:46 -0500 Subject: [PATCH 07/33] feat: Added education level assignment based on age in HireBulkPersonnelDialog and Campaign classes --- MekHQ/src/mekhq/campaign/Campaign.java | 6 ++++++ MekHQ/src/mekhq/gui/dialog/HireBulkPersonnelDialog.java | 8 ++++++++ 2 files changed, 14 insertions(+) diff --git a/MekHQ/src/mekhq/campaign/Campaign.java b/MekHQ/src/mekhq/campaign/Campaign.java index 4b66245935..d8c8aa821e 100644 --- a/MekHQ/src/mekhq/campaign/Campaign.java +++ b/MekHQ/src/mekhq/campaign/Campaign.java @@ -1334,6 +1334,12 @@ public Person newDependent(boolean baby) { Gender.RANDOMIZE); } + if (person.getAge(getLocalDate()) <= 16) { + person.setEduHighestEducation(EducationLevel.EARLY_CHILDHOOD); + } else { + person.setEduHighestEducation(EducationLevel.HIGH_SCHOOL); + } + return person; } diff --git a/MekHQ/src/mekhq/gui/dialog/HireBulkPersonnelDialog.java b/MekHQ/src/mekhq/gui/dialog/HireBulkPersonnelDialog.java index e443dbce1d..5811180f8b 100644 --- a/MekHQ/src/mekhq/gui/dialog/HireBulkPersonnelDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/HireBulkPersonnelDialog.java @@ -28,6 +28,7 @@ import mekhq.campaign.personnel.Person; import mekhq.campaign.personnel.enums.PersonnelRole; import mekhq.campaign.personnel.enums.Profession; +import mekhq.campaign.personnel.enums.education.EducationLevel; import mekhq.gui.CampaignGUI; import mekhq.gui.displayWrappers.RankDisplay; import org.apache.logging.log4j.LogManager; @@ -357,6 +358,13 @@ private void hire(boolean isGmHire) { person.limitSkills(age - 13); } + // set education based on age + if (age <= 16) { + person.setEduHighestEducation(EducationLevel.EARLY_CHILDHOOD); + } else { + person.setEduHighestEducation(EducationLevel.HIGH_SCHOOL); + } + if (!campaign.recruitPerson(person, isGmHire)) { number = 0; } else { From b9853ac587ecd2859b76bf59fbaf90c74823c00f Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Mon, 17 Jun 2024 15:48:23 -0500 Subject: [PATCH 08/33] feat(EducationController): added new school types and generation method - Added new school types to Education.properties - Added 'generateTypeChild' method to generate random educational institution type in EducationController.java - Updated 'generateName' method to handle PrepSchool type --- .../mekhq/resources/Education.properties | 3 ++ .../education/EducationController.java | 35 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/MekHQ/resources/mekhq/resources/Education.properties b/MekHQ/resources/mekhq/resources/Education.properties index 85cf74a19d..56416b13d1 100644 --- a/MekHQ/resources/mekhq/resources/Education.properties +++ b/MekHQ/resources/mekhq/resources/Education.properties @@ -28,6 +28,9 @@ typeInstitute.text=Institute typeUniversity.text=University typePolytechnic.text=Polytechnic typeSchool.text=School +typeSchoolBoarding.text=Boarding School +typeFinishingSchool.text=Finishing School +typePreparatorySchool.text=Preparatory School #### Academy Suffix suffixTechnology.text=Technology diff --git a/MekHQ/src/mekhq/campaign/personnel/education/EducationController.java b/MekHQ/src/mekhq/campaign/personnel/education/EducationController.java index daafb53cdd..e5bd3b407b 100644 --- a/MekHQ/src/mekhq/campaign/personnel/education/EducationController.java +++ b/MekHQ/src/mekhq/campaign/personnel/education/EducationController.java @@ -146,6 +146,14 @@ public static void enrollPerson(Campaign campaign, Person person, Academy academ public static String generateName(Academy academy, String campus) { ResourceBundle resources = ResourceBundle.getBundle("mekhq.resources.Education", MekHQ.getMHQOptions().getLocale()); + if (academy.isPrepSchool()) { + if (Compute.d6(1) <= 3) { + return campus + ' ' + generateTypeChild(resources) + ' ' + resources.getString("conjoinerOf.text") + ' ' + generateSuffix(resources); + } else { + return generateTypeChild(resources) + ' ' + resources.getString("conjoinerOf.text") + ' ' + campus; + } + } + if (Compute.d6(1) <= 3) { if (academy.isMilitary()) { return campus + ' ' + generateMilitaryPrefix(resources) + ' ' + generateTypeAdult(resources) + ' ' + resources.getString("conjoinerOf.text") + ' ' + generateSuffix(resources); @@ -239,6 +247,33 @@ private static String generateTypeAdult(ResourceBundle resources) { } } + + /** + * Generates a random educational institution type from the provided ResourceBundle. + * + * @param resources the ResourceBundle containing the localized strings for the educational institution types + * @return a randomly selected educational institution type + * @throws IllegalStateException if the generated roll is unexpected + */ + private static String generateTypeChild(ResourceBundle resources) { + switch (Compute.d6(1)) { + case 1: + return resources.getString("typeAcademy.text"); + case 2: + return resources.getString("typePreparatorySchool.text"); + case 3: + return resources.getString("typeInstitute.text"); + case 4: + return resources.getString("typeSchoolBoarding.text"); + case 5: + return resources.getString("typeFinishingSchool.text"); + case 6: + return resources.getString("typeSchool.text"); + default: + throw new IllegalStateException("Unexpected roll in generateTypeAdult"); + } + } + /** * Processes a new day for a person in a campaign. * From cbc439c942be0648ba5a94875f09909f636cb8f9 Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Mon, 17 Jun 2024 16:01:12 -0500 Subject: [PATCH 09/33] "fix: updated fatigue display calculations in PersonViewPanel" --- MekHQ/src/mekhq/gui/view/PersonViewPanel.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/MekHQ/src/mekhq/gui/view/PersonViewPanel.java b/MekHQ/src/mekhq/gui/view/PersonViewPanel.java index fd592263da..ad1f0b6f62 100644 --- a/MekHQ/src/mekhq/gui/view/PersonViewPanel.java +++ b/MekHQ/src/mekhq/gui/view/PersonViewPanel.java @@ -1468,8 +1468,7 @@ private JPanel fillSkills() { firsty++; } - if ((campaign.getCampaignOptions().isUseFatigue()) - && (person.getEffectiveFatigue(campaign) > 0)) { + if ((campaign.getCampaignOptions().isUseFatigue()) && (person.getFatigue() > 0)) { lblFatigue1.setName("lblFatigue1"); lblFatigue1.setText(resourceMap.getString("lblFatigue1.text")); gridBagConstraints = new GridBagConstraints(); @@ -1481,7 +1480,7 @@ private JPanel fillSkills() { StringBuilder fatigueDisplay = new StringBuilder(); int effectiveFatigue = person.getEffectiveFatigue(campaign); - int fatigueTurnoverModifier = MathUtility.clamp(((person.getFatigue() - 1) / 4) - 1, 0, 3); + int fatigueTurnoverModifier = MathUtility.clamp(((person.getEffectiveFatigue(campaign) - 1) / 4) - 1, 0, 3); fatigueDisplay.append(person.getFatigue()); From d832c2ea56f780151424bb0a1ecc5813209771fd Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Mon, 17 Jun 2024 16:29:00 -0500 Subject: [PATCH 10/33] feat(MekHQ data): added start and end years to factions.xml --- MekHQ/data/universe/factions.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MekHQ/data/universe/factions.xml b/MekHQ/data/universe/factions.xml index f7670bbb69..6d74a4141b 100644 --- a/MekHQ/data/universe/factions.xml +++ b/MekHQ/data/universe/factions.xml @@ -1110,6 +1110,8 @@ successor - unimplemented tag describing another faction code as the specified f Federated Commonwealth.png 248,212,44 is,super,playable + 3055 + 3067 FVC From 6d643afb9c002f0cbd35f591abef69b2eca9ebdd Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Mon, 17 Jun 2024 17:45:19 -0500 Subject: [PATCH 11/33] feat(MekHQ data): updated Federated Commonwealth details in factions.xml - Added alternative names by year for Federated Commonwealth - Updated starting and ending years of Federated Commonwealth --- MekHQ/data/universe/factions.xml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/MekHQ/data/universe/factions.xml b/MekHQ/data/universe/factions.xml index 6d74a4141b..9eae41e27d 100644 --- a/MekHQ/data/universe/factions.xml +++ b/MekHQ/data/universe/factions.xml @@ -1101,6 +1101,8 @@ successor - unimplemented tag describing another faction code as the specified f FC Federated Commonwealth + Federated Commonwealth Alliance + Federated Commonwealth FS,LA New Avalon 0,0,0,1,2,2,1,0,0 @@ -1110,8 +1112,8 @@ successor - unimplemented tag describing another faction code as the specified f Federated Commonwealth.png 248,212,44 is,super,playable - 3055 - 3067 + 3028 + 3068 FVC From 9da32490770fa9b168bc34dc40d9aa57120a79b9 Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Mon, 17 Jun 2024 17:46:51 -0500 Subject: [PATCH 12/33] Added change of faction event to Yed Posterior --- MekHQ/data/universe/planetary_systems/system_events.xml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/MekHQ/data/universe/planetary_systems/system_events.xml b/MekHQ/data/universe/planetary_systems/system_events.xml index 019f8b6c9e..655ff9747e 100644 --- a/MekHQ/data/universe/planetary_systems/system_events.xml +++ b/MekHQ/data/universe/planetary_systems/system_events.xml @@ -932465,6 +932465,10 @@ 3064-01-05 FC + + 3063-01-01 + LA + 3070-01-01 5162011707 From 39fa9420ed937537e7039cd210fa0b96f5b7477d Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Mon, 17 Jun 2024 17:49:34 -0500 Subject: [PATCH 13/33] feat(MHQOptionsDialog): added optionInvalidFactionNag for invalid faction checking - Created new InvalidFactionNagDialog class - Updated MHQConstants, CampaignGUI, and GUI.properties to include invalid faction handling - Added faction validity check logic --- .../resources/mekhq/resources/GUI.properties | 6 ++ MekHQ/src/mekhq/MHQConstants.java | 1 + MekHQ/src/mekhq/gui/CampaignGUI.java | 5 ++ .../mekhq/gui/dialog/MHQOptionsDialog.java | 9 +++ .../nagDialogs/InvalidFactionNagDialog.java | 62 +++++++++++++++++++ 5 files changed, 83 insertions(+) create mode 100644 MekHQ/src/mekhq/gui/dialog/nagDialogs/InvalidFactionNagDialog.java diff --git a/MekHQ/resources/mekhq/resources/GUI.properties b/MekHQ/resources/mekhq/resources/GUI.properties index 0838bd8f9e..45d215ae12 100644 --- a/MekHQ/resources/mekhq/resources/GUI.properties +++ b/MekHQ/resources/mekhq/resources/GUI.properties @@ -336,6 +336,10 @@ UnresolvedStratConContactsNagDialog.text=You have unresolved contacts on the Str cargoCapacityNagDialog.title=Exceeded Cargo Capacity cargoCapacityNagDialog.text=You have exceeded your available cargo capacity. Do you really wish to advance the day? +### FactionDestroyedNagDialog Class +InvalidFactionNagDialog.title=Invalid Faction +InvalidFactionNagDialog.text=Your campaign faction is invalid. Either it has not yet been created, or it has been destroyed.\n\nPlease pick a new faction in campaign options.\nAdvance day anyway? + #### Report Dialogs ### CargoReportDialog Class CargoReportDialog.title=Cargo Report @@ -713,6 +717,8 @@ optionOutstandingScenariosNag.text=Hide Outstanding Scenarios Nag optionOutstandingScenariosNag.toolTipText=This allows you to ignore the daily warning for having unfinished scenarios on the current day. optionCargoCapacityNag.text=Hide Exceeded Cargo Capacity Nag optionCargoCapacityNag.toolTipText=This allows you to ignore the daily warning for having exceeded your available cargo capacity. +optionInvalidFactionNag.text=Hide Invalid Faction Nag +optionInvalidFactionNag.toolTipText=This allows you to ignore the daily warning for having an invalid faction. ## Miscellaneous Tab miscellaneousTab.title=Miscellaneous Options lblUserDir.text=User Files Directory: diff --git a/MekHQ/src/mekhq/MHQConstants.java b/MekHQ/src/mekhq/MHQConstants.java index feb0413b54..70f1a462c7 100644 --- a/MekHQ/src/mekhq/MHQConstants.java +++ b/MekHQ/src/mekhq/MHQConstants.java @@ -176,6 +176,7 @@ public final class MHQConstants extends SuiteConstants { public static final String NAG_UNRESOLVED_STRATCON_CONTACTS = "nagUnresolvedStratConContacts"; public static final String NAG_OUTSTANDING_SCENARIOS = "nagOutstandingScenarios"; public static final String NAG_CARGO_CAPACITY = "nagCargoCapacity"; + public static final String NAG_INVALID_FACTION = "nagInvalidFaction"; //endregion Nag Tab //region Miscellaneous Options diff --git a/MekHQ/src/mekhq/gui/CampaignGUI.java b/MekHQ/src/mekhq/gui/CampaignGUI.java index 2f158d0fc7..7a61c7fd14 100644 --- a/MekHQ/src/mekhq/gui/CampaignGUI.java +++ b/MekHQ/src/mekhq/gui/CampaignGUI.java @@ -2447,6 +2447,11 @@ public void handleDayEnding(DayEndingEvent evt) { return; } + if (new InvalidFactionNagDialog(getFrame(), getCampaign()).showDialog().isCancelled()) { + evt.cancel(); + return; + } + if (new InsufficientAstechsNagDialog(getFrame(), getCampaign()).showDialog().isCancelled()) { evt.cancel(); return; diff --git a/MekHQ/src/mekhq/gui/dialog/MHQOptionsDialog.java b/MekHQ/src/mekhq/gui/dialog/MHQOptionsDialog.java index fff07f6f89..0447e32d16 100644 --- a/MekHQ/src/mekhq/gui/dialog/MHQOptionsDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/MHQOptionsDialog.java @@ -159,6 +159,7 @@ public class MHQOptionsDialog extends AbstractMHQButtonDialog { private JCheckBox optionUnresolvedStratConContactsNag; private JCheckBox optionOutstandingScenariosNag; private JCheckBox optionCargoCapacityNag; + private JCheckBox optionInvalidFactionNag; //endregion Nag Tab //region Miscellaneous @@ -915,6 +916,10 @@ private JPanel createNagTab() { optionCargoCapacityNag.setToolTipText(resources.getString("optionCargoCapacityNag.toolTipText")); optionCargoCapacityNag.setName("optionCargoCapacityNag"); + optionInvalidFactionNag = new JCheckBox(resources.getString("optionInvalidFactionNag.text")); + optionInvalidFactionNag.setToolTipText(resources.getString("optionInvalidFactionNag.toolTipText")); + optionInvalidFactionNag.setName("optionInvalidFactionNag"); + // Layout the UI final JPanel panel = new JPanel(); panel.setName("nagPanel"); @@ -938,6 +943,7 @@ private JPanel createNagTab() { .addComponent(optionUnresolvedStratConContactsNag) .addComponent(optionOutstandingScenariosNag) .addComponent(optionCargoCapacityNag) + .addComponent(optionInvalidFactionNag) ); layout.setHorizontalGroup( @@ -955,6 +961,7 @@ private JPanel createNagTab() { .addComponent(optionUnresolvedStratConContactsNag) .addComponent(optionOutstandingScenariosNag) .addComponent(optionCargoCapacityNag) + .addComponent(optionInvalidFactionNag) ); return panel; @@ -1215,6 +1222,7 @@ protected void okAction() { MekHQ.getMHQOptions().setNagDialogIgnore(MHQConstants.NAG_UNRESOLVED_STRATCON_CONTACTS, optionUnresolvedStratConContactsNag.isSelected()); MekHQ.getMHQOptions().setNagDialogIgnore(MHQConstants.NAG_OUTSTANDING_SCENARIOS, optionOutstandingScenariosNag.isSelected()); MekHQ.getMHQOptions().setNagDialogIgnore(MHQConstants.NAG_CARGO_CAPACITY, optionCargoCapacityNag.isSelected()); + MekHQ.getMHQOptions().setNagDialogIgnore(MHQConstants.NAG_INVALID_FACTION, optionCargoCapacityNag.isSelected()); PreferenceManager.getClientPreferences().setUserDir(txtUserDir.getText()); PreferenceManager.getInstance().save(); @@ -1330,6 +1338,7 @@ private void setInitialState() { optionUnresolvedStratConContactsNag.setSelected(MekHQ.getMHQOptions().getNagDialogIgnore(MHQConstants.NAG_UNRESOLVED_STRATCON_CONTACTS)); optionOutstandingScenariosNag.setSelected(MekHQ.getMHQOptions().getNagDialogIgnore(MHQConstants.NAG_OUTSTANDING_SCENARIOS)); optionCargoCapacityNag.setSelected(MekHQ.getMHQOptions().getNagDialogIgnore(MHQConstants.NAG_CARGO_CAPACITY)); + optionInvalidFactionNag.setSelected(MekHQ.getMHQOptions().getNagDialogIgnore(MHQConstants.NAG_INVALID_FACTION)); txtUserDir.setText(PreferenceManager.getClientPreferences().getUserDir()); spnStartGameDelay.setValue(MekHQ.getMHQOptions().getStartGameDelay()); diff --git a/MekHQ/src/mekhq/gui/dialog/nagDialogs/InvalidFactionNagDialog.java b/MekHQ/src/mekhq/gui/dialog/nagDialogs/InvalidFactionNagDialog.java new file mode 100644 index 0000000000..da621e0262 --- /dev/null +++ b/MekHQ/src/mekhq/gui/dialog/nagDialogs/InvalidFactionNagDialog.java @@ -0,0 +1,62 @@ +/* + * Copyright (c) 2021 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MekHQ. + * + * MekHQ is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MekHQ is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MekHQ. If not, see . + */ +package mekhq.gui.dialog.nagDialogs; + +import mekhq.MHQConstants; +import mekhq.MekHQ; +import mekhq.campaign.Campaign; +import mekhq.campaign.universe.Faction; +import mekhq.gui.baseComponents.AbstractMHQNagDialog; + +import javax.swing.*; +import java.time.LocalDate; +import java.util.Objects; + +public class InvalidFactionNagDialog extends AbstractMHQNagDialog { + private static boolean isFactionInvalid (Campaign campaign) { + Faction campaignFaction = campaign.getFaction(); + + if (!campaign.getFaction().validIn(campaign.getLocalDate())) { + return true; + } + + // this is a special handler for FedSuns as they're the main culprit behind the issue of users having invalid factions. + // FS and LA campaigns won't trigger the above conditional, because those factions aren't technically ended when the FedSuns forms + // they just become dormant. + if ((Objects.equals(campaignFaction.getShortName(), "FS")) || (Objects.equals(campaignFaction.getShortName(), "LA"))) { + // the dates picked are chosen as these are when mhq does the bulk of the faction ownership transfers + return ((campaign.getLocalDate().isAfter(LocalDate.of(3040, 1, 18))) + && (campaign.getLocalDate().isBefore(LocalDate.of(3067, 4, 20)))); + } + + return false; + } + + //region Constructors + public InvalidFactionNagDialog(final JFrame frame, final Campaign campaign) { + super(frame, "InvalidFactionNagDialog", "InvalidFactionNagDialog.title", + "InvalidFactionNagDialog.text", campaign, MHQConstants.NAG_INVALID_FACTION); + } + + //endregion Constructors + @Override + protected boolean checkNag() { + return !MekHQ.getMHQOptions().getNagDialogIgnore(getKey()) && (isFactionInvalid(getCampaign())); + } +} From c9bb49796c967e30956ce8186bf8ba0b5235c09c Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Mon, 17 Jun 2024 18:08:32 -0500 Subject: [PATCH 14/33] "refactor(InvalidFactionNagDialog): separated FS and LA faction date validation" --- .../gui/dialog/nagDialogs/InvalidFactionNagDialog.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/MekHQ/src/mekhq/gui/dialog/nagDialogs/InvalidFactionNagDialog.java b/MekHQ/src/mekhq/gui/dialog/nagDialogs/InvalidFactionNagDialog.java index da621e0262..d3e501c089 100644 --- a/MekHQ/src/mekhq/gui/dialog/nagDialogs/InvalidFactionNagDialog.java +++ b/MekHQ/src/mekhq/gui/dialog/nagDialogs/InvalidFactionNagDialog.java @@ -39,12 +39,18 @@ private static boolean isFactionInvalid (Campaign campaign) { // this is a special handler for FedSuns as they're the main culprit behind the issue of users having invalid factions. // FS and LA campaigns won't trigger the above conditional, because those factions aren't technically ended when the FedSuns forms // they just become dormant. - if ((Objects.equals(campaignFaction.getShortName(), "FS")) || (Objects.equals(campaignFaction.getShortName(), "LA"))) { + if (Objects.equals(campaignFaction.getShortName(), "LA")) { // the dates picked are chosen as these are when mhq does the bulk of the faction ownership transfers return ((campaign.getLocalDate().isAfter(LocalDate.of(3040, 1, 18))) && (campaign.getLocalDate().isBefore(LocalDate.of(3067, 4, 20)))); } + // this is another special handler for FedSuns as they're the main culprit behind the issue of users having invalid factions. + if (Objects.equals(campaignFaction.getShortName(), "FS")) { + return ((campaign.getLocalDate().isAfter(LocalDate.of(3040, 1, 18))) + && (campaign.getLocalDate().isBefore(LocalDate.of(3057, 9, 18)))); + } + return false; } From b304fe4b8a69534ff11a687988629d2c4c5da9fc Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Mon, 17 Jun 2024 20:37:01 -0500 Subject: [PATCH 15/33] feat: Updated loyalty generation in various components - Added loyalty regeneration to reeducation camps - Adjusted loyalty generation boundaries in Person.java - Updated documentation --- .../Turnover & Retention Module.pdf | Bin 617552 -> 618754 bytes .../campaign/ResolveScenarioTracker.java | 1 + .../src/mekhq/campaign/personnel/Person.java | 4 ++-- .../education/EducationController.java | 6 ++++-- 4 files changed, 7 insertions(+), 4 deletions(-) diff --git a/MekHQ/docs/Personnel Modules/Turnover & Retention Module.pdf b/MekHQ/docs/Personnel Modules/Turnover & Retention Module.pdf index 2d072eac141115d12888abb52a5ffe7b9dd22f0d..27adf50d92d8677d94820c4105e7ee8eaf1cc621 100644 GIT binary patch delta 19193 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 delta 17988 zcmV)6K*+y>;w8}7C4hthgaU*Egam{Iga(8MvFETGCn>ab98cLVQmU{ob6p% zk0iNqexF~_kJf{@3`Q_W0*eJ^dV2Ka2ix-p1X(NCkPKUv0snjlt11swX7I?YtghVt*zk6B!@UMUR z^waO~f8|gA{V9Jh0>6Ou{PNd7e){#(KV3Z;V*W>-ZBIXv=bisBJ>$#wPd|O57a+s= zukiBy*H194m!kald;a!sXTR{TFF#vH@XO2hfB*FMz5E0pObijpX%DjS*7TqNCLsm{ z?LiRED@w)!vg6Y)o<2yi=?%%s`345{4HmvOe?3U9!&q_%sGnXsJ;@tna^S|LezT{a zM`IC~$Da?U?M(>eBc$mI=MREhHbP7=edF`$8yvc}JrK#eybq-AA>w7N%n+mXg( z%i_!R(3uy&83=5hr*T0eX+*Nt@wC#<_QKN4WI=W|e(-wwK+b^V12-`oosW+UQ4~VM z@dJN8Z(%vl@{%}yu#{wc%_1ohh_qFAfA-~dSSGNnhOeKU4CWm>yry|xEK~hJ-Pm{( zHlLB@`l+h#_=*L>h$Nz7hp@6WzRlbxj0+U5@4v@ zgR|aJi7eIys59h3sDYA^_W@Wj2|}d;OOB z31nnQ8;IunZY5fq@7HmGa#T7{btw#&;gYi{T`%^hfBDbf|Hsci|Md9}fBT=`|M~kL z|Mzb%|M2U-{pRJDUtYd^eO=khf7|(aZ~yq3

f+fcgbDYIKoFCfWkmUY_IS1;XF3 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 diff --git a/MekHQ/src/mekhq/campaign/ResolveScenarioTracker.java b/MekHQ/src/mekhq/campaign/ResolveScenarioTracker.java index 60d3d8f27c..6a3fb160d1 100644 --- a/MekHQ/src/mekhq/campaign/ResolveScenarioTracker.java +++ b/MekHQ/src/mekhq/campaign/ResolveScenarioTracker.java @@ -1475,6 +1475,7 @@ public void resolveScenario(ScenarioStatus resolution, String report) { person.getHyperlinkedName())); } + // prisoners should generate with lower than average loyalty, so only roll 2d6 person.generateLoyalty(Compute.d6(2)); } else { continue; diff --git a/MekHQ/src/mekhq/campaign/personnel/Person.java b/MekHQ/src/mekhq/campaign/personnel/Person.java index cd1fb0567d..81c7e9cf91 100644 --- a/MekHQ/src/mekhq/campaign/personnel/Person.java +++ b/MekHQ/src/mekhq/campaign/personnel/Person.java @@ -3800,7 +3800,7 @@ public void fixReferences(final Campaign campaign) { * @throws IllegalArgumentException if the provided roll is not between 3 and 18 */ public void generateLoyalty(int roll) { - if (roll == 3) { + if (roll <= 3) { setLoyalty(3); } else if (roll == 4) { setLoyalty(2); @@ -3812,7 +3812,7 @@ public void generateLoyalty(int roll) { setLoyalty(-1); } else if (roll == 17) { setLoyalty(-2); - } else if (roll == 18){ + } else if (roll >= 18){ setLoyalty(-3); } else { throw new IllegalArgumentException("Invalid roll in mekhq/campaign/personnel/Person.java/generateLoyalty: " + roll); diff --git a/MekHQ/src/mekhq/campaign/personnel/education/EducationController.java b/MekHQ/src/mekhq/campaign/personnel/education/EducationController.java index daafb53cdd..0eaf6ad072 100644 --- a/MekHQ/src/mekhq/campaign/personnel/education/EducationController.java +++ b/MekHQ/src/mekhq/campaign/personnel/education/EducationController.java @@ -816,10 +816,12 @@ private static void processGraduation(Campaign campaign, Person person, Academy person.setEduHighestEducation(EducationLevel.parseFromInt(educationLevel)); } - if ((academy.isReeducationCamp()) && (campaign.getCampaignOptions().isUseReeducationCamps())) { - if (!Objects.equals(person.getOriginFaction(), campaign.getFaction())) { + if (academy.isReeducationCamp()) { + if (campaign.getCampaignOptions().isUseReeducationCamps()) { person.setOriginFaction(campaign.getFaction()); } + + person.generateLoyalty(Compute.d6(4)); } } From 5dec6ad19a7861ae5e90f581c78b528542c7f8a4 Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Mon, 17 Jun 2024 21:20:30 -0500 Subject: [PATCH 16/33] feat: Enhanced FactionHunterAwards processing - Added detailed conditions to check missionFaction against special super-factions - Updated documentation --- .../docs/Personnel Modules/Awards Module.pdf | Bin 1125762 -> 1087581 bytes .../autoAwards/FactionHunterAwards.java | 85 +++++++++++++++--- 2 files changed, 74 insertions(+), 11 deletions(-) diff --git a/MekHQ/docs/Personnel Modules/Awards Module.pdf b/MekHQ/docs/Personnel Modules/Awards Module.pdf index 0c1f720a6269f648d045ab6b90cad3cfa92433cc..526d5a2ca463f62dd790059860a2b640524aa316 100644 GIT binary patch delta 77129 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