Skip to content

Commit 5eb8092

Browse files
authored
Merge pull request #7343 from IllianiBird/skillCheckUtilityReputationModifierBug
Fix: Fixed Skill Check Utility Not Correctly Using Reputation Modifiers
2 parents 6c95e67 + 729765e commit 5eb8092

File tree

6 files changed

+181
-54
lines changed

6 files changed

+181
-54
lines changed

MekHQ/src/mekhq/campaign/Campaign.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3502,8 +3502,6 @@ public int getPatientsFor(Person doctor) {
35023502
for (Person person : getActivePersonnel(false)) {
35033503
int effectiveMaxAcquisitions = defaultMaxAcquisitions;
35043504

3505-
PersonnelOptions options = person.getOptions();
3506-
35073505
if (isIneligibleToPerformProcurement(person, acquisitionCategory)) {
35083506
continue;
35093507
}
@@ -5278,7 +5276,10 @@ public void processNewDayPersonnel() {
52785276
person.resetMinutesLeft(campaignOptions.isTechsUseAdministration());
52795277
person.setAcquisition(0);
52805278

5281-
medicalController.processMedicalEvents(person);
5279+
medicalController.processMedicalEvents(person,
5280+
campaignOptions.isUseAgeEffects(),
5281+
isClanCampaign(),
5282+
currentDay);
52825283

52835284
processAnniversaries(person);
52845285

MekHQ/src/mekhq/campaign/personnel/medical/MedicalController.java

Lines changed: 47 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import static mekhq.campaign.personnel.skills.SkillType.S_SURGERY;
3737
import static mekhq.utilities.MHQInternationalization.getFormattedTextAt;
3838

39+
import java.time.LocalDate;
3940
import java.util.ArrayList;
4041
import java.util.List;
4142

@@ -88,18 +89,35 @@ public MedicalController(Campaign campaign) {
8889
isUseMedicalController = campaignOptions.isUseAdvancedMedical();
8990
}
9091

92+
/**
93+
* Use {@link #processMedicalEvents(Person, boolean, boolean, LocalDate)} instead
94+
*/
95+
@Deprecated(since = "0.50.07", forRemoval = true)
96+
public void processMedicalEvents(Person patient) {
97+
processMedicalEvents(patient, false, false, LocalDate.of(3151, 1, 1));
98+
}
9199

92100
/**
93-
* Processes the medical events for the given patient. This includes doctor-assisted healing,
94-
* natural healing, and advanced medical rules (if enabled).
101+
* Processes daily medical events for a given patient, handling both standard and advanced medical healing.
95102
*
96-
* <p>For non-advanced medical rules, the method validates and assigns doctors and handles
97-
* natural healing if the doctor cannot assist. For advanced medical rules, it delegates
98-
* the processing to the advanced medical subsystem.</p>
103+
* <p>The method orchestrates healing for a {@link Person} by applying doctor-assisted healing, natural healing
104+
* rolls, and advanced medical rules, depending on campaign settings and the patient's needs.</p>
105+
* <ul>
106+
* <li>If the patient requires healing and advanced medical rules are <b>not</b> enabled,
107+
* it attempts to validate and assign a doctor for assisted healing. If a doctor is not available or able
108+
* to help, it attempts natural healing instead. Successful natural healing is logged, and related
109+
* unit states are reset.</li>
110+
* <li>If advanced medical rules are enabled, the method defers the healing process to the advanced
111+
* medical subsystem and resets unit-related state as needed.</li>
112+
* </ul>
99113
*
100-
* @param patient the {@link Person} being healed
114+
* @param patient the {@link Person} undergoing healing
115+
* @param isUseAgingEffects {@code true} if aging effects should be included when applying healing
116+
* @param isClanCampaign {@code true} if the campaign uses clan-based rules
117+
* @param today the current {@link LocalDate} for time-dependent calculations
101118
*/
102-
public void processMedicalEvents(Person patient) {
119+
public void processMedicalEvents(Person patient, boolean isUseAgingEffects, boolean isClanCampaign,
120+
LocalDate today) {
103121
Person doctor = campaign.getPerson(patient.getDoctorId());
104122

105123
if (doctor != null) {
@@ -111,7 +129,7 @@ public void processMedicalEvents(Person patient) {
111129
patient.decrementDaysToWaitForHealing();
112130

113131
if (doctor != null && patient.getDaysToWaitForHealing() <= 0) {
114-
healPerson(patient, doctor);
132+
healPerson(patient, doctor, isUseAgingEffects, isClanCampaign, today);
115133
} else if (checkNaturalHealing(patient)) {
116134
// TODO change logging level from info to debug in 50.08
117135
logger.info(getFormattedTextAt(RESOURCE_BUNDLE, "MedicalController.report.natural",
@@ -133,7 +151,6 @@ public void processMedicalEvents(Person patient) {
133151
}
134152
}
135153

136-
137154
/**
138155
* Checks if the patient can heal naturally (without a doctor) and processes the healing if possible.
139156
*
@@ -149,29 +166,39 @@ public boolean checkNaturalHealing(Person patient) {
149166
return false;
150167
}
151168

169+
/**
170+
* Use {@link #healPerson(Person, Person, boolean, boolean, LocalDate)} instead
171+
*/
172+
@Deprecated(since = "0.50.07", forRemoval = true)
173+
private void healPerson(Person patient, Person doctor) {
174+
healPerson(patient, doctor, false, false, LocalDate.of(3151, 1, 1));
175+
}
152176

153177
/**
154-
* Heals the given patient with assistance from the specified doctor if they meet all necessary conditions.
178+
* Applies medical treatment to the specified patient, using the given doctor as the medical provider.
155179
*
156-
* <p>The method calculates modifiers using campaign rules, performs a skill check for the doctor, and updates
157-
* the patient's healing status based on the result.</p>
180+
* <p>This method performs a skill check for the doctor using current campaign rules and relevant situational
181+
* modifiers. If the skill check succeeds, the patient is healed and any associated unit state is reset. Regardless
182+
* of the outcome, the patient's healing waiting period is reset.</p>
158183
*
159-
* @param patient the {@link Person} receiving medical treatment
160-
* @param doctor the {@link Person} performing the treatment
184+
* @param patient the {@link Person} receiving treatment
185+
* @param doctor the {@link Person} performing the medical treatment
186+
* @param isUseAgingEffects {@code true} if aging effects should influence the healing process
187+
* @param isClanCampaign {@code true} if campaign-specific (clan) rules apply to healing
188+
* @param today the current date, used for time-dependent effects
161189
*/
162-
private void healPerson(Person patient, Person doctor) {
163-
// TODO change logging level from info to debug in 50.08
164-
logger.info(getFormattedTextAt(RESOURCE_BUNDLE, "MedicalController.report.intro",
190+
private void healPerson(Person patient, Person doctor, boolean isUseAgingEffects, boolean isClanCampaign,
191+
LocalDate today) {
192+
logger.debug(getFormattedTextAt(RESOURCE_BUNDLE, "MedicalController.report.intro",
165193
doctor.getHyperlinkedFullTitle(), patient.getHyperlinkedFullTitle()));
166194

167195
SkillCheckUtility skillCheckUtility = new SkillCheckUtility(doctor, S_SURGERY,
168196
getAdditionalHealingModifiers(patient),
169197
0,
170198
isUseSupportEdge,
171-
false);
199+
false, isUseAgingEffects, isClanCampaign, today);
172200

173-
// TODO change logging level from info to debug in 50.08
174-
logger.info(skillCheckUtility.getResultsText());
201+
logger.debug(skillCheckUtility.getResultsText());
175202

176203
if (skillCheckUtility.isSuccess()) {
177204
patient.heal();
@@ -184,7 +211,6 @@ private void healPerson(Person patient, Person doctor) {
184211
patient.setDaysToWaitForHealing(healingWaitingPeriod);
185212
}
186213

187-
188214
/**
189215
* Retrieves additional healing modifiers for the given patient. These modifiers are based on campaign-specific
190216
* rules, such as staff shortages.

MekHQ/src/mekhq/campaign/personnel/skills/SkillCheckUtility.java

Lines changed: 60 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import static mekhq.utilities.ReportingUtilities.CLOSING_SPAN_TAG;
4444
import static mekhq.utilities.ReportingUtilities.spanOpeningWithCustomColor;
4545

46+
import java.time.LocalDate;
4647
import java.util.List;
4748

4849
import megamek.common.TargetRoll;
@@ -92,6 +93,27 @@ public class SkillCheckUtility {
9293
private int roll;
9394
private boolean usedEdge;
9495

96+
/**
97+
* Use
98+
* {@link SkillCheckUtility#SkillCheckUtility(Person, String, List, int, boolean, boolean, boolean, boolean,
99+
* LocalDate)} instead
100+
*/
101+
@Deprecated(since = "0.50.07", forRemoval = true)
102+
public SkillCheckUtility(final Person person, final String skillName,
103+
@Nullable List<TargetRollModifier> externalModifiers, final int miscModifier, final boolean useEdge,
104+
final boolean includeMarginsOfSuccessText) {
105+
this.person = person;
106+
this.skillName = skillName;
107+
SkillCheckUtility proxy = new SkillCheckUtility(person, skillName, externalModifiers, miscModifier, useEdge,
108+
includeMarginsOfSuccessText,
109+
false, false, LocalDate.of(3151, 1, 1));
110+
marginOfSuccess = proxy.getMarginOfSuccess();
111+
resultsText = proxy.getResultsText();
112+
targetNumber = proxy.getTargetNumber();
113+
roll = proxy.getRoll();
114+
usedEdge = proxy.isUsedEdge();
115+
}
116+
95117
/**
96118
* Executes a skill check for the specified person and skill type.
97119
*
@@ -105,7 +127,8 @@ public class SkillCheckUtility {
105127
* include margins of success text as part of the results, if desired.</p>
106128
*
107129
* <p><b>Usage:</b> This constructor offers detailed control over the skill check process.
108-
* For simpler use-cases, the {@link #performQuickSkillCheck(Person, String, List, int)} method
130+
* For simpler use-cases, the
131+
* {@link #performQuickSkillCheck(Person, String, List, int, boolean, boolean, LocalDate)} method
109132
* provides a more streamlined approach.</p>
110133
*
111134
* @param person the {@link Person} performing the skill check
@@ -125,13 +148,17 @@ public class SkillCheckUtility {
125148
* attempt fails
126149
* @param includeMarginsOfSuccessText whether to include detailed margins of success information
127150
* in the results
151+
* @param isUseAgingEffects if {@code true}, considers aging effects during the check
152+
* @param isClanCampaign if {@code true}, applies rules specific to clan campaigns
153+
* @param today the current date, used for time-dependent logic
128154
*
129155
* @author Illiani
130156
* @since 0.50.05
131157
*/
132158
public SkillCheckUtility(final Person person, final String skillName,
133159
@Nullable List<TargetRollModifier> externalModifiers, final int miscModifier, final boolean useEdge,
134-
final boolean includeMarginsOfSuccessText) {
160+
final boolean includeMarginsOfSuccessText, boolean isUseAgingEffects, boolean isClanCampaign,
161+
LocalDate today) {
135162
this.person = person;
136163
this.skillName = skillName;
137164

@@ -141,7 +168,7 @@ public SkillCheckUtility(final Person person, final String skillName,
141168

142169
final SkillType skillType = SkillType.getType(skillName);
143170
isCountUp = skillType.isCountUp();
144-
targetNumber = determineTargetNumber(person, skillType, miscModifier);
171+
targetNumber = determineTargetNumber(person, skillType, miscModifier, isUseAgingEffects, isClanCampaign, today);
145172

146173
if (externalModifiers != null) {
147174
for (TargetRollModifier modifier : externalModifiers) {
@@ -152,6 +179,16 @@ public SkillCheckUtility(final Person person, final String skillName,
152179
performCheck(useEdge, includeMarginsOfSuccessText);
153180
}
154181

182+
/**
183+
* Use {@link #performQuickSkillCheck(Person, String, List, int, boolean, boolean, LocalDate)} instead
184+
*/
185+
@Deprecated(since = "0.50.07", forRemoval = true)
186+
public static boolean performQuickSkillCheck(final Person person, final String skillName,
187+
final @Nullable List<TargetRollModifier> externalModifiers, final int miscModifier) {
188+
return performQuickSkillCheck(person, skillName, externalModifiers, miscModifier, false, false,
189+
LocalDate.of(3151, 1, 1));
190+
}
191+
155192
/**
156193
* Performs a quick and simple skill check for a person based on the specified skill name.
157194
*
@@ -175,6 +212,9 @@ public SkillCheckUtility(final Person person, final String skillName,
175212
* <li>For non-'count up' skills, this value is added to the target number
176213
* (i.e., positive values are penalties).</li>
177214
* </ul>
215+
* @param isUseAgingEffects if {@code true}, considers aging effects during the check
216+
* @param isClanCampaign if {@code true}, applies rules specific to clan campaigns
217+
* @param today the current date, used for time-dependent logic
178218
*
179219
* @return {@code true} if the skill check succeeds, {@code false} otherwise
180220
*
@@ -184,9 +224,10 @@ public SkillCheckUtility(final Person person, final String skillName,
184224
* @since 0.50.05
185225
*/
186226
public static boolean performQuickSkillCheck(final Person person, final String skillName,
187-
final @Nullable List<TargetRollModifier> externalModifiers, final int miscModifier) {
227+
final @Nullable List<TargetRollModifier> externalModifiers, final int miscModifier,
228+
boolean isUseAgingEffects, boolean isClanCampaign, LocalDate today) {
188229
SkillCheckUtility skillCheck = new SkillCheckUtility(person, skillName, externalModifiers, miscModifier,
189-
false, false);
230+
false, false, isUseAgingEffects, isClanCampaign, today);
190231
return skillCheck.isSuccess();
191232
}
192233

@@ -398,6 +439,14 @@ public boolean isUsedEdge() {
398439
return usedEdge;
399440
}
400441

442+
/**
443+
* Use {@link #determineTargetNumber(Person, SkillType, int, boolean, boolean, LocalDate)} instead
444+
*/
445+
@Deprecated(since = "0.50.07", forRemoval = true)
446+
public static TargetRoll determineTargetNumber(Person person, SkillType skillType, int miscModifier) {
447+
return determineTargetNumber(person, skillType, miscModifier, false, false, LocalDate.of(3151, 1, 1));
448+
}
449+
401450
/**
402451
* Determines the target number for a skill check based on the person's attributes, skill type, and whether they are
403452
* trained in the skill.
@@ -412,11 +461,15 @@ public boolean isUsedEdge() {
412461
* target number. This means negative values are bonuses, positive values are penalties.
413462
*
414463
* @return the target number for the skill check
464+
* @param isUseAgingEffects if {@code true}, considers aging effects during the check
465+
* @param isClanCampaign if {@code true}, applies rules specific to clan campaigns
466+
* @param today the current date, used for time-dependent logic
415467
*
416468
* @author Illiani
417469
* @since 0.50.05
418470
*/
419-
public static TargetRoll determineTargetNumber(Person person, SkillType skillType, int miscModifier) {
471+
public static TargetRoll determineTargetNumber(Person person, SkillType skillType, int miscModifier,
472+
boolean isUseAgingEffects, boolean isClanCampaign, LocalDate today) {
420473
final String skillName = skillType.getName();
421474
final Attributes characterAttributes = person.getATOWAttributes();
422475

@@ -441,7 +494,7 @@ public static TargetRoll determineTargetNumber(Person person, SkillType skillTyp
441494
Skill skill = person.getSkill(skillName);
442495
int skillValue = skill.getFinalSkillValue(person.getOptions(),
443496
person.getATOWAttributes(),
444-
person.getReputation());
497+
person.getAdjustedReputation(isUseAgingEffects, isClanCampaign, today, person.getRankNumeric()));
445498
targetNumber.addModifier(skillValue, skillName);
446499
}
447500

MekHQ/src/mekhq/campaign/stratcon/StratconRulesManager.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1666,7 +1666,8 @@ public static ReinforcementResultsType processReinforcementDeployment(Force forc
16661666
int targetNumber = 9;
16671667
Skill tactics = commander.getSkill(S_TACTICS);
16681668

1669-
SkillCheckUtility skillCheckUtility = new SkillCheckUtility(commander, S_TACTICS, null, 0, true, false);
1669+
SkillCheckUtility skillCheckUtility = new SkillCheckUtility(commander, S_TACTICS, null, 0, true, false,
1670+
campaign.getCampaignOptions().isUseAgeEffects(), campaign.isClanCampaign(), campaign.getLocalDate());
16701671
campaign.addReport(skillCheckUtility.getResultsText());
16711672

16721673
if (skillCheckUtility.isSuccess()) {

0 commit comments

Comments
 (0)