From e5343704a15be633d51d84e4baf2da2e2a1f1849 Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Mon, 17 Jun 2024 09:12:09 -0500 Subject: [PATCH 01/18] 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/18] 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/18] 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/18] 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/18] 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/18] 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/18] 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/18] 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/18] "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/18] 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/18] 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/18] 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/18] 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/18] "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 51a236deccfb48d0a425dfd818db3ab88bdac260 Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Wed, 19 Jun 2024 21:50:10 -0500 Subject: [PATCH 15/18] feat: Updated academy qualification data in Prestigious Academies.xml - Removed duplicate qualificationStartYear entries - Updated tuition cost for a specific academy - Added new qualification with corresponding curriculum and start year --- MekHQ/data/universe/academies/Prestigious Academies.xml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/MekHQ/data/universe/academies/Prestigious Academies.xml b/MekHQ/data/universe/academies/Prestigious Academies.xml index b94ef7bc41..430022aa32 100644 --- a/MekHQ/data/universe/academies/Prestigious Academies.xml +++ b/MekHQ/data/universe/academies/Prestigious Academies.xml @@ -1795,7 +1795,6 @@ Semester One Curriculum Small Arms 2300 - 2300 -1 @@ -2324,7 +2323,6 @@ Armored Infantry Graduate Gunnery/Battlesuit, Anti-Mech 3058 - 3058 Aerospace Graduate Piloting/Aerospace, Gunnery/Aerospace 2490 @@ -2422,12 +2420,15 @@ Terra 2300 2777 - #N/A + 7500 1200 5 High School Doctorate 16 + Intergalactic Diplomacy in the Modern Age + Negotiation, Leadership + 2300 0 From 2549b2a1042a0419a14d46c5964281237ed01724 Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Wed, 19 Jun 2024 22:04:23 -0500 Subject: [PATCH 16/18] Updated history.txt --- MekHQ/docs/history.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/MekHQ/docs/history.txt b/MekHQ/docs/history.txt index 187bf27459..167759b7a9 100644 --- a/MekHQ/docs/history.txt +++ b/MekHQ/docs/history.txt @@ -103,6 +103,7 @@ MEKHQ VERSION HISTORY: + Fix #4235: Fixed Invalid Parsing of Early Childhood when Loading Personnel + PR #4242: Added Prestigious Academies D-F + PR #4246: Added Prestigious Academies G-J ++ PR #4248: Fixed Missing Qualification from James McKenna University 0.49.19.1 (2024-05-14 1800 UTC) + Milestone Release. Backported fixes. From 829e89736377504c5ed49115945eac88a9788c85 Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Thu, 20 Jun 2024 00:35:47 -0500 Subject: [PATCH 17/18] feat: Updated academy attributes in Prestigious Academies.xml - Removed factionDiscount and isFactionRestricted attributes from Addicks University - Added qualification, curriculum, and qualificationStartYear attributes --- MekHQ/data/universe/academies/Prestigious Academies.xml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/MekHQ/data/universe/academies/Prestigious Academies.xml b/MekHQ/data/universe/academies/Prestigious Academies.xml index 430022aa32..4cb0fd5eef 100644 --- a/MekHQ/data/universe/academies/Prestigious Academies.xml +++ b/MekHQ/data/universe/academies/Prestigious Academies.xml @@ -23,8 +23,6 @@ Addicks University University Located in the heart of the Inner Sphere, Addicks University is celebrated for its progressive liberal arts education, particularly in teacher training. The institution uniquely integrates its academic programs with community schools, allowing student teachers to gain invaluable hands-on experience. - 0 - true Addicks 2400 2777 @@ -34,6 +32,9 @@ High School College 16 + Teaching Graduate + Leadership + 2300 0 From 78b26eb29377ba6be35ac9110c9e62ffe9ff5918 Mon Sep 17 00:00:00 2001 From: IllianiCBT Date: Thu, 20 Jun 2024 10:08:23 -0500 Subject: [PATCH 18/18] feat: Adjusted market item rarity and price mods in AtBMonthlyUnitMarket * Decreased modifier for very rare, rare, and uncommon item offers in black market * Changed item rarity for tank from uncommon to rare * Refactored getPricePercentage method in UnitMarketType, rearranged modifier operand for clarity --- .../campaign/market/enums/UnitMarketType.java | 15 ++++++++------- .../market/unitMarket/AtBMonthlyUnitMarket.java | 10 +++++----- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/MekHQ/src/mekhq/campaign/market/enums/UnitMarketType.java b/MekHQ/src/mekhq/campaign/market/enums/UnitMarketType.java index a529ca5099..9cc648fd4c 100644 --- a/MekHQ/src/mekhq/campaign/market/enums/UnitMarketType.java +++ b/MekHQ/src/mekhq/campaign/market/enums/UnitMarketType.java @@ -117,32 +117,33 @@ public String toString() { */ public static int getPricePercentage(int modifier) { int roll = Compute.d6(2); - int value = 0; + int value; switch (roll) { case 2: - value = 3 + modifier; + value = modifier + 3; break; case 3: - value = 2 + modifier; + value = modifier + 2; break; case 4: case 5: - value = 1 + modifier; + value = modifier + 1; break; case 6: case 7: case 8: + value = modifier; break; case 9: case 10: - value = -1 + modifier; + value = modifier - 1; break; case 11: - value = -2 + modifier; + value = modifier - 2; break; case 12: - value = -3 + modifier; + value = modifier - 3; break; default: throw new IllegalStateException("Unexpected value in mekhq/campaign/market/unitMarket/AtBMonthlyUnitMarket.java/getPrice: " + roll); diff --git a/MekHQ/src/mekhq/campaign/market/unitMarket/AtBMonthlyUnitMarket.java b/MekHQ/src/mekhq/campaign/market/unitMarket/AtBMonthlyUnitMarket.java index 057aac33dd..23050ce4b2 100644 --- a/MekHQ/src/mekhq/campaign/market/unitMarket/AtBMonthlyUnitMarket.java +++ b/MekHQ/src/mekhq/campaign/market/unitMarket/AtBMonthlyUnitMarket.java @@ -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, -8); addOffers(campaign, getMarketItemCount("very rare"), UnitMarketType.BLACK_MARKET, UnitType.AEROSPACEFIGHTER, - faction, IUnitRating.DRAGOON_A, -4); + faction, IUnitRating.DRAGOON_A, -8); - addOffers(campaign, getMarketItemCount("uncommon"), UnitMarketType.BLACK_MARKET, UnitType.TANK, - faction, IUnitRating.DRAGOON_A, -4); + addOffers(campaign, getMarketItemCount("rare"), UnitMarketType.BLACK_MARKET, UnitType.TANK, + faction, IUnitRating.DRAGOON_A, -8); addOffers(campaign, getMarketItemCount("rare"), UnitMarketType.BLACK_MARKET, UnitType.CONV_FIGHTER, - faction, IUnitRating.DRAGOON_A, -4); + faction, IUnitRating.DRAGOON_A, -8); } writeRefreshReport(campaign);