Skip to content

Commit 2a315f6

Browse files
authored
Merge pull request #7194 from IllianiBird/bugTechAssignments
Fix: #7142 Cleaned Up Profession Assignments to Prevent Invalid Assignments
2 parents 6038bf1 + 4f79ef9 commit 2a315f6

File tree

1 file changed

+76
-44
lines changed

1 file changed

+76
-44
lines changed

MekHQ/src/mekhq/campaign/personnel/Person.java

Lines changed: 76 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -906,29 +906,26 @@ public PersonnelRole getPrimaryRole() {
906906
return primaryRole;
907907
}
908908

909+
/**
910+
* Sets the primary role for this person within the specified {@link Campaign}.
911+
*
912+
* <p>If the new primary role is different from the current one, this method performs any necessary updates, such
913+
* as adjusting recruitment-related dates for non-civilian roles, updating the primary role, and triggering a
914+
* {@link PersonChangedEvent}.</p>
915+
*
916+
* <p><b>Usage:</b> if there is any uncertainty as to whether the character is eligible for the role they are
917+
* being assigned, make sure to call {@link #canPerformRole(LocalDate, PersonnelRole, boolean)} prior to this
918+
* method.</p>
919+
*
920+
* @param campaign the {@link Campaign} context, used for date retrieval and event tracking
921+
* @param primaryRole the new {@link PersonnelRole} to be set as primary for this person
922+
*/
909923
public void setPrimaryRole(final Campaign campaign, final PersonnelRole primaryRole) {
910924
// don't need to do any processing for no changes
911925
if (primaryRole == getPrimaryRole()) {
912926
return;
913927
}
914928

915-
// We need to make some secondary role assignments to None here for better UX in
916-
// assigning roles, following these rules:
917-
// 1) Cannot have the same primary and secondary roles
918-
// 2) Must have a None secondary role if you are a Dependent
919-
// 3) Cannot be a primary tech and a secondary Astech
920-
// 4) Cannot be a primary Astech and a secondary tech
921-
// 5) Cannot be primary medical staff and a secondary Medic
922-
// 6) Cannot be a primary Medic and secondary medical staff
923-
if ((primaryRole == getSecondaryRole()) ||
924-
primaryRole.isDependent() ||
925-
(primaryRole.isTech() && getSecondaryRole().isAstech()) ||
926-
(primaryRole.isAstech() && getSecondaryRole().isTechSecondary()) ||
927-
(primaryRole.isMedicalStaff() && getSecondaryRole().isMedic()) ||
928-
(primaryRole.isMedic() && getSecondaryRole().isMedicalStaff())) {
929-
setSecondaryRoleDirect(PersonnelRole.NONE);
930-
}
931-
932929
// Now, we can perform the time in service and last rank change tracking change for dependents
933930
if (!primaryRole.isCivilian() && recruitment != null) {
934931
setRecruitment(campaign.getLocalDate());
@@ -1063,24 +1060,55 @@ public String getSecondaryRoleDesc() {
10631060
return getSecondaryRole().getLabel(isClanPersonnel());
10641061
}
10651062

1063+
/**
1064+
* Determines if this person can perform the specified {@link PersonnelRole} as either a primary or secondary role
1065+
* on the given date.
1066+
*
1067+
* <p>For primary roles, certain constraints are enforced, such as uniqueness compared to the secondary role and
1068+
* limitations based on the type of role (e.g., tech, medical, administrator).</p>
1069+
*
1070+
* <p>For secondary roles, different restrictions apply, including the ability to always select "None" and
1071+
* disallowing dependent roles.</p>
1072+
*
1073+
* <p>Additionally, the person's age and required skill sets are considered to ensure eligibility for the chosen
1074+
* role.</p>
1075+
*
1076+
* @param today the {@link LocalDate} representing the current date, used for age-based checks
1077+
* @param role the {@link PersonnelRole} being considered for assignment
1078+
* @param primary {@code true} to check eligibility as a primary role, {@code false} for secondary
1079+
*
1080+
* @return {@code true} if the person is eligible to perform the given role as specified; {@code false} otherwise
1081+
*/
10661082
public boolean canPerformRole(LocalDate today, final PersonnelRole role, final boolean primary) {
10671083
if (primary) {
10681084
// Primary Role:
10691085
// 1) Can always be Dependent
10701086
// 2) Cannot be None
10711087
// 3) Cannot be equal to the secondary role
10721088
// 4) Cannot be a tech role if the secondary role is a tech role (inc. Astech)
1073-
// 5) Cannot be Medic if the secondary role is one of the medical staff roles
1074-
// 6) Cannot be Admin if the secondary role is one of the administrator roles
1089+
// 5) Cannot be a medical if the secondary role is one of the medical staff roles
1090+
// 6) Cannot be an admin role if the secondary role is one of the administrator roles
10751091
if (role.isDependent()) {
10761092
return true;
1077-
} else if (role.isNone()) {
1093+
}
1094+
1095+
if (role.isNone()) {
10781096
return false;
1079-
} else if ((role == getSecondaryRole()) ||
1080-
((role.isTech() || role.isAstech()) &&
1081-
(getSecondaryRole().isTech() || getSecondaryRole().isAstech())) ||
1082-
(role.isMedicalStaff() && getSecondaryRole().isMedicalStaff()) ||
1083-
(role.isAdministrator() && getSecondaryRole().isAdministrator())) {
1097+
}
1098+
1099+
if (role == secondaryRole) {
1100+
return false;
1101+
}
1102+
1103+
if (role.isTech() && (secondaryRole.isTech() || secondaryRole.isAstech())) {
1104+
return false;
1105+
}
1106+
1107+
if (role.isMedicalStaff() && secondaryRole.isMedicalStaff()) {
1108+
return false;
1109+
}
1110+
1111+
if (role.isAdministrator() && secondaryRole.isAdministrator()) {
10841112
return false;
10851113
}
10861114
} else {
@@ -1089,17 +1117,29 @@ public boolean canPerformRole(LocalDate today, final PersonnelRole role, final b
10891117
// 2) Cannot be Dependent
10901118
// 3) Cannot be equal to the primary role
10911119
// 4) Cannot be a tech role if the primary role is a tech role (inc. Astech)
1092-
// 5) Cannot be Medic if the primary role is one of the medical staff roles
1093-
// 6) Cannot be Admin if the primary role is one of the administrator roles
1120+
// 5) Cannot be a medical role if the primary role is one of the medical staff roles
1121+
// 6) Cannot be an admin role if the primary role is one of the administrator roles
10941122
if (role.isNone()) {
10951123
return true;
1096-
} else if ((role.isDependent()) ||
1097-
(getPrimaryRole().isDependent()) ||
1098-
(getPrimaryRole() == role) ||
1099-
((role.isTech() || role.isAstech()) &&
1100-
(getPrimaryRole().isTech() || getPrimaryRole().isAstech())) ||
1101-
(role.isMedicalStaff() && getPrimaryRole().isMedicalStaff()) ||
1102-
(role.isAdministrator() && getPrimaryRole().isAdministrator())) {
1124+
}
1125+
1126+
if (role.isDependent()) {
1127+
return false;
1128+
}
1129+
1130+
if (role == primaryRole) {
1131+
return false;
1132+
}
1133+
1134+
if (role.isTech() && (primaryRole.isTech() || primaryRole.isAstech())) {
1135+
return false;
1136+
}
1137+
1138+
if (role.isMedicalStaff() && primaryRole.isMedicalStaff()) {
1139+
return false;
1140+
}
1141+
1142+
if (role.isAdministrator() && primaryRole.isAdministrator()) {
11031143
return false;
11041144
}
11051145
}
@@ -1108,6 +1148,7 @@ public boolean canPerformRole(LocalDate today, final PersonnelRole role, final b
11081148
return false;
11091149
}
11101150

1151+
List<String> skillsForProfession = role.getSkillsForProfession();
11111152
return switch (role) {
11121153
case VEHICLE_CREW -> Stream.of(SkillType.S_TECH_MEK,
11131154
SkillType.S_TECH_AERO,
@@ -1119,21 +1160,12 @@ public boolean canPerformRole(LocalDate today, final PersonnelRole role, final b
11191160
SkillType.S_COMMUNICATIONS,
11201161
SkillType.S_SENSOR_OPERATIONS,
11211162
SkillType.S_ART_COOKING).anyMatch(this::hasSkill);
1122-
case AEROSPACE_PILOT -> hasSkill(SkillType.S_GUN_AERO) && hasSkill(SkillType.S_PILOT_AERO);
1123-
case CONVENTIONAL_AIRCRAFT_PILOT -> hasSkill(SkillType.S_GUN_JET) && hasSkill(SkillType.S_PILOT_JET);
1124-
case PROTOMEK_PILOT -> hasSkill(SkillType.S_GUN_PROTO);
11251163
case BATTLE_ARMOUR -> hasSkill(SkillType.S_GUN_BA);
1126-
case SOLDIER -> hasSkill(SkillType.S_SMALL_ARMS);
1127-
case VESSEL_PILOT -> hasSkill(SkillType.S_PILOT_SPACE);
11281164
case VESSEL_CREW -> hasSkill(SkillType.S_TECH_VESSEL);
1129-
case VESSEL_GUNNER -> hasSkill(SkillType.S_GUN_SPACE);
1130-
case VESSEL_NAVIGATOR -> hasSkill(SkillType.S_NAVIGATION);
11311165
case MEK_TECH -> hasSkill(SkillType.S_TECH_MEK);
11321166
case AERO_TEK -> hasSkill(SkillType.S_TECH_AERO);
11331167
case BA_TECH -> hasSkill(SkillType.S_TECH_BA);
1134-
case ASTECH -> hasSkill(SkillType.S_ASTECH);
11351168
case DOCTOR -> hasSkill(SkillType.S_SURGERY);
1136-
case MEDIC -> hasSkill(SkillType.S_MEDTECH);
11371169
case ADMINISTRATOR_COMMAND, ADMINISTRATOR_LOGISTICS, ADMINISTRATOR_TRANSPORT, ADMINISTRATOR_HR ->
11381170
hasSkill(SkillType.S_ADMIN);
11391171
case ADULT_ENTERTAINER -> {
@@ -1153,7 +1185,7 @@ public boolean canPerformRole(LocalDate today, final PersonnelRole role, final b
11531185
}
11541186
}
11551187
default -> {
1156-
for (String skillName : role.getSkillsForProfession()) {
1188+
for (String skillName : skillsForProfession) {
11571189
if (!hasSkill(skillName)) {
11581190
yield false;
11591191
}

0 commit comments

Comments
 (0)