diff --git a/MekHQ/resources/mekhq/resources/Campaign.properties b/MekHQ/resources/mekhq/resources/Campaign.properties
index e48ef36fce..fc11a9cd6d 100644
--- a/MekHQ/resources/mekhq/resources/Campaign.properties
+++ b/MekHQ/resources/mekhq/resources/Campaign.properties
@@ -39,7 +39,8 @@ LayeredForceIconLayer.LOGO.text=Logos
LayeredForceIconLayer.LOGO.toolTipText=This tab contains canon faction logos that can be added to the center of a force icon.
#### Anniversaries
-anniversaryBirthday.text=%s is %s today!
+anniversaryBirthday.text=%s is %s%s%s today!
+anniversaryRecruitment.text=%s celebrates %s%s%s years with %s!
#### Personnel Removal
personnelRemoval.text=Old personnel records have been tidied away.
diff --git a/MekHQ/resources/mekhq/resources/CampaignOptionsDialog.properties b/MekHQ/resources/mekhq/resources/CampaignOptionsDialog.properties
index 953d2055bd..98b73033b1 100644
--- a/MekHQ/resources/mekhq/resources/CampaignOptionsDialog.properties
+++ b/MekHQ/resources/mekhq/resources/CampaignOptionsDialog.properties
@@ -364,8 +364,10 @@ chkUseRemovalExemptRetirees.toolTipText=Data from retired personnel is exempt fr
anniversaryPanel.title=Anniversaries
chkAnnounceBirthdays.text=Announce Birthdays
chkAnnounceBirthdays.toolTipText=A daily report notification will occur whenever someone celebrates their birthday.
+chkAnnounceRecruitmentAnniversaries.text=Announce Recruitment Anniversaries
+chkAnnounceRecruitmentAnniversaries.toolTipText=A daily report notification will occur whenever someone celebrates a recruitment anniversary.
chkAnnounceOfficersOnly.text=Officers Only
-chkAnnounceOfficersOnly.toolTipText=Only report officer birthdays.
+chkAnnounceOfficersOnly.toolTipText=Only report officer anniversaries.
chkAnnounceChildBirthdays.text=Coming of Age Override
chkAnnounceChildBirthdays.toolTipText=If enabled, 18th birthdays will always be announced. Enabling this option will override any other settings.
diff --git a/MekHQ/src/mekhq/campaign/Campaign.java b/MekHQ/src/mekhq/campaign/Campaign.java
index a72aea8008..ff1a843a06 100644
--- a/MekHQ/src/mekhq/campaign/Campaign.java
+++ b/MekHQ/src/mekhq/campaign/Campaign.java
@@ -59,7 +59,9 @@
import mekhq.campaign.log.HistoricalLogEntry;
import mekhq.campaign.log.LogEntry;
import mekhq.campaign.log.ServiceLogger;
-import mekhq.campaign.market.*;
+import mekhq.campaign.market.PartsStore;
+import mekhq.campaign.market.PersonnelMarket;
+import mekhq.campaign.market.ShoppingList;
import mekhq.campaign.market.contractMarket.AbstractContractMarket;
import mekhq.campaign.market.contractMarket.AtbMonthlyContractMarket;
import mekhq.campaign.market.unitMarket.AbstractUnitMarket;
@@ -125,6 +127,7 @@
import mekhq.service.IAutosaveService;
import mekhq.service.mrms.MRMSService;
import mekhq.utilities.MHQXMLUtility;
+import mekhq.utilities.ReportingUtilities;
import javax.swing.*;
import java.io.PrintWriter;
@@ -141,6 +144,7 @@
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 static mekhq.utilities.ReportingUtilities.CLOSING_SPAN_TAG;
/**
* The main campaign class, keeps track of teams and units
@@ -1663,7 +1667,7 @@ public boolean recruitPerson(Person p, PrisonerStatus prisonerStatus, boolean gm
private void simulateRelationshipHistory(Person person) {
// how many weeks should the simulation run?
LocalDate localDate = getLocalDate();
- long weeksBetween = ChronoUnit.WEEKS.between(person.getBirthday().plusYears(18), localDate);
+ long weeksBetween = ChronoUnit.WEEKS.between(person.getDateOfBirth().plusYears(18), localDate);
// this means there is nothing to simulate
if (weeksBetween == 0) {
@@ -3787,6 +3791,34 @@ && getCampaignOptions().getRandomDependentMethod().isAgainstTheBot()
processNewDayATBScenarios();
}
+ /**
+ * Processes the new day for all active personnel.
+ *
+ * This method loops through all active personnel and performs the necessary actions
+ * for each person for a new day.
+ *
+ * The following tasks are performed for each person:
+ *
+ * - Death - If the person has died, skip processing further for the dead person.
+ * - Marriage - Process any marriage-related actions.
+ * - Reset minutes left for the person.
+ * - Reset acquisitions made to 0.
+ * - Healing - If the person needs healing and advanced medical is not used,
+ * decrement the days to wait for healing and heal naturally or with a doctor.
+ * - Advanced Medical - If advanced medical is used, resolve the daily healing for the person.
+ * - Reset current edge points for support personnel on Mondays.
+ * - Idle XP - If idle XP is enabled and it's the first day of the month,
+ * check if the person qualifies for idle XP and award them if they do.
+ * - Divorce - Process any divorce-related actions.
+ * - Procreation - Process any procreation-related actions.
+ * - Anniversaries - Check if it's the person's birthday or 18th birthday
+ * and announce it if needed.
+ * - Auto Awards - If it's the first day of the month, calculate the auto award
+ * support points based on the person's roles and experience level.
+ *
+ *
+ * Note: This method uses several other methods to perform the specific actions for each task.
+ */
public void processNewDayPersonnel() {
// This MUST use getActivePersonnel as we only want to process active personnel, and
// furthermore, this allows us to add and remove personnel without issue
@@ -3865,9 +3897,9 @@ public void processNewDayPersonnel() {
if ((person.getStatus().isOnMaternityLeave()) && (!children.isEmpty())) {
- children.sort(Comparator.comparing(Person::getBirthday).reversed());
+ children.sort(Comparator.comparing(Person::getDateOfBirth).reversed());
- if (getLocalDate().isAfter(children.get(0).getBirthday().plusDays(41))) {
+ if (getLocalDate().isAfter(children.get(0).getDateOfBirth().plusDays(41))) {
person.changeStatus(this, getLocalDate(), PersonnelStatus.ACTIVE);
}
}
@@ -3877,16 +3909,35 @@ public void processNewDayPersonnel() {
// Anniversaries
if ((person.getRank().isOfficer()) || (!getCampaignOptions().isAnnounceOfficersOnly())) {
- if ((person.getBirthday().isEqual(getLocalDate())) && (campaignOptions.isAnnounceBirthdays())) {
+ if ((person.getBirthday(getGameYear()).isEqual(getLocalDate()))
+ && (campaignOptions.isAnnounceBirthdays())) {
addReport(String.format(resources.getString("anniversaryBirthday.text"),
+ person.getHyperlinkedFullTitle(),
+ ReportingUtilities.spanOpeningWithCustomColor(MekHQ.getMHQOptions().getFontColorPositiveHexColor()),
+ person.getAge(getLocalDate()),
+ CLOSING_SPAN_TAG));
+ }
+
+ LocalDate recruitmentDate = person.getRecruitment();
+ if (recruitmentDate != null) {
+ LocalDate recruitmentAnniversary = recruitmentDate.withYear(getGameYear());
+ int yearsOfEmployment = (int) ChronoUnit.YEARS.between(recruitmentDate, currentDay);
+
+ if ((recruitmentAnniversary.isEqual(getLocalDate()))
+ && (campaignOptions.isAnnounceRecruitmentAnniversaries())) {
+ addReport(String.format(resources.getString("anniversaryRecruitment.text"),
person.getHyperlinkedFullTitle(),
- person.getAge(getLocalDate())));
+ ReportingUtilities.spanOpeningWithCustomColor(MekHQ.getMHQOptions().getFontColorPositiveHexColor()),
+ yearsOfEmployment, CLOSING_SPAN_TAG, name));
+ }
}
- } else if ((person.getAge(getLocalDate()) == 18) && (campaignOptions.isAnnounceChildBirthdays()) ){
- if (person.getBirthday().isEqual(getLocalDate())) {
+ } else if ((person.getAge(getLocalDate()) == 18) && (campaignOptions.isAnnounceChildBirthdays())) {
+ if (person.getBirthday(getGameYear()).isEqual(getLocalDate())) {
addReport(String.format(resources.getString("anniversaryBirthday.text"),
- person.getHyperlinkedFullTitle(),
- 18));
+ person.getHyperlinkedFullTitle(),
+ ReportingUtilities.spanOpeningWithCustomColor(MekHQ.getMHQOptions().getFontColorPositiveHexColor()),
+ person.getAge(getLocalDate()),
+ CLOSING_SPAN_TAG));
}
}
diff --git a/MekHQ/src/mekhq/campaign/CampaignOptions.java b/MekHQ/src/mekhq/campaign/CampaignOptions.java
index ba53e682e9..18439cff29 100644
--- a/MekHQ/src/mekhq/campaign/CampaignOptions.java
+++ b/MekHQ/src/mekhq/campaign/CampaignOptions.java
@@ -291,6 +291,7 @@ public static String getTransitUnitName(final int unit) {
// Anniversaries
private boolean announceBirthdays;
+ private boolean announceRecruitmentAnniversaries;
private boolean announceOfficersOnly;
private boolean announceChildBirthdays;
@@ -858,6 +859,7 @@ public CampaignOptions() {
// Anniversaries
setAnnounceBirthdays(true);
+ setAnnounceRecruitmentAnniversaries(true);
setAnnounceOfficersOnly(true);
setAnnounceChildBirthdays(true);
@@ -2221,6 +2223,25 @@ public void setAnnounceBirthdays(final boolean announceBirthdays) {
this.announceBirthdays = announceBirthdays;
}
+ /**
+ * Checks if recruitment anniversaries should be announced.
+ *
+ * @return {@code true} if recruitment anniversaries should be announced, {@code false} otherwise.
+ */
+ public boolean isAnnounceRecruitmentAnniversaries() {
+ return announceRecruitmentAnniversaries;
+ }
+
+ /**
+ * Set whether to announce recruitment anniversaries.
+ *
+ * @param announceRecruitmentAnniversaries {@code true} to announce recruitment anniversaries,
+ * {@code false} otherwise
+ */
+ public void setAnnounceRecruitmentAnniversaries(final boolean announceRecruitmentAnniversaries) {
+ this.announceRecruitmentAnniversaries = announceRecruitmentAnniversaries;
+ }
+
public boolean isAnnounceOfficersOnly() {
return announceOfficersOnly;
}
@@ -4923,6 +4944,7 @@ public void writeToXml(final PrintWriter pw, int indent) {
// region Announcements
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "announceBirthdays", isAnnounceBirthdays());
+ MHQXMLUtility.writeSimpleXMLTag(pw, indent, "announceRecruitmentAnniversaries", isAnnounceRecruitmentAnniversaries());
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "announceOfficersOnly", isAnnounceOfficersOnly());
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "announceChildBirthdays", isAnnounceChildBirthdays());
// endregion Announcements
@@ -5631,6 +5653,8 @@ public static CampaignOptions generateCampaignOptionsFromXml(Node wn, Version ve
// region anniversaries
} else if (wn2.getNodeName().equalsIgnoreCase("announceBirthdays")) {
retVal.setAnnounceBirthdays(Boolean.parseBoolean(wn2.getTextContent().trim()));
+ } else if (wn2.getNodeName().equalsIgnoreCase("announceRecruitmentAnniversaries")) {
+ retVal.setAnnounceRecruitmentAnniversaries(Boolean.parseBoolean(wn2.getTextContent().trim()));
} else if (wn2.getNodeName().equalsIgnoreCase("announceOfficersOnly")) {
retVal.setAnnounceOfficersOnly(Boolean.parseBoolean(wn2.getTextContent().trim()));
} else if (wn2.getNodeName().equalsIgnoreCase("announceChildBirthdays")) {
diff --git a/MekHQ/src/mekhq/campaign/MercRosterAccess.java b/MekHQ/src/mekhq/campaign/MercRosterAccess.java
index ed403a0837..0f87ba64ab 100644
--- a/MekHQ/src/mekhq/campaign/MercRosterAccess.java
+++ b/MekHQ/src/mekhq/campaign/MercRosterAccess.java
@@ -18,21 +18,6 @@
*/
package mekhq.campaign;
-import java.sql.Connection;
-import java.sql.Date;
-import java.sql.DriverManager;
-import java.sql.PreparedStatement;
-import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
-import java.sql.SQLException;
-import java.sql.Statement;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Properties;
-import java.util.UUID;
-
-import javax.swing.SwingWorker;
-
import megamek.common.UnitType;
import megamek.logging.MMLogger;
import mekhq.campaign.force.Force;
@@ -44,6 +29,13 @@
import mekhq.campaign.personnel.ranks.Rank;
import mekhq.campaign.unit.Unit;
+import javax.swing.*;
+import java.sql.*;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Properties;
+import java.util.UUID;
+
public class MercRosterAccess extends SwingWorker {
private static final MMLogger logger = MMLogger.create(MercRosterAccess.class);
@@ -91,7 +83,7 @@ public void connect() throws SQLException {
conProperties.put("password", passwd);
try {
Class.forName("com.mysql.jdbc.Driver");
- connect = DriverManager.getConnection("jdbc:mysql://" + hostname + ":" + port + "/" + table, conProperties);
+ connect = DriverManager.getConnection("jdbc:mysql://" + hostname + ':' + port + '/' + table, conProperties);
} catch (SQLException e) {
throw e;
} catch (ClassNotFoundException e) {
@@ -562,10 +554,10 @@ private void writePersonnelData() {
preparedStatement.setInt(6, forceId);
preparedStatement.setInt(7, 1);
// TODO: get joining date right
- preparedStatement.setDate(8, Date.valueOf(p.getBirthday()));
+ preparedStatement.setDate(8, Date.valueOf(p.getDateOfBirth()));
// TODO: combine personnel log with biography
preparedStatement.setString(9, p.getBiography());
- preparedStatement.setDate(10, Date.valueOf(p.getBirthday()));
+ preparedStatement.setDate(10, Date.valueOf(p.getDateOfBirth()));
preparedStatement.setString(11, p.getId().toString());
if (preparedStatement.executeUpdate() < 1) {
// no prior record so insert
@@ -578,9 +570,9 @@ private void writePersonnelData() {
preparedStatement.setString(5, p.getStatus().toString());
preparedStatement.setInt(6, forceId);
preparedStatement.setInt(7, 1);
- preparedStatement.setDate(8, Date.valueOf(p.getBirthday()));
+ preparedStatement.setDate(8, Date.valueOf(p.getDateOfBirth()));
preparedStatement.setString(9, p.getBiography());
- preparedStatement.setDate(10, Date.valueOf(p.getBirthday()));
+ preparedStatement.setDate(10, Date.valueOf(p.getDateOfBirth()));
preparedStatement.setString(11, p.getId().toString());
preparedStatement.executeUpdate();
}
diff --git a/MekHQ/src/mekhq/campaign/personnel/Person.java b/MekHQ/src/mekhq/campaign/personnel/Person.java
index 22e53a1ec3..acf05c9aa1 100644
--- a/MekHQ/src/mekhq/campaign/personnel/Person.java
+++ b/MekHQ/src/mekhq/campaign/personnel/Person.java
@@ -329,7 +329,7 @@ public Person(final String preNominal, final String givenName, final String surn
secondaryRole = PersonnelRole.NONE;
primaryDesignator = ROMDesignation.NONE;
secondaryDesignator = ROMDesignation.NONE;
- setBirthday(LocalDate.now());
+ setDateOfBirth(LocalDate.now());
originFaction = Factions.getInstance().getFaction(factionCode);
originPlanet = null;
@@ -1337,7 +1337,12 @@ public Gender getGender() {
return gender;
}
- public void setBirthday(final LocalDate birthday) {
+ /**
+ * Sets the date of birth (the date they are born) for the person.
+ *
+ * @param birthday the person's new date of birth
+ */
+ public void setDateOfBirth(final LocalDate birthday) {
this.birthday = birthday;
}
@@ -1346,10 +1351,20 @@ public void setBirthday(final LocalDate birthday) {
*
* @return a LocalDate representing the person's date of birth
*/
- public LocalDate getBirthday() {
+ public LocalDate getDateOfBirth() {
return birthday;
}
+ /**
+ * Retrieves the birthday for a person, with the year set to the same as the provided year.
+ *
+ * @param currentYear the current in-game year
+ * @return the birthday with the year updated to match the provided year
+ */
+ public LocalDate getBirthday(int currentYear) {
+ return birthday.withYear(currentYear);
+ }
+
public @Nullable LocalDate getDateOfDeath() {
return dateOfDeath;
}
@@ -1365,7 +1380,7 @@ public int getAge(LocalDate today) {
today = getDateOfDeath();
}
- return Math.toIntExact(ChronoUnit.YEARS.between(getBirthday(), today));
+ return Math.toIntExact(ChronoUnit.YEARS.between(getDateOfBirth(), today));
}
public @Nullable LocalDate getJoinedCampaign() {
@@ -2048,7 +2063,7 @@ public void writeToXML(final PrintWriter pw, int indent, final Campaign campaign
if (overtimeLeft > 0) {
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "overtimeLeft", overtimeLeft);
}
- MHQXMLUtility.writeSimpleXMLTag(pw, indent, "birthday", getBirthday());
+ MHQXMLUtility.writeSimpleXMLTag(pw, indent, "birthday", getDateOfBirth());
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "deathday", getDateOfDeath());
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "recruitment", getRecruitment());
MHQXMLUtility.writeSimpleXMLTag(pw, indent, "joinedCampaign", getJoinedCampaign());
diff --git a/MekHQ/src/mekhq/campaign/personnel/generator/AbstractPersonnelGenerator.java b/MekHQ/src/mekhq/campaign/personnel/generator/AbstractPersonnelGenerator.java
index 4312bebd85..7ee60f39dc 100644
--- a/MekHQ/src/mekhq/campaign/personnel/generator/AbstractPersonnelGenerator.java
+++ b/MekHQ/src/mekhq/campaign/personnel/generator/AbstractPersonnelGenerator.java
@@ -221,6 +221,6 @@ protected void generateBirthday(Campaign campaign, Person person, int expLvl, bo
int nDays = birthday.isLeapYear() ? 366 : 365;
int randomDay = Compute.randomInt(nDays) + 1;
- person.setBirthday(birthday.withDayOfYear(randomDay));
+ person.setDateOfBirth(birthday.withDayOfYear(randomDay));
}
}
diff --git a/MekHQ/src/mekhq/campaign/personnel/marriage/AbstractMarriage.java b/MekHQ/src/mekhq/campaign/personnel/marriage/AbstractMarriage.java
index 536434303c..3f5ef99913 100644
--- a/MekHQ/src/mekhq/campaign/personnel/marriage/AbstractMarriage.java
+++ b/MekHQ/src/mekhq/campaign/personnel/marriage/AbstractMarriage.java
@@ -389,11 +389,11 @@ Person createExternalSpouse(final Campaign campaign, final LocalDate today, fina
if (externalSpouseAge < externalSpouseMinAge) {
int difference = externalSpouseMinAge - externalSpouseAge;
- externalSpouse.setBirthday(externalSpouse.getBirthday().minusYears(difference));
+ externalSpouse.setDateOfBirth(externalSpouse.getDateOfBirth().minusYears(difference));
} else if (externalSpouseAge > externalSpouseMaxAge) {
int difference = externalSpouseMaxAge - externalSpouseAge;
- externalSpouse.setBirthday(externalSpouse.getBirthday().plusYears(difference));
+ externalSpouse.setDateOfBirth(externalSpouse.getDateOfBirth().plusYears(difference));
}
return externalSpouse;
diff --git a/MekHQ/src/mekhq/campaign/personnel/procreation/AbstractProcreation.java b/MekHQ/src/mekhq/campaign/personnel/procreation/AbstractProcreation.java
index 7bcf080005..7d2794d92e 100644
--- a/MekHQ/src/mekhq/campaign/personnel/procreation/AbstractProcreation.java
+++ b/MekHQ/src/mekhq/campaign/personnel/procreation/AbstractProcreation.java
@@ -340,7 +340,7 @@ public void birth(final Campaign campaign, final LocalDate today, final Person m
final Person baby = campaign.newDependent(true, Gender.RANDOMIZE);
baby.setSurname(campaign.getCampaignOptions().getBabySurnameStyle()
.generateBabySurname(mother, father, baby.getGender()));
- baby.setBirthday(today);
+ baby.setDateOfBirth(today);
// Create reports and log the birth
campaign.addReport(String.format(resources.getString("babyBorn.report"),
@@ -441,7 +441,7 @@ public List birthHistoric(final Campaign campaign, final LocalDate today
baby.setSurname(campaign.getCampaignOptions().getBabySurnameStyle()
.generateBabySurname(mother, father, baby.getGender()));
- baby.setBirthday(today);// Limit skills by age for children and adolescents
+ baby.setDateOfBirth(today);// Limit skills by age for children and adolescents
baby.removeAllSkills();
diff --git a/MekHQ/src/mekhq/campaign/storyarc/storypoint/CreateCharacterStoryPoint.java b/MekHQ/src/mekhq/campaign/storyarc/storypoint/CreateCharacterStoryPoint.java
index bf98e5bcc3..599bfe6201 100644
--- a/MekHQ/src/mekhq/campaign/storyarc/storypoint/CreateCharacterStoryPoint.java
+++ b/MekHQ/src/mekhq/campaign/storyarc/storypoint/CreateCharacterStoryPoint.java
@@ -20,14 +20,6 @@
*/
package mekhq.campaign.storyarc.storypoint;
-import java.io.PrintWriter;
-import java.text.ParseException;
-import java.util.Enumeration;
-import java.util.UUID;
-
-import org.w3c.dom.Node;
-import org.w3c.dom.NodeList;
-
import megamek.Version;
import megamek.common.options.IOption;
import megamek.common.options.IOptionGroup;
@@ -54,6 +46,13 @@
import mekhq.gui.dialog.CreateCharacterDialog;
import mekhq.gui.dialog.CreateCharacterDialog.NameRestrictions;
import mekhq.utilities.MHQXMLUtility;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+
+import java.io.PrintWriter;
+import java.text.ParseException;
+import java.util.Enumeration;
+import java.util.UUID;
/**
* This StoryPoint opens a {@link CreateCharacterDialog CreateCharacterDialog}
@@ -180,7 +179,7 @@ public Person createPerson() {
AbstractSkillGenerator skillGenerator = new DefaultSkillGenerator(skillPrefs);
skillGenerator.generateSkills(getCampaign(), p, SkillType.EXP_ULTRA_GREEN);
- p.setBirthday(getCampaign().getLocalDate().minusYears(age));
+ p.setDateOfBirth(getCampaign().getLocalDate().minusYears(age));
// set education
EducationController.setInitialEducation(campaign, p);
diff --git a/MekHQ/src/mekhq/gui/dialog/CreateCharacterDialog.java b/MekHQ/src/mekhq/gui/dialog/CreateCharacterDialog.java
index 44a9af261b..b966ec467e 100644
--- a/MekHQ/src/mekhq/gui/dialog/CreateCharacterDialog.java
+++ b/MekHQ/src/mekhq/gui/dialog/CreateCharacterDialog.java
@@ -157,7 +157,7 @@ public CreateCharacterDialog(JFrame parent, boolean modal, Person person, Campai
}
private void initializePilotAndOptions () {
- birthdate = person.getBirthday();
+ birthdate = person.getDateOfBirth();
selectedPhenotype = person.getPhenotype();
options = person.getOptions();
portrait = person.getPortrait();
@@ -932,7 +932,7 @@ private DefaultComboBoxModel getFactionsComboBoxModel() {
int endYear = person.getRecruitment() != null
? Math.min(person.getRecruitment().getYear(), year)
: year;
- if (faction.validBetween(person.getBirthday().getYear(), endYear)) {
+ if (faction.validBetween(person.getDateOfBirth().getYear(), endYear)) {
factionsModel.addElement(faction);
}
}
@@ -959,8 +959,8 @@ private DefaultComboBoxModel getPlanetarySystemsComboBoxModel(F
DefaultComboBoxModel model = new DefaultComboBoxModel<>();
List orderedSystems = campaign.getSystems().stream()
- .filter(a -> a.getFactionSet(person.getBirthday()).contains(faction))
- .sorted(Comparator.comparing(a -> a.getName(person.getBirthday())))
+ .filter(a -> a.getFactionSet(person.getDateOfBirth()).contains(faction))
+ .sorted(Comparator.comparing(a -> a.getName(person.getDateOfBirth())))
.toList();
for (PlanetarySystem system : orderedSystems) {
model.addElement(system);
@@ -1451,7 +1451,7 @@ private void done() {
if (choiceGender.getSelectedItem() != null) {
person.setGender((Gender) choiceGender.getSelectedItem());
}
- person.setBirthday(birthdate);
+ person.setDateOfBirth(birthdate);
person.setOriginFaction((Faction) choiceFaction.getSelectedItem());
if (choiceSystem.getSelectedItem() != null && choicePlanet.getSelectedItem() != null) {
person.setOriginPlanet((Planet)choicePlanet.getSelectedItem());
diff --git a/MekHQ/src/mekhq/gui/dialog/CustomizePersonDialog.java b/MekHQ/src/mekhq/gui/dialog/CustomizePersonDialog.java
index 80ecefb149..413261071a 100644
--- a/MekHQ/src/mekhq/gui/dialog/CustomizePersonDialog.java
+++ b/MekHQ/src/mekhq/gui/dialog/CustomizePersonDialog.java
@@ -18,25 +18,6 @@
*/
package mekhq.gui.dialog;
-import java.awt.Component;
-import java.awt.Dimension;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Insets;
-import java.awt.event.ActionEvent;
-import java.time.LocalDate;
-import java.time.Period;
-import java.util.ArrayList;
-import java.util.Comparator;
-import java.util.Enumeration;
-import java.util.Hashtable;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.ResourceBundle;
-
-import javax.swing.*;
-
import megamek.client.generator.RandomCallsignGenerator;
import megamek.client.generator.RandomNameGenerator;
import megamek.client.ui.baseComponents.MMComboBox;
@@ -55,20 +36,11 @@
import megamek.logging.MMLogger;
import mekhq.MekHQ;
import mekhq.campaign.Campaign;
-import mekhq.campaign.personnel.Bloodname;
-import mekhq.campaign.personnel.Person;
-import mekhq.campaign.personnel.PersonnelOptions;
-import mekhq.campaign.personnel.SkillType;
-import mekhq.campaign.personnel.SpecialAbility;
+import mekhq.campaign.personnel.*;
import mekhq.campaign.personnel.enums.Phenotype;
import mekhq.campaign.personnel.enums.education.EducationLevel;
import mekhq.campaign.personnel.randomEvents.PersonalityController;
-import mekhq.campaign.personnel.randomEvents.enums.personalities.Aggression;
-import mekhq.campaign.personnel.randomEvents.enums.personalities.Ambition;
-import mekhq.campaign.personnel.randomEvents.enums.personalities.Greed;
-import mekhq.campaign.personnel.randomEvents.enums.personalities.Intelligence;
-import mekhq.campaign.personnel.randomEvents.enums.personalities.PersonalityQuirk;
-import mekhq.campaign.personnel.randomEvents.enums.personalities.Social;
+import mekhq.campaign.personnel.randomEvents.enums.personalities.*;
import mekhq.campaign.unit.Unit;
import mekhq.campaign.universe.Faction;
import mekhq.campaign.universe.Faction.Tag;
@@ -82,6 +54,14 @@
import mekhq.gui.control.EditScenarioLogControl;
import mekhq.gui.utilities.MarkdownEditorPanel;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.time.LocalDate;
+import java.time.Period;
+import java.util.List;
+import java.util.*;
+
/**
* This dialog is used to both hire new pilots and to edit existing ones
*
@@ -165,7 +145,7 @@ public CustomizePersonDialog(JFrame parent, boolean modal, Person person, Campai
}
private void initializePilotAndOptions() {
- birthdate = person.getBirthday();
+ birthdate = person.getDateOfBirth();
if (person.getRecruitment() != null) {
recruitment = person.getRecruitment();
}
@@ -1105,7 +1085,7 @@ private DefaultComboBoxModel getFactionsComboBoxModel() {
int endYear = person.getRecruitment() != null
? Math.min(person.getRecruitment().getYear(), year)
: year;
- if (faction.validBetween(person.getBirthday().getYear(), endYear)) {
+ if (faction.validBetween(person.getDateOfBirth().getYear(), endYear)) {
factionsModel.addElement(faction);
}
}
@@ -1130,8 +1110,8 @@ private DefaultComboBoxModel getPlanetarySystemsComboBoxModel(F
DefaultComboBoxModel model = new DefaultComboBoxModel<>();
List orderedSystems = campaign.getSystems().stream()
- .filter(a -> a.getFactionSet(person.getBirthday()).contains(faction))
- .sorted(Comparator.comparing(a -> a.getName(person.getBirthday())))
+ .filter(a -> a.getFactionSet(person.getDateOfBirth()).contains(faction))
+ .sorted(Comparator.comparing(a -> a.getName(person.getDateOfBirth())))
.toList();
for (PlanetarySystem system : orderedSystems) {
model.addElement(system);
@@ -1194,7 +1174,7 @@ private void btnOkActionPerformed(ActionEvent evt) {
person.setGender((Gender) choiceGender.getSelectedItem());
}
- person.setBirthday(birthdate);
+ person.setDateOfBirth(birthdate);
person.setRecruitment(recruitment);
person.setLastRankChangeDate(lastRankChangeDate);
person.setRetirement(retirement);
diff --git a/MekHQ/src/mekhq/gui/dialog/GMToolsDialog.java b/MekHQ/src/mekhq/gui/dialog/GMToolsDialog.java
index 083d5309d1..5a3730a9aa 100644
--- a/MekHQ/src/mekhq/gui/dialog/GMToolsDialog.java
+++ b/MekHQ/src/mekhq/gui/dialog/GMToolsDialog.java
@@ -20,43 +20,14 @@
*/
package mekhq.gui.dialog;
-import static mekhq.campaign.personnel.backgrounds.BackgroundsController.randomMercenaryCompanyNameGenerator;
-
-import java.awt.Component;
-import java.awt.Container;
-import java.awt.Cursor;
-import java.awt.GridBagConstraints;
-import java.awt.GridBagLayout;
-import java.awt.Insets;
-import java.awt.event.ActionEvent;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.util.List;
-import java.util.Objects;
-import java.util.StringJoiner;
-import java.util.function.Predicate;
-
-import javax.swing.*;
-import javax.swing.GroupLayout.Alignment;
-
import megamek.client.generator.RandomCallsignGenerator;
import megamek.client.generator.RandomNameGenerator;
import megamek.client.ui.baseComponents.MMButton;
import megamek.client.ui.baseComponents.MMComboBox;
import megamek.client.ui.dialogs.EntityReadoutDialog;
-import megamek.client.ui.preferences.JComboBoxPreference;
-import megamek.client.ui.preferences.JIntNumberSpinnerPreference;
-import megamek.client.ui.preferences.JTabbedPanePreference;
-import megamek.client.ui.preferences.JTextFieldPreference;
-import megamek.client.ui.preferences.PreferencesNode;
+import megamek.client.ui.preferences.*;
import megamek.codeUtilities.StringUtility;
-import megamek.common.Compute;
-import megamek.common.Entity;
-import megamek.common.EntityWeightClass;
-import megamek.common.MekFileParser;
-import megamek.common.MekSummary;
-import megamek.common.Messages;
-import megamek.common.UnitType;
+import megamek.common.*;
import megamek.common.annotations.Nullable;
import megamek.common.enums.Gender;
import megamek.logging.MMLogger;
@@ -78,6 +49,19 @@
import mekhq.gui.displayWrappers.FactionDisplay;
import mekhq.gui.panels.LayeredForceIconCreationPanel;
+import javax.swing.*;
+import javax.swing.GroupLayout.Alignment;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.util.List;
+import java.util.Objects;
+import java.util.StringJoiner;
+import java.util.function.Predicate;
+
+import static mekhq.campaign.personnel.backgrounds.BackgroundsController.randomMercenaryCompanyNameGenerator;
+
public class GMToolsDialog extends AbstractMHQDialog {
private static final MMLogger logger = MMLogger.create(GMToolsDialog.class);
@@ -708,7 +692,7 @@ private JPanel createRATPanel() {
final DefaultComboBoxModel factionModel = new DefaultComboBoxModel<>();
factionModel.addAll(FactionDisplay.getSortedValidFactionDisplays(Factions.getInstance().getFactions(),
- (getPerson() == null) ? getGUI().getCampaign().getLocalDate() : getPerson().getBirthday()));
+ (getPerson() == null) ? getGUI().getCampaign().getLocalDate() : getPerson().getDateOfBirth()));
setComboRATFaction(new MMComboBox<>("comboRATFaction", factionModel));
getComboRATFaction().setSelectedIndex(0);
gbc.gridx++;
@@ -854,7 +838,7 @@ private JPanel createNamePanel() {
final DefaultComboBoxModel factionModel = new DefaultComboBoxModel<>();
factionModel.addAll(FactionDisplay.getSortedValidFactionDisplays(Factions.getInstance().getFactions(),
- (getPerson() == null) ? getGUI().getCampaign().getLocalDate() : getPerson().getBirthday()));
+ (getPerson() == null) ? getGUI().getCampaign().getLocalDate() : getPerson().getDateOfBirth()));
setComboNameGeneratorFaction(new MMComboBox<>("comboRATFaction", factionModel));
getComboNameGeneratorFaction().setSelectedIndex(0);
gbc.gridx++;
@@ -1396,7 +1380,7 @@ private void setValuesFromPerson() {
getChkClanPersonnel().setSelected(getPerson().isClanPersonnel());
// Now we figure out the person's origin faction
- final FactionDisplay faction = new FactionDisplay(getPerson().getOriginFaction(), getPerson().getBirthday());
+ final FactionDisplay faction = new FactionDisplay(getPerson().getOriginFaction(), getPerson().getDateOfBirth());
getComboRATFaction().setSelectedItem(faction);
getComboNameGeneratorFaction().setSelectedItem(faction);
diff --git a/MekHQ/src/mekhq/gui/dialog/HireBulkPersonnelDialog.java b/MekHQ/src/mekhq/gui/dialog/HireBulkPersonnelDialog.java
index 25254f2bc7..9dcfc9fcbd 100644
--- a/MekHQ/src/mekhq/gui/dialog/HireBulkPersonnelDialog.java
+++ b/MekHQ/src/mekhq/gui/dialog/HireBulkPersonnelDialog.java
@@ -369,7 +369,7 @@ private void hire(boolean isGmHire) {
if (useAge) {
if ((age > maxAgeVal) || (age < minAgeVal)) {
LocalDate birthDay = earliestBirthDate.plusDays(Compute.randomInt(days));
- person.setBirthday(birthDay);
+ person.setDateOfBirth(birthDay);
age = person.getAge(today);
}
diff --git a/MekHQ/src/mekhq/gui/dialog/MedicalViewDialog.java b/MekHQ/src/mekhq/gui/dialog/MedicalViewDialog.java
index ae220ea98e..75e916c7ef 100644
--- a/MekHQ/src/mekhq/gui/dialog/MedicalViewDialog.java
+++ b/MekHQ/src/mekhq/gui/dialog/MedicalViewDialog.java
@@ -18,34 +18,14 @@
*/
package mekhq.gui.dialog;
-import java.awt.*;
-import java.awt.event.ActionListener;
-import java.awt.event.MouseAdapter;
-import java.awt.event.MouseEvent;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.time.Period;
-import java.util.Arrays;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.ResourceBundle;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-import java.util.stream.Stream;
-
-import javax.swing.*;
-
import megamek.client.ui.preferences.JWindowPreference;
import megamek.client.ui.preferences.PreferencesNode;
import megamek.logging.MMLogger;
import mekhq.MekHQ;
import mekhq.Utilities;
import mekhq.campaign.Campaign;
-import mekhq.campaign.ExtraData;
+import mekhq.campaign.ExtraData.Key;
+import mekhq.campaign.ExtraData.StringKey;
import mekhq.campaign.force.Force;
import mekhq.campaign.log.LogEntry;
import mekhq.campaign.log.LogEntryType;
@@ -56,15 +36,31 @@
import mekhq.campaign.personnel.enums.InjuryLevel;
import mekhq.gui.view.Paperdoll;
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.time.Period;
+import java.util.List;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+
public class MedicalViewDialog extends JDialog {
private static final MMLogger logger = MMLogger.create(MedicalViewDialog.class);
private static final String MENU_CMD_SEPARATOR = ",";
- private static final ExtraData.Key DOCTOR_NOTES = new ExtraData.StringKey("doctor_notes");
+ private static final Key DOCTOR_NOTES = new StringKey("doctor_notes");
// TODO: Custom paper dolls
@SuppressWarnings("unused")
- private static final ExtraData.Key PAPERDOLL = new ExtraData.StringKey("paperdoll_xml_file");
+ private static final Key PAPERDOLL = new StringKey("paperdoll_xml_file");
private final Campaign campaign;
private final Person person;
@@ -324,7 +320,7 @@ private JPanel genBaseData(Campaign c, Person p) {
surname = p.getBloodname();
}
- Period age = Period.between(p.getBirthday(), c.getLocalDate());
+ Period age = Period.between(p.getDateOfBirth(), c.getLocalDate());
String phenotype = p.getPhenotype().isNone() ? resourceMap.getString("baselinePhenotype.text")
: p.getPhenotype().toString();
@@ -343,7 +339,7 @@ private JPanel genBaseData(Campaign c, Person p) {
panel.add(genWrittenPanel(givenName));
panel.add(genLabel(resourceMap.getString("birthDate.text")));
panel.add(genLabel(resourceMap.getString("age.text")));
- panel.add(genWrittenPanel(MekHQ.getMHQOptions().getDisplayFormattedDate(p.getBirthday())));
+ panel.add(genWrittenPanel(MekHQ.getMHQOptions().getDisplayFormattedDate(p.getDateOfBirth())));
panel.add(genWrittenPanel(String.format(resourceMap.getString("age.format"), age.getYears(), age.getMonths())));
panel.add(genLabel(resourceMap.getString("gender.text")));
panel.add(genLabel(resourceMap.getString("phenotype.text")));
@@ -373,7 +369,7 @@ private JPanel genMedicalHistory(Campaign c, Person p) {
Collectors.groupingBy(entry -> MekHQ.getMHQOptions().getDisplayFormattedDate(entry.getDate())));
groupedEntries.entrySet().stream()
.filter(e -> !e.getValue().isEmpty())
- .sorted(Map.Entry.comparingByKey())
+ .sorted(Entry.comparingByKey())
.forEachOrdered(e -> {
if (e.getValue().size() > 1) {
panel.add(genWrittenText(e.getKey()));
@@ -433,7 +429,7 @@ private Stream maxInjuryLevelLocationStream(Person p) {
.forEach(bl -> levelMap.put(bl, getMaxInjuryLevel(p, bl)));
return levelMap.entrySet().stream()
.sorted((entry1, entry2) -> Integer.compare(entry2.getValue().ordinal(), entry1.getValue().ordinal()))
- .map(Map.Entry::getKey);
+ .map(Entry::getKey);
}
private JPanel fillInjuries(JPanel panel, Campaign c, Person p) {
diff --git a/MekHQ/src/mekhq/gui/enums/PersonnelTableModelColumn.java b/MekHQ/src/mekhq/gui/enums/PersonnelTableModelColumn.java
index 3d7a673fb9..8b42f7fd2c 100644
--- a/MekHQ/src/mekhq/gui/enums/PersonnelTableModelColumn.java
+++ b/MekHQ/src/mekhq/gui/enums/PersonnelTableModelColumn.java
@@ -18,14 +18,6 @@
*/
package mekhq.gui.enums;
-import java.util.Comparator;
-import java.util.ResourceBundle;
-import java.util.stream.Collectors;
-
-import javax.swing.JTable;
-import javax.swing.SortOrder;
-import javax.swing.SwingConstants;
-
import megamek.codeUtilities.StringUtility;
import megamek.common.Entity;
import megamek.common.Jumpship;
@@ -41,19 +33,15 @@
import mekhq.campaign.personnel.PersonnelOptions;
import mekhq.campaign.personnel.SkillType;
import mekhq.campaign.personnel.enums.GenderDescriptors;
-import mekhq.campaign.personnel.randomEvents.enums.personalities.Aggression;
-import mekhq.campaign.personnel.randomEvents.enums.personalities.Ambition;
-import mekhq.campaign.personnel.randomEvents.enums.personalities.Greed;
-import mekhq.campaign.personnel.randomEvents.enums.personalities.Intelligence;
-import mekhq.campaign.personnel.randomEvents.enums.personalities.Social;
+import mekhq.campaign.personnel.randomEvents.enums.personalities.*;
import mekhq.campaign.unit.Unit;
import mekhq.campaign.universe.Planet;
-import mekhq.gui.sorter.BonusSorter;
-import mekhq.gui.sorter.DateStringComparator;
-import mekhq.gui.sorter.FormattedNumberSorter;
-import mekhq.gui.sorter.IntegerStringSorter;
-import mekhq.gui.sorter.LevelSorter;
-import mekhq.gui.sorter.PersonRankStringSorter;
+import mekhq.gui.sorter.*;
+
+import javax.swing.*;
+import java.util.Comparator;
+import java.util.ResourceBundle;
+import java.util.stream.Collectors;
public enum PersonnelTableModelColumn {
// region Enum Declarations
@@ -495,7 +483,7 @@ public String getCellValue(final Campaign campaign, final PersonnelMarket person
return person.getCallsign();
case AGE:
case BIRTHDAY:
- return MekHQ.getMHQOptions().getDisplayFormattedDate(person.getBirthday());
+ return MekHQ.getMHQOptions().getDisplayFormattedDate(person.getDateOfBirth());
case PERSONNEL_STATUS:
return person.getStatus().toString();
case GENDER:
diff --git a/MekHQ/src/mekhq/gui/panes/CampaignOptionsPane.java b/MekHQ/src/mekhq/gui/panes/CampaignOptionsPane.java
index d3a2330a14..a25e74b287 100644
--- a/MekHQ/src/mekhq/gui/panes/CampaignOptionsPane.java
+++ b/MekHQ/src/mekhq/gui/panes/CampaignOptionsPane.java
@@ -450,6 +450,7 @@ public class CampaignOptionsPane extends AbstractMHQTabbedPane {
// Anniversaries
private final JPanel anniversaryPanel = new JPanel();
private JCheckBox chkAnnounceBirthdays;
+ private JCheckBox chkAnnounceRecruitmentAnniversaries;
private JCheckBox chkAnnounceOfficersOnly;
private JCheckBox chkAnnounceChildBirthdays;
@@ -5316,10 +5317,13 @@ private JPanel createAnniversaryPanel() {
chkAnnounceBirthdays.addActionListener(evt -> {
final boolean isEnabled = chkAnnounceBirthdays.isSelected();
- chkAnnounceOfficersOnly.setEnabled(isEnabled);
chkAnnounceChildBirthdays.setEnabled(isEnabled);
});
+ chkAnnounceRecruitmentAnniversaries = new JCheckBox(resources.getString("chkAnnounceRecruitmentAnniversaries.text"));
+ chkAnnounceRecruitmentAnniversaries.setToolTipText(resources.getString("chkAnnounceRecruitmentAnniversaries.toolTipText"));
+ chkAnnounceRecruitmentAnniversaries.setName("chkAnnounceRecruitmentAnniversaries");
+
chkAnnounceOfficersOnly = new JCheckBox(resources.getString("chkAnnounceOfficersOnly.text"));
chkAnnounceOfficersOnly.setToolTipText(resources.getString("chkAnnounceOfficersOnly.toolTipText"));
chkAnnounceOfficersOnly.setName("chkAnnounceOfficersOnly");
@@ -5342,12 +5346,14 @@ private JPanel createAnniversaryPanel() {
layout.setVerticalGroup(
layout.createSequentialGroup()
.addComponent(chkAnnounceBirthdays)
+ .addComponent(chkAnnounceRecruitmentAnniversaries)
.addComponent(chkAnnounceOfficersOnly)
.addComponent(chkAnnounceChildBirthdays));
layout.setHorizontalGroup(
layout.createParallelGroup(Alignment.LEADING)
.addComponent(chkAnnounceBirthdays)
+ .addComponent(chkAnnounceRecruitmentAnniversaries)
.addComponent(chkAnnounceOfficersOnly)
.addComponent(chkAnnounceChildBirthdays));
@@ -8643,6 +8649,7 @@ public void setOptions(@Nullable CampaignOptions options,
// Anniversaries
chkAnnounceBirthdays.setSelected(options.isAnnounceBirthdays());
+ chkAnnounceRecruitmentAnniversaries.setSelected(options.isAnnounceRecruitmentAnniversaries());
chkAnnounceOfficersOnly.setSelected(options.isAnnounceOfficersOnly());
chkAnnounceChildBirthdays.setSelected(options.isAnnounceChildBirthdays());
@@ -9387,6 +9394,7 @@ public void updateOptions() {
// Anniversaries
options.setAnnounceBirthdays(chkAnnounceBirthdays.isSelected());
+ options.setAnnounceRecruitmentAnniversaries(chkAnnounceRecruitmentAnniversaries.isSelected());
options.setAnnounceOfficersOnly(chkAnnounceOfficersOnly.isSelected());
options.setAnnounceChildBirthdays(chkAnnounceChildBirthdays.isSelected());