Skip to content

Commit 4bbdffa

Browse files
committed
Updated Insufficient Medics Nag To Use Immersive Dialog
- Refactored `InsufficientMedicsNagDialog` to utilize `ImmersiveDialogSimple` for improved modularity and customization. - Replaced inheritance from `AbstractMHQNagDialog` with a standalone class to simplify and streamline the implementation. - Updated NagController logic to replace `wasAdvanceDayCanceled()` with `shouldCancelAdvanceDay()` to reflect the updated behavior.
1 parent e3d7ba2 commit 4bbdffa

File tree

4 files changed

+143
-36
lines changed

4 files changed

+143
-36
lines changed

MekHQ/resources/mekhq/resources/GUI.properties

-6
Original file line numberDiff line numberDiff line change
@@ -309,12 +309,6 @@ NoCommanderNagDialog.text=Please be advised that no commanding officer is curren
309309
<br>\
310310
<br><i>You can assign one of your personnel as the campaign commander by right-clicking on that\
311311
\ character, navigating to Flags and selecting the Commander flag.</i>
312-
InsufficientMedicsNagDialog.text=%s, our medical teams are short by %d medic%s. This may lead to\
313-
\ delays in treatment or personnel remaining untreated. Confirm if you wish to advance the day\
314-
\ regardless.\
315-
<br>\
316-
<br><i>You can resolve this issue by selecting 'Marketplace' in the taskbar, then 'Medic Pool,'\
317-
\ then selecting the option to bring all teams up to full strength.</i>
318312
InvalidFactionNagDialog.text=%s, reports indicate our parent faction is invalid. Possibly\
319313
\ destroyed. Confirm your intent to advance the day under these circumstances.\
320314
<br>\

MekHQ/resources/mekhq/resources/NagDialogs.properties

+10-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,8 @@ EndContractNagDialog.ic={0}, a contract has reached its conclusion and requires
2424
\ final resolution. While you may advance the day, I recommend addressing this to avoid delays in\
2525
\ resource allocation and payment. Confirm your decision to proceed.
2626
EndContractNagDialog.ooc=You can resolve a contract by selecting the contract in the Briefing Room,\
27-
\ followed by 'Complete Mission'.</i>
27+
\ followed by 'Complete Mission'.\
28+
<p>If you accidentally suppress this warning, you can re-enable it in MekHQ Options.</p>
2829
# Insufficient Astech Time
2930
InsufficientAstechTimeNagDialog.ic={0}, current maintenance requires an additional {1}\
3031
\ {1, choice, 0#Astechs|1#Astech|2#Astechs}. Proceeding without resolving this will prevent some\
@@ -43,5 +44,12 @@ InsufficientAstechsNagDialog.ic={0}, a shortage of {1} {1, choice, 0#Astechs|1#A
4344
InsufficientAstechsNagDialog.ooc=You can resolve this issue by selecting 'Marketplace' in the toolbar,\
4445
\ then 'Astech Pool,' then selecting the option to bring all teams up to full strength. If this\
4546
\ does not resolve the issue, you have likely spread your techs too thinly by assigning them to too\
46-
\ many units. Consider hiring more techs.</i>\
47+
\ many units. Consider hiring more techs.\
48+
<p>If you accidentally suppress this warning, you can re-enable it in MekHQ Options.</p>
49+
# Insufficient Medics
50+
InsufficientMedicsNagDialog.ic={0}, our medical teams are short by {1} {1, choice, 0#Medics|1#Medic|2#Medics}.\
51+
\ This may lead to delays in treatment or personnel remaining untreated. Confirm if you wish to\
52+
\ advance the day regardless.
53+
InsufficientMedicsNagDialog.ooc=You can resolve this issue by selecting 'Marketplace' in the taskbar,\
54+
\ then 'Medic Pool,' then selecting the option to bring all teams up to full strength.\
4755
<p>If you accidentally suppress this warning, you can re-enable it in MekHQ Options.</p>

MekHQ/src/mekhq/gui/dialog/nagDialogs/InsufficientMedicsNagDialog.java

+132-27
Original file line numberDiff line numberDiff line change
@@ -27,54 +27,160 @@
2727
*/
2828
package mekhq.gui.dialog.nagDialogs;
2929

30-
import mekhq.MHQConstants;
30+
import static mekhq.MHQConstants.NAG_INSUFFICIENT_MEDICS;
31+
import static mekhq.campaign.Campaign.AdministratorSpecialization.COMMAND;
32+
import static mekhq.campaign.Campaign.AdministratorSpecialization.HR;
33+
import static mekhq.gui.dialog.nagDialogs.nagLogic.InsufficientMedicsNagLogic.hasMedicsNeeded;
34+
import static mekhq.utilities.MHQInternationalization.getFormattedTextAt;
35+
36+
import java.util.ArrayList;
37+
import java.util.List;
38+
3139
import mekhq.MekHQ;
3240
import mekhq.campaign.Campaign;
33-
import mekhq.gui.baseComponents.AbstractMHQNagDialog;
34-
35-
import static mekhq.gui.dialog.nagDialogs.nagLogic.InsufficientMedicsNagLogic.hasMedicsNeeded;
41+
import mekhq.campaign.personnel.Person;
42+
import mekhq.gui.baseComponents.immersiveDialogs.ImmersiveDialogSimple;
3643

3744
/**
3845
* A dialog used to notify the user about insufficient medics required to meet the medical needs of the campaign.
3946
*
4047
* <p>
41-
* This nag dialog is triggered when the count of available medics in the campaign falls short of
42-
* the total number required for handling the current medical workload. It displays a localized
43-
* message for the user with specifics about the deficit, and optionally allows the user to dismiss
44-
* or ignore future warnings.
48+
* This nag dialog is triggered when the count of available medics in the campaign falls short of the total number
49+
* required for handling the current medical workload. It displays a localized message for the user with specifics about
50+
* the deficit, and optionally allows the user to dismiss or ignore future warnings.
4551
* </p>
4652
*
4753
* <strong>Features:</strong>
4854
* <ul>
4955
* <li>Calculates the number of medics required for a campaign using {@link Campaign#getMedicsNeed()}.</li>
5056
* <li>Displays a dialog to warn the user if the required number of medics exceeds the available count.</li>
51-
* <li>Extends {@link AbstractMHQNagDialog} to provide consistent behavior with other nag dialogs.</li>
5257
* </ul>
5358
*/
54-
public class InsufficientMedicsNagDialog extends AbstractMHQNagDialog {
59+
public class InsufficientMedicsNagDialog {
60+
private final String RESOURCE_BUNDLE = "mekhq.resources.NagDialogs";
61+
62+
private final int CHOICE_CANCEL = 0;
63+
private final int CHOICE_CONTINUE = 1;
64+
private final int CHOICE_SUPPRESS = 2;
65+
66+
private final Campaign campaign;
67+
private boolean cancelAdvanceDay;
68+
5569
/**
5670
* Constructs an {@code InsufficientMedicsNagDialog} for the given campaign.
5771
*
5872
* <p>
59-
* This dialog calculates the number of medics required and uses a localized
60-
* message to notify the user about the shortage. The message includes the
61-
* commander's address, the medic deficit, and a pluralized suffix based on the deficit count.
73+
* This dialog calculates the number of medics required and uses a localized message to notify the user about the
74+
* shortage. The message includes the commander's address, the medic deficit, and a pluralized suffix based on the
75+
* deficit count.
6276
* </p>
6377
*
64-
* @param campaign The {@link Campaign} associated with this nag dialog.
65-
* The campaign provides the medical requirements for the calculation.
78+
* @param campaign The {@link Campaign} associated with this nag dialog. The campaign provides the medical
79+
* requirements for the calculation.
6680
*/
6781
public InsufficientMedicsNagDialog(final Campaign campaign) {
68-
super(campaign, MHQConstants.NAG_INSUFFICIENT_MEDICS);
82+
this.campaign = campaign;
83+
84+
int medicsRequired = campaign.getMedicsNeed();
85+
86+
ImmersiveDialogSimple dialog = new ImmersiveDialogSimple(campaign,
87+
getSpeaker(),
88+
null,
89+
getFormattedTextAt(RESOURCE_BUNDLE,
90+
"InsufficientMedicsNagDialog.ic",
91+
campaign.getCommanderAddress(false),
92+
medicsRequired),
93+
getButtonLabels(),
94+
getFormattedTextAt(RESOURCE_BUNDLE, "InsufficientMedicsNagDialog.ooc"),
95+
true);
96+
97+
int choiceIndex = dialog.getDialogChoice();
98+
99+
switch (choiceIndex) {
100+
case CHOICE_CANCEL -> cancelAdvanceDay = true;
101+
case CHOICE_CONTINUE -> cancelAdvanceDay = false;
102+
case CHOICE_SUPPRESS -> {
103+
MekHQ.getMHQOptions().setNagDialogIgnore(NAG_INSUFFICIENT_MEDICS, true);
104+
cancelAdvanceDay = false;
105+
}
106+
default ->
107+
throw new IllegalStateException("Unexpected value in InsufficientMedicsNagDialog: " + choiceIndex);
108+
}
109+
}
110+
111+
/**
112+
* Retrieves a list of button labels from the resource bundle.
113+
*
114+
* <p>The method collects and returns button labels such as "Cancel", "Continue", and "Suppress" after
115+
* formatting them using the provided resource bundle.</p>
116+
*
117+
* @return a {@link List} of formatted button labels as {@link String}.
118+
*/
119+
private List<String> getButtonLabels() {
120+
List<String> buttonLabels = new ArrayList<>();
69121

70-
int medicsRequired = campaign.getMedicsNeed();
122+
buttonLabels.add(getFormattedTextAt(RESOURCE_BUNDLE, "button.cancel"));
123+
buttonLabels.add(getFormattedTextAt(RESOURCE_BUNDLE, "button.continue"));
124+
buttonLabels.add(getFormattedTextAt(RESOURCE_BUNDLE, "button.suppress"));
71125

72-
String pluralizer = (medicsRequired > 1) ? "s" : "";
126+
return buttonLabels;
127+
}
128+
129+
/**
130+
* Retrieves the speaker based on the active personnel.
131+
*
132+
* <p>This method iterates through the active personnel within the campaign and attempts to identify a speaker who
133+
* meets the criteria. It prioritizes selecting a person with technical specialization, using a tie-breaking
134+
* mechanism based on rank and skills. If no suitable speaker is found, it defaults to the senior administrator
135+
* person with the "COMMAND" specialization.</p>
136+
*
137+
* @return the {@link Person} designated as the speaker, either the highest-ranking technical specialist or the
138+
* senior administrator with the "COMMAND" specialization if no other suitable speaker is found.
139+
*/
140+
private Person getSpeaker() {
141+
List<Person> activePersonnel = campaign.getActivePersonnel(false);
142+
143+
Person speaker = null;
144+
145+
for (Person person : activePersonnel) {
146+
if (!person.isDoctor()) {
147+
continue;
148+
}
149+
150+
if (speaker == null) {
151+
speaker = person;
152+
continue;
153+
}
73154

74-
final String DIALOG_BODY = "InsufficientMedicsNagDialog.text";
75-
setRightDescriptionMessage(String.format(resources.getString(DIALOG_BODY),
76-
campaign.getCommanderAddress(false), medicsRequired, pluralizer));
77-
showDialog();
155+
if (person.outRanksUsingSkillTiebreaker(campaign, speaker)) {
156+
speaker = person;
157+
}
158+
}
159+
160+
// First fallback
161+
if (speaker == null) {
162+
speaker = campaign.getSeniorAdminPerson(HR);
163+
} else {
164+
return speaker;
165+
}
166+
167+
// Second fallback
168+
if (speaker == null) {
169+
speaker = campaign.getSeniorAdminPerson(COMMAND);
170+
} else {
171+
return speaker;
172+
}
173+
174+
return speaker;
175+
}
176+
177+
/**
178+
* Determines whether the advance day operation should be canceled.
179+
*
180+
* @return {@code true} if advancing the day should be canceled, {@code false} otherwise.
181+
*/
182+
public boolean shouldCancelAdvanceDay() {
183+
return cancelAdvanceDay;
78184
}
79185

80186
/**
@@ -87,13 +193,12 @@ public InsufficientMedicsNagDialog(final Campaign campaign) {
87193
* </ul>
88194
*
89195
* @param medicsRequired The number of additional medics required to meet the campaign's needs.
90-
* @return {@code true} if the nag dialog should be displayed due to insufficient medics,
91-
* {@code false} otherwise.
196+
*
197+
* @return {@code true} if the nag dialog should be displayed due to insufficient medics, {@code false} otherwise.
92198
*/
93199
public static boolean checkNag(int medicsRequired) {
94-
final String NAG_KEY = MHQConstants.NAG_INSUFFICIENT_MEDICS;
200+
final String NAG_KEY = NAG_INSUFFICIENT_MEDICS;
95201

96-
return !MekHQ.getMHQOptions().getNagDialogIgnore(NAG_KEY)
97-
&& hasMedicsNeeded(medicsRequired);
202+
return !MekHQ.getMHQOptions().getNagDialogIgnore(NAG_KEY) && hasMedicsNeeded(medicsRequired);
98203
}
99204
}

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ public static boolean triggerDailyNags(Campaign campaign) {
151151
// Insufficient Medics
152152
if (InsufficientMedicsNagDialog.checkNag(campaign.getMedicsNeed())) {
153153
InsufficientMedicsNagDialog insufficientMedicsNagDialog = new InsufficientMedicsNagDialog(campaign);
154-
if (insufficientMedicsNagDialog.wasAdvanceDayCanceled()) {
154+
if (insufficientMedicsNagDialog.shouldCancelAdvanceDay()) {
155155
return true;
156156
}
157157
}

0 commit comments

Comments
 (0)