From 288f359caa1dc5ce709c47e1d81fb0033b40da8f Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 25 Sep 2021 15:59:07 -0400 Subject: [PATCH 1/2] 210: Ensuring we generate at least one person with the artillery skill when hiring the full complement for units with an artillery weapon --- .../generator/AbstractSkillGenerator.java | 17 ++++++++++++++++- .../generator/DefaultPersonnelGenerator.java | 3 +-- .../generator/DefaultSkillGenerator.java | 10 ++++++---- .../unit/actions/HirePersonnelUnitAction.java | 18 +++++++++++++++++- 4 files changed, 40 insertions(+), 8 deletions(-) diff --git a/MekHQ/src/mekhq/campaign/personnel/generator/AbstractSkillGenerator.java b/MekHQ/src/mekhq/campaign/personnel/generator/AbstractSkillGenerator.java index 040a621b5c..63a3b8f03c 100644 --- a/MekHQ/src/mekhq/campaign/personnel/generator/AbstractSkillGenerator.java +++ b/MekHQ/src/mekhq/campaign/personnel/generator/AbstractSkillGenerator.java @@ -34,7 +34,11 @@ */ public abstract class AbstractSkillGenerator { - private RandomSkillPreferences rskillPrefs = new RandomSkillPreferences(); + private RandomSkillPreferences rskillPrefs; + + protected AbstractSkillGenerator(final RandomSkillPreferences randomSkillPreferences) { + this.rskillPrefs = randomSkillPreferences; + } /** * Gets the {@link RandomSkillPreferences}. @@ -163,6 +167,17 @@ protected void generateDefaultSkills(Person person, PersonnelRole primaryRole, i } } + public void generateArtillerySkill(final Person person) { + generateArtillerySkill(person, getPhenotypeBonus(person)); + } + + protected void generateArtillerySkill(final Person person, final int bonus) { + final int experienceLevel = Utilities.generateExpLevel(rskillPrefs.getArtilleryBonus()); + if (experienceLevel > SkillType.EXP_ULTRA_GREEN) { + addSkill(person, SkillType.S_ARTILLERY, experienceLevel, rskillPrefs.randomizeSkill(), bonus); + } + } + protected static void addSkill(Person person, String skillName, int level, int bonus) { person.addSkill(skillName, new Skill(skillName, level, bonus)); } diff --git a/MekHQ/src/mekhq/campaign/personnel/generator/DefaultPersonnelGenerator.java b/MekHQ/src/mekhq/campaign/personnel/generator/DefaultPersonnelGenerator.java index d92618bb29..32d40057f6 100644 --- a/MekHQ/src/mekhq/campaign/personnel/generator/DefaultPersonnelGenerator.java +++ b/MekHQ/src/mekhq/campaign/personnel/generator/DefaultPersonnelGenerator.java @@ -93,8 +93,7 @@ public Person generate(Campaign campaign, PersonnelRole primaryRole, PersonnelRo generateBirthday(campaign, person, expLvl, person.isClanner() && person.getPhenotype() != Phenotype.NONE); - AbstractSkillGenerator skillGenerator = new DefaultSkillGenerator(); - skillGenerator.setSkillPreferences(getSkillPreferences()); + AbstractSkillGenerator skillGenerator = new DefaultSkillGenerator(getSkillPreferences()); skillGenerator.generateSkills(person, expLvl); AbstractSpecialAbilityGenerator specialAbilityGenerator = new DefaultSpecialAbilityGenerator(); diff --git a/MekHQ/src/mekhq/campaign/personnel/generator/DefaultSkillGenerator.java b/MekHQ/src/mekhq/campaign/personnel/generator/DefaultSkillGenerator.java index ed998ab767..333cd0c322 100644 --- a/MekHQ/src/mekhq/campaign/personnel/generator/DefaultSkillGenerator.java +++ b/MekHQ/src/mekhq/campaign/personnel/generator/DefaultSkillGenerator.java @@ -30,6 +30,11 @@ import mekhq.campaign.personnel.enums.PersonnelRole; public class DefaultSkillGenerator extends AbstractSkillGenerator { + //region Constructors + public DefaultSkillGenerator(final RandomSkillPreferences randomSkillPreferences) { + super(randomSkillPreferences); + } + //endregion Constructors @Override public void generateSkills(Person person, int expLvl) { @@ -74,10 +79,7 @@ public void generateSkills(Person person, int expLvl) { if (getCampaignOptions(person).useArtillery() && (primaryRole.isMechWarrior() || primaryRole.isVehicleGunner() || primaryRole.isSoldier()) && Utilities.rollProbability(rskillPrefs.getArtilleryProb())) { - int artyLvl = Utilities.generateExpLevel(rskillPrefs.getArtilleryBonus()); - if (artyLvl > SkillType.EXP_ULTRA_GREEN) { - addSkill(person, SkillType.S_ARTILLERY, artyLvl, rskillPrefs.randomizeSkill(), bonus); - } + generateArtillerySkill(person, bonus); } // roll random secondary skill diff --git a/MekHQ/src/mekhq/campaign/unit/actions/HirePersonnelUnitAction.java b/MekHQ/src/mekhq/campaign/unit/actions/HirePersonnelUnitAction.java index 87251f76a1..8ab70d9195 100644 --- a/MekHQ/src/mekhq/campaign/unit/actions/HirePersonnelUnitAction.java +++ b/MekHQ/src/mekhq/campaign/unit/actions/HirePersonnelUnitAction.java @@ -21,11 +21,16 @@ package mekhq.campaign.unit.actions; import megamek.common.*; +import mekhq.Utilities; import mekhq.campaign.Campaign; import mekhq.campaign.personnel.Person; +import mekhq.campaign.personnel.SkillType; import mekhq.campaign.personnel.enums.PersonnelRole; +import mekhq.campaign.personnel.generator.DefaultSkillGenerator; import mekhq.campaign.unit.Unit; +import java.util.List; + /** * Hires a full complement of personnel for a unit. */ @@ -144,8 +149,19 @@ public void execute(Campaign campaign, Unit unit) { unit.setTechOfficer(p); } + // Ensure we generate at least one person with the artillery skill if using that skill and + // the unit has an artillery weapon + if (campaign.getCampaignOptions().useArtillery() && (unit.getEntity() != null) + && unit.getEntity().getWeaponList().stream() + .anyMatch(weapon -> (weapon.getType() instanceof WeaponType) + && (((WeaponType) weapon.getType()).getDamage() == WeaponType.DAMAGE_ARTILLERY))) { + final List gunners = unit.getGunners(); + if (!gunners.isEmpty() && gunners.stream().noneMatch(person -> person.getSkills().hasSkill(SkillType.S_ARTILLERY))) { + new DefaultSkillGenerator(campaign.getRandomSkillPreferences()).generateArtillerySkill(Utilities.getRandomItem(gunners)); + } + } + unit.resetPilotAndEntity(); unit.runDiagnostic(false); } - } From 70103a1bd87b6da14868fdc1687c03d91ce5bd47 Mon Sep 17 00:00:00 2001 From: unknown Date: Sat, 25 Sep 2021 16:35:29 -0400 Subject: [PATCH 2/2] Fixing unit testing --- .../actions/HirePersonnelUnitActionTest.java | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/MekHQ/unittests/mekhq/campaign/unit/actions/HirePersonnelUnitActionTest.java b/MekHQ/unittests/mekhq/campaign/unit/actions/HirePersonnelUnitActionTest.java index c383f53d72..4939aaeef0 100644 --- a/MekHQ/unittests/mekhq/campaign/unit/actions/HirePersonnelUnitActionTest.java +++ b/MekHQ/unittests/mekhq/campaign/unit/actions/HirePersonnelUnitActionTest.java @@ -20,6 +20,7 @@ import static org.mockito.Mockito.*; +import mekhq.campaign.CampaignOptions; import mekhq.campaign.personnel.enums.PersonnelRole; import org.junit.Test; @@ -38,6 +39,9 @@ public class HirePersonnelUnitActionTest { @Test public void fullUnitTakesNoAction() { Campaign mockCampaign = mock(Campaign.class); + CampaignOptions mockOptions = mock(CampaignOptions.class); + doReturn(mockOptions).when(mockCampaign).getCampaignOptions(); + doReturn(false).when(mockOptions).useArtillery(); Entity mockEntity = mock(Mech.class); Unit unit = spy(new Unit(mockEntity, mockCampaign)); @@ -59,6 +63,9 @@ public void fullUnitTakesNoAction() { @Test public void actionPassesAlongGMSetting() { Campaign mockCampaign = mock(Campaign.class); + CampaignOptions mockOptions = mock(CampaignOptions.class); + doReturn(mockOptions).when(mockCampaign).getCampaignOptions(); + doReturn(false).when(mockOptions).useArtillery(); Entity mockEntity = mock(Mech.class); Unit unit = spy(new Unit(mockEntity, mockCampaign)); @@ -87,6 +94,9 @@ public void actionPassesAlongGMSetting() { @Test public void mechNeedingDriverAddsDriver() { Campaign mockCampaign = mock(Campaign.class); + CampaignOptions mockOptions = mock(CampaignOptions.class); + doReturn(mockOptions).when(mockCampaign).getCampaignOptions(); + doReturn(false).when(mockOptions).useArtillery(); Entity mockEntity = mock(Mech.class); Unit unit = spy(new Unit(mockEntity, mockCampaign)); @@ -143,6 +153,9 @@ public void mechDoesntAddDriverIfRecruitFails() { @Test public void lamNeedingDriverAddsDriver() { Campaign mockCampaign = mock(Campaign.class); + CampaignOptions mockOptions = mock(CampaignOptions.class); + doReturn(mockOptions).when(mockCampaign).getCampaignOptions(); + doReturn(false).when(mockOptions).useArtillery(); Entity mockEntity = mock(LandAirMech.class); Unit unit = spy(new Unit(mockEntity, mockCampaign)); @@ -171,6 +184,9 @@ public void lamNeedingDriverAddsDriver() { @Test public void mechNeedingGunnerAddsGunner() { Campaign mockCampaign = mock(Campaign.class); + CampaignOptions mockOptions = mock(CampaignOptions.class); + doReturn(mockOptions).when(mockCampaign).getCampaignOptions(); + doReturn(false).when(mockOptions).useArtillery(); Entity mockEntity = mock(Mech.class); Unit unit = spy(new Unit(mockEntity, mockCampaign)); @@ -198,6 +214,9 @@ public void mechNeedingGunnerAddsGunner() { @Test public void tankNeedingGunnerAddsGunner() { Campaign mockCampaign = mock(Campaign.class); + CampaignOptions mockOptions = mock(CampaignOptions.class); + doReturn(mockOptions).when(mockCampaign).getCampaignOptions(); + doReturn(false).when(mockOptions).useArtillery(); Entity mockEntity = mock(Tank.class); Unit unit = spy(new Unit(mockEntity, mockCampaign)); @@ -225,6 +244,9 @@ public void tankNeedingGunnerAddsGunner() { @Test public void spaceShipNeedingGunnerAddsGunner() { Campaign mockCampaign = mock(Campaign.class); + CampaignOptions mockOptions = mock(CampaignOptions.class); + doReturn(mockOptions).when(mockCampaign).getCampaignOptions(); + doReturn(false).when(mockOptions).useArtillery(); Entity mockEntity = mock(Jumpship.class); Unit unit = spy(new Unit(mockEntity, mockCampaign)); @@ -252,6 +274,9 @@ public void spaceShipNeedingGunnerAddsGunner() { @Test public void smallCraftNeedingGunnerAddsGunner() { Campaign mockCampaign = mock(Campaign.class); + CampaignOptions mockOptions = mock(CampaignOptions.class); + doReturn(mockOptions).when(mockCampaign).getCampaignOptions(); + doReturn(false).when(mockOptions).useArtillery(); Entity mockEntity = mock(SmallCraft.class); Unit unit = spy(new Unit(mockEntity, mockCampaign)); @@ -279,6 +304,9 @@ public void smallCraftNeedingGunnerAddsGunner() { @Test public void spaceShipNeedingCrewAddsCrew() { Campaign mockCampaign = mock(Campaign.class); + CampaignOptions mockOptions = mock(CampaignOptions.class); + doReturn(mockOptions).when(mockCampaign).getCampaignOptions(); + doReturn(false).when(mockOptions).useArtillery(); Entity mockEntity = mock(Jumpship.class); when(mockEntity.isSupportVehicle()).thenReturn(false); Unit unit = spy(new Unit(mockEntity, mockCampaign)); @@ -307,6 +335,9 @@ public void spaceShipNeedingCrewAddsCrew() { @Test public void supportVehicleNeedingCrewAddsCrew() { Campaign mockCampaign = mock(Campaign.class); + CampaignOptions mockOptions = mock(CampaignOptions.class); + doReturn(mockOptions).when(mockCampaign).getCampaignOptions(); + doReturn(false).when(mockOptions).useArtillery(); Entity mockEntity = mock(SupportTank.class); when(mockEntity.isSupportVehicle()).thenReturn(true); Unit unit = spy(new Unit(mockEntity, mockCampaign)); @@ -335,6 +366,9 @@ public void supportVehicleNeedingCrewAddsCrew() { @Test public void spaceShipNeedingNavigatorAddsNavigator() { Campaign mockCampaign = mock(Campaign.class); + CampaignOptions mockOptions = mock(CampaignOptions.class); + doReturn(mockOptions).when(mockCampaign).getCampaignOptions(); + doReturn(false).when(mockOptions).useArtillery(); Entity mockEntity = mock(Jumpship.class); when(mockEntity.isSupportVehicle()).thenReturn(false); Unit unit = spy(new Unit(mockEntity, mockCampaign)); @@ -363,6 +397,9 @@ public void spaceShipNeedingNavigatorAddsNavigator() { @Test public void mechNeedingTechOfficerAddsTechOfficer() { Campaign mockCampaign = mock(Campaign.class); + CampaignOptions mockOptions = mock(CampaignOptions.class); + doReturn(mockOptions).when(mockCampaign).getCampaignOptions(); + doReturn(false).when(mockOptions).useArtillery(); Entity mockEntity = mock(Mech.class); Unit unit = spy(new Unit(mockEntity, mockCampaign)); @@ -390,6 +427,9 @@ public void mechNeedingTechOfficerAddsTechOfficer() { @Test public void tankNeedingTechOfficerAddsTechOfficer() { Campaign mockCampaign = mock(Campaign.class); + CampaignOptions mockOptions = mock(CampaignOptions.class); + doReturn(mockOptions).when(mockCampaign).getCampaignOptions(); + doReturn(false).when(mockOptions).useArtillery(); Entity mockEntity = mock(Tank.class); Unit unit = spy(new Unit(mockEntity, mockCampaign));