@@ -4318,34 +4318,57 @@ public void processNewDayPersonnel() {
43184318 // This list ensures we don't hit a concurrent modification error
43194319 List <Person > personnel = getPersonnelFilteringOutDeparted ();
43204320
4321+ // Prep some data for vocational xp
4322+ int vocationalXpRate = campaignOptions .getVocationalXP ();
4323+ if (hasActiveContract ) {
4324+ if (campaignOptions .isUseAtB ()) {
4325+ for (AtBContract contract : getActiveAtBContracts ()) {
4326+ if (!contract .getContractType ().isGarrisonType ()) {
4327+ vocationalXpRate *= 2 ;
4328+ break ;
4329+ }
4330+ }
4331+ } else {
4332+ vocationalXpRate *= 2 ;
4333+ }
4334+ }
4335+
4336+ // Process personnel
43214337 for (Person person : personnel ) {
43224338 if (person .getStatus ().isDepartedUnit ()) {
43234339 continue ;
43244340 }
43254341
4342+ // Daily events
43264343 if (getDeath ().processNewDay (this , getLocalDate (), person )) {
43274344 // The person has died, so don't continue to process the dead
43284345 continue ;
43294346 }
43304347
4331- processWeeklyRelationshipEvents (person );
4332-
43334348 person .resetMinutesLeft ();
43344349 person .setAcquisition (0 );
43354350
43364351 processAdvancedMedicalEvents (person );
43374352
4338- // Reset edge points to the purchased value each week. This should only
4339- // apply for support personnel - combat troops reset with each new mm game
4340- processWeeklyEdgeResets (person );
4353+ processAnniversaries (person );
4354+
4355+ // Weekly events
4356+ if (currentDay .getDayOfWeek () == DayOfWeek .MONDAY ) {
4357+ processWeeklyRelationshipEvents (person );
43414358
4342- if (processMonthlyVocationalXp (person )) {
4343- personnelWhoAdvancedInXP .add (person );
4359+ processWeeklyEdgeResets (person );
43444360 }
43454361
4346- processAnniversaries (person );
4362+ // Monthly events
4363+ if (currentDay .getDayOfMonth () == 1 ) {
4364+ processMonthlyAutoAwards (person );
43474365
4348- processMonthlyAutoAwards (person );
4366+ if (vocationalXpRate > 0 ) {
4367+ if (processMonthlyVocationalXp (person , vocationalXpRate )) {
4368+ personnelWhoAdvancedInXP .add (person );
4369+ }
4370+ }
4371+ }
43494372 }
43504373
43514374 if (!personnelWhoAdvancedInXP .isEmpty ()) {
@@ -4392,45 +4415,29 @@ private void processAdvancedMedicalEvents(Person person) {
43924415 * @param person the person for whom weekly Edge resets will be processed
43934416 */
43944417 private void processWeeklyEdgeResets (Person person ) {
4395- if ((person .hasSupportRole (true ) || person .isEngineer ())
4396- && (getLocalDate ().getDayOfWeek () == DayOfWeek .MONDAY )) {
4418+ if ((person .hasSupportRole (true ) || person .isEngineer ())) {
43974419 person .resetCurrentEdge ();
43984420 }
43994421 }
44004422
44014423 /**
4402- * Processes the monthly vocational experience (XP) gain for a given person based on specific
4403- * eligibility criteria. If the person meets the conditions, XP is awarded and their progress
4404- * is tracked.
4405- *
4406- * <p>The method checks the following conditions to determine eligibility for XP gain:
4407- * <ul>
4408- * <li>The person must have an active status (e.g., not retired, deceased, or in education).</li>
4409- * <li>The person must not be a child on the current date.</li>
4410- * <li>The person must not be categorized as a dependent.</li>
4411- * <li>The campaign must enable idle XP, and the current date must be the first day of the month.</li>
4412- * <li>The person must not have the status of a prisoner (Bondsmen are exempt from this
4413- * and remain eligible for XP).</li>
4414- * </ul>
4424+ * Processes the monthly vocational experience (XP) gain for a given person based on their
4425+ * eligibility and the vocational experience rules defined in campaign options.
44154426 *
4416- * <p>If all of these conditions are satisfied :
4427+ * <p>Eligibility for receiving vocational XP is determined by checking the following conditions :
44174428 * <ul>
4418- * <li>The person’s idle month count is incremented.</li>
4419- * <li>If the accumulated idle months reach the threshold defined in the campaign options,
4420- * an idle XP roll (2d6) is performed.</li>
4421- * <li>If the roll result meets or exceeds the target threshold:
4422- * <ul>
4423- * <li>XP is awarded to the person based on the campaign's idle XP configuration.</li>
4424- * <li>The idle month count is reset.</li>
4425- * </ul>
4426- * </li>
4427- * <li>If the roll is unsuccessful, the idle month count is still reset.</li>
4429+ * <li>The person must have an <b>active status</b> (e.g., not retired, deceased, or in education).</li>
4430+ * <li>The person must not be a <b>child</b> as of the current date.</li>
4431+ * <li>The person must not be categorized as a <b>dependent</b>.</li>
4432+ * <li>The person must not have the status of a <b>prisoner</b>.</li>
4433+ * <b>Note:</b> Bondsmen are exempt from this restriction and are eligible for vocational XP.
44284434 * </ul>
44294435 *
44304436 * @param person the {@link Person} whose monthly vocational XP is to be processed
4437+ * @param vocationalXpRate the amount of XP awarded on a successful roll
44314438 * @return {@code true} if XP was successfully awarded during the process, {@code false} otherwise
44324439 */
4433- private boolean processMonthlyVocationalXp (Person person ) {
4440+ private boolean processMonthlyVocationalXp (Person person , int vocationalXpRate ) {
44344441 if (!person .getStatus ().isActive ()) {
44354442 return false ;
44364443 }
@@ -4443,16 +4450,22 @@ private boolean processMonthlyVocationalXp(Person person) {
44434450 return false ;
44444451 }
44454452
4446- if ((getCampaignOptions ().getIdleXP () > 0 ) && (getLocalDate ().getDayOfMonth () == 1 )
4447- && !person .getPrisonerStatus ().isCurrentPrisoner ()) { // Prisoners can't gain XP, while Bondsmen can
4448- person .setIdleMonths (person .getIdleMonths () + 1 );
4449- if (person .getIdleMonths () >= getCampaignOptions ().getMonthsIdleXP ()) {
4450- if (Compute .d6 (2 ) >= getCampaignOptions ().getTargetIdleXP ()) {
4451- person .awardXP (this , getCampaignOptions ().getIdleXP ());
4452- person .setIdleMonths (0 );
4453- return true ;
4454- }
4455- person .setIdleMonths (0 );
4453+ if (person .getPrisonerStatus ().isCurrentPrisoner ()) {
4454+ // Prisoners can't gain vocational XP, while Bondsmen can
4455+ return false ;
4456+ }
4457+
4458+ int checkFrequency = campaignOptions .getVocationalXPCheckFrequency ();
4459+ int targetNumber = campaignOptions .getVocationalXPTargetNumber ();
4460+
4461+ person .setVocationalXPTimer (person .getVocationalXPTimer () + 1 );
4462+ if (person .getVocationalXPTimer () >= checkFrequency ) {
4463+ if (Compute .d6 (2 ) >= targetNumber ) {
4464+ person .awardXP (this , vocationalXpRate );
4465+ person .setVocationalXPTimer (0 );
4466+ return true ;
4467+ } else {
4468+ person .setVocationalXPTimer (0 );
44564469 }
44574470 }
44584471
@@ -4519,35 +4532,33 @@ private void processAnniversaries(Person person) {
45194532 * @param person the person for whom the monthly auto awards are being processed
45204533 */
45214534 private void processMonthlyAutoAwards (Person person ) {
4522- if (getLocalDate ().getDayOfMonth () == 1 ) {
4523- double multiplier = 0 ;
4535+ double multiplier = 0 ;
45244536
4525- int score = 0 ;
4537+ int score = 0 ;
45264538
4527- if (person .getPrimaryRole ().isSupport (true )) {
4528- int dice = person .getExperienceLevel (this , false );
4529-
4530- if (dice > 0 ) {
4531- score = Compute .d6 (dice );
4532- }
4539+ if (person .getPrimaryRole ().isSupport (true )) {
4540+ int dice = person .getExperienceLevel (this , false );
45334541
4534- multiplier += 0.5 ;
4542+ if (dice > 0 ) {
4543+ score = Compute .d6 (dice );
45354544 }
45364545
4537- if ( person . getSecondaryRole (). isSupport ( true )) {
4538- int dice = person . getExperienceLevel ( this , true );
4546+ multiplier += 0.5 ;
4547+ }
45394548
4540- if (dice > 0 ) {
4541- score += Compute .d6 (dice );
4542- }
4549+ if (person .getSecondaryRole ().isSupport (true )) {
4550+ int dice = person .getExperienceLevel (this , true );
45434551
4544- multiplier += 0.5 ;
4545- } else if (person .getSecondaryRole ().isNone ()) {
4546- multiplier += 0.5 ;
4552+ if (dice > 0 ) {
4553+ score += Compute .d6 (dice );
45474554 }
45484555
4549- person .changeAutoAwardSupportPoints ((int ) (score * multiplier ));
4556+ multiplier += 0.5 ;
4557+ } else if (person .getSecondaryRole ().isNone ()) {
4558+ multiplier += 0.5 ;
45504559 }
4560+
4561+ person .changeAutoAwardSupportPoints ((int ) (score * multiplier ));
45514562 }
45524563
45534564 /**
0 commit comments