27
27
*/
28
28
package mekhq .gui .dialog .nagDialogs ;
29
29
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
+
31
39
import mekhq .MekHQ ;
32
40
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 ;
36
43
37
44
/**
38
45
* A dialog used to notify the user about insufficient medics required to meet the medical needs of the campaign.
39
46
*
40
47
* <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.
45
51
* </p>
46
52
*
47
53
* <strong>Features:</strong>
48
54
* <ul>
49
55
* <li>Calculates the number of medics required for a campaign using {@link Campaign#getMedicsNeed()}.</li>
50
56
* <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>
52
57
* </ul>
53
58
*/
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
+
55
69
/**
56
70
* Constructs an {@code InsufficientMedicsNagDialog} for the given campaign.
57
71
*
58
72
* <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.
62
76
* </p>
63
77
*
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.
66
80
*/
67
81
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 <>();
69
121
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" ));
71
125
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
+ }
73
154
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 ;
78
184
}
79
185
80
186
/**
@@ -87,13 +193,12 @@ public InsufficientMedicsNagDialog(final Campaign campaign) {
87
193
* </ul>
88
194
*
89
195
* @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.
92
198
*/
93
199
public static boolean checkNag (int medicsRequired ) {
94
- final String NAG_KEY = MHQConstants . NAG_INSUFFICIENT_MEDICS ;
200
+ final String NAG_KEY = NAG_INSUFFICIENT_MEDICS ;
95
201
96
- return !MekHQ .getMHQOptions ().getNagDialogIgnore (NAG_KEY )
97
- && hasMedicsNeeded (medicsRequired );
202
+ return !MekHQ .getMHQOptions ().getNagDialogIgnore (NAG_KEY ) && hasMedicsNeeded (medicsRequired );
98
203
}
99
204
}
0 commit comments