diff --git a/megamek/src/megamek/client/bot/CEntity.java b/megamek/src/megamek/client/bot/CEntity.java index 2874aae4475..7d33461dea2 100644 --- a/megamek/src/megamek/client/bot/CEntity.java +++ b/megamek/src/megamek/client/bot/CEntity.java @@ -1838,7 +1838,7 @@ private static double[] getExpectedDamage(Infantry attacker, int gunskill) { // If there are two secondary weapons per squad then use that weapons // range. Otherwise use the primary weapons range. - if ((null != secondary_weapon) && (attacker.getSecondaryN() >= 2)) { + if ((null != secondary_weapon) && (attacker.getSecondaryWeaponsPerSquad() >= 2)) { base_range = secondary_weapon.getInfantryRange(); } else { base_range = primary_weapon.getInfantryRange(); diff --git a/megamek/src/megamek/client/ui/swing/EquipChoicePanel.java b/megamek/src/megamek/client/ui/swing/EquipChoicePanel.java index 10f5a5678c8..984c193c65e 100644 --- a/megamek/src/megamek/client/ui/swing/EquipChoicePanel.java +++ b/megamek/src/megamek/client/ui/swing/EquipChoicePanel.java @@ -244,7 +244,7 @@ public EquipChoicePanel(Entity entity, ClientGUI clientgui, Client client) { // Can't set up munitions on infantry. if (!((entity instanceof Infantry) && !((Infantry) entity) - .hasFieldGun()) || (entity instanceof BattleArmor)) { + .hasFieldWeapon()) || (entity instanceof BattleArmor)) { setupMunitions(); panMunitions.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), Messages.getString("CustomMechDialog.MunitionsPanelTitle"), diff --git a/megamek/src/megamek/client/ui/swing/UnitEditorDialog.java b/megamek/src/megamek/client/ui/swing/UnitEditorDialog.java index 57905e53808..7342f8d21e2 100644 --- a/megamek/src/megamek/client/ui/swing/UnitEditorDialog.java +++ b/megamek/src/megamek/client/ui/swing/UnitEditorDialog.java @@ -281,7 +281,7 @@ private void initInfantryArmorPanel() { int men = Math.max(infantry.getShootingStrength(), 0); spnInternal[0] = new JSpinner(new SpinnerNumberModel(men, 0, - infantry.getSquadN() * infantry.getSquadSize(), 1)); + infantry.getSquadCount() * infantry.getSquadSize(), 1)); gridBagConstraints = new GridBagConstraints(); gridBagConstraints.gridx = 0; gridBagConstraints.gridy = 0; @@ -1190,7 +1190,7 @@ private void btnOkayActionPerformed(java.awt.event.ActionEvent evt) { } } if (entity instanceof Infantry) { - ((Infantry) entity).damageOrRestoreFieldGunsAndArty(); + ((Infantry) entity).damageOrRestoreFieldWeapons(); entity.applyDamage(); } diff --git a/megamek/src/megamek/client/ui/swing/boardview/EntitySprite.java b/megamek/src/megamek/client/ui/swing/boardview/EntitySprite.java index dd5e53a43e7..c303fd95c20 100644 --- a/megamek/src/megamek/client/ui/swing/boardview/EntitySprite.java +++ b/megamek/src/megamek/client/ui/swing/boardview/EntitySprite.java @@ -700,7 +700,7 @@ public void prepare() { // draw facing graph.setColor(Color.white); if ((entity.getFacing() != -1) - && !(isInfantry && !((Infantry) entity).hasFieldGun() + && !(isInfantry && !((Infantry) entity).hasFieldWeapon() && !((Infantry) entity).isTakingCover()) && !(isAero && ((IAero) entity).isSpheroid() && !board.inSpace())) { // Indicate a stacked unit with the same facing that can still move diff --git a/megamek/src/megamek/common/BattleArmor.java b/megamek/src/megamek/common/BattleArmor.java index 82f64e61f02..c90226fce70 100644 --- a/megamek/src/megamek/common/BattleArmor.java +++ b/megamek/src/megamek/common/BattleArmor.java @@ -24,8 +24,7 @@ import org.apache.logging.log4j.LogManager; import java.text.NumberFormat; -import java.util.Arrays; -import java.util.Vector; +import java.util.*; /** * This class represents a squad or point of battle armor equipped infantry, @@ -341,7 +340,7 @@ public BattleArmor() { setArmorType(EquipmentType.T_ARMOR_BA_STANDARD); // BA are always one squad - squadn = 1; + squadCount = 1; // All Battle Armor squads are Clan until specified otherwise. setTechLevel(TechConstants.T_CLAN_TW); @@ -736,16 +735,6 @@ public HitData getTransferLocation(HitData hit) { return new HitData(Entity.LOC_DESTROYED); } - /** - * Battle Armor units use default behavior for armor and internals. - * - * @see megamek.common.Infantry#isPlatoon() - */ - @Override - protected boolean isPlatoon() { - return false; - } - /** * Battle Armor units have no armor on their squad location. * @@ -2214,8 +2203,7 @@ public int getSpriteDrawPriority() { } @Override - public void damageOrRestoreFieldGunsAndArty() { } - - @Override - protected void damageFieldGunsAndArty() { } + protected boolean isFieldWeapon(Mounted equipment) { + return false; + } } diff --git a/megamek/src/megamek/common/BattleForceElement.java b/megamek/src/megamek/common/BattleForceElement.java new file mode 100644 index 00000000000..e69de29bb2d diff --git a/megamek/src/megamek/common/Compute.java b/megamek/src/megamek/common/Compute.java index 8463fd8286f..1e6e408ad0a 100644 --- a/megamek/src/megamek/common/Compute.java +++ b/megamek/src/megamek/common/Compute.java @@ -7043,7 +7043,7 @@ public static int getFullCrewSize(Entity entity) { } return ntroopers; } else if (entity instanceof Infantry) { - return ((Infantry) entity).getSquadN() * ((Infantry) entity).getSquadSize(); + return ((Infantry) entity).getSquadCount() * ((Infantry) entity).getSquadSize(); } else if (entity instanceof Jumpship || entity instanceof SmallCraft) { return getAeroCrewNeeds(entity) + getTotalGunnerNeeds(entity); } else { diff --git a/megamek/src/megamek/common/Infantry.java b/megamek/src/megamek/common/Infantry.java index 8665957972f..3e0146996e3 100644 --- a/megamek/src/megamek/common/Infantry.java +++ b/megamek/src/megamek/common/Infantry.java @@ -31,27 +31,22 @@ import java.text.NumberFormat; import java.util.*; -import java.util.stream.Collectors; + +import static java.util.stream.Collectors.toList; /** - * This class represents the lowest of the low, the ground pounders, the city - * rats, the PBI (Poor Bloody Infantry).
PLEASE NOTE!!! This class just
- * represents unarmored infantry platoons as described by CitiTech (c) 1986.
- * I've never seen the rules for powered armor, "anti-mech" troops, or
- * Immortals.
+ * This class represents Conventional Infantry (with BattleArmor as a subclass).
+ * The lowest of the low, the ground pounders, the city rats, the PBI (Poor Bloody Infantry).
*
- * PLEASE NOTE!!! My programming style is to put constants first in tests so the
- * compiler catches my "= for ==" errors.
+ * Note that BattleArmor extends Infantry!
*
* @author Suvarov454@sourceforge.net (James A. Damour)
*/
public class Infantry extends Entity {
private static final long serialVersionUID = -8706716079307721282L;
- /**
- * Infantry Specializations
- */
- public static int BRIDGE_ENGINEERS = 1 << 0;
+ // Infantry Specializations
+ public static int BRIDGE_ENGINEERS = 1;
public static int DEMO_ENGINEERS = 1 << 1;
public static int FIRE_ENGINEERS = 1 << 2;
public static int MINE_ENGINEERS = 1 << 3;
@@ -65,47 +60,28 @@ public class Infantry extends Entity {
public static int XCT = 1 << 11;
public static int SCUBA = 1 << 12;
public static int NUM_SPECIALIZATIONS = 13;
- public static int COMBAT_ENGINEERS = BRIDGE_ENGINEERS | DEMO_ENGINEERS
- | FIRE_ENGINEERS | MINE_ENGINEERS | SENSOR_ENGINEERS
- | TRENCH_ENGINEERS;
-
- /**
- * squad size and number
- */
- protected int squadn = 1;
- private int squadsize = 1;
+ public static int COMBAT_ENGINEERS = BRIDGE_ENGINEERS | DEMO_ENGINEERS | FIRE_ENGINEERS | MINE_ENGINEERS
+ | SENSOR_ENGINEERS | TRENCH_ENGINEERS;
- /**
- * The number of men originally in this platoon.
- */
- protected int menStarting = 0;
+ protected int squadCount = 1;
+ private int squadSize = 1;
+ protected int originalTrooperCount;
- /**
- * The number of men alive in this platoon at the beginning of the phase,
- * before it begins to take damage.
- */
- private int menShooting = 0;
+ /** The number of troopers alive in this platoon at the beginning of the phase, before taking damage. */
+ private int troopersShooting;
- /**
- * The number of men left alive in this platoon.
- */
- private int men = 0;
+ /** The number of troopers alive in this platoon, including any damage sustained in the current phase. */
+ private int activeTroopers;
- /**
- * Information on primary and secondary weapons
- * This must be kept separate from the equipment array
- * because they are not fired as separate weapons
- */
- private transient InfantryWeapon primaryW;
+ // Information on primary and secondary weapons. This must be kept separate from the equipment array
+ // because they are not fired as separate weapons
+ private InfantryWeapon primaryWeapon;
private String primaryName;
- private transient InfantryWeapon secondW;
+ private InfantryWeapon secondaryWeapon;
private String secondName;
- private int secondn = 0;
+ private int secondaryWeaponsPerSquad = 0;
-
- /**
- * Infantry armor
- */
+ // Armor
private double damageDivisor = 1.0;
private boolean encumbering = false;
private boolean spaceSuit = false;
@@ -114,55 +90,40 @@ public class Infantry extends Entity {
private boolean sneak_ir = false;
private boolean sneak_ecm = false;
- /**
- * Stores which infantry specializations are active.
- */
+ /** The active specializations of this platoon. */
private int infSpecs = 0;
/**
* For mechanized VTOL infantry, stores whether the platoon are microlite troops,
* which need to enter a hex every turn to remain in flight.
*/
- private boolean microlite = false;
+ private boolean isMicrolite = false;
- /**
- * The location for infantry equipment.
- */
public static final int LOC_INFANTRY = 0;
public static final int LOC_FIELD_GUNS = 1;
- /**
- * Infantry only have critical slots for field gun ammo
- */
+ // Infantry only have critical slots for field gun ammo
private static final int[] NUM_OF_SLOTS = { 20, 20 };
- private static final String[] LOCATION_ABBRS = { "MEN", "FGUN" };
- private static final String[] LOCATION_NAMES = { "Men", "Field Guns"};
+ private static final String[] LOCATION_ABBRS = { "TPRS", "FGUN" };
+ private static final String[] LOCATION_NAMES = { "Troopers", "Field Guns" };
public int turnsLayingExplosives = -1;
public static final int DUG_IN_NONE = 0;
public static final int DUG_IN_WORKING = 1; // no protection, can't attack
public static final int DUG_IN_COMPLETE = 2; // protected, restricted arc
- public static final int DUG_IN_FORTIFYING1 = 3; // no protection, can't
- // attack
- public static final int DUG_IN_FORTIFYING2 = 4; // no protection, can't
- // attack
+ public static final int DUG_IN_FORTIFYING1 = 3; // no protection, can't attack
+ public static final int DUG_IN_FORTIFYING2 = 4; // no protection, can't attack
private int dugIn = DUG_IN_NONE;
private boolean isTakingCover = false;
private boolean canCallSupport = true;
private boolean isCallingSupport = false;
- // Public and Protected constants, constructors, and methods.
-
- /**
- * The maximum number of men in an infantry platoon.
- */
+ /** The maximum number of troopers in an infantry platoon. */
public static final int INF_PLT_MAX_MEN = 30;
- /**
- * The internal names of the anti-Mek attacks.
- */
+ // Anti-Mek attacks
public static final String LEG_ATTACK = "LegAttack";
public static final String SWARM_MEK = "SwarmMek";
public static final String SWARM_WEAPON_MEK = "SwarmWeaponMek";
@@ -182,27 +143,19 @@ public String[] getLocationNames() {
return LOCATION_NAMES;
}
- /**
- * Returns the number of locations in this platoon
- */
@Override
public int locations() {
return 2;
}
- /**
- * Generate a new, blank, infantry platoon. Hopefully, we'll be loaded from
- * somewhere.
- */
+ /** Generate a new, blank, infantry platoon. Hopefully, we'll be loaded from somewhere. */
public Infantry() {
- // Instantiate the superclass.
super();
// Create a "dead" leg rifle platoon.
- menStarting = 0;
- menShooting = 0;
- men = 0;
+ originalTrooperCount = 0;
+ troopersShooting = 0;
+ activeTroopers = 0;
setMovementMode(EntityMovementMode.INF_LEG);
- // Determine the number of MPs.
setOriginalWalkMP(1);
}
@@ -359,33 +312,22 @@ protected void addSystemTechAdvancement(CompositeTechLevel ctl) {
}
}
- /**
- * Infantry can face freely (except when dug in)
- */
@Override
public boolean canChangeSecondaryFacing() {
return !hasActiveFieldArtillery();
}
- /**
- * Infantry can face freely
- */
@Override
public boolean isValidSecondaryFacing(int dir) {
return true;
}
- /**
- * Infantry can face freely
- */
@Override
public int clipSecondaryFacing(int dir) {
return dir;
}
- /**
- * Create local platoon for Urban Guerrilla
- */
+ /** Creates a local platoon for Urban Guerrilla. */
public void createLocalSupport() {
if (Compute.isInUrbanEnvironment(game, getPosition())) {
setIsCallingSupport(true);
@@ -401,22 +343,19 @@ public boolean getIsCallingSupport() {
return isCallingSupport;
}
- /**
- * return this infantry's walk mp, adjusted for planetary conditions
- */
@Override
public int getWalkMP(boolean gravity, boolean ignoreheat, boolean ignoremodulararmor) {
int mp = getOriginalWalkMP();
- // encumbering armor reduces MP by 1 to a minimum of one (TacOps, pg. 318)
+ // Encumbering armor (TacOps, pg. 318)
if (encumbering) {
mp = Math.max(mp - 1, 1);
}
- if ((getSecondaryN() > 1)
+ if ((getSecondaryWeaponsPerSquad() > 1)
&& !hasAbility(OptionsConstants.MD_TSM_IMPLANT)
&& !hasAbility(OptionsConstants.MD_DERMAL_ARMOR)
- && (null != secondW) && secondW.hasFlag(WeaponType.F_INF_SUPPORT)
- && (getMovementMode() != EntityMovementMode.TRACKED)
- && (getMovementMode() != EntityMovementMode.INF_JUMP)) {
+ && (null != secondaryWeapon) && secondaryWeapon.hasFlag(WeaponType.F_INF_SUPPORT)
+ && !getMovementMode().isTracked()
+ && !getMovementMode().isJumpInfantry()) {
mp = Math.max(mp - 1, 0);
}
// PL-MASC IntOps p.84
@@ -428,12 +367,10 @@ && isConventionalInfantry()) {
}
if ((null != getCrew()) && hasAbility(OptionsConstants.INFANTRY_FOOT_CAV)
- && ((getMovementMode() == EntityMovementMode.INF_LEG)
- || (getMovementMode() == EntityMovementMode.INF_JUMP))) {
+ && ((getMovementMode().isLegInfantry()) || (getMovementMode().isJumpInfantry()))) {
mp += 1;
}
if (hasActiveFieldArtillery()) {
- //mp of 1 at the most
mp = Math.min(mp, 1);
}
if (null != game) {
@@ -448,71 +385,51 @@ && isConventionalInfantry()) {
return mp;
}
- /**
- * Return this Infantry's run MP, which is identical to its walk MP
- */
@Override
public int getRunMP(boolean gravity, boolean ignoreheat, boolean ignoremodulararmor) {
- if ( (game != null)
+ int walkMP = getWalkMP(gravity, ignoreheat, ignoremodulararmor);
+ if ((game != null)
&& game.getOptions().booleanOption(OptionsConstants.ADVGRNDMOV_TACOPS_FAST_INFANTRY_MOVE)) {
- if (getWalkMP(gravity, ignoreheat, ignoremodulararmor) > 0) {
- return getWalkMP(gravity, ignoreheat, ignoremodulararmor) + 1;
- }
- return getWalkMP(gravity, ignoreheat, ignoremodulararmor) + 2;
+ return (walkMP > 0) ? walkMP + 1 : walkMP + 2;
+ } else {
+ return walkMP;
}
- return getWalkMP(gravity, ignoreheat, ignoremodulararmor);
}
- /**
- * Infantry don't have MASC
- */
@Override
public int getRunMPwithoutMASC(boolean gravity, boolean ignoreheat, boolean ignoremodulararmor) {
return getRunMP(gravity, ignoreheat, ignoremodulararmor);
}
-
- /*
- * (non-Javadoc)
- * @see megamek.common.Entity#getJumpMP(boolean)
- */
@Override
public int getJumpMP(boolean gravity) {
- int mp = 0;
- if (getMovementMode() != EntityMovementMode.INF_UMU
- && getMovementMode() != EntityMovementMode.SUBMARINE) {
- mp = getOriginalJumpMP();
- }
- if ((getSecondaryN() > 1)
+ int mp = hasUMU() ? 0 : getOriginalJumpMP();
+ if ((getSecondaryWeaponsPerSquad() > 1)
&& !hasAbility(OptionsConstants.MD_TSM_IMPLANT)
&& !hasAbility(OptionsConstants.MD_DERMAL_ARMOR)
- && (getMovementMode() != EntityMovementMode.SUBMARINE)
- && (null != secondW) && secondW.hasFlag(WeaponType.F_INF_SUPPORT)) {
+ && !getMovementMode().isSubmarine()
+ && (null != secondaryWeapon) && secondaryWeapon.hasFlag(WeaponType.F_INF_SUPPORT)) {
mp = Math.max(mp - 1, 0);
- } else if (movementMode.equals(EntityMovementMode.VTOL) && getSecondaryN() > 0) {
+ } else if (movementMode.isVTOL() && getSecondaryWeaponsPerSquad() > 0) {
mp = Math.max(mp - 1, 0);
}
if (gravity) {
mp = applyGravityEffectsOnMP(mp);
}
- int windP = 0;
if (null != game) {
int windCond = game.getPlanetaryConditions().getWindStrength();
- if (windCond == PlanetaryConditions.WI_MOD_GALE) {
- windP++;
- }
if (windCond >= PlanetaryConditions.WI_STRONG_GALE) {
return 0;
+ } else if (windCond == PlanetaryConditions.WI_MOD_GALE) {
+ mp--;
}
}
- mp = Math.max(mp - windP, 0);
- return mp;
+ return Math.max(mp, 0);
}
@Override
public boolean hasUMU() {
- return getMovementMode().equals(EntityMovementMode.INF_UMU)
- || getMovementMode().equals(EntityMovementMode.SUBMARINE);
+ return getMovementMode().isUMUInfantry() || getMovementMode().isSubmarine();
}
@Override
@@ -522,11 +439,7 @@ public int getActiveUMUCount() {
@Override
public int getAllUMUCount() {
- if (hasUMU()) {
- return jumpMP;
- } else {
- return 0;
- }
+ return hasUMU() ? jumpMP : 0;
}
@Override
@@ -536,13 +449,9 @@ public boolean antiTSMVulnerable() {
}
EquipmentType armorKit = getArmorKit();
return (armorKit == null)
- || !armorKit.hasSubType(MiscType.S_SPACE_SUIT | MiscType.S_XCT_VACUUM
- | MiscType.S_TOXIC_ATMO);
+ || !armorKit.hasSubType(MiscType.S_SPACE_SUIT | MiscType.S_XCT_VACUUM | MiscType.S_TOXIC_ATMO);
}
- /**
- * Infantry can not enter water unless they have UMU mp or hover.
- */
@Override
public boolean isLocationProhibited(Coords c, int currElevation) {
// Coords off the board aren't legal
@@ -550,10 +459,8 @@ public boolean isLocationProhibited(Coords c, int currElevation) {
return true;
}
Hex hex = game.getBoard().getHex(c);
- // Taharqa: waiting to hear back from Welshie but I am going to assume
- // that units pulling artillery
- // should be treated as wheeled rather than motorized because otherwise
- // mechanized units face fewer
+ // Taharqa: waiting to hear back from Welshie but I am going to assume that units pulling artillery
+ // should be treated as wheeled rather than motorized because otherwise mechanized units face fewer
// terrain restrictions when pulling field artillery
if (hex.containsTerrain(Terrains.IMPASSABLE)) {
@@ -569,15 +476,12 @@ public boolean isLocationProhibited(Coords c, int currElevation) {
// Additional restrictions for hidden units
if (isHidden()) {
// Can't deploy in paved hexes
- if ((hex.containsTerrain(Terrains.PAVEMENT)
- || hex.containsTerrain(Terrains.ROAD))
- && (!hex.containsTerrain(Terrains.BUILDING)
- && !hex.containsTerrain(Terrains.RUBBLE))) {
+ if ((hex.containsTerrain(Terrains.PAVEMENT) || hex.containsTerrain(Terrains.ROAD))
+ && (!hex.containsTerrain(Terrains.BUILDING) && !hex.containsTerrain(Terrains.RUBBLE))) {
return true;
}
// Can't deploy on a bridge
- if ((hex.terrainLevel(Terrains.BRIDGE_ELEV) == currElevation)
- && hex.containsTerrain(Terrains.BRIDGE)) {
+ if ((hex.terrainLevel(Terrains.BRIDGE_ELEV) == currElevation) && hex.containsTerrain(Terrains.BRIDGE)) {
return true;
}
// Can't deploy on the surface of water
@@ -590,7 +494,7 @@ public boolean isLocationProhibited(Coords c, int currElevation) {
return true;
}
- if (getMovementMode() == EntityMovementMode.WHEELED) {
+ if (getMovementMode().isWheeled()) {
if (hex.containsTerrain(Terrains.WOODS)
|| hex.containsTerrain(Terrains.ROUGH)
|| hex.containsTerrain(Terrains.RUBBLE)
@@ -601,7 +505,7 @@ public boolean isLocationProhibited(Coords c, int currElevation) {
}
}
- if (getMovementMode() == EntityMovementMode.TRACKED) {
+ if (getMovementMode().isTracked()) {
if ((hex.terrainLevel(Terrains.WOODS) > 1)
|| hex.containsTerrain(Terrains.JUNGLE)
|| (hex.terrainLevel(Terrains.ROUGH) > 1)
@@ -610,7 +514,7 @@ public boolean isLocationProhibited(Coords c, int currElevation) {
}
}
- if (getMovementMode() == EntityMovementMode.HOVER) {
+ if (getMovementMode().isHover()) {
if (hex.containsTerrain(Terrains.WOODS)
|| hex.containsTerrain(Terrains.JUNGLE)
|| (hex.terrainLevel(Terrains.ROUGH) > 1)
@@ -619,27 +523,17 @@ public boolean isLocationProhibited(Coords c, int currElevation) {
}
}
- if (hex.terrainLevel(Terrains.WATER) <= 0
- && getMovementMode() == EntityMovementMode.SUBMARINE) {
+ if ((hex.terrainLevel(Terrains.WATER) <= 0) && getMovementMode().isSubmarine()) {
return true;
}
- if ((hex.terrainLevel(Terrains.WATER) > 0)
- && !hex.containsTerrain(Terrains.ICE)) {
- if ((getMovementMode() == EntityMovementMode.HOVER)
- || (getMovementMode() == EntityMovementMode.INF_UMU)
- || (getMovementMode() == EntityMovementMode.SUBMARINE)
- || (getMovementMode() == EntityMovementMode.VTOL)) {
- return false;
- }
- return true;
+ if ((hex.terrainLevel(Terrains.WATER) > 0) && !hex.containsTerrain(Terrains.ICE)) {
+ return !getMovementMode().isHover() && !getMovementMode().isUMUInfantry()
+ && !getMovementMode().isSubmarine() && !getMovementMode().isVTOL();
}
return false;
}
- /**
- * Returns the name of the type of movement used. This is Infantry-specific.
- */
@Override
public String getMovementString(EntityMovementType mtype) {
switch (mtype) {
@@ -670,10 +564,6 @@ public String getMovementString(EntityMovementType mtype) {
}
}
- /**
- * Returns the abbreviation of the type of movement used. This is
- * Infantry-specific.
- */
@Override
public String getMovementAbbr(EntityMovementType mtype) {
switch (mtype) {
@@ -701,12 +591,8 @@ public String getMovementAbbr(EntityMovementType mtype) {
}
}
- /**
- * Infantry only have one hit location.
- */
@Override
- public HitData rollHitLocation(int table, int side, int aimedLocation, AimingMode aimingMode,
- int cover) {
+ public HitData rollHitLocation(int table, int side, int aimedLocation, AimingMode aimingMode, int cover) {
return rollHitLocation(table, side);
}
@@ -715,170 +601,115 @@ public HitData rollHitLocation(int table, int side) {
return new HitData(LOC_INFANTRY);
}
- /**
- * Infantry only have one hit location.
- */
@Override
public HitData getTransferLocation(HitData hit) {
return new HitData(Entity.LOC_DESTROYED);
}
- /**
- * Gets the location that is destroyed recursively.
- */
@Override
public int getDependentLocation(int loc) {
return Entity.LOC_NONE;
}
- /**
- * Infantry have no rear armor.
- */
@Override
public boolean hasRearArmor(int loc) {
return false;
}
- /**
- * Infantry platoons do wierd and wacky things with armor and internals, but
- * not all Infantry objects are platoons.
- *
- * @see megamek.common.BattleArmor#isPlatoon()
- */
- protected boolean isPlatoon() {
- return true;
- }
-
- /**
- * Returns the number of men left in the platoon, or
- * IArmorState.ARMOR_DESTROYED.
- */
@Override
public int getInternal(int loc) {
- if (!isPlatoon()) {
+ if (!isConventionalInfantry()) {
return super.getInternal(loc);
}
if (loc != LOC_INFANTRY) {
return 0;
}
- return (men > 0 ? men : IArmorState.ARMOR_DESTROYED);
+ return (activeTroopers > 0 ? activeTroopers : IArmorState.ARMOR_DESTROYED);
}
- /**
- * Returns the number of men originally the platoon.
- */
@Override
public int getOInternal(int loc) {
- if (!isPlatoon()) {
- return super.getOInternal(loc);
- }
- return menStarting;
+ return isConventionalInfantry() ? originalTrooperCount : super.getOInternal(loc);
}
- /**
- * Sets the amount of men remaining in the platoon.
- */
@Override
public void setInternal(int val, int loc) {
super.setInternal(val, loc);
if (loc == LOC_INFANTRY) {
- men = val;
- damageFieldGunsAndArty();
+ activeTroopers = Math.max(val, 0);
+ damageFieldWeapons();
}
}
/**
- * Returns the percent of the men remaining in the platoon.
+ * Returns the percent of the troopers remaining in the platoon.
*/
@Override
public double getInternalRemainingPercent() {
- if (!isPlatoon()) {
+ if (isConventionalInfantry()) {
+ return (double) Math.max(activeTroopers, 0) / originalTrooperCount;
+ } else {
return super.getInternalRemainingPercent();
}
- int menTotal = men > 0 ? men : 0; // Handle "DESTROYED"
- return ((double) menTotal / menStarting);
}
/**
- * Initializes the number of men in the platoon. Sets the original and
+ * Initializes the number of troopers in the platoon. Sets the original and
* starting point of the platoon to the same number.
*/
@Override
public void initializeInternal(int val, int loc) {
if (loc == LOC_INFANTRY) {
- menStarting = val;
- menShooting = val;
+ originalTrooperCount = val;
+ troopersShooting = val;
}
super.initializeInternal(val, loc);
}
@Override
public void autoSetInternal() {
- initializeInternal(squadsize * squadn, LOC_INFANTRY);
+ initializeInternal(squadSize * squadCount, LOC_INFANTRY);
}
- /**
- * Infantry can fire all around themselves. But field guns are set up to a
- * vehicular turret facing
- */
@Override
public int getWeaponArc(int wn) {
- Mounted mounted = getEquipment(wn);
- if (mounted.getLocation() == LOC_FIELD_GUNS) {
+ Mounted weapon = getEquipment(wn);
+ // Infantry can fire all around themselves. But field guns are set up to a vehicular turret facing
+ if (isFieldWeapon(weapon)) {
if (game.getOptions().booleanOption(OptionsConstants.ADVCOMBAT_TACOPS_VEHICLE_ARCS)) {
return Compute.ARC_TURRET;
}
return Compute.ARC_FORWARD;
}
- //This is interesting, according to TacOps rules, Dug in units no longer
- //have to declare a facing
+ // According to TacOps rules, dug-in units no longer have to declare a facing
return Compute.ARC_360;
}
- /**
- * Infantry can fire all around themselves. But field guns act like turret
- * mounted on a tank
- */
@Override
public boolean isSecondaryArcWeapon(int wn) {
- return (getEquipment(wn).getLocation() == LOC_FIELD_GUNS) && !hasActiveFieldArtillery();
+ return isFieldWeapon((getEquipment(wn))) && !hasActiveFieldArtillery();
}
- /**
- * Infantry build no heat.
- */
@Override
public int getHeatCapacity(boolean radicalHeatSinks) {
return DOES_NOT_TRACK_HEAT;
}
- /**
- * Infantry build no heat.
- */
@Override
public int getHeatCapacityWithWater() {
return getHeatCapacity();
}
- /**
- * Infantry build no heat.
- */
@Override
public int getEngineCritHeat() {
return 0;
}
- /**
- * Infantry have no critical slots.
- */
@Override
protected int[] getNoOfSlots() {
return NUM_OF_SLOTS;
}
- /**
- * Infantry criticals can't be hit.
- */
public boolean hasHittableCriticals(int loc) {
return false;
}
@@ -925,30 +756,20 @@ public Vector Sub-classes
- * are encouraged to override this method.
- *
- * @param range - an range
is not one of the
- * Entity
class range constants, an
- * IllegalArgumentException
will be thrown. int
value that must match one of the
- * Compute
class range constants.
- * @param ae - the entity making the attack.
- * @return a TargetRoll
value that contains the stealth
- * modifier for the given range.
- */
@Override
public TargetRoll getStealthModifier(int range, Entity ae) {
TargetRoll result = null;
- // Note: infantry are immune to stealth, but not camoflage
- // or mimetic armor
-
- if ((sneak_ir || dest)
- && !(ae instanceof Infantry)) {
+ // Note: infantry are immune to stealth, but not camoflage or mimetic armor
+ if ((sneak_ir || dest) && !(ae instanceof Infantry)) {
switch (range) {
case RangeType.RANGE_MINIMUM:
case RangeType.RANGE_SHORT:
@@ -1616,8 +1374,7 @@ public TargetRoll getStealthModifier(int range, Entity ae) {
case RangeType.RANGE_OUT:
break;
default:
- throw new IllegalArgumentException(
- "Unknown range constant: " + range);
+ throw new IllegalArgumentException("Unknown range constant: " + range);
}
}
@@ -1640,52 +1397,45 @@ public TargetRoll getStealthModifier(int range, Entity ae) {
}
}
-
if (result == null) {
result = new TargetRoll(0, "no sneak mods");
}
- // Return the result.
return result;
- } // End public TargetRoll getStealthModifier( char )
+ }
- /**
- * Determines if the infantry has any type of stealth system.
- *
- * @return
- */
+ /** @return True if this infantry has any type of stealth system. */
public boolean isStealthy() {
- return dest || sneak_camo || sneak_ir || sneak_ecm;
+ return dest || sneak_camo || sneak_ir || sneak_ecm;
}
public boolean hasMicrolite() {
- return microlite;
+ return isMicrolite;
}
public void setMicrolite(boolean microlite) {
- this.microlite = microlite;
+ this.isMicrolite = microlite;
}
/**
- * Used to check for standard or motorized SCUBA infantry, which have a maximum
- * depth of 2.
+ * Used to check for standard or motorized SCUBA infantry, which have a maximum depth of 2.
* @return true if this is a conventional infantry unit with non-mechanized SCUBA specialization
*/
public boolean isNonMechSCUBA() {
- return isConventionalInfantry() && (getMovementMode() == EntityMovementMode.INF_UMU);
+ return isConventionalInfantry() && getMovementMode().isUMUInfantry();
}
public void setPrimaryWeapon(InfantryWeapon w) {
- primaryW = w;
+ primaryWeapon = w;
primaryName = w.getName();
}
public InfantryWeapon getPrimaryWeapon() {
- return primaryW;
+ return primaryWeapon;
}
public void setSecondaryWeapon(InfantryWeapon w) {
- secondW = w;
+ secondaryWeapon = w;
if (null == w) {
secondName = null;
} else {
@@ -1694,45 +1444,45 @@ public void setSecondaryWeapon(InfantryWeapon w) {
}
public InfantryWeapon getSecondaryWeapon() {
- return secondW;
+ return secondaryWeapon;
}
public void setSquadSize(int size) {
- squadsize = size;
+ squadSize = size;
}
public int getSquadSize() {
- return squadsize;
+ return squadSize;
}
- public void setSquadN(int n) {
- squadn = n;
+ public void setSquadCount(int n) {
+ squadCount = n;
}
- public int getSquadN() {
- return squadn;
+ public int getSquadCount() {
+ return squadCount;
}
- public void setSecondaryN(int n) {
- secondn = n;
+ public void setSecondaryWeaponsPerSquad(int n) {
+ secondaryWeaponsPerSquad = n;
}
- public int getSecondaryN() {
- return secondn;
+ public int getSecondaryWeaponsPerSquad() {
+ return secondaryWeaponsPerSquad;
}
public double getDamagePerTrooper() {
- if (null == primaryW) {
+ if (null == primaryWeapon) {
return 0;
}
// per 09/2021 errata, primary infantry weapon damage caps out at 0.6
- double adjustedDamage = Math.min(MMConstants.INFANTRY_PRIMARY_WEAPON_DAMAGE_CAP, primaryW.getInfantryDamage());
- double damage = adjustedDamage * (squadsize - secondn);
- if (null != secondW) {
- damage += secondW.getInfantryDamage() * secondn;
+ double adjustedDamage = Math.min(MMConstants.INFANTRY_PRIMARY_WEAPON_DAMAGE_CAP, primaryWeapon.getInfantryDamage());
+ double damage = adjustedDamage * (squadSize - secondaryWeaponsPerSquad);
+ if (null != secondaryWeapon) {
+ damage += secondaryWeapon.getInfantryDamage() * secondaryWeaponsPerSquad;
}
- return damage/squadsize;
+ return damage / squadSize;
}
public boolean primaryWeaponDamageCapped() {
@@ -1740,20 +1490,13 @@ public boolean primaryWeaponDamageCapped() {
}
public double getPrimaryWeaponDamage() {
- if (null == primaryW) {
- return 0;
- }
-
- return primaryW.getInfantryDamage();
+ return (primaryWeapon != null) ? primaryWeapon.getInfantryDamage() : 0;
}
public boolean isSquad() {
- return (squadn == 1);
+ return squadCount == 1;
}
- /**
- * Set the movement type of the entity
- */
@Override
public void setMovementMode(EntityMovementMode movementMode) {
super.setMovementMode(movementMode);
@@ -1762,14 +1505,12 @@ public void setMovementMode(EntityMovementMode movementMode) {
setOriginalJumpMP(0);
switch (getMovementMode()) {
case INF_MOTORIZED:
+ case TRACKED:
setOriginalWalkMP(3);
break;
case HOVER:
setOriginalWalkMP(5);
break;
- case TRACKED:
- setOriginalWalkMP(3);
- break;
case WHEELED:
setOriginalWalkMP(4);
break;
@@ -1806,8 +1547,7 @@ public void setMovementMode(EntityMovementMode movementMode) {
/**
* Standard and motorized SCUBA only differ in base movement, so they both use
- * INF_UMU. If the motion_type contains the string "motorized",
- * the movement is set here instead.
+ * INF_UMU. If the motion_type contains the string "motorized", the movement is set here instead.
*/
public void setMotorizedScuba() {
setMovementMode(EntityMovementMode.INF_UMU);
@@ -1817,10 +1557,10 @@ public void setMotorizedScuba() {
@Override
public String getMovementModeAsString() {
if (!hasETypeFlag(Entity.ETYPE_BATTLEARMOR)) {
- if (getMovementMode().equals(EntityMovementMode.VTOL)) {
+ if (getMovementMode().isVTOL()) {
return hasMicrolite() ? "Microlite" : "Microcopter";
}
- if (getMovementMode() == EntityMovementMode.INF_UMU) {
+ if (getMovementMode().isUMUInfantry()) {
return getOriginalJumpMP() > 1 ? "Motorized SCUBA" : "SCUBA";
}
}
@@ -1834,7 +1574,7 @@ public String getMovementModeAsString() {
* but has a fixed 8 AM skill rating.
*/
public boolean canMakeAntiMekAttacks() {
- return !isMechanized() && !isArmorEncumbering() && !hasActiveFieldGun();
+ return !isMechanized() && !isArmorEncumbering() && !hasActiveFieldWeapon();
}
@Override
@@ -1850,16 +1590,16 @@ public double getWeight() {
mult = 1.0;
break;
case VTOL:
- mult = (hasMicrolite() ? 1.4 : 1.9);
+ mult = hasMicrolite() ? 1.4 : 1.9;
break;
case INF_JUMP:
mult = 0.165;
break;
case INF_UMU:
if (getActiveUMUCount() > 1) {
- mult = 0.295; //motorized + 0.1 for motorized scuba
+ mult = 0.295; // motorized + 0.1 for motorized scuba
} else {
- mult = 0.135; //foot + 0.05 for scuba
+ mult = 0.135; // foot + 0.05 for scuba
}
break;
case SUBMARINE:
@@ -1886,14 +1626,8 @@ public double getWeight() {
mult +=.015;
}
- double ton = men * mult;
-
- // Add field gun weight
- ton += getEquipment().stream()
- .filter(e -> e.getLocation() == LOC_FIELD_GUNS)
- .filter(e -> !e.isDestroyed())
- .mapToDouble(Mounted::getTonnage).sum();
-
+ double ton = activeTroopers * mult;
+ ton += activeFieldWeapons().stream().mapToDouble(Mounted::getTonnage).sum();
return RoundWeight.nearestHalfTon(ton);
}
@@ -1912,9 +1646,7 @@ public String getArmorDesc() {
sArmor.append(" (DEST) ");
}
- if (hasSneakCamo() ||
- (getCrew() != null
- && hasAbility(OptionsConstants.MD_DERMAL_CAMO_ARMOR))) {
+ if (hasSneakCamo() || (getCrew() != null && hasAbility(OptionsConstants.MD_DERMAL_CAMO_ARMOR))) {
sArmor.append(" (Camo) ");
}
@@ -1929,33 +1661,26 @@ && hasAbility(OptionsConstants.MD_DERMAL_CAMO_ARMOR))) {
return sArmor.toString();
}
- /**
- * Restores the entity after serialization
- */
@Override
public void restore() {
super.restore();
if (null != primaryName) {
- primaryW = (InfantryWeapon) EquipmentType.get(primaryName);
+ primaryWeapon = (InfantryWeapon) EquipmentType.get(primaryName);
}
if (null != secondName) {
- secondW = (InfantryWeapon) EquipmentType.get(secondName);
+ secondaryWeapon = (InfantryWeapon) EquipmentType.get(secondName);
}
}
/** @return True if this infantry has a field artillery weapon that is not destroyed. */
public boolean hasActiveFieldArtillery() {
- return getWeaponList().stream()
- .filter(weapon -> weapon.getLocation() == LOC_FIELD_GUNS)
- .filter(weapon -> weapon.getType().hasFlag(WeaponType.F_ARTILLERY))
- .anyMatch(weapon -> !weapon.isDestroyed());
+ return activeFieldWeapons().stream().anyMatch(gun -> gun.getType().hasFlag(WeaponType.F_ARTILLERY));
}
/**
- * Infantry don't use MP to change facing, and don't
- * do PSRs, so just don't let them use maneuvering ace
+ * Infantry don't use MP to change facing, and don't do PSRs, so just don't let them use maneuvering ace
* otherwise, their movement gets screwed up
*/
@Override
@@ -2005,14 +1730,14 @@ public boolean isDmgLight() {
return (((double) getInternal(LOC_INFANTRY) / getOInternal(LOC_INFANTRY)) < 0.9);
}
- /** @return True if this infantry has any field gun (destroyed or not). */
- public boolean hasFieldGun() {
- return getWeaponList().stream().anyMatch(m -> m.getLocation() == LOC_FIELD_GUNS);
+ /** @return True if this infantry has any field gun or artillery (destroyed or not). */
+ public boolean hasFieldWeapon() {
+ return !originalFieldWeapons().isEmpty();
}
- /** @return True if this infantry has any working (not destroyed) field gun. */
- public boolean hasActiveFieldGun() {
- return getWeaponList().stream().filter(m -> !m.isDestroyed()).anyMatch(m -> m.getLocation() == LOC_FIELD_GUNS);
+ /** @return True if this infantry has any working (not destroyed) field gun or artillery. */
+ public boolean hasActiveFieldWeapon() {
+ return !activeFieldWeapons().isEmpty();
}
@Override
@@ -2020,18 +1745,11 @@ public boolean hasEngine() {
return false;
}
- /**
- * Mounts the specified equipment in the specified location.
- */
@Override
public void addEquipment(Mounted mounted, int loc, boolean rearMounted) throws LocationFullException {
- // Implement parent's behavior.
super.addEquipment(mounted, loc, rearMounted);
-
- //we do need to equipment slots for ammo switching of field guns and field artillery
- // Add the piece equipment to our slots.
+ // Add equipment slots for ammo switching of field guns and field artillery
addCritical(loc, new CriticalSlot(mounted));
-
}
@Override
@@ -2045,11 +1763,9 @@ public long getEntityType() {
}
@Override
- public PilotingRollData checkLandingInHeavyWoods(
- EntityMovementType overallMoveType, Hex curHex) {
+ public PilotingRollData checkLandingInHeavyWoods(EntityMovementType overallMoveType, Hex curHex) {
PilotingRollData roll = getBasePilotingRoll(overallMoveType);
- roll.addModifier(TargetRoll.CHECK_FALSE,
- "Infantry cannot fall");
+ roll.addModifier(TargetRoll.CHECK_FALSE, "Infantry cannot fall");
return roll;
}
@@ -2057,9 +1773,9 @@ public PilotingRollData checkLandingInHeavyWoods(
* Determines if there is valid cover for an infantry unit to utilize the
* Using Non-Infantry as Cover rules (TO pg 108).
* @param game The current {@link Game}
- * @param pos
- * @param elevation
- * @return
+ * @param pos The hex coords
+ * @param elevation The elevation (flying or in building)
+ * @return True when this infantry has valid conver
*/
public static boolean hasValidCover(Game game, Coords pos, int elevation) {
// Can't do anything if we don't have a position
@@ -2071,8 +1787,7 @@ public static boolean hasValidCover(Game game, Coords pos, int elevation) {
boolean hasMovedEntity = false;
// First, look for ground untis in the same hex that have already moved
for (Entity e : game.getEntitiesVector(pos)) {
- if (e.isDone() && !(e instanceof Infantry)
- && (e.getElevation() == elevation)) {
+ if (e.isDone() && !(e instanceof Infantry) && (e.getElevation() == elevation)) {
hasMovedEntity = true;
break;
}
@@ -2083,8 +1798,7 @@ public static boolean hasValidCover(Game game, Coords pos, int elevation) {
Enumeration