Skip to content

Commit

Permalink
Merge pull request #4837 from IllianiCBT/nag_collateral
Browse files Browse the repository at this point in the history
Refactored Nag Dialogs, Split `UnableToAffordExpensesNagDialog` into Two Dialogs, Added Unit Tests
  • Loading branch information
HammerGS authored Sep 25, 2024
2 parents d2e230e + 1ea5472 commit ddbe027
Show file tree
Hide file tree
Showing 40 changed files with 2,852 additions and 359 deletions.
5 changes: 4 additions & 1 deletion MekHQ/resources/mekhq/resources/CampaignGUI.properties
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,10 @@ lblCargoSummary.text=<html><nobr><b>Cargo Summary:</b></nobr></html>;
lblFacilityCapacities.text=<html><nobr><b>Facility Capacities:</b></nobr></html>;
panLog.title=Daily Activity Log

dialogCheckDueScenarios.text=You must complete scenarios with a date of today or earlier before advancing the day.
dialogOverdueLoans.title=Overdue loans
dialogOverdueLoans.text=You must resolve overdue loans before advancing the day.

dialogCheckDueScenarios.title=Scenarios Must Be Completed
dialogCheckDueScenarios.text=You must complete scenarios with a date of today or earlier before advancing the day.

spareBonusPartExchange.text=Bonus Part Exchange Program
22 changes: 14 additions & 8 deletions MekHQ/resources/mekhq/resources/GUI.properties
Original file line number Diff line number Diff line change
Expand Up @@ -306,15 +306,15 @@ UnitIconDialog.btnNone.toolTipText=The unit does not have a unit icon. This will
#### Nag Dialogs
### InsufficientAstechsNagDialog Class
InsufficientAstechsNagDialog.title=Astech Shortage
InsufficientAstechsNagDialog.text=You do not have enough astechs for your techs. You need %d more astech(s). Do you wish to proceed?
InsufficientAstechsNagDialog.text=Your Tech Teams require more Astechs. You need %d more Astech(s). Do you wish to proceed?

### InsufficientAstechTimeNagDialog Class
InsufficientAstechTimeNagDialog.title=Astech Shortage
InsufficientAstechTimeNagDialog.text=You do not have enough remaining astech time for maintenance. You need %d more astech(s). Do you wish to proceed?
InsufficientAstechTimeNagDialog.title=Astech Time Shortage
InsufficientAstechTimeNagDialog.text=You need more astech time for maintenance. You need %d more astech(s). Do you wish to proceed?

### InsufficientMedicsNagDialog Class
InsufficientMedicsNagDialog.title=Medic Shortage
InsufficientMedicsNagDialog.text=You do not have enough medics for your doctors. You need %d more medic(s). Do you wish to proceed?
InsufficientMedicsNagDialog.text=Your Medical Teams require more Astechs. You need %d more medic(s). Do you wish to proceed?

### OutstandingScenariosNagDialog Class
OutstandingScenariosNagDialog.title=Pending Battle
Expand Down Expand Up @@ -358,12 +358,16 @@ InvalidFactionNagDialog.text=Your campaign faction is invalid. Either it has not

### UnableToAffordExpensesNagDialog Class
UnableToAffordExpensesNagDialog.title=Unable to Afford Expenses
UnableToAffordExpensesNagDialog.text=Payday is due tomorrow, but you cannot afford to cover all expenses.\n\nAdvance day anyway?
UnableToAffordExpensesNagDialog.text=Payday is due tomorrow, but you cannot afford your monthly expenses of %s.\n\nAdvance day anyway?

### UnableToAffordLoanPaymentNagDialog Class
UnableToAffordLoanPaymentNagDialog.title=Unable to Afford Loan Payment
UnableToAffordLoanPaymentNagDialog.text=One or more loans are due tomorrow, but you cannot afford to cover the %s payment.\n\nAdvance day anyway?


### UnableToAffordJumpNagDialog Class
UnableToAffordJumpNagDialog.title=Unable to Afford Jump
UnableToAffordJumpNagDialog.text=You are unable to afford your next jump.\n\nAdvance day anyway?
UnableToAffordJumpNagDialog.title=Unable to Afford the Next Jump
UnableToAffordJumpNagDialog.text=The next jump is %s which you cannot afford.\n\nAdvance day anyway?

#### Report Dialogs
### CargoReportDialog Class
Expand Down Expand Up @@ -753,7 +757,9 @@ optionOutstandingScenariosNag.toolTipText=This allows you to ignore the daily wa
optionInvalidFactionNag.text=Hide Invalid Faction Nag
optionInvalidFactionNag.toolTipText=This allows you to ignore the daily warning for having an invalid faction.
optionUnableToAffordExpensesNag.text=Hide Unable to Afford Expenses Nag
optionUnableToAffordExpensesNag.toolTipText=This allows you to ignore the monthly warning for having insufficient funds to cover all expenses.
optionUnableToAffordExpensesNag.toolTipText=This allows you to ignore the monthly warning for having insufficient funds to cover monthly expenses.
optionUnableToAffordLoanPaymentNag.text=Hide Unable to Afford Loan Payments Nag
optionUnableToAffordLoanPaymentNag.toolTipText=This allows you to ignore the monthly warning for having insufficient funds to cover all loan payments due the next day.
optionUnableToAffordJumpNag.text=Hide Unable to Afford Next Jump Nag
optionUnableToAffordJumpNag.toolTipText=This allows you to ignore the daily warning when unable to afford a jump.
## Miscellaneous Tab
Expand Down
1 change: 1 addition & 0 deletions MekHQ/src/mekhq/MHQConstants.java
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,7 @@ public final class MHQConstants extends SuiteConstants {
public static final String NAG_OUTSTANDING_SCENARIOS = "nagOutstandingScenarios";
public static final String NAG_INVALID_FACTION = "nagInvalidFaction";
public static final String NAG_UNABLE_TO_AFFORD_EXPENSES = "nagUnableToAffordExpenses";
public static final String NAG_UNABLE_TO_AFFORD_LOAN_PAYMENT = "nagUnableToAffordLoanPayment";
public static final String NAG_UNABLE_TO_AFFORD_JUMP = "nagUnableToAffordJump";
// endregion Nag Tab

Expand Down
80 changes: 28 additions & 52 deletions MekHQ/src/mekhq/campaign/Campaign.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,6 @@
*/
package mekhq.campaign;

import static mekhq.campaign.personnel.backgrounds.BackgroundsController.randomMercenaryCompanyNameGenerator;
import static mekhq.campaign.personnel.education.EducationController.getAcademy;
import static mekhq.campaign.personnel.turnoverAndRetention.RetirementDefectionTracker.Payout.isBreakingContract;
import static mekhq.campaign.unit.Unit.SITE_FACILITY_MAINTENANCE;

import java.io.PrintWriter;
import java.text.MessageFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Month;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import javax.swing.JOptionPane;

import megamek.client.generator.RandomGenderGenerator;
import megamek.client.generator.RandomNameGenerator;
import megamek.client.generator.RandomUnitGenerator;
Expand All @@ -54,11 +37,7 @@
import megamek.common.loaders.BLKFile;
import megamek.common.loaders.EntityLoadingException;
import megamek.common.loaders.EntitySavingException;
import megamek.common.options.GameOptions;
import megamek.common.options.IBasicOption;
import megamek.common.options.IOption;
import megamek.common.options.IOptionGroup;
import megamek.common.options.OptionsConstants;
import megamek.common.options.*;
import megamek.common.util.BuildingBlock;
import megamek.common.weapons.autocannons.ACWeapon;
import megamek.common.weapons.flamers.FlamerWeapon;
Expand All @@ -71,11 +50,7 @@
import mekhq.campaign.Quartermaster.PartAcquisitionResult;
import mekhq.campaign.againstTheBot.AtBConfiguration;
import mekhq.campaign.event.*;
import mekhq.campaign.finances.Accountant;
import mekhq.campaign.finances.CurrencyManager;
import mekhq.campaign.finances.Finances;
import mekhq.campaign.finances.Loan;
import mekhq.campaign.finances.Money;
import mekhq.campaign.finances.*;
import mekhq.campaign.finances.enums.TransactionType;
import mekhq.campaign.force.Force;
import mekhq.campaign.force.Lance;
Expand All @@ -90,12 +65,7 @@
import mekhq.campaign.market.ShoppingList;
import mekhq.campaign.market.unitMarket.AbstractUnitMarket;
import mekhq.campaign.market.unitMarket.DisabledUnitMarket;
import mekhq.campaign.mission.AtBContract;
import mekhq.campaign.mission.AtBDynamicScenario;
import mekhq.campaign.mission.AtBScenario;
import mekhq.campaign.mission.Contract;
import mekhq.campaign.mission.Mission;
import mekhq.campaign.mission.Scenario;
import mekhq.campaign.mission.*;
import mekhq.campaign.mission.atb.AtBScenarioFactory;
import mekhq.campaign.mission.enums.AtBLanceRole;
import mekhq.campaign.mission.enums.MissionStatus;
Expand All @@ -105,25 +75,15 @@
import mekhq.campaign.parts.equipment.AmmoBin;
import mekhq.campaign.parts.equipment.EquipmentPart;
import mekhq.campaign.parts.equipment.MissingEquipmentPart;
import mekhq.campaign.personnel.Bloodname;
import mekhq.campaign.personnel.Person;
import mekhq.campaign.personnel.PersonnelOptions;
import mekhq.campaign.personnel.Skill;
import mekhq.campaign.personnel.SkillType;
import mekhq.campaign.personnel.SpecialAbility;
import mekhq.campaign.personnel.*;
import mekhq.campaign.personnel.autoAwards.AutoAwardsController;
import mekhq.campaign.personnel.death.AbstractDeath;
import mekhq.campaign.personnel.death.DisabledRandomDeath;
import mekhq.campaign.personnel.divorce.AbstractDivorce;
import mekhq.campaign.personnel.divorce.DisabledRandomDivorce;
import mekhq.campaign.personnel.education.Academy;
import mekhq.campaign.personnel.education.EducationController;
import mekhq.campaign.personnel.enums.FamilialRelationshipType;
import mekhq.campaign.personnel.enums.PersonnelRole;
import mekhq.campaign.personnel.enums.PersonnelStatus;
import mekhq.campaign.personnel.enums.Phenotype;
import mekhq.campaign.personnel.enums.PrisonerStatus;
import mekhq.campaign.personnel.enums.SplittingSurnameStyle;
import mekhq.campaign.personnel.enums.*;
import mekhq.campaign.personnel.generator.AbstractPersonnelGenerator;
import mekhq.campaign.personnel.generator.DefaultPersonnelGenerator;
import mekhq.campaign.personnel.generator.RandomPortraitGenerator;
Expand All @@ -136,21 +96,16 @@
import mekhq.campaign.personnel.ranks.Ranks;
import mekhq.campaign.personnel.turnoverAndRetention.Fatigue;
import mekhq.campaign.personnel.turnoverAndRetention.RetirementDefectionTracker;
import mekhq.campaign.rating.CamOpsReputation.ReputationController;
import mekhq.campaign.rating.FieldManualMercRevDragoonsRating;
import mekhq.campaign.rating.IUnitRating;
import mekhq.campaign.rating.UnitRatingMethod;
import mekhq.campaign.rating.CamOpsReputation.ReputationController;
import mekhq.campaign.storyarc.StoryArc;
import mekhq.campaign.stratcon.StratconContractInitializer;
import mekhq.campaign.stratcon.StratconRulesManager;
import mekhq.campaign.stratcon.StratconTrackState;
import mekhq.campaign.unit.CargoStatistics;
import mekhq.campaign.unit.CrewType;
import mekhq.campaign.unit.HangarStatistics;
import mekhq.campaign.unit.TestUnit;
import mekhq.campaign.unit.Unit;
import mekhq.campaign.unit.UnitOrder;
import mekhq.campaign.unit.UnitTechProgression;
import mekhq.campaign.unit.*;
import mekhq.campaign.universe.*;
import mekhq.campaign.universe.Planet.PlanetaryEvent;
import mekhq.campaign.universe.PlanetarySystem.PlanetarySystemEvent;
Expand All @@ -171,6 +126,22 @@
import mekhq.service.mrms.MRMSService;
import mekhq.utilities.MHQXMLUtility;

import javax.swing.*;
import java.io.PrintWriter;
import java.text.MessageFormat;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Month;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.Map.Entry;
import java.util.stream.Collectors;

import static mekhq.campaign.personnel.backgrounds.BackgroundsController.randomMercenaryCompanyNameGenerator;
import static mekhq.campaign.personnel.education.EducationController.getAcademy;
import static mekhq.campaign.personnel.turnoverAndRetention.RetirementDefectionTracker.Payout.isBreakingContract;
import static mekhq.campaign.unit.Unit.SITE_FACILITY_MAINTENANCE;

/**
* The main campaign class, keeps track of teams and units
*
Expand Down Expand Up @@ -7749,6 +7720,11 @@ public int checkTurnoverPrompt() {
options[0]);
}

/**
* Checks if there are any scenarios that are due based on the current date.
*
* @return {@code true} if there are scenarios due, {@code false} otherwise
*/
public boolean checkScenariosDue() {
return getActiveMissions(true).stream()
.flatMap(m -> m.getCurrentScenarios().stream())
Expand Down
48 changes: 6 additions & 42 deletions MekHQ/src/mekhq/campaign/stratcon/StratconRulesManager.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,6 @@
*/
package mekhq.campaign.stratcon;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

import megamek.codeUtilities.ObjectUtility;
import megamek.common.Compute;
import megamek.common.Minefield;
Expand All @@ -39,16 +34,10 @@
import mekhq.campaign.event.StratconDeploymentEvent;
import mekhq.campaign.force.Force;
import mekhq.campaign.force.Lance;
import mekhq.campaign.mission.AtBContract;
import mekhq.campaign.mission.AtBDynamicScenario;
import mekhq.campaign.mission.AtBDynamicScenarioFactory;
import mekhq.campaign.mission.AtBScenario;
import mekhq.campaign.mission.Scenario;
import mekhq.campaign.mission.ScenarioForceTemplate;
import mekhq.campaign.mission.*;
import mekhq.campaign.mission.ScenarioForceTemplate.ForceAlignment;
import mekhq.campaign.mission.ScenarioForceTemplate.ForceGenerationMethod;
import mekhq.campaign.mission.ScenarioMapParameters.MapLocation;
import mekhq.campaign.mission.ScenarioTemplate;
import mekhq.campaign.mission.atb.AtBScenarioModifier;
import mekhq.campaign.mission.atb.AtBScenarioModifier.EventTiming;
import mekhq.campaign.personnel.Person;
Expand All @@ -58,6 +47,11 @@
import mekhq.campaign.stratcon.StratconScenario.ScenarioState;
import mekhq.campaign.unit.Unit;

import java.time.DayOfWeek;
import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;

/**
* This class contains "rules" logic for the AtB-Stratcon state
*
Expand Down Expand Up @@ -771,36 +765,6 @@ private static Map<MapLocation, List<Integer>> sortForcesByMapType(List<Integer>
return retVal;
}

/**
* Determine whether the user should be nagged about unresolved scenarios on AtB
* Stratcon tracks.
*
* @param campaign Campaign to check.
* @return An informative string containing the reasons the user was nagged.
*/
public static String nagUnresolvedContacts(Campaign campaign) {
String sb = "";

// check every track attached to an active contract for unresolved scenarios
// to which the player must deploy forces today
for (AtBContract contract : campaign.getActiveAtBContracts()) {
if (contract.getStratconCampaignState() == null) {
continue;
}

for (StratconTrackState track : contract.getStratconCampaignState().getTracks()) {
// "scenario name, track name"
sb = track.getScenarios().values().stream()
.filter(scenario -> (scenario.getCurrentState() == ScenarioState.UNRESOLVED)
&& campaign.getLocalDate().equals(scenario.getDeploymentDate()))
.map(scenario -> String.format("%s, %s\n", scenario.getName(), track.getDisplayableName()))
.collect(Collectors.joining());
}
}

return sb;
}

/**
* Worker function that generates stratcon scenario at the given coords, for the
* given force, on the
Expand Down
Loading

0 comments on commit ddbe027

Please sign in to comment.