Skip to content

Commit

Permalink
Merge branch 'master' into wvr-RSWD-flailing
Browse files Browse the repository at this point in the history
  • Loading branch information
WeaverThree committed Oct 29, 2024
2 parents 97fa784 + 16ba8e2 commit d30f495
Show file tree
Hide file tree
Showing 15 changed files with 346 additions and 116 deletions.
2 changes: 1 addition & 1 deletion MekHQ/data/scenariotemplates/Convoy Escort.xml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
<forceAlignment>1</forceAlignment>
<forceMultiplier>0.5</forceMultiplier>
<forceName>Convoy</forceName>
<generationMethod>2</generationMethod>
<generationMethod>1</generationMethod>
<generationOrder>4</generationOrder>
<maxWeightClass>4</maxWeightClass>
<minWeightClass>1</minWeightClass>
Expand Down
2 changes: 1 addition & 1 deletion MekHQ/data/scenariotemplates/Convoy Interdiction.xml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
<forceAlignment>2</forceAlignment>
<forceMultiplier>0.5</forceMultiplier>
<forceName>Convoy</forceName>
<generationMethod>2</generationMethod>
<generationMethod>1</generationMethod>
<generationOrder>5</generationOrder>
<maxWeightClass>4</maxWeightClass>
<minWeightClass>1</minWeightClass>
Expand Down
2 changes: 1 addition & 1 deletion MekHQ/data/scenariotemplates/Convoy Raid.xml
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
<forceAlignment>2</forceAlignment>
<forceMultiplier>0.5</forceMultiplier>
<forceName>Convoy</forceName>
<generationMethod>2</generationMethod>
<generationMethod>1</generationMethod>
<generationOrder>5</generationOrder>
<maxWeightClass>4</maxWeightClass>
<minWeightClass>1</minWeightClass>
Expand Down
2 changes: 1 addition & 1 deletion MekHQ/data/scenariotemplates/Critical Convoy Escort.xml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@
<forceAlignment>1</forceAlignment>
<forceMultiplier>0.5</forceMultiplier>
<forceName>Convoy</forceName>
<generationMethod>2</generationMethod>
<generationMethod>1</generationMethod>
<generationOrder>4</generationOrder>
<maxWeightClass>4</maxWeightClass>
<minWeightClass>1</minWeightClass>
Expand Down
4 changes: 2 additions & 2 deletions MekHQ/data/scenariotemplates/Irregular Force Assault.xml
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@
<forceAlignment>2</forceAlignment>
<forceMultiplier>1.0</forceMultiplier>
<forceName>Infantry</forceName>
<generationMethod>2</generationMethod>
<generationMethod>1</generationMethod>
<generationOrder>5</generationOrder>
<maxWeightClass>4</maxWeightClass>
<minWeightClass>0</minWeightClass>
Expand Down Expand Up @@ -140,7 +140,7 @@
<forceAlignment>2</forceAlignment>
<forceMultiplier>1.0</forceMultiplier>
<forceName>Irregulars</forceName>
<generationMethod>2</generationMethod>
<generationMethod>1</generationMethod>
<generationOrder>5</generationOrder>
<maxWeightClass>4</maxWeightClass>
<minWeightClass>0</minWeightClass>
Expand Down
4 changes: 2 additions & 2 deletions MekHQ/data/scenariotemplates/Irregular Force Suppression.xml
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@
<forceAlignment>2</forceAlignment>
<forceMultiplier>1.0</forceMultiplier>
<forceName>Infantry</forceName>
<generationMethod>2</generationMethod>
<generationMethod>1</generationMethod>
<generationOrder>5</generationOrder>
<maxWeightClass>4</maxWeightClass>
<minWeightClass>0</minWeightClass>
Expand Down Expand Up @@ -110,7 +110,7 @@
<forceAlignment>2</forceAlignment>
<forceMultiplier>1.0</forceMultiplier>
<forceName>Irregulars</forceName>
<generationMethod>2</generationMethod>
<generationMethod>1</generationMethod>
<generationOrder>5</generationOrder>
<maxWeightClass>4</maxWeightClass>
<minWeightClass>0</minWeightClass>
Expand Down
10 changes: 10 additions & 0 deletions MekHQ/docs/history.txt
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,16 @@ MEKHQ VERSION HISTORY:
+ PR #5121: Label OmniUnits as Omni in the MekHQ UI
+ Fix #5119 && #5108 && #4297 Fixed Position of NewDayEvent Trigger in processNewDay
+ PR #5126: Rebalanced Random Unit Quality
+ Fix #5131: Fixed Faction Conflict Checks for Reeducation Camps
+ PR #5137: Stopped Scenarios Pulling Units from the Hangar
+ Fix #5139: Refactored Field Kitchen Personnel Count Logic
+ PR #5141: Handled StratCon Scenario Placement Failure when All Coordinates Occupied
+ PR #5142: Added New StratCon Scenario Generation Utility Method
+ PR #5143: Fix Track Calculation in StratconContractInitializer
+ PR #5144: [FG3] Adjusted Generation Method in Some Scenarios
+ PR #5145: [FG3] Refactored Difficulty Multiplier Application
+ PR #5146: Adjusted Scenario Loot Box Behavior
+ PR #5147: Refactored JScrollPaneWithSpeed Constructor


0.50.0 (2024-09-01 2000 UTC) (THIS MARKS THE START OF JAVA 17 AS THE MINIMUM REQUIRED)
Expand Down
15 changes: 9 additions & 6 deletions MekHQ/src/mekhq/campaign/Campaign.java
Original file line number Diff line number Diff line change
Expand Up @@ -4598,16 +4598,19 @@ private void processFatigueNewDay() {
// otherwise we would need to check it once for each active person in the
// campaign
if (campaignOptions.isUseFatigue()) {
long validPersonnel;
int personnelCount;

if (campaignOptions.isUseFieldKitchenIgnoreNonCombatants()) {
validPersonnel = getActivePersonnel().stream()
.filter(person -> person.getPrimaryRole().isCombat() || person.getSecondaryRole().isCombat())
.count();
personnelCount = (int) getActivePersonnel().stream()
.filter(person -> !(person.getPrisonerStatus().isFree() && person.getPrimaryRole().isNone()))
.filter(person -> person.getPrimaryRole().isCombat() || person.getSecondaryRole().isCombat())
.count();
} else {
validPersonnel = getActivePersonnel().size();
personnelCount = (int) getActivePersonnel().stream()
.filter(person -> !(person.getPrisonerStatus().isFree() && person.getPrimaryRole().isNone()))
.count();
}
fieldKitchenWithinCapacity = validPersonnel <= Fatigue.checkFieldKitchenCapacity(this);
fieldKitchenWithinCapacity = personnelCount <= Fatigue.checkFieldKitchenCapacity(this);
} else {
fieldKitchenWithinCapacity = false;
}
Expand Down
51 changes: 31 additions & 20 deletions MekHQ/src/mekhq/campaign/CampaignSummary.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,6 @@
*/
package mekhq.campaign;

import static mekhq.campaign.personnel.turnoverAndRetention.RetirementDefectionTracker.getAdministrativeStrain;
import static mekhq.campaign.personnel.turnoverAndRetention.RetirementDefectionTracker.getAdministrativeStrainModifier;
import static mekhq.campaign.personnel.turnoverAndRetention.RetirementDefectionTracker.getCombinedSkillValues;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import org.apache.commons.lang3.StringUtils;

import megamek.common.Entity;
import megamek.common.Infantry;
import megamek.common.UnitType;
Expand All @@ -40,6 +30,15 @@
import mekhq.campaign.unit.CargoStatistics;
import mekhq.campaign.unit.HangarStatistics;
import mekhq.campaign.unit.Unit;
import org.apache.commons.lang3.StringUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import static mekhq.campaign.personnel.turnoverAndRetention.RetirementDefectionTracker.getAdministrativeStrain;
import static mekhq.campaign.personnel.turnoverAndRetention.RetirementDefectionTracker.getAdministrativeStrainModifier;
import static mekhq.campaign.personnel.turnoverAndRetention.RetirementDefectionTracker.getCombinedSkillValues;

/**
* calculates and stores summary information on a campaign for use in reporting,
Expand Down Expand Up @@ -220,7 +219,7 @@ public void updateInformation() {
/**
* A report that gives numbers of combat and support personnel as well as
* injuries
*
*
* @return a <code>String</code> of the report
*/
public String getPersonnelReport() {
Expand All @@ -230,7 +229,7 @@ public String getPersonnelReport() {

/**
* A report that gives the number of units in different damage states
*
*
* @return a <code>String</code> of the report
*/
public String getForceRepairReport() {
Expand All @@ -243,7 +242,7 @@ public String getForceRepairReport() {
/**
* A report that gives the percentage composition of the force in mek, armor,
* infantry, and aero units.
*
*
* @return a <code>String</code> of the report
*/
public String getForceCompositionReport() {
Expand All @@ -265,7 +264,7 @@ public String getForceCompositionReport() {

/**
* A report that gives the percentage of successful missions
*
*
* @return a <code>String</code> of the report
*/
public String getMissionSuccessReport() {
Expand All @@ -276,7 +275,7 @@ public String getMissionSuccessReport() {

/**
* A report that gives capacity and existing tonnage of all cargo
*
*
* @return a <code>String</code> of the report
*/
public StringBuilder getCargoCapacityReport() {
Expand Down Expand Up @@ -310,7 +309,7 @@ public StringBuilder getCargoCapacityReport() {

/**
* A report that gives information about the transportation capacity
*
*
* @return a <code>String</code> of the report
*/
public String getTransportCapacity() {
Expand Down Expand Up @@ -358,24 +357,36 @@ public String getAdministrativeCapacityReport(Campaign campaign) {
* @return A summary of fatigue related facilities.
*/
public String getFacilityReport() {
int personnelCount = campaign.getActivePersonnel().size();
CampaignOptions campaignOptions = campaign.getCampaignOptions();
int personnelCount;

if (campaignOptions.isUseFieldKitchenIgnoreNonCombatants()) {
personnelCount = (int) campaign.getActivePersonnel().stream()
.filter(person -> !(person.getPrisonerStatus().isFree() && person.getPrimaryRole().isNone()))
.filter(person -> person.getPrimaryRole().isCombat() || person.getSecondaryRole().isCombat())
.count();
} else {
personnelCount = (int) campaign.getActivePersonnel().stream()
.filter(person -> !(person.getPrisonerStatus().isFree() && person.getPrimaryRole().isNone()))
.count();
}

StringBuilder report = new StringBuilder();

if (campaign.getCampaignOptions().isUseFatigue()) {
if (campaignOptions.isUseFatigue()) {
report.append(String.format("Kitchens (%s/%s) ",
personnelCount,
Fatigue.checkFieldKitchenCapacity(campaign)));
}

if (campaign.getCampaignOptions().isUseAdvancedMedical()) {
if (campaignOptions.isUseAdvancedMedical()) {
int patients = (int) campaign.getPatients().stream()
.filter(patient -> patient.getDoctorId() != null)
.count();

int doctorCapacity = campaign.getActivePersonnel().stream()
.filter(person -> (person.getPrimaryRole().isDoctor()) || (person.getSecondaryRole().isDoctor()))
.mapToInt(person -> campaign.getCampaignOptions().getMaximumPatients())
.mapToInt(person -> campaignOptions.getMaximumPatients())
.sum();

report.append(String.format("Hospital Beds (%s/%s)",
Expand Down
26 changes: 11 additions & 15 deletions MekHQ/src/mekhq/campaign/mission/AtBDynamicScenarioFactory.java
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ private static int generateForces(AtBDynamicScenario scenario, AtBContract contr
// how close to the allowances do we want to get?
int targetPercentage = 100 + ((Compute.randomInt(8) - 3) * 5);
logger.info(String.format("Target Percentage: %s", targetPercentage));
logger.info(String.format("Difficulty Multiplier: %s", getDifficultyMultiplier(campaign)));

for (int generationOrder : generationOrders) {
List<ScenarioForceTemplate> currentForceTemplates = orderedForceTemplates.get(generationOrder);
Expand All @@ -283,10 +284,8 @@ private static int generateForces(AtBDynamicScenario scenario, AtBContract contr
generatedLanceCount += generateFixedForce(scenario, contract, campaign, forceTemplate);
} else {
int weightClass = randomForceWeight();
logger.info(String.format("++ Generating a force for the %s template ++", forceTemplate.getForceName()).toUpperCase());

if (forceTemplate.isPlayerForce()) {
logger.info(String.format("++ Generating a force for the %s template ++", forceTemplate.getForceName()).toUpperCase());
}
generatedLanceCount += generateForce(scenario, contract, campaign,
effectiveBV, effectiveUnitCount, weightClass, forceTemplate, false);
}
Expand Down Expand Up @@ -390,11 +389,15 @@ public static int generateForce(AtBDynamicScenario scenario, AtBContract contrac
break;
case Opposing:
factionCode = contract.getEnemyCode();

// We only want the difficulty multipliers applying to enemy forces
double difficultyMultiplier = getDifficultyMultiplier(campaign);
effectiveBV = (int) round(effectiveBV * difficultyMultiplier);
effectiveUnitCount = (int) round(effectiveUnitCount * difficultyMultiplier);

// Intentional fall-through: opposing third parties are either the contracted
// enemy or
// "Unidentified Hostiles" which are considered pirates or bandit caste with
// random
// quality and skill
// enemy or "Unidentified Hostiles" which are considered pirates or bandit caste
// with random quality and skill
case Third:
skill = scenario.getEffectiveOpforSkill();
quality = scenario.getEffectiveOpforQuality();
Expand Down Expand Up @@ -2689,7 +2692,6 @@ public static int calculateEffectiveBV(AtBDynamicScenario scenario, Campaign cam
// for each deployed player and bot force that's marked as contributing to the
// BV budget
int bvBudget = 0;
double difficultyMultiplier = getDifficultyMultiplier(campaign);

String generationMethod = campaign.getCampaignOptions().isUseGenericBattleValue() ?
"Generic BV" : "BV2";
Expand Down Expand Up @@ -2720,9 +2722,7 @@ public static int calculateEffectiveBV(AtBDynamicScenario scenario, Campaign cam
double bvMultiplier = scenario.getEffectivePlayerBVMultiplier();

if (bvMultiplier > 0) {
bvBudget = (int) round(bvBudget * scenario.getEffectivePlayerBVMultiplier() * difficultyMultiplier);
} else {
bvBudget = (int) round(bvBudget * difficultyMultiplier);
bvBudget = (int) round(bvBudget * scenario.getEffectivePlayerBVMultiplier());
}

// allied bot forces that contribute to BV do not get multiplied by the
Expand Down Expand Up @@ -2756,7 +2756,6 @@ public static int calculateEffectiveUnitCount(AtBDynamicScenario scenario, Campa
// for each deployed player and bot force that's marked as contributing to the
// unit count budget
int unitCount = 0;
double difficultyMultiplier = getDifficultyMultiplier(campaign);

// deployed player forces:
for (int forceID : scenario.getForceIDs()) {
Expand All @@ -2776,9 +2775,6 @@ public static int calculateEffectiveUnitCount(AtBDynamicScenario scenario, Campa
}
}

// the player unit count is now multiplied by the difficulty multiplier
unitCount = (int) Math.floor((double) unitCount * difficultyMultiplier);

// allied bot forces that contribute to BV do not get multiplied by the
// difficulty even if the player is good, the AI doesn't get any better
for (int index = 0; index < scenario.getNumBots(); index++) {
Expand Down
17 changes: 15 additions & 2 deletions MekHQ/src/mekhq/campaign/personnel/education/Academy.java
Original file line number Diff line number Diff line change
Expand Up @@ -622,9 +622,16 @@ public String getFilteredFaction(Campaign campaign, Person person, List<String>
return null;
}

if (!hints.isAtWarWith(originFaction, faction, campaign.getLocalDate())
// For reeducation camps we only care about whether the campaign faction is at war
if (isReeducationCamp) {
if (!hints.isAtWarWith(campaignFaction, faction, campaign.getLocalDate())) {
return faction.getShortName();
}
} else {
if (!hints.isAtWarWith(originFaction, faction, campaign.getLocalDate())
|| !hints.isAtWarWith(campaignFaction, faction, campaign.getLocalDate())) {
return faction.getShortName();
return faction.getShortName();
}
}
}

Expand Down Expand Up @@ -697,6 +704,12 @@ public int getEducationLevel(Person person) {
* @return true if there is a faction conflict, false otherwise.
*/
public Boolean isFactionConflict(Campaign campaign, Person person) {
// Reeducation camps only care if they're at war with the campaign faction
if (isReeducationCamp) {
return RandomFactionGenerator.getInstance().getFactionHints().isAtWarWith(campaign.getFaction(),
Factions.getInstance().getFaction(person.getEduAcademyFaction()), campaign.getLocalDate());
}

// is there a conflict between academy faction & person's faction?
if (RandomFactionGenerator.getInstance().getFactionHints().isAtWarWith(person.getOriginFaction(),
Factions.getInstance().getFaction(person.getEduAcademyFaction()), campaign.getLocalDate())) {
Expand Down
Loading

0 comments on commit d30f495

Please sign in to comment.