diff --git a/megamek/src/megamek/client/bot/PhysicalCalculator.java b/megamek/src/megamek/client/bot/PhysicalCalculator.java index e45cded44f3..9691d794261 100644 --- a/megamek/src/megamek/client/bot/PhysicalCalculator.java +++ b/megamek/src/megamek/client/bot/PhysicalCalculator.java @@ -40,6 +40,7 @@ import megamek.common.actions.KickAttackAction; import megamek.common.actions.PunchAttackAction; import megamek.common.actions.PushAttackAction; +import megamek.common.equipment.MiscMounted; import megamek.common.options.OptionsConstants; public final class PhysicalCalculator { @@ -313,7 +314,7 @@ static PhysicalOption getBestPhysicalAttack(Entity from, Entity to, int target_arc; int location_table; int bestType = PhysicalOption.NONE; - Mounted bestClub = null; + MiscMounted bestClub = null; boolean targetConvInfantry = false; boolean fromAptPiloting = from.hasAbility(OptionsConstants.PILOT_APTITUDE_PILOTING); boolean toAptPiloting = to.hasAbility(OptionsConstants.PILOT_APTITUDE_PILOTING); @@ -425,7 +426,7 @@ static PhysicalOption getBestPhysicalAttack(Entity from, Entity to, } // Check for mounted club-type weapon or carried improvised club - for (Mounted club : from.getClubs()) { + for (MiscMounted club : from.getClubs()) { // If the target is a Mech, must determine if it hits full body, // punch, or kick table if (to instanceof Mech) { diff --git a/megamek/src/megamek/client/bot/PhysicalOption.java b/megamek/src/megamek/client/bot/PhysicalOption.java index f27ce3ff581..1168efa5fa1 100644 --- a/megamek/src/megamek/client/bot/PhysicalOption.java +++ b/megamek/src/megamek/client/bot/PhysicalOption.java @@ -28,6 +28,7 @@ import megamek.common.actions.KickAttackAction; import megamek.common.actions.PunchAttackAction; import megamek.common.actions.PushAttackAction; +import megamek.common.equipment.MiscMounted; /** * TODO: add more options, pushing, kick both for quad mechs, etc. @@ -59,7 +60,7 @@ public class PhysicalOption { INarcPod i_target; double expectedDmg; int type; - Mounted club; + MiscMounted club; public PhysicalOption(Entity attacker) { this.attacker = attacker; @@ -67,7 +68,7 @@ public PhysicalOption(Entity attacker) { } public PhysicalOption(Entity attacker, Targetable target, double dmg, - int type, Mounted club) { + int type, MiscMounted club) { this.attacker = attacker; this.target = target; diff --git a/megamek/src/megamek/client/bot/princess/ArtilleryTargetingControl.java b/megamek/src/megamek/client/bot/princess/ArtilleryTargetingControl.java index ab04886db85..edfb3010445 100644 --- a/megamek/src/megamek/client/bot/princess/ArtilleryTargetingControl.java +++ b/megamek/src/megamek/client/bot/princess/ArtilleryTargetingControl.java @@ -18,6 +18,8 @@ import megamek.common.*; import megamek.common.actions.ArtilleryAttackAction; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.OptionsConstants; /** @@ -192,9 +194,9 @@ public void initializeForTargetingPhase() { private boolean getAmmoTypeAvailable(Entity shooter, AmmoType.Munitions mtype) { boolean available = false; - for (Mounted weapon: shooter.getWeaponList()){ + for (WeaponMounted weapon: shooter.getWeaponList()){ if (weapon.getType().hasFlag(WeaponType.F_ARTILLERY)){ - for (Mounted ammo: shooter.getAmmo(weapon)) { + for (AmmoMounted ammo: shooter.getAmmo(weapon)) { if (((AmmoType) ammo.getType()).getMunitionType().contains(mtype) && !weapon.isFired() && ammo.getUsableShotsLeft() > 0) { available = true; @@ -367,19 +369,19 @@ private FiringPlan calculateIndirectArtilleryPlan(Entity shooter, Game game, Pri // or we have a 1+ top valued coordinates. // Track ADA WFIs separately. List topValuedADAInfos = new ArrayList<>(); - for (Mounted currentWeapon : shooter.getWeaponList()) { + for (WeaponMounted currentWeapon : shooter.getWeaponList()) { List topValuedFireInfos = new ArrayList<>(); double maxDamage = 0; if (currentWeapon.getType().hasFlag(WeaponType.F_ARTILLERY)) { - WeaponType wType = (WeaponType) currentWeapon.getType(); + WeaponType wType = currentWeapon.getType(); int damage = wType.getRackSize(); // crazy, but rack size appears to correspond to given damage values for arty pieces in tacops // Iterate over all loaded Artillery ammo so we can compare various options - for (final Mounted ammo : shooter.getAmmo(currentWeapon)) { + for (final AmmoMounted ammo : shooter.getAmmo(currentWeapon)) { // for each enemy unit, evaluate damage value of firing at its hex. // keep track of top target hexes with the same value and fire at them - boolean isADA = ((AmmoType) ammo.getType()).getMunitionType().contains(AmmoType.Munitions.M_ADA); - boolean isSmoke = ((AmmoType) ammo.getType()).getMunitionType().contains(AmmoType.Munitions.M_SMOKE); + boolean isADA = ammo.getType().getMunitionType().contains(AmmoType.Munitions.M_ADA); + boolean isSmoke = ammo.getType().getMunitionType().contains(AmmoType.Munitions.M_SMOKE); for (Targetable target : targetSet) { WeaponFireInfo wfi; double damageValue = 0.0; @@ -499,7 +501,7 @@ private FiringPlan calculateIndirectArtilleryPlan(Entity shooter, Game game, Pri * @param owner * @return */ - private WeaponFireInfo getTAGInfo(Mounted weapon, Entity shooter, Game game, Princess owner) { + private WeaponFireInfo getTAGInfo(WeaponMounted weapon, Entity shooter, Game game, Princess owner) { WeaponFireInfo retval = null; double hitOdds = 0.0; diff --git a/megamek/src/megamek/client/bot/princess/FireControl.java b/megamek/src/megamek/client/bot/princess/FireControl.java index 36973039424..89f1647f9c1 100644 --- a/megamek/src/megamek/client/bot/princess/FireControl.java +++ b/megamek/src/megamek/client/bot/princess/FireControl.java @@ -17,6 +17,9 @@ import megamek.common.actions.*; import megamek.common.annotations.Nullable; import megamek.common.annotations.StaticWrapper; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.BombMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.OptionsConstants; import megamek.common.pathfinder.AeroGroundPathFinder; import megamek.common.planetaryconditions.IlluminationLevel; @@ -645,8 +648,8 @@ ToHitData guessToHitModifierForWeapon(final Entity shooter, @Nullable EntityState shooterState, final Targetable target, @Nullable EntityState targetState, - final Mounted weapon, - @Nullable final Mounted ammo, + final WeaponMounted weapon, + @Nullable final AmmoMounted ammo, final Game game) { if (null == shooterState) { @@ -663,10 +666,10 @@ ToHitData guessToHitModifierForWeapon(final Entity shooter, // Make sure we have ammo. final WeaponType weaponType = (WeaponType) weapon.getType(); - final Mounted firingAmmo; + final AmmoMounted firingAmmo; if (AmmoType.T_NA != weaponType.getAmmoType()) { // Use ammo arg if provided, else use linked ammo. - firingAmmo = (ammo == null) ? weapon.getLinked() : ammo; + firingAmmo = (ammo == null) ? weapon.getLinkedAmmo() : ammo; if (null == firingAmmo) { return new ToHitData(TH_WEAP_NO_AMMO); } @@ -701,7 +704,7 @@ ToHitData guessToHitModifierForWeapon(final Entity shooter, } // Bays compute arc differently final boolean inArc = (bayWeapon) - ? Compute.isInArc(game, shooter.getId(), weapon.getBayWeapons().get(0), target) + ? Compute.isInArc(game, shooter.getId(), (int) weapon.getBayWeapons().get(0), target) : isInArc(shooterState.getPosition(), shooterFacing, targetState.getPosition(), shooter.getWeaponArc(shooter.getEquipmentNum(weapon))); if (!inArc) { @@ -1023,8 +1026,8 @@ ToHitData guessAirToGroundStrikeToHitModifier(final Entity shooter, final Targetable target, @Nullable EntityState targetState, final MovePath flightPath, - final Mounted weapon, - @Nullable final Mounted ammo, + final WeaponMounted weapon, + @Nullable final AmmoMounted ammo, final Game game, final boolean assumeUnderFlightPlan) { @@ -1041,7 +1044,7 @@ ToHitData guessAirToGroundStrikeToHitModifier(final Entity shooter, } // Is the weapon loaded? - Mounted firingAmmo = (ammo == null) ? weapon.getLinked() : ammo; + AmmoMounted firingAmmo = (ammo == null) ? weapon.getLinkedAmmo() : ammo; if (AmmoType.T_NA != ((WeaponType) weapon.getType()).ammoType) { if (null == firingAmmo) { return new ToHitData(TH_WEAP_NO_AMMO); @@ -1104,8 +1107,8 @@ boolean isTargetUnderFlightPath(final MovePath flightPath, */ private String checkGuess(final Entity shooter, final Targetable target, - final Mounted weapon, - final Mounted ammo, + final WeaponMounted weapon, + final AmmoMounted ammo, final Game game) { // This really should only be done for debugging purposes. Regular play should avoid the overhead. @@ -1197,8 +1200,8 @@ private String checkGuess(final Entity shooter, final StringBuilder ret = new StringBuilder(); final List enemies = getTargetableEnemyEntities(shooter, game, owner.getFireControlState()); for (final Targetable enemy : enemies) { - for (final Mounted weapon : shooter.getWeaponList()) { - final WeaponType wtype = (WeaponType) weapon.getType(); + for (final WeaponMounted weapon : shooter.getWeaponList()) { + final WeaponType wtype = weapon.getType(); String shootingCheck; // Energy / ammo-independent weapons @@ -1209,16 +1212,16 @@ private String checkGuess(final Entity shooter, } } else { // For certain weapon types, look over all their loaded ammos - ArrayList ammos; + List ammos; if (wtype.getAmmoType() == AmmoType.T_ATM || wtype.getAmmoType() == AmmoType.T_MML) { ammos = shooter.getAmmo(weapon); } else { // Otherwise assume the current loaded ammo is suitable representative - ammos = new ArrayList(); - ammos.add(weapon.getLinked()); + ammos = new ArrayList<>(); + ammos.add(weapon.getLinkedAmmo()); } - for (Mounted ammo: ammos) { + for (AmmoMounted ammo: ammos) { shootingCheck = checkGuess(shooter, enemy, weapon, ammo, game); if (null != shootingCheck) { ret.append(shootingCheck); @@ -1499,8 +1502,8 @@ WeaponFireInfo buildWeaponFireInfo(final Entity shooter, final EntityState shooterState, final Targetable target, final EntityState targetState, - final Mounted weapon, - final Mounted ammo, + final WeaponMounted weapon, + final AmmoMounted ammo, final Game game, final boolean guessToHit) { return new WeaponFireInfo(shooter, shooterState, target, targetState, @@ -1525,8 +1528,8 @@ WeaponFireInfo buildWeaponFireInfo(final Entity shooter, final MovePath flightPath, final Targetable target, final EntityState targetState, - final Mounted weapon, - final Mounted ammo, + final WeaponMounted weapon, + final AmmoMounted ammo, final Game game, final boolean assumeUnderFlightPath, final boolean guessToHit) { @@ -1546,15 +1549,15 @@ WeaponFireInfo buildWeaponFireInfo(final Entity shooter, * @param assumeUnderFlightPath Set TRUE to assume the target is under the flight path and avoid * doing the full calculation. * @param guessToHit Set TRUE to estimate the odds to hit rather than doing the full calculation. - * @param bombPayload The bomb payload, as described in WeaponAttackAction.setBombPayload + * @param bombPayloads The bomb payload, as described in WeaponAttackAction.setBombPayload * @return The resulting {@link WeaponFireInfo}. */ private WeaponFireInfo buildWeaponFireInfo(final Entity shooter, final MovePath flightPath, final Targetable target, @SuppressWarnings("SameParameterValue") final EntityState targetState, - final Mounted weapon, - final Mounted ammo, + final WeaponMounted weapon, + final AmmoMounted ammo, final Game game, final boolean assumeUnderFlightPath, final boolean guessToHit, @@ -1575,8 +1578,8 @@ private WeaponFireInfo buildWeaponFireInfo(final Entity shooter, */ WeaponFireInfo buildWeaponFireInfo(final Entity shooter, final Targetable target, - final Mounted weapon, - final Mounted ammo, + final WeaponMounted weapon, + final AmmoMounted ammo, final Game game, final boolean guessToHit) { return new WeaponFireInfo(shooter, target, weapon, ammo, game, guessToHit, owner); @@ -1641,7 +1644,7 @@ FiringPlan guessFullFiringPlan(final Entity shooter, } // cycle through my weapons - for (final Mounted weapon : shooter.getWeaponList()) { + for (final WeaponMounted weapon : shooter.getWeaponList()) { // respect restriction on manual AMS firing. if (!game.getOptions().booleanOption(OptionsConstants.ADVCOMBAT_TACOPS_MANUAL_AMS) && weapon.getType().hasFlag(WeaponType.F_AMS)) { @@ -1657,17 +1660,17 @@ FiringPlan guessFullFiringPlan(final Entity shooter, bestShoot = buildWeaponFireInfo(shooter, target, weapon, null, game, true); } else { // For certain weapon types, look over all their loaded ammos - ArrayList ammos; + List ammos; if (wtype.getAmmoType() == AmmoType.T_ATM || wtype.getAmmoType() == AmmoType.T_MML) { ammos = shooter.getAmmo(weapon); } else { // Otherwise assume the current loaded ammo is suitable representative - ammos = new ArrayList(); - ammos.add(weapon.getLinked()); + ammos = new ArrayList<>(); + ammos.add(weapon.getLinkedAmmo()); } WeaponFireInfo shoot; - for (Mounted ammo: ammos) { + for (AmmoMounted ammo: ammos) { shoot = buildWeaponFireInfo(shooter, shooterState, target, @@ -1696,7 +1699,7 @@ FiringPlan guessFullFiringPlan(final Entity shooter, if (shoot.getAmmo() != null && bestShoot != null) { bestShoot.getAmmo().setSwitchedReason( - (bestShoot.getAmmo() == weapon.getLinked()) ? 0 : switchedReason + (bestShoot.getAmmo() == weapon.getLinkedAmmo()) ? 0 : switchedReason ); } } @@ -1791,7 +1794,7 @@ FiringPlan guessFullAirToGroundPlan(final Entity shooter, } // cycle through my weapons - for (final Mounted weapon : shooter.getWeaponList()) { + for (final WeaponMounted weapon : shooter.getWeaponList()) { // bombing attacks have to be carried out separately from other weapon attacks, so we handle them in a special case if (weapon.isGroundBomb()) { continue; @@ -1806,17 +1809,17 @@ FiringPlan guessFullAirToGroundPlan(final Entity shooter, bestShoot = buildWeaponFireInfo(shooter, target, weapon, null, game, false); } else { // For certain weapon types, look over all their loaded ammos - ArrayList ammos; + List ammos; if (wtype.getAmmoType() == AmmoType.T_ATM || wtype.getAmmoType() == AmmoType.T_MML) { ammos = shooter.getAmmo(weapon); } else { // Otherwise assume the current loaded ammo is suitable representative - ammos = new ArrayList(); - ammos.add(weapon.getLinked()); + ammos = new ArrayList<>(); + ammos.add(weapon.getLinkedAmmo()); } WeaponFireInfo shoot; - for (Mounted ammo: ammos) { + for (AmmoMounted ammo: ammos) { shoot = buildWeaponFireInfo(shooter, flightPath, @@ -1882,7 +1885,7 @@ private FiringPlan getDiveBombPlan(final Entity shooter, // things that cause us to avoid calculating a bomb plan: // not having any bombs (in the first place) - final Iterator weaponIter = shooter.getWeapons(); + final Iterator weaponIter = shooter.getWeapons(); if (null == weaponIter) { return diveBombPlan; } @@ -1893,7 +1896,7 @@ private FiringPlan getDiveBombPlan(final Entity shooter, } while (weaponIter.hasNext()) { - final Mounted weapon = weaponIter.next(); + final WeaponMounted weapon = weaponIter.next(); if (weapon.getType().hasFlag(WeaponType.F_DIVE_BOMB)) { final HashMap bombPayloads = new HashMap(); bombPayloads.put("internal", new int[BombType.B_NUM]); @@ -1901,8 +1904,8 @@ private FiringPlan getDiveBombPlan(final Entity shooter, // load up all droppable bombs, yeah baby! Mix thunder bombs and infernos 'cause why the hell not. // seriously, though, TODO: more intelligent bomb drops - for (final Mounted bomb : shooter.getBombs(BombType.F_GROUND_BOMB)) { - int bType = ((BombType) bomb.getType()).getBombType(); + for (final BombMounted bomb : shooter.getBombs(BombType.F_GROUND_BOMB)) { + int bType = bomb.getType().getBombType(); if (bomb.isInternalBomb()) { // Can only drop 6 internal bombs in one turn. if (bombPayloads.get("internal")[bType] < 6) { @@ -1941,7 +1944,7 @@ private FiringPlan getDiveBombPlan(final Entity shooter, */ FiringPlan getFullFiringPlan(final Entity shooter, final Targetable target, - final Map ammoConservation, + final Map ammoConservation, final Game game) { final NumberFormat DECF = new DecimalFormat("0.000"); boolean debug = LogManager.getLogger().isDebugEnabled(); @@ -1960,7 +1963,7 @@ FiringPlan getFullFiringPlan(final Entity shooter, } // cycle through my weapons; should probably filter out already-fired / IDF arty - for (final Mounted weapon : shooter.getWeaponList()) { + for (final WeaponMounted weapon : shooter.getWeaponList()) { if (!weapon.canFire()) { continue; } @@ -1981,10 +1984,10 @@ FiringPlan getFullFiringPlan(final Entity shooter, bestShoot = buildWeaponFireInfo(shooter, target, weapon, null, game, false); } else { // Check _all_ ammunition for _all_ weapons here. - ArrayList ammos; + List ammos; ammos = shooter.getAmmo(weapon); - for (Mounted ammo: ammos) { + for (AmmoMounted ammo: ammos) { WeaponFireInfo shoot = buildWeaponFireInfo(shooter, target, weapon, ammo, game, false); // if we're below the threshold, try switching missile modes @@ -2210,7 +2213,7 @@ FiringPlan[] calcFiringPlansUnderHeat(final Entity shooter, FiringPlan getBestFiringPlan(final Entity shooter, final Targetable target, final Game game, - final Map ammoConservation) { + final Map ammoConservation) { // Start with an alpha strike. FiringPlan alphaStrike = getFullFiringPlan(shooter, target, @@ -2339,7 +2342,7 @@ FiringPlan determineBestFiringPlan(final FiringPlanCalculationParameters params) final EntityState shooterState = params.getShooterState(); final EntityState targetState = params.getTargetState(); final int maxHeat = params.getMaxHeat(); - final Map ammoConservation = params.getAmmoConservation(); + final Map ammoConservation = params.getAmmoConservation(); // Get the best plan without any twists. FiringPlan noTwistPlan = null; @@ -2568,7 +2571,7 @@ static List getAllTargetableEnemyEntities(final Player player, final FiringPlan getBestFiringPlan(final Entity shooter, final IHonorUtil honorUtil, final Game game, - final Map ammoConservation) { + final Map ammoConservation) { FiringPlan bestPlan = null; // Get a list of potential targets. @@ -2623,8 +2626,8 @@ public static double getMaxDamageAtRange(final Entity shooter, double maxDamage = 0; // cycle through my weapons - for (final Mounted weapon : shooter.getWeaponList()) { - final WeaponType weaponType = (WeaponType) weapon.getType(); + for (final WeaponMounted weapon : shooter.getWeaponList()) { + final WeaponType weaponType = weapon.getType(); // if the weapon has been disabled or is out of ammo, don't count it if (weapon.isCrippled()) { @@ -2645,16 +2648,16 @@ public static double getMaxDamageAtRange(final Entity shooter, int bracket; // For certain weapon types, look over all their loaded ammos - ArrayList ammos; + List ammos; if (weaponType.getAmmoType() == AmmoType.T_ATM || weaponType.getAmmoType() == AmmoType.T_MML) { ammos = shooter.getAmmo(weapon); } else { // Otherwise assume the current loaded ammo is suitable representative - ammos = new ArrayList(); - ammos.add(weapon.getLinked()); + ammos = new ArrayList<>(); + ammos.add(weapon.getLinkedAmmo()); } - for (Mounted ammo: ammos) { + for (AmmoMounted ammo: ammos) { bracket = RangeType.rangeBracket(range, weaponType.getRanges(weapon, ammo), useExtremeRange, @@ -2713,7 +2716,7 @@ void loadAmmo(final Entity shooter, // Loading ammo for all my weapons. for (final WeaponFireInfo info : plan) { - final Mounted currentWeapon = info.getWeapon(); + final WeaponMounted currentWeapon = info.getWeapon(); if (null == currentWeapon) { continue; } @@ -2724,8 +2727,8 @@ void loadAmmo(final Entity shooter, continue; } - final Mounted suggestedAmmo = info.getAmmo(); - final Mounted mountedAmmo = getPreferredAmmo(shooter, info.getTarget(), currentWeapon, suggestedAmmo); + final AmmoMounted suggestedAmmo = info.getAmmo(); + final AmmoMounted mountedAmmo = getPreferredAmmo(shooter, info.getTarget(), currentWeapon); // if we found preferred ammo but can't apply it to the weapon, log it and continue. if ((null != mountedAmmo) && !shooter.loadWeapon(currentWeapon, mountedAmmo)) { LogManager.getLogger().warn(shooter.getDisplayName() + " tried to load " @@ -2746,14 +2749,14 @@ void loadAmmo(final Entity shooter, } } - Mounted getClusterAmmo(final List ammoList, + AmmoMounted getClusterAmmo(final List ammoList, final WeaponType weaponType, final int range) { - Mounted returnAmmo = null; - Mounted mmlLrm = null; - Mounted mmlSrm = null; + AmmoMounted returnAmmo = null; + AmmoMounted mmlLrm = null; + AmmoMounted mmlSrm = null; - for (final Mounted ammo : ammoList) { + for (final AmmoMounted ammo : ammoList) { final AmmoType ammoType = (AmmoType) ammo.getType(); if (ammoType.getMunitionType().contains(AmmoType.Munitions.M_CLUSTER)) { // MMLs have additional considerations. @@ -2794,16 +2797,16 @@ Mounted getClusterAmmo(final List ammoList, * @param weapon which is mounted on Shooter * @return */ - Mounted getPreferredAmmo(final Entity shooter, + AmmoMounted getPreferredAmmo(final Entity shooter, final Targetable target, - final Mounted weapon) { + final WeaponMounted weapon) { return getPreferredAmmo(shooter, target, weapon, null); } - Mounted getPreferredAmmo(final Entity shooter, + AmmoMounted getPreferredAmmo(final Entity shooter, final Targetable target, - final Mounted weapon, - final Mounted suggestedAmmo) { + final WeaponMounted weapon, + final AmmoMounted suggestedAmmo) { boolean debug = LogManager.getLogger().isDebugEnabled(); final StringBuilder msg = (debug) ? new StringBuilder("Getting ammo for ") .append(weapon.getType().getShortName()) @@ -2813,8 +2816,8 @@ Mounted getPreferredAmmo(final Entity shooter, Entity targetEntity = null; // May be null or any valid ammo that can make an attack - Mounted preferredAmmo = suggestedAmmo; - WeaponType weaponType = (WeaponType) weapon.getType(); + AmmoMounted preferredAmmo = suggestedAmmo; + WeaponType weaponType = weapon.getType(); try { boolean fireResistant = false; @@ -2831,15 +2834,15 @@ Mounted getPreferredAmmo(final Entity shooter, } // Find the ammo that is valid for this weapon. - final List ammo = shooter.getAmmo(); - final List validAmmo = new ArrayList<>(); + final List ammo = shooter.getAmmo(); + final List validAmmo = new ArrayList<>(); // If the Firing Plan liked a specific ammo, give it priority if (null != preferredAmmo) { validAmmo.add(preferredAmmo); } - for (final Mounted a : ammo) { + for (final AmmoMounted a : ammo) { if (AmmoType.isAmmoValid(a, weaponType) - && AmmoType.canSwitchToAmmo(weapon, (AmmoType) a.getType()) + && AmmoType.canSwitchToAmmo(weapon, a.getType()) && !a.equals(preferredAmmo) && (!shooter.isLargeCraft() || shooter.whichBay(shooter.getEquipmentNum(weapon)).ammoInBay(shooter.getEquipmentNum(a)))) { @@ -2988,17 +2991,16 @@ Mounted getPreferredAmmo(final Entity shooter, } } - Mounted getGeneralMmlAmmo(final List ammoList, + AmmoMounted getGeneralMmlAmmo(final List ammoList, final int range) { - final Mounted returnAmmo; + final AmmoMounted returnAmmo; // Get the LRM and SRM bins if we have them. - Mounted mmlSrm = null; - Mounted mmlLrm = null; + AmmoMounted mmlSrm = null; + AmmoMounted mmlLrm = null; int switchedReason = 0; - for (final Mounted ammo : ammoList) { - final AmmoType type = (AmmoType) ammo.getType(); - if ((null == mmlLrm) && type.hasFlag(AmmoType.F_MML_LRM)) { + for (final AmmoMounted ammo : ammoList) { + if ((null == mmlLrm) && ammo.getType().hasFlag(AmmoType.F_MML_LRM)) { mmlLrm = ammo; } else if (null == mmlSrm) { mmlSrm = ammo; @@ -3033,18 +3035,18 @@ Mounted getGeneralMmlAmmo(final List ammoList, return returnAmmo; } - Mounted getAtmAmmo(final List ammoList, + AmmoMounted getAtmAmmo(final List ammoList, final int range, final EntityState target, final boolean fireResistant) { - Mounted returnAmmo; + AmmoMounted returnAmmo; // Get the Hi-Ex, Ex-Range and Standard ammo bins if we have them. - Mounted heAmmo = null; - Mounted erAmmo = null; - Mounted stAmmo = null; - Mounted infernoAmmo = null; - for (final Mounted ammo : ammoList) { + AmmoMounted heAmmo = null; + AmmoMounted erAmmo = null; + AmmoMounted stAmmo = null; + AmmoMounted infernoAmmo = null; + for (final AmmoMounted ammo : ammoList) { final AmmoType type = (AmmoType) ammo.getType(); if ((null == heAmmo) && (type.getMunitionType().contains(AmmoType.Munitions.M_HIGH_EXPLOSIVE))) { heAmmo = ammo; @@ -3112,15 +3114,15 @@ Mounted getAtmAmmo(final List ammoList, return returnAmmo; } - Mounted getAntiVeeAmmo(final List ammoList, + AmmoMounted getAntiVeeAmmo(final List ammoList, final WeaponType weaponType, final int range, final boolean fireResistant) { - Mounted returnAmmo = null; - Mounted mmlLrm = null; - Mounted mmlSrm = null; + AmmoMounted returnAmmo = null; + AmmoMounted mmlLrm = null; + AmmoMounted mmlSrm = null; - for (final Mounted ammo : ammoList) { + for (final AmmoMounted ammo : ammoList) { final AmmoType ammoType = (AmmoType) ammo.getType(); if (ammoType.getMunitionType().contains(AmmoType.Munitions.M_CLUSTER) || (ammoType.getMunitionType().contains(AmmoType.Munitions.M_INFERNO) && !fireResistant) @@ -3155,14 +3157,14 @@ Mounted getAntiVeeAmmo(final List ammoList, return returnAmmo; } - Mounted getAntiInfantryAmmo(final List ammoList, + AmmoMounted getAntiInfantryAmmo(final List ammoList, final WeaponType weaponType, final int range) { - Mounted returnAmmo = null; - Mounted mmlLrm = null; - Mounted mmlSrm = null; + AmmoMounted returnAmmo = null; + AmmoMounted mmlLrm = null; + AmmoMounted mmlSrm = null; - for (final Mounted ammo : ammoList) { + for (final AmmoMounted ammo : ammoList) { final AmmoType ammoType = (AmmoType) ammo.getType(); if (ammoType.getMunitionType().contains(AmmoType.Munitions.M_FLECHETTE) || ammoType.getMunitionType().contains(AmmoType.Munitions.M_FRAGMENTATION) @@ -3199,14 +3201,14 @@ Mounted getAntiInfantryAmmo(final List ammoList, return returnAmmo; } - private Mounted getHeatAmmo(final List ammoList, + private AmmoMounted getHeatAmmo(final List ammoList, final WeaponType weaponType, final int range) { - Mounted returnAmmo = null; - Mounted mmlLrm = null; - Mounted mmlSrm = null; + AmmoMounted returnAmmo = null; + AmmoMounted mmlLrm = null; + AmmoMounted mmlSrm = null; - for (final Mounted ammo : ammoList) { + for (final AmmoMounted ammo : ammoList) { final AmmoType ammoType = (AmmoType) ammo.getType(); if (ammoType.getMunitionType().contains(AmmoType.Munitions.M_INFERNO) || ammoType.getMunitionType().contains(AmmoType.Munitions.M_INFERNO_IV)) { @@ -3240,14 +3242,14 @@ private Mounted getHeatAmmo(final List ammoList, return returnAmmo; } - Mounted getIncendiaryAmmo(final List ammoList, + AmmoMounted getIncendiaryAmmo(final List ammoList, final WeaponType weaponType, final int range) { - Mounted returnAmmo = null; - Mounted mmlLrm = null; - Mounted mmlSrm = null; + AmmoMounted returnAmmo = null; + AmmoMounted mmlLrm = null; + AmmoMounted mmlSrm = null; - for (final Mounted ammo : ammoList) { + for (final AmmoMounted ammo : ammoList) { final AmmoType ammoType = (AmmoType) ammo.getType(); if (ammoType.getMunitionType().contains(AmmoType.Munitions.M_INCENDIARY) || ammoType.getMunitionType().contains(AmmoType.Munitions.M_INCENDIARY_LRM) @@ -3284,14 +3286,14 @@ Mounted getIncendiaryAmmo(final List ammoList, return returnAmmo; } - Mounted getHardTargetAmmo(final List ammoList, + AmmoMounted getHardTargetAmmo(final List ammoList, final WeaponType weaponType, final int range) { - Mounted returnAmmo = null; - Mounted mmlLrm = null; - Mounted mmlSrm = null; + AmmoMounted returnAmmo = null; + AmmoMounted mmlLrm = null; + AmmoMounted mmlSrm = null; - for (final Mounted ammo : ammoList) { + for (final AmmoMounted ammo : ammoList) { final AmmoType ammoType = (AmmoType) ammo.getType(); if (ammoType.getMunitionType().contains(AmmoType.Munitions.M_CLUSTER) || ammoType.getMunitionType().contains(AmmoType.Munitions.M_ANTI_FLAME_FOAM) @@ -3355,14 +3357,14 @@ Mounted getHardTargetAmmo(final List ammoList, return returnAmmo; } - Mounted getAntiAirAmmo(final List ammoList, + AmmoMounted getAntiAirAmmo(final List ammoList, final WeaponType weaponType, final int range) { - Mounted returnAmmo = null; - Mounted mmlLrm = null; - Mounted mmlSrm = null; + AmmoMounted returnAmmo = null; + AmmoMounted mmlLrm = null; + AmmoMounted mmlSrm = null; - for (final Mounted ammo : ammoList) { + for (final AmmoMounted ammo : ammoList) { final AmmoType ammoType = (AmmoType) ammo.getType(); if (ammoType.getMunitionType().contains(AmmoType.Munitions.M_ADA)){ // Air-Defense Arrow IVs are the premiere long-range AA munition. diff --git a/megamek/src/megamek/client/bot/princess/FiringPlan.java b/megamek/src/megamek/client/bot/princess/FiringPlan.java index 07e9bbd4b79..66aee39e5b1 100644 --- a/megamek/src/megamek/client/bot/princess/FiringPlan.java +++ b/megamek/src/megamek/client/bot/princess/FiringPlan.java @@ -21,6 +21,8 @@ import megamek.common.actions.EntityAction; import megamek.common.actions.FlipArmsAction; import megamek.common.actions.TorsoTwistAction; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import java.text.DecimalFormat; import java.util.*; @@ -272,8 +274,8 @@ public int hashCode() { */ void sortPlan() { this.sort((o1, o2) -> { - Mounted weapon1 = o1.getWeapon(); - Mounted weapon2 = o2.getWeapon(); + WeaponMounted weapon1 = o1.getWeapon(); + WeaponMounted weapon2 = o2.getWeapon(); // Both null, both equal. if (weapon1 == null && weapon2 == null) { @@ -291,14 +293,14 @@ void sortPlan() { double dmg1 = -1; double dmg2 = -1; - WeaponType weaponType1 = (WeaponType) weapon1.getType(); - WeaponType weaponType2 = (WeaponType) weapon2.getType(); + WeaponType weaponType1 = weapon1.getType(); + WeaponType weaponType2 = weapon2.getType(); - Mounted ammo1 = weapon1.getLinked(); - Mounted ammo2 = weapon2.getLinked(); + AmmoMounted ammo1 = weapon1.getLinkedAmmo(); + AmmoMounted ammo2 = weapon2.getLinkedAmmo(); - if ((ammo1 != null) && (ammo1.getType() instanceof AmmoType)) { - AmmoType ammoType = (AmmoType) ammo1.getType(); + if (ammo1 != null) { + AmmoType ammoType = ammo1.getType(); if ((WeaponType.DAMAGE_BY_CLUSTERTABLE == weaponType1.getDamage()) || (ammoType.getMunitionType().contains(AmmoType.Munitions.M_CLUSTER))) { dmg1 = ammoType.getDamagePerShot(); @@ -309,8 +311,8 @@ void sortPlan() { dmg1 = weaponType1.getDamage(); } - if ((ammo2 != null) && (ammo2.getType() instanceof AmmoType)) { - AmmoType ammoType = (AmmoType) ammo2.getType(); + if (ammo2 != null) { + AmmoType ammoType = ammo2.getType(); if ((WeaponType.DAMAGE_BY_CLUSTERTABLE == weaponType2.getDamage()) || (ammoType.getMunitionType().contains(AmmoType.Munitions.M_CLUSTER))) { dmg2 = ammoType.getDamagePerShot(); diff --git a/megamek/src/megamek/client/bot/princess/FiringPlanCalculationParameters.java b/megamek/src/megamek/client/bot/princess/FiringPlanCalculationParameters.java index 33402a8f19d..f197d1aa0ae 100644 --- a/megamek/src/megamek/client/bot/princess/FiringPlanCalculationParameters.java +++ b/megamek/src/megamek/client/bot/princess/FiringPlanCalculationParameters.java @@ -1,9 +1,9 @@ package megamek.client.bot.princess; import megamek.common.Entity; -import megamek.common.Mounted; import megamek.common.Targetable; import megamek.common.annotations.Nullable; +import megamek.common.equipment.WeaponMounted; import org.apache.logging.log4j.LogManager; import java.util.HashMap; @@ -34,7 +34,7 @@ public enum FiringPlanCalculationType { private final Targetable target; private final EntityState targetState; private final int maxHeat; - private final Map ammoConservation; + private final Map ammoConservation; private final FiringPlanCalculationType calculationType; public static class Builder { @@ -43,7 +43,7 @@ public static class Builder { private Targetable target = null; private EntityState targetState = null; private int maxHeat = Entity.DOES_NOT_TRACK_HEAT; - private Map ammoConservation = new HashMap<>(); + private Map ammoConservation = new HashMap<>(); private FiringPlanCalculationType calculationType = GUESS; /** @@ -103,7 +103,7 @@ public Builder setMaxHeat(final int value) { * Ammo conservation biases of the unit's mounted weapons. * Defaults to an empty map. */ - public Builder setAmmoConservation(@Nullable final Map value) { + public Builder setAmmoConservation(@Nullable final Map value) { ammoConservation = value; return this; } @@ -133,7 +133,7 @@ public FiringPlanCalculationParameters buildGuess(final Entity shooter, final Targetable target, @Nullable final EntityState targetState, final int maxHeat, - @Nullable final Map ammoConservation) { + @Nullable final Map ammoConservation) { return setShooter(shooter).setShooterState(shooterState) .setTarget(target) .setTargetState(targetState) @@ -145,7 +145,7 @@ public FiringPlanCalculationParameters buildGuess(final Entity shooter, public FiringPlanCalculationParameters buildExact(final Entity shooter, final Targetable target, - final Map ammoConservation) { + final Map ammoConservation) { return setShooter(shooter).setTarget(target) .setAmmoConservation(ammoConservation) .setCalculationType(GET) @@ -160,7 +160,7 @@ private FiringPlanCalculationParameters(final Builder builder) { this.shooterState = builder.shooterState; this.target = builder.target; this.targetState = builder.targetState; - maxHeat = builder.maxHeat < 0 ? 0 : builder.maxHeat; + maxHeat = Math.max(builder.maxHeat, 0); this.ammoConservation = builder.ammoConservation; this.calculationType = builder.calculationType; } @@ -188,7 +188,7 @@ int getMaxHeat() { } @Nullable - Map getAmmoConservation() { + Map getAmmoConservation() { return ammoConservation; } diff --git a/megamek/src/megamek/client/bot/princess/InfantryFireControl.java b/megamek/src/megamek/client/bot/princess/InfantryFireControl.java index 0f43e07a335..39ec44929be 100644 --- a/megamek/src/megamek/client/bot/princess/InfantryFireControl.java +++ b/megamek/src/megamek/client/bot/princess/InfantryFireControl.java @@ -15,6 +15,7 @@ import megamek.common.*; import megamek.common.annotations.Nullable; +import megamek.common.equipment.WeaponMounted; import megamek.common.weapons.infantry.InfantryWeapon; import megamek.server.ServerHelper; import org.apache.logging.log4j.LogManager; @@ -74,8 +75,8 @@ public double getMaxDamageAtRange(final MovePath shooterPath, final MovePath tar && target.hasETypeFlag(Entity.ETYPE_INFANTRY) && ((Infantry) target).isMechanized(); // cycle through my weapons - for (final Mounted weapon : shooter.getWeaponList()) { - final WeaponType weaponType = (WeaponType) weapon.getType(); + for (final WeaponMounted weapon : shooter.getWeaponList()) { + final WeaponType weaponType = weapon.getType(); final int bracket = RangeType.rangeBracket(range, weaponType.getRanges(weapon), useExtremeRange, useLOSRange); @@ -247,7 +248,7 @@ private FiringPlan guessFiringPlan(final Entity shooter, @Nullable EntityState s final FiringPlan myPlan = new FiringPlan(target); // cycle through my field guns - for (final Mounted weapon : shooter.getWeaponList()) { + for (final WeaponMounted weapon : shooter.getWeaponList()) { if (weaponIsAppropriate(weapon, firingPlanType)) { WeaponFireInfo bestShoot = null; @@ -277,7 +278,7 @@ private FiringPlan guessFiringPlan(final Entity shooter, @Nullable EntityState s * Helper method that determines whether a weapon type is appropriate for a given firing plan type, * e.g. field guns cannot be fired when we're going to do a swarm attack, etc. */ - private boolean weaponIsAppropriate(Mounted weapon, InfantryFiringPlanType firingPlanType) { + private boolean weaponIsAppropriate(WeaponMounted weapon, InfantryFiringPlanType firingPlanType) { boolean weaponIsSwarm = (weapon.getType()).getInternalName().equals(Infantry.SWARM_MEK); boolean weaponIsLegAttack = (weapon.getType()).getInternalName().equals(Infantry.LEG_ATTACK); boolean weaponIsFieldGuns = weapon.getLocation() == Infantry.LOC_FIELD_GUNS; diff --git a/megamek/src/megamek/client/bot/princess/MultiTargetFireControl.java b/megamek/src/megamek/client/bot/princess/MultiTargetFireControl.java index 6e42bad4461..db292a0134c 100644 --- a/megamek/src/megamek/client/bot/princess/MultiTargetFireControl.java +++ b/megamek/src/megamek/client/bot/princess/MultiTargetFireControl.java @@ -20,6 +20,8 @@ import java.util.Map; import megamek.common.*; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.OptionsConstants; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; @@ -44,7 +46,7 @@ public MultiTargetFireControl(Princess owningPrincess) { public FiringPlan getBestFiringPlan(final Entity shooter, final IHonorUtil honorUtil, final Game game, - final Map ammoConservation) { + final Map ammoConservation) { FiringPlan bestPlan = new FiringPlan(); // optimal firing patterns for units such as dropships, Thunderbolts with multi-trac @@ -55,9 +57,9 @@ public FiringPlan getBestFiringPlan(final Entity shooter, // So, the basic algorithm is as follows: // For each weapon, calculate the easiest shot. // Then, solve the backpack problem. - - List weaponList; - + + List weaponList; + if (shooter.usesWeaponBays()) { weaponList = shooter.getWeaponBayList(); } else { @@ -108,7 +110,7 @@ public FiringPlan getBestFiringPlan(final Entity shooter, * @param weapon Weapon to fire. * @return The weapon fire info with the most expected damage. Null if no such thing. */ - WeaponFireInfo getBestShot(Entity shooter, Mounted weapon) { + WeaponFireInfo getBestShot(Entity shooter, WeaponMounted weapon) { WeaponFireInfo bestShot = null; for (Targetable target : getTargetableEnemyEntities(shooter, owner.getGame(), owner.getFireControlState())) { @@ -119,10 +121,10 @@ WeaponFireInfo getBestShot(Entity shooter, Mounted weapon) { continue; } - if (effectivelyAmmoless((WeaponType) weapon.getType())) { + if (effectivelyAmmoless(weapon.getType())) { betterShot = buildWeaponFireInfo(shooter, target, weapon, null, owner.getGame(), false); } else { - ArrayList ammos; + List ammos; if (weapon.getBayWeapons().isEmpty()) { ammos = shooter.getAmmo(weapon); } else { @@ -130,7 +132,7 @@ WeaponFireInfo getBestShot(Entity shooter, Mounted weapon) { ammos.add(null); } - for (Mounted ammo : ammos) { + for (AmmoMounted ammo : ammos) { WeaponFireInfo shot = buildWeaponFireInfo(shooter, target, weapon, ammo, owner.getGame(), false); // this is a better shot if it has a chance of doing damage and the damage is better than the previous best shot @@ -187,11 +189,11 @@ void calculateUtility(final FiringPlan firingPlan, firingPlan.setUtility(utility); } - protected FiringPlan calculateFiringPlan(Entity shooter, List weaponList) { + protected FiringPlan calculateFiringPlan(Entity shooter, List weaponList) { FiringPlan retVal = new FiringPlan(); List shotList = new ArrayList<>(); - for (Mounted weapon : weaponList) { + for (WeaponMounted weapon : weaponList) { WeaponFireInfo shot = getBestShot(shooter, weapon); if (shot != null) { shotList.add(shot); diff --git a/megamek/src/megamek/client/bot/princess/Princess.java b/megamek/src/megamek/client/bot/princess/Princess.java index afd61779467..fda0b728a08 100644 --- a/megamek/src/megamek/client/bot/princess/Princess.java +++ b/megamek/src/megamek/client/bot/princess/Princess.java @@ -29,6 +29,7 @@ import megamek.common.actions.*; import megamek.common.annotations.Nullable; import megamek.common.containers.PlayerIDandList; +import megamek.common.equipment.WeaponMounted; import megamek.common.event.GameCFREvent; import megamek.common.event.GamePlayerChatEvent; import megamek.common.net.enums.PacketCommand; @@ -78,7 +79,7 @@ public class Princess extends BotClient { */ private final ConcurrentHashMap damageMap = new ConcurrentHashMap<>(); private final ConcurrentHashMap teamTagTargetsMap = new ConcurrentHashMap<>(); - private final ConcurrentHashMap, ArrayList> incomingGuidablesMap = new ConcurrentHashMap<>(); + private final ConcurrentHashMap, List> incomingGuidablesMap = new ConcurrentHashMap<>(); private final Set strategicBuildingTargets = new HashSet<>(); private boolean fallBack = false; private final ChatProcessor chatProcessor = new ChatProcessor(); @@ -602,7 +603,7 @@ protected void calculateFiringTurn() { // we skip this step if we have already decided not to fire due to being hidden or under "peaceful forced withdrawal" if (!skipFiring) { // Set up ammo conservation. - final Map ammoConservation = calcAmmoConservation(shooter); + final Map ammoConservation = calcAmmoConservation(shooter); // entity that can act this turn make sure weapons are loaded final FiringPlan plan = getFireControl(shooter).getBestFiringPlan(shooter, @@ -733,7 +734,7 @@ protected void calculateTargetingOffBoardTurn() { sendDone(true); } - private Map calcAmmoConservation(final Entity shooter) { + private Map calcAmmoConservation(final Entity shooter) { final double aggroFactor = getBehaviorSettings().getHyperAggressionIndex(); final StringBuilder msg = new StringBuilder("\nCalculating ammo conservation for ") .append(shooter.getDisplayName()); @@ -756,11 +757,11 @@ private Map calcAmmoConservation(final Entity shooter) { .append(" = ").append(ammoCounts.get(ammoType)); } - final Map ammoConservation = new HashMap<>(); + final Map ammoConservation = new HashMap<>(); msg.append("\nCalculating conservation for each weapon"); - for (final Mounted weapon : shooter.getWeaponList()) { - final WeaponType weaponType = (WeaponType) weapon.getType(); - msg.append("\n\t").append(weaponType); + for (final WeaponMounted weapon : shooter.getWeaponList()) { + final WeaponType weaponType = weapon.getType(); + msg.append("\n\t").append(weapon); if (!(weaponType instanceof AmmoWeapon)) { ammoConservation.put(weapon, 0.0); msg.append(" doesn't use ammo."); @@ -1719,7 +1720,7 @@ public int computeTeamTagUtility(Targetable te, int damage) { * whether they want to TAG or reserve their activation for actual attacks. * 4. All info is cleared at the start of the next turn. */ - public ArrayList computeGuidedWeapons(Entity entityToFire, Coords location){ + public List computeGuidedWeapons(Entity entityToFire, Coords location){ // Key cached entries to firing entity _and_ coordinates, as each shooter may have different targets and weapons // to support. Map.Entry key = Map.entry(entityToFire.getId(), location); @@ -1727,7 +1728,7 @@ public ArrayList computeGuidedWeapons(Entity entityToFire, Coords locat return incomingGuidablesMap.get(key); } - ArrayList friendlyGuidedWeapons = new ArrayList(); + List friendlyGuidedWeapons = new ArrayList<>(); // First, friendly incoming homing artillery that will land this turn. May include entity's own shots from prior // turns, but not from this turn. @@ -1736,7 +1737,7 @@ public ArrayList computeGuidedWeapons(Entity entityToFire, Coords locat if (a.getTurnsTilHit() == 0 && a.getAmmoMunitionType().contains(AmmoType.Munitions.M_HOMING) && (!a.getEntity(game).isEnemyOf(entityToFire))) { // Must be a shot that should land within 8 hexes of the target hex if (a.getCoords().distance(location) <= Compute.HOMING_RADIUS) { - friendlyGuidedWeapons.add(a.getEntity(game).getEquipment(a.getWeaponId())); + friendlyGuidedWeapons.add((WeaponMounted) a.getEntity(game).getEquipment(a.getWeaponId())); } } } @@ -1746,16 +1747,15 @@ public ArrayList computeGuidedWeapons(Entity entityToFire, Coords locat if (f.equals(entityToFire)) { continue; // This entity's weapons should not be considered for this calculation } - Set candidateWeapons = new HashSet(); + Set candidateWeapons = new HashSet<>(); Coords fLoc = f.getPosition(); - for (Mounted m : f.getTotalWeaponList()) { - WeaponType w = (WeaponType) m.getType(); + for (WeaponMounted m : f.getTotalWeaponList()) { // Ignore weapons outside of viable long range; does not apply to bombs. - if (fLoc.distance(location) > w.getLongRange() + f.getRunMP() && !m.isGroundBomb()) { + if (fLoc.distance(location) > m.getType().getLongRange() + f.getRunMP() && !m.isGroundBomb()) { continue; } - if (w.hasIndirectFire() && !f.isAero()) { + if (m.getType().hasIndirectFire() && !f.isAero()) { // Only care about ground IF weapons. candidateWeapons.add(m); } else if (m.getLinked() != null && m.getLinked().isHomingAmmoInHomingMode()) { diff --git a/megamek/src/megamek/client/bot/princess/WeaponFireInfo.java b/megamek/src/megamek/client/bot/princess/WeaponFireInfo.java index 2e543592d9d..379b15aba5f 100644 --- a/megamek/src/megamek/client/bot/princess/WeaponFireInfo.java +++ b/megamek/src/megamek/client/bot/princess/WeaponFireInfo.java @@ -17,6 +17,9 @@ import megamek.common.actions.ArtilleryAttackAction; import megamek.common.actions.WeaponAttackAction; import megamek.common.annotations.Nullable; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.BombMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.OptionsConstants; import megamek.common.weapons.capitalweapons.CapitalMissileWeapon; import megamek.common.weapons.infantry.InfantryWeapon; @@ -42,8 +45,8 @@ public class WeaponFireInfo { private WeaponAttackAction action; private Entity shooter; private Targetable target; - private Mounted weapon; - private Mounted preferredAmmo; + private WeaponMounted weapon; + private AmmoMounted preferredAmmo; private double probabilityToHit; private int heat; private double maxDamage; @@ -77,8 +80,8 @@ protected WeaponFireInfo(final Princess owner) { */ WeaponFireInfo(final Entity shooter, final Targetable target, - final Mounted weapon, - final Mounted ammo, + final WeaponMounted weapon, + final AmmoMounted ammo, final Game game, final boolean guess, final Princess owner) { @@ -100,8 +103,8 @@ protected WeaponFireInfo(final Princess owner) { final EntityState shooterState, final Targetable target, final EntityState targetState, - final Mounted weapon, - final Mounted ammo, + final WeaponMounted weapon, + final AmmoMounted ammo, final Game game, final boolean guess, final Princess owner) { @@ -120,14 +123,14 @@ protected WeaponFireInfo(final Princess owner) { * @param assumeUnderFlightPath Set TRUE for aerial units performing air-to-ground attacks. * @param guess Set TRUE to estimate the chance to hit rather than doing the full calculation. * @param owner Instance of the princess owner - * @param bombPayload The bomb payload, as described in WeaponAttackAction.setBombPayload + * @param bombPayloads The bomb payload, as described in WeaponAttackAction.setBombPayload */ WeaponFireInfo(final Entity shooter, final MovePath shooterPath, final Targetable target, final EntityState targetState, - final Mounted weapon, - final Mounted ammo, + final WeaponMounted weapon, + final AmmoMounted ammo, final Game game, final boolean assumeUnderFlightPath, final boolean guess, @@ -151,15 +154,15 @@ protected WeaponFireInfo(final Princess owner) { * @param guess Set TRUE to estimate the chance to hit rather than going through the full * calculation. * @param owner Instance of the princess owner - * @param bombPayload The bomb payload, as described in WeaponAttackAction.setBombPayload + * @param bombPayloads The bomb payload, as described in WeaponAttackAction.setBombPayload */ private WeaponFireInfo(final Entity shooter, final EntityState shooterState, final MovePath shooterPath, final Targetable target, final EntityState targetState, - final Mounted weapon, - final Mounted ammo, + final WeaponMounted weapon, + final AmmoMounted ammo, final Game game, final boolean assumeUnderFlightPath, final boolean guess, @@ -317,11 +320,11 @@ void setTargetState(final EntityState targetState) { this.targetState = targetState; } - protected void setWeapon(final Mounted weapon) { + protected void setWeapon(final WeaponMounted weapon) { this.weapon = weapon; } - protected void setAmmo(final Mounted ammo) { + protected void setAmmo(final AmmoMounted ammo) { this.preferredAmmo = ammo; } @@ -333,11 +336,11 @@ public int getHeat() { return heat; } - public Mounted getWeapon() { + public WeaponMounted getWeapon() { return weapon; } - public Mounted getAmmo() { + public AmmoMounted getAmmo() { return preferredAmmo; } @@ -380,7 +383,7 @@ private WeaponAttackAction buildBombAttackAction(final HashMap bo if ((null != weapon.getBayWeapons()) && !weapon.getBayWeapons().isEmpty()) { int bayDamage = 0; for (int weaponID : weapon.getBayWeapons()) { - Mounted bayWeapon = weapon.getEntity().getEquipment(weaponID); + Mounted bayWeapon = weapon.getEntity().getEquipment(weaponID); WeaponType weaponType = (WeaponType) bayWeapon.getType(); int maxRange = game.getOptions().booleanOption(OptionsConstants.ADVCOMBAT_TACOPS_RANGE) ? weaponType.getExtremeRange() : weaponType.getLongRange(); @@ -518,7 +521,7 @@ private WeaponAttackAction buildBombAttackAction(final HashMap bo * @param weapon The weapon to check. * @return Generated heat. */ - int computeHeat(Mounted weapon) { + int computeHeat(Mounted weapon) { // bay weapons require special consideration, by looping through all weapons and adding up the damage // A bay's weapons may have different ranges, most noticeable in laser bays, where the damage potential // varies with distance to target. @@ -549,8 +552,8 @@ private double computeExpectedBombDamage(final Entity shooter, final Mounted wea // for dive attacks, we can pretty much assume that we're going to drop everything we've got on the poor scrubs in this hex if (weapon.getType().hasFlag(WeaponType.F_DIVE_BOMB)) { - for (final Mounted bomb : shooter.getBombs(BombType.F_GROUND_BOMB)) { - final int damagePerShot = ((BombType) bomb.getType()).getDamagePerShot(); + for (final BombMounted bomb : shooter.getBombs(BombType.F_GROUND_BOMB)) { + final int damagePerShot = bomb.getType().getDamagePerShot(); // some bombs affect a blast radius, so we take that into account final List affectedHexes = new ArrayList<>(); diff --git a/megamek/src/megamek/client/generator/TeamLoadoutGenerator.java b/megamek/src/megamek/client/generator/TeamLoadoutGenerator.java index d83f786f74f..79aaeae89c3 100644 --- a/megamek/src/megamek/client/generator/TeamLoadoutGenerator.java +++ b/megamek/src/megamek/client/generator/TeamLoadoutGenerator.java @@ -4,6 +4,7 @@ import megamek.client.ui.swing.dialog.AbstractUnitSelectorDialog; import megamek.common.*; import megamek.common.containers.MunitionTree; +import megamek.common.equipment.AmmoMounted; import megamek.common.equipment.ArmorType; import megamek.common.options.GameOptions; import megamek.common.options.OptionsConstants; @@ -387,7 +388,7 @@ private static boolean setLRMImperatives(Entity e, MunitionTree mt, Reconfigurat * Generate the list of desired ammo load-outs for this team. * TODO: implement generateDetailedMunitionTree with more complex breakdowns per unit type * NOTE: if subclassing this generator, should only need to override this method. - * @param rc + * @param rp * @param t * @param defaultSettingsFile * @return generated MunitionTree with imperatives for each weapon type @@ -522,7 +523,7 @@ public static MunitionTree generateMunitionTree(ReconfigurationParameters rp, Te /** * Turn a selection of the computed munition weights into imperatives to load in the MunitionTree * @param mt - * @param rp + * @param mwc * @return */ public static MunitionTree applyWeightsToMunitionTree(MunitionTree mt, MunitionWeightCollection mwc) { @@ -562,7 +563,8 @@ public void reconfigureTeam(Team team, String faction, MunitionTree mt) { /** * Wrapper to load a file of preset munition imperatives * @param team - * @param defaultFile + * @param faction + * @param adfFile */ public void reconfigureTeam(Team team, String faction, String adfFile) { ReconfigurationParameters rp = generateParameters(game, gameOptions, team); @@ -590,8 +592,8 @@ public void reconfigureTeam(Game g, Team team, String faction, MunitionTree mt) /** * Configure Bot Team with all munitions randomized - * @param g * @param team + * @param faction */ public void randomizeBotTeamConfiguration(Team team, String faction) { reconfigureTeam(game, team, faction, generateRandomizedMT()); @@ -618,11 +620,11 @@ public void reconfigureEntity(Entity e, MunitionTree mt, String faction) { String pilot = e.getCrew().getName(0); // Create map of bin counts in unit by type - HashMap> binLists = new HashMap<>(); + HashMap> binLists = new HashMap<>(); // Populate map with _valid_, _available_ ammo - for (Mounted ammoBin: e.getAmmo()) { - AmmoType aType = (AmmoType) ammoBin.getType(); + for (AmmoMounted ammoBin: e.getAmmo()) { + AmmoType aType = ammoBin.getType(); String sName = ("".equals(aType.getBaseName())) ? ammoBin.getType().getShortName() : aType.getBaseName(); // Store the actual bins under their types @@ -639,7 +641,7 @@ public void reconfigureEntity(Entity e, MunitionTree mt, String faction) { } private void iterativelyLoadAmmo( - Entity e, MunitionTree mt, ArrayList binList, String binName, String faction + Entity e, MunitionTree mt, List binList, String binName, String faction ){ String techBase = (e.isClan()) ? "CL" : "IS"; iterativelyLoadAmmo(e, mt, binList, binName, techBase, faction); @@ -663,7 +665,7 @@ private void iterativelyLoadAmmo( * @param faction Faction to outfit for, used in ammo validity checks (uses MM, not IO, faction codes) */ private void iterativelyLoadAmmo( - Entity e, MunitionTree mt, ArrayList binList, String binName, String techBase, String faction + Entity e, MunitionTree mt, List binList, String binName, String techBase, String faction ) { Logger logger = LogManager.getLogger(); // Copy counts that we will update, otherwise mt entry gets edited permanently. @@ -762,7 +764,7 @@ private void iterativelyLoadAmmo( } if (!(defaultType == null || binList.isEmpty())) { - for (Mounted bin : binList) { + for (AmmoMounted bin : binList) { bin.changeAmmoType(defaultType); } } diff --git a/megamek/src/megamek/client/ui/swing/AimedShotHandler.java b/megamek/src/megamek/client/ui/swing/AimedShotHandler.java index 491a74175f0..393dd989993 100644 --- a/megamek/src/megamek/client/ui/swing/AimedShotHandler.java +++ b/megamek/src/megamek/client/ui/swing/AimedShotHandler.java @@ -4,6 +4,7 @@ import megamek.client.ui.swing.widget.IndexedRadioButton; import megamek.common.*; import megamek.common.enums.AimingMode; +import megamek.common.equipment.WeaponMounted; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -359,7 +360,7 @@ public boolean isAimingAtLocation() { * @param weapon * @return */ - public boolean allowAimedShotWith(Mounted weapon) { + public boolean allowAimedShotWith(WeaponMounted weapon) { return Compute.allowAimedShotWith(weapon, aimingMode); } diff --git a/megamek/src/megamek/client/ui/swing/BayMunitionsChoicePanel.java b/megamek/src/megamek/client/ui/swing/BayMunitionsChoicePanel.java index 9d40f83e309..aba18054dfc 100644 --- a/megamek/src/megamek/client/ui/swing/BayMunitionsChoicePanel.java +++ b/megamek/src/megamek/client/ui/swing/BayMunitionsChoicePanel.java @@ -15,6 +15,8 @@ import megamek.client.ui.Messages; import megamek.common.*; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.OptionsConstants; import org.apache.logging.log4j.LogManager; @@ -45,15 +47,14 @@ public BayMunitionsChoicePanel(Entity entity, Game game) { gbc.anchor = GridBagConstraints.WEST; gbc.insets = new Insets(10, 0, 10, 0); - for (Mounted bay : entity.getWeaponBayList()) { - Map,List> ammoByType = new HashMap<>(); + for (WeaponMounted bay : entity.getWeaponBayList()) { + Map,List> ammoByType = new HashMap<>(); for (Integer aNum : bay.getBayAmmo()) { - final Mounted ammo = entity.getEquipment(aNum); - if ((null != ammo) && (ammo.getType() instanceof AmmoType)) { - AmmoType atype = (AmmoType) ammo.getType(); + final AmmoMounted ammo = (AmmoMounted) entity.getEquipment(aNum); + if (null != ammo) { List key = new ArrayList<>(2); - key.add(atype.getAmmoType()); - key.add(atype.getRackSize()); + key.add(ammo.getType().getAmmoType()); + key.add(ammo.getType().getRackSize()); ammoByType.putIfAbsent(key, new ArrayList<>()); ammoByType.get(key).add(ammo); } @@ -79,9 +80,9 @@ public void apply() { for (int i = 0; i < row.munitions.size(); i++) { int shots = (Integer) row.spinners.get(i).getValue(); if (shots > 0) { - Mounted mounted; + AmmoMounted mounted; if (mountIndex >= row.ammoMounts.size()) { - mounted = new Mounted(entity, row.munitions.get(i)); + mounted = (AmmoMounted) Mounted.createMounted(entity, row.munitions.get(i)); try { entity.addEquipment(mounted, row.bay.getLocation(), row.bay.isRearMounted()); row.bay.addAmmoToBay(entity.getEquipmentNum(mounted)); @@ -103,7 +104,7 @@ public void apply() { } // Zero out any remaining unused bins. while (mountIndex < row.ammoMounts.size()) { - Mounted mount = row.ammoMounts.get(mountIndex); + AmmoMounted mount = row.ammoMounts.get(mountIndex); mount.setSize(0); mount.setOriginalShots(0); mount.setShotsLeft(0); @@ -112,10 +113,9 @@ public void apply() { // If the unit is assigned less ammo than the capacity, assign remaining weight to first mount // and adjust original shots. if (remainingWeight > 0) { - Mounted m = row.ammoMounts.get(0); - AmmoType at = (AmmoType) m.getType(); + AmmoMounted m = row.ammoMounts.get(0); m.setSize(m.getSize() + remainingWeight); - m.setOriginalShots((int) Math.floor(m.getSize() / (at.getShots() * m.getTonnage()))); + m.setOriginalShots((int) Math.floor(m.getSize() / (m.getType().getShots() * m.getTonnage()))); } } } @@ -128,18 +128,18 @@ class AmmoRowPanel extends JPanel implements ChangeListener { private final JLabel lblTonnage = new JLabel(); - private final Mounted bay; + private final WeaponMounted bay; private final int at; private final int rackSize; private final int techBase; - private final List ammoMounts; + private final List ammoMounts; private final List spinners; private final List munitions; private double tonnage; - AmmoRowPanel(Mounted bay, int at, int rackSize, List ammoMounts) { + AmmoRowPanel(WeaponMounted bay, int at, int rackSize, List ammoMounts) { this.bay = bay; this.at = at; this.rackSize = rackSize; diff --git a/megamek/src/megamek/client/ui/swing/CustomMechDialog.java b/megamek/src/megamek/client/ui/swing/CustomMechDialog.java index 70d4b51babe..059e75d908c 100644 --- a/megamek/src/megamek/client/ui/swing/CustomMechDialog.java +++ b/megamek/src/megamek/client/ui/swing/CustomMechDialog.java @@ -20,6 +20,7 @@ import megamek.client.ui.swing.util.UIUtil; import megamek.common.*; import megamek.common.enums.Gender; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.*; import megamek.common.verifier.*; import megamek.common.weapons.bayweapons.ArtilleryBayWeapon; @@ -521,9 +522,8 @@ public void actionPerformed(ActionEvent actionEvent) { // effective range, even if many of the unit's weapons would be out of range int maxDistance = 0; for (Entity entity : entities) { - for (Mounted wep : entity.getWeaponList()) { - EquipmentType e = wep.getType(); - WeaponType w = (WeaponType) e; + for (WeaponMounted wep : entity.getWeaponList()) { + WeaponType w = wep.getType(); int nDistance = 0; if (w.hasFlag(WeaponType.F_ARTILLERY)) { if (w instanceof ArtilleryBayWeapon) { @@ -531,8 +531,8 @@ public void actionPerformed(ActionEvent actionEvent) { // to the shortest range of the weapons in it int bayShortestRange = 150; // Cruise missile/120 for (int wId : wep.getBayWeapons()) { - Mounted bweap = entity.getEquipment(wId); - WeaponType bwtype = (WeaponType) bweap.getType(); + WeaponMounted bweap = (WeaponMounted) entity.getEquipment(wId); + WeaponType bwtype = bweap.getType(); // Max TO range in mapsheets - 1 for the actual play area int currentDistance = (bwtype.getLongRange() - 1); if (currentDistance < bayShortestRange) { diff --git a/megamek/src/megamek/client/ui/swing/EquipChoicePanel.java b/megamek/src/megamek/client/ui/swing/EquipChoicePanel.java index efa6d5798c6..3d8cef81569 100644 --- a/megamek/src/megamek/client/ui/swing/EquipChoicePanel.java +++ b/megamek/src/megamek/client/ui/swing/EquipChoicePanel.java @@ -17,6 +17,9 @@ import megamek.client.ui.GBC; import megamek.client.ui.Messages; import megamek.common.*; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.MiscMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.AbstractOptions; import megamek.common.options.OptionsConstants; import megamek.common.util.fileUtils.MegaMekFile; @@ -420,7 +423,7 @@ private void setupMines() { GridBagConstraints gbc = new GridBagConstraints(); int row = 0; - for (Mounted m : entity.getMisc()) { + for (MiscMounted m : entity.getMisc()) { if (!m.getType().hasFlag((MiscType.F_MINE)) && !m.getType().hasFlag((MiscType.F_VEHICLE_MINE_DISPENSER))) { continue; @@ -582,8 +585,8 @@ private void setupMunitions() { } panMunitions.setLayout(gbl); - for (Mounted m : entity.getAmmo()) { - AmmoType at = (AmmoType) m.getType(); + for (AmmoMounted m : entity.getAmmo()) { + AmmoType at = m.getType(); ArrayList vTypes = new ArrayList<>(); Vector vAllTypes = AmmoType.getMunitionsFor(at.getAmmoType()); if (vAllTypes == null) { @@ -701,11 +704,9 @@ private void setupWeaponAmmoChoice() { GridBagLayout gbl = new GridBagLayout(); panWeaponAmmoSelector.setLayout(gbl); - for (Mounted weapon : entity.getWeaponList()) { - WeaponType weaponType = weapon.getType() instanceof WeaponType ? (WeaponType) weapon.getType() : null; - + for (WeaponMounted weapon : entity.getWeaponList()) { // don't deal with bay or grouped weapons for now - if (weaponType == null || weaponType.getAmmoType() == AmmoType.T_NA) { + if (weapon.getType().getAmmoType() == AmmoType.T_NA) { continue; } @@ -720,9 +721,9 @@ class MineChoicePanel extends JPanel { private JComboBox m_choice; - private Mounted m_mounted; + private MiscMounted m_mounted; - MineChoicePanel(Mounted m) { + MineChoicePanel(MiscMounted m) { m_mounted = m; m_choice = new JComboBox<>(); m_choice.addItem(Messages.getString("CustomMechDialog.Conventional")); @@ -976,7 +977,7 @@ class MunitionChoicePanel extends JPanel { boolean numShotsChanged = false; - private Mounted m_mounted; + private AmmoMounted m_mounted; JLabel labDump = new JLabel(Messages.getString("CustomMechDialog.labDump")); @@ -987,7 +988,7 @@ class MunitionChoicePanel extends JPanel { JCheckBox chHotLoad = new JCheckBox(); @SuppressWarnings("unchecked") - MunitionChoicePanel(Mounted m, ArrayList vTypes, List weaponAmmoChoicePanels) { + MunitionChoicePanel(AmmoMounted m, ArrayList vTypes, List weaponAmmoChoicePanels) { m_vTypes = vTypes; m_mounted = m; @@ -1156,8 +1157,8 @@ void setShotsLeft(int shots) { class WeaponAmmoChoicePanel extends JPanel { private static final long serialVersionUID = 604670659251519188L; // the weapon being displayed in this row - private Mounted m_mounted; - private ArrayList matchingAmmoBins; + private WeaponMounted m_mounted; + private ArrayList matchingAmmoBins; private JComboBox ammoBins; @@ -1165,12 +1166,7 @@ class WeaponAmmoChoicePanel extends JPanel { * Constructor * @param weapon The mounted weapon. Assumes that the weapon uses ammo. */ - public WeaponAmmoChoicePanel(Mounted weapon) { - // for safety purposes, if the given mounted isn't a weapon, don't do anything. - if (!(weapon.getType() instanceof WeaponType)) { - return; - } - + public WeaponAmmoChoicePanel(WeaponMounted weapon) { m_mounted = weapon; this.setLayout(new GridBagLayout()); @@ -1181,18 +1177,18 @@ public WeaponAmmoChoicePanel(Mounted weapon) { if (m_mounted.isOneShot() || (entity.isSupportVehicle() && (m_mounted.getType() instanceof InfantryWeapon))) { // One-shot weapons can only access their own bin - matchingAmmoBins.add(m_mounted.getLinked()); + matchingAmmoBins.add(m_mounted.getLinkedAmmo()); // Fusillade and some small SV weapons are treated like one-shot // weapons but may have a second munition type available. if ((m_mounted.getLinked().getLinked() != null) && (((AmmoType) m_mounted.getLinked().getType()).getMunitionType() != (((AmmoType) m_mounted.getLinked().getLinked().getType()).getMunitionType()))) { - matchingAmmoBins.add(m_mounted.getLinked().getLinked()); + matchingAmmoBins.add((AmmoMounted) m_mounted.getLinked().getLinked()); } } else { - for (Mounted ammoBin : weapon.getEntity().getAmmo()) { + for (AmmoMounted ammoBin : weapon.getEntity().getAmmo()) { if ((ammoBin.getLocation() != Entity.LOC_NONE) - && AmmoType.canSwitchToAmmo(weapon, (AmmoType) ammoBin.getType())) { + && AmmoType.canSwitchToAmmo(weapon, ammoBin.getType())) { matchingAmmoBins.add(ammoBin); } } diff --git a/megamek/src/megamek/client/ui/swing/FiringDisplay.java b/megamek/src/megamek/client/ui/swing/FiringDisplay.java index ea462af7fb6..8d16f7e520c 100644 --- a/megamek/src/megamek/client/ui/swing/FiringDisplay.java +++ b/megamek/src/megamek/client/ui/swing/FiringDisplay.java @@ -22,6 +22,7 @@ import megamek.common.*; import megamek.common.actions.*; import megamek.common.enums.AimingMode; +import megamek.common.equipment.WeaponMounted; import megamek.common.event.GamePhaseChangeEvent; import megamek.common.event.GameTurnChangeEvent; import megamek.common.options.OptionsConstants; @@ -1155,13 +1156,12 @@ void fire() { final Game game = clientgui.getClient().getGame(); // get the selected weaponnum final int weaponNum = clientgui.getUnitDisplay().wPan.getSelectedWeaponNum(); - Mounted mounted = ce().getEquipment(weaponNum); + WeaponMounted mounted = (WeaponMounted) ce().getEquipment(weaponNum); // validate if ((ce() == null) || (target == null && (!isStrafing || strafingCoords.isEmpty())) - || (mounted == null) - || !(mounted.getType() instanceof WeaponType)) { + || (mounted == null)) { throw new IllegalArgumentException("current fire parameters are invalid"); } // check if we now shoot at a target in the front arc and previously @@ -1549,7 +1549,7 @@ public void updateTarget() { ToHitData toHit; if (!ash.getAimingMode().isNone()) { - Mounted weapon = ce().getEquipment(weaponId); + WeaponMounted weapon = (WeaponMounted) ce().getEquipment(weaponId); boolean aiming = ash.isAimingAtLocation() && ash.allowAimedShotWith(weapon); ash.setEnableAll(aiming); if (aiming) { diff --git a/megamek/src/megamek/client/ui/swing/MapMenu.java b/megamek/src/megamek/client/ui/swing/MapMenu.java index 76a8c9fc67f..70e797b3152 100644 --- a/megamek/src/megamek/client/ui/swing/MapMenu.java +++ b/megamek/src/megamek/client/ui/swing/MapMenu.java @@ -30,6 +30,8 @@ import megamek.common.actions.GrappleAttackAction; import megamek.common.actions.WeaponAttackAction; import megamek.common.annotations.Nullable; +import megamek.common.equipment.MiscMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.OptionsConstants; import megamek.common.util.fileUtils.MegaMekFile; import megamek.common.verifier.*; @@ -773,17 +775,17 @@ private JMenuItem createAlphaStrikeJMenuItem() { try { FiringDisplay panel = (FiringDisplay) currentPanel; // Get all weapons - ArrayList weapons = myEntity.getWeaponList(); + List weapons = myEntity.getWeaponList(); // We will need to map a Mounted to its weapon number - HashMap weapToId = new HashMap<>(); - for (Mounted weapon : weapons) { + HashMap weapToId = new HashMap<>(); + for (WeaponMounted weapon : weapons) { weapToId.put(weapon, myEntity.getEquipmentNum(weapon)); } // Sort weapons from high damage to low weapons.sort(new WeaponComparatorDamage(false)); Targetable target = panel.getTarget(); - for (Mounted weapon : weapons) { + for (WeaponMounted weapon : weapons) { // If the weapon has been used at all this turn, ignore if (!weapon.usedInPhase().isUnknown()) { continue; @@ -1584,7 +1586,7 @@ private JMenuItem createClubJMenuItem(String clubName, int clubNumber) { item.setActionCommand(Integer.toString(clubNumber)); item.addActionListener(evt -> { try { - Mounted club = myEntity.getClubs().get( + MiscMounted club = myEntity.getClubs().get( Integer.parseInt(evt.getActionCommand())); ((PhysicalDisplay) currentPanel).club(club); } catch (Exception ex) { diff --git a/megamek/src/megamek/client/ui/swing/MovementDisplay.java b/megamek/src/megamek/client/ui/swing/MovementDisplay.java index 048aa9bd148..06b895f2ac9 100644 --- a/megamek/src/megamek/client/ui/swing/MovementDisplay.java +++ b/megamek/src/megamek/client/ui/swing/MovementDisplay.java @@ -34,6 +34,7 @@ import megamek.common.actions.DfaAttackAction; import megamek.common.actions.RamAttackAction; import megamek.common.annotations.Nullable; +import megamek.common.equipment.MiscMounted; import megamek.common.event.GamePhaseChangeEvent; import megamek.common.event.GameTurnChangeEvent; import megamek.common.options.AbstractOptions; @@ -4928,8 +4929,8 @@ public synchronized void actionPerformed(ActionEvent ev) { } else if (actionCmd.equals(MoveCommand.MOVE_LAY_MINE.getCmd())) { int i = chooseMineToLay(); if (i != -1) { - Mounted m = ce.getEquipment(i); - if (m.getMineType() == Mounted.MINE_VIBRABOMB) { + MiscMounted m = (MiscMounted) ce.getEquipment(i); + if (m.getMineType() == MiscMounted.MINE_VIBRABOMB) { VibrabombSettingDialog vsd = new VibrabombSettingDialog( clientgui.frame); vsd.setVisible(true); diff --git a/megamek/src/megamek/client/ui/swing/PhysicalDisplay.java b/megamek/src/megamek/client/ui/swing/PhysicalDisplay.java index 0a214a977d6..3a9e5bf4b49 100644 --- a/megamek/src/megamek/client/ui/swing/PhysicalDisplay.java +++ b/megamek/src/megamek/client/ui/swing/PhysicalDisplay.java @@ -21,6 +21,7 @@ import megamek.common.*; import megamek.common.actions.*; import megamek.common.enums.AimingMode; +import megamek.common.equipment.MiscMounted; import megamek.common.event.GamePhaseChangeEvent; import megamek.common.event.GameTurnChangeEvent; import megamek.common.options.OptionsConstants; @@ -821,20 +822,20 @@ void jumpjetatt() { } } - private Mounted chooseClub() { - java.util.List clubs = ce().getClubs(); + private MiscMounted chooseClub() { + java.util.List clubs = ce().getClubs(); if (clubs.size() == 1) { return clubs.get(0); } else if (clubs.size() > 1) { String[] names = new String[clubs.size()]; for (int loop = 0; loop < names.length; loop++) { - Mounted club = clubs.get(loop); + MiscMounted club = clubs.get(loop); final ToHitData toHit = ClubAttackAction.toHit(clientgui.getClient().getGame(), cen, target, club, ash.getAimTable(), false); final int dmg = ClubAttackAction.getDamageFor(ce(), club, target.isConventionalInfantry(), false); // Need to do this outside getDamageFor, as it only returns int - String dmgString = dmg + ""; + String dmgString = String.valueOf(dmg); if ((club.getType().hasSubType(MiscType.S_COMBINE) || club.getType().hasSubType(MiscType.S_CHAINSAW) || club.getType().hasSubType(MiscType.S_DUAL_SAW)) @@ -864,14 +865,14 @@ private Mounted chooseClub() { * Club that target! */ void club() { - Mounted club = chooseClub(); + MiscMounted club = chooseClub(); club(club); } /** * Club that target! */ - void club(Mounted club) { + void club(MiscMounted club) { if (null == club) { return; } @@ -894,7 +895,7 @@ void club(Mounted club) { isAptPiloting); final int clubDmg = ClubAttackAction.getDamageFor(en, club, target.isConventionalInfantry(), false); // Need to do this outside getDamageFor, as it only returns int - String dmgString = clubDmg + ""; + String dmgString = String.valueOf(clubDmg); if ((club.getType().hasSubType(MiscType.S_COMBINE) || club.getType().hasSubType(MiscType.S_CHAINSAW) || club.getType().hasSubType(MiscType.S_DUAL_SAW)) diff --git a/megamek/src/megamek/client/ui/swing/PointblankShotDisplay.java b/megamek/src/megamek/client/ui/swing/PointblankShotDisplay.java index 4c583a50f64..be5b36c4f1b 100644 --- a/megamek/src/megamek/client/ui/swing/PointblankShotDisplay.java +++ b/megamek/src/megamek/client/ui/swing/PointblankShotDisplay.java @@ -25,6 +25,7 @@ import megamek.common.actions.WeaponAttackAction; import megamek.common.enums.AimingMode; import megamek.common.enums.GamePhase; +import megamek.common.equipment.WeaponMounted; import megamek.common.event.GamePhaseChangeEvent; import megamek.common.event.GameTurnChangeEvent; import megamek.common.options.OptionsConstants; @@ -524,12 +525,10 @@ void fire() { final Game game = clientgui.getClient().getGame(); // get the selected weaponnum final int weaponNum = clientgui.getUnitDisplay().wPan.getSelectedWeaponNum(); - Mounted mounted = ce().getEquipment(weaponNum); + WeaponMounted mounted = (WeaponMounted) ce().getEquipment(weaponNum); // validate - if ((ce() == null) - || (mounted == null) - || !(mounted.getType() instanceof WeaponType)) { + if ((ce() == null) || (mounted == null)) { throw new IllegalArgumentException("current fire parameters are invalid"); } @@ -664,9 +663,8 @@ public void updateTarget() { && (target != null) && (target.getPosition() != null) && (weaponId != -1)) { ToHitData toHit; if (!ash.getAimingMode().isNone()) { - Mounted weapon = ce().getEquipment(weaponId); - boolean aiming = ash.isAimingAtLocation() - && ash.allowAimedShotWith(weapon); + WeaponMounted weapon = (WeaponMounted) ce().getEquipment(weaponId); + boolean aiming = ash.isAimingAtLocation() && ash.allowAimedShotWith(weapon); ash.setEnableAll(aiming); if (aiming) { toHit = WeaponAttackAction.toHit(game, cen, target, diff --git a/megamek/src/megamek/client/ui/swing/SmallSVMunitionsChoicePanel.java b/megamek/src/megamek/client/ui/swing/SmallSVMunitionsChoicePanel.java index a88f06fe276..072768e21bf 100644 --- a/megamek/src/megamek/client/ui/swing/SmallSVMunitionsChoicePanel.java +++ b/megamek/src/megamek/client/ui/swing/SmallSVMunitionsChoicePanel.java @@ -125,7 +125,7 @@ class AmmoRowPanel extends JPanel { } private Mounted addAmmoMount(EquipmentType ammo, int shots) { - Mounted mount = new Mounted(weapon.getEntity(), ammo); + Mounted mount = Mounted.createMounted(weapon.getEntity(), ammo); mount.setOmniPodMounted(mount.isOmniPodMounted()); mount.setShotsLeft(shots); mount.setOriginalShots(shots); diff --git a/megamek/src/megamek/client/ui/swing/tooltip/UnitToolTip.java b/megamek/src/megamek/client/ui/swing/tooltip/UnitToolTip.java index 0050e49ea89..30bfcdac6c5 100644 --- a/megamek/src/megamek/client/ui/swing/tooltip/UnitToolTip.java +++ b/megamek/src/megamek/client/ui/swing/tooltip/UnitToolTip.java @@ -20,6 +20,7 @@ import megamek.common.*; import megamek.common.alphaStrike.AlphaStrikeElement; import megamek.common.annotations.Nullable; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.GameOptions; import megamek.common.options.OptionsConstants; import megamek.common.planetaryconditions.PlanetaryConditions; @@ -751,12 +752,12 @@ private static StringBuilder weaponList(Entity entity) { return new StringBuilder(); } - ArrayList weapons = entity.getWeaponList(); + List weapons = entity.getWeaponList(); HashMap wpInfos = new HashMap<>(); // Gather names, counts, Clan/IS WeaponInfo currentWp; - for (Mounted curWp: weapons) { - WeaponType wtype = (WeaponType) curWp.getType(); + for (WeaponMounted curWp: weapons) { + WeaponType wtype = curWp.getType(); if (isNotTTRelevant(wtype)) { continue; } diff --git a/megamek/src/megamek/client/ui/swing/unitDisplay/SystemPanel.java b/megamek/src/megamek/client/ui/swing/unitDisplay/SystemPanel.java index cefd08f53f3..a17f3790fe6 100644 --- a/megamek/src/megamek/client/ui/swing/unitDisplay/SystemPanel.java +++ b/megamek/src/megamek/client/ui/swing/unitDisplay/SystemPanel.java @@ -8,6 +8,7 @@ import megamek.client.ui.swing.util.UIUtil; import megamek.client.ui.swing.widget.*; import megamek.common.*; +import megamek.common.equipment.MiscMounted; import megamek.common.options.OptionsConstants; import megamek.common.preference.IPreferenceChangeListener; import megamek.common.preference.PreferenceChangeEvent; @@ -428,9 +429,9 @@ private String getMountedDisplay(Mounted m, int loc, CriticalSlot cs) { sb.append(')'); } - if ((m.getType() instanceof MiscType) && ((MiscType) m.getType()).isShield()) { - sb.append(" ").append(m.getDamageAbsorption(en, m.getLocation())).append('/') - .append(m.getCurrentDamageCapacity(en, m.getLocation())).append(')'); + if ((m instanceof MiscMounted) && ((MiscMounted) m).getType().isShield()) { + sb.append(" ").append(((MiscMounted) m).getDamageAbsorption(en, m.getLocation())).append('/') + .append(((MiscMounted) m).getCurrentDamageCapacity(en, m.getLocation())).append(')'); } } return sb.toString(); @@ -545,7 +546,7 @@ public void actionPerformed(ActionEvent ae) { return; } if ("dump".equals(ae.getActionCommand())) { - Mounted m = getSelectedEquipment(); + Mounted m = getSelectedEquipment(); boolean bOwner = clientgui.getClient().getLocalPlayer().equals(en.getOwner()); if ((m == null) || !bOwner) { return; diff --git a/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java b/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java index 04c0c351372..761009c6b1c 100644 --- a/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java +++ b/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java @@ -13,6 +13,8 @@ import megamek.common.*; import megamek.common.annotations.Nullable; import megamek.common.enums.WeaponSortOrder; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.OptionsConstants; import megamek.common.preference.IPreferenceChangeListener; import megamek.common.preference.PreferenceChangeEvent; @@ -79,7 +81,7 @@ public void mouseDragged(MouseEvent e) { int currentIndex = srcList.locationToIndex(e.getPoint()); if (currentIndex != dragSourceIndex) { int dragTargetIndex = srcList.getSelectedIndex(); - Mounted weap1 = srcModel.getWeaponAt(dragSourceIndex); + WeaponMounted weap1 = srcModel.getWeaponAt(dragSourceIndex); srcModel.swapIdx(dragSourceIndex, dragTargetIndex); dragSourceIndex = currentIndex; Entity ent = weap1.getEntity(); @@ -93,7 +95,7 @@ public void mouseDragged(MouseEvent e) { // Update custom order for (int i = 0; i < srcModel.getSize(); i++) { - Mounted m = srcModel.getWeaponAt(i); + WeaponMounted m = srcModel.getWeaponAt(i); ent.setCustomWeaponOrder(m, i); } } @@ -114,7 +116,7 @@ class WeaponListModel extends AbstractListModel { /** * A collection of Mounted instantiations. */ - private ArrayList weapons; + private List weapons; /** * The Entity that owns the collection of Mounteds. @@ -131,7 +133,7 @@ class WeaponListModel extends AbstractListModel { * * @param w */ - public void addWeapon(Mounted w) { + public void addWeapon(WeaponMounted w) { weapons.add(w); fireIntervalAdded(this, weapons.size() - 1, weapons.size() - 1); } @@ -144,7 +146,7 @@ public void addWeapon(Mounted w) { * @return */ public int getIndex(int weaponId) { - Mounted mount = en.getEquipment(weaponId); + Mounted mount = en.getEquipment(weaponId); for (int i = 0; i < weapons.size(); i++) { if (weapons.get(i).equals(mount)) { return i; @@ -171,14 +173,14 @@ public void swapIdx(int idx1, int idx2) { || (idx1 < 0) || (idx2 < 0)) { return; } - Mounted m1 = weapons.get(idx1); + WeaponMounted m1 = weapons.get(idx1); weapons.set(idx1, weapons.get(idx2)); weapons.set(idx2, m1); fireContentsChanged(this, idx1, idx1); fireContentsChanged(this, idx2, idx2); } - public Mounted getWeaponAt(int index) { + public WeaponMounted getWeaponAt(int index) { return weapons.get(index); } @@ -190,7 +192,7 @@ public Mounted getWeaponAt(int index) { */ @Override public String getElementAt(int index) { - final Mounted mounted = weapons.get(index); + final WeaponMounted mounted = weapons.get(index); final WeaponType wtype = (WeaponType) mounted.getType(); Game game = null; if (unitDisplay.getClientGUI() != null) { @@ -280,7 +282,7 @@ public int getSize() { * * @param comparator */ - public void sort(Comparator comparator) { + public void sort(Comparator comparator) { weapons.sort(comparator); fireContentsChanged(this, 0, weapons.size() - 1); } @@ -354,7 +356,7 @@ public void sort(Comparator comparator) { // I need to keep a pointer to the weapon list of the // currently selected mech. - private ArrayList vAmmo; + private ArrayList vAmmo; private Entity entity; private int minTopMargin = 8; @@ -930,7 +932,7 @@ public void setTarget(@Nullable Targetable target, @Nullable String extraInfo) { wTargetExtraInfo.setText(UnitToolTip.wrapWithHTML(txt)); } - private void updateTargetInfo() {; + private void updateTargetInfo() { String txt = ""; if (target == null) { @@ -1129,13 +1131,13 @@ public void displayMech(Entity en) { boolean hasFiredWeapons = false; for (int i = 0; i < entity.getWeaponList().size(); i++) { - Mounted mounted = entity.getWeaponList().get(i); + WeaponMounted mounted = entity.getWeaponList().get(i); // Don't add bomb weapons for LAMs in mech mode except RL and TAG. if ((entity instanceof LandAirMech) && (entity.getConversionMode() == LandAirMech.CONV_MODE_MECH) && mounted.getType().hasFlag(WeaponType.F_BOMB_WEAPON) - && ((WeaponType) mounted.getType()).getAmmoType() != AmmoType.T_RL_BOMB + && mounted.getType().getAmmoType() != AmmoType.T_RL_BOMB && !mounted.getType().hasFlag(WeaponType.F_TAG)) { continue; } @@ -1291,7 +1293,7 @@ public void selectWeapon(int wn) { /** * @return the Mounted for the selected weapon in the weapon list. */ - public Mounted getSelectedWeapon() { + public WeaponMounted getSelectedWeapon() { int selected = weaponList.getSelectedIndex(); if (selected == -1) { return null; @@ -1322,7 +1324,7 @@ public int selectFirstWeapon() { } WeaponListModel weapList = (WeaponListModel) weaponList.getModel(); for (int i = 0; i < weaponList.getModel().getSize(); i++) { - Mounted selectedWeap = weapList.getWeaponAt(i); + WeaponMounted selectedWeap = weapList.getWeaponAt(i); if (entity.isWeaponValidForPhase(selectedWeap)) { weaponList.setSelectedIndex(i); weaponList.ensureIndexIsVisible(i); @@ -1340,7 +1342,7 @@ public int getNextWeaponListIdx() { if (selected == -1) { selected = weaponList.getModel().getSize() - 1; } - Mounted selectedWeap; + WeaponMounted selectedWeap; int initialSelection = selected; boolean hasLooped = false; @@ -1370,7 +1372,7 @@ public int getPrevWeaponListIdx() { if (selected == -1) { selected = 0; } - Mounted selectedWeap; + WeaponMounted selectedWeap; int initialSelection = selected; boolean hasLooped = false; do { @@ -1478,9 +1480,9 @@ private void displaySelected() { return; } - Mounted mounted = ((WeaponListModel) weaponList.getModel()) + WeaponMounted mounted = (WeaponMounted) ((WeaponListModel) weaponList.getModel()) .getWeaponAt(weaponList.getSelectedIndex()); - WeaponType wtype = (WeaponType) mounted.getType(); + WeaponType wtype = mounted.getType(); // The rules are a bit sparse on airborne (dropping) ground units, but it seems they should // still attack like ground units. boolean aerospaceAttack = entity.isAero() && (entity.isAirborne() || entity.usesWeaponBays()); @@ -1876,8 +1878,8 @@ private void displaySelected() { } // Update the range display to account for the weapon's loaded ammo. - if (mounted.getLinked() != null) { - updateRangeDisplayForAmmo(mounted.getLinked()); + if ((mounted.getLinked() != null) && (mounted.getLinked() instanceof AmmoMounted)) { + updateRangeDisplayForAmmo((AmmoMounted) mounted.getLinked()); } if (aerospaceAttack) { @@ -1895,7 +1897,7 @@ private void displaySelected() { } else { // otherwise I need to replace range display with standard // ranges and attack values - updateAttackValues(mounted, mounted.getLinked()); + updateAttackValues(mounted, (AmmoMounted) mounted.getLinked()); } } @@ -1908,7 +1910,7 @@ private void displaySelected() { } else { m_chBayWeapon.setEnabled(true); for (int wId : mounted.getBayWeapons()) { - Mounted curWeapon = entity.getEquipment(wId); + WeaponMounted curWeapon = (WeaponMounted) entity.getEquipment(wId); if (null == curWeapon) { continue; } @@ -1925,15 +1927,14 @@ private void displaySelected() { // update ammo selector ((DefaultComboBoxModel) m_chAmmo.getModel()).removeAllElements(); - Mounted oldmount = mounted; + WeaponMounted oldmount = mounted; if (wtype instanceof BayWeapon) { int n = m_chBayWeapon.getSelectedIndex(); if (n == -1) { n = 0; } - mounted = entity.getEquipment(mounted.getBayWeapons() - .elementAt(n)); - wtype = (WeaponType) mounted.getType(); + mounted = (WeaponMounted) entity.getEquipment(mounted.getBayWeapons().get(n)); + wtype = mounted.getType(); } if (wtype.getAmmoType() == AmmoType.T_NA) { @@ -1942,7 +1943,7 @@ private void displaySelected() { || (entity.isSupportVehicle() && (wtype.getAmmoType() == AmmoType.T_INFANTRY))) { int count = 0; vAmmo = new ArrayList<>(); - for (Mounted current = mounted.getLinked(); current != null; current = current.getLinked()) { + for (AmmoMounted current = mounted.getLinkedAmmo(); current != null; current = (AmmoMounted) current.getLinked()) { if (current.getUsableShotsLeft() > 0) { vAmmo.add(current); m_chAmmo.addItem(formatAmmo(current)); @@ -1959,7 +1960,7 @@ private void displaySelected() { // this is the situation where there's some kind of ammo but it's not changeable } else if (wtype.hasFlag(WeaponType.F_ONESHOT)) { m_chAmmo.setEnabled(false); - Mounted mountedAmmo = mounted.getLinked(); + Mounted mountedAmmo = mounted.getLinked(); if (mountedAmmo != null) { m_chAmmo.addItem(formatAmmo(mountedAmmo)); } @@ -1969,7 +1970,7 @@ private void displaySelected() { int nCur = -1; int i = 0; //Ammo sharing between adjacent trailers - List fullAmmoList = new ArrayList<>(entity.getAmmo()); + List fullAmmoList = new ArrayList<>(entity.getAmmo()); if (entity.getTowedBy() != Entity.NONE) { Entity ahead = entity.getGame().getEntity(entity.getTowedBy()); fullAmmoList.addAll(ahead.getAmmo()); @@ -1978,8 +1979,8 @@ private void displaySelected() { Entity behind = entity.getGame().getEntity(entity.getTowing()); fullAmmoList.addAll(behind.getAmmo()); } - for (Mounted mountedAmmo : fullAmmoList) { - AmmoType atype = (AmmoType) mountedAmmo.getType(); + for (AmmoMounted mountedAmmo : fullAmmoList) { + AmmoType atype = mountedAmmo.getType(); // for all aero units other than fighters, // ammo must be located in the same place to be usable boolean same = true; @@ -2030,7 +2031,7 @@ private void displaySelected() { // this gathers all the range data // it is a boiled down version of displaySelected, // updateAttackValues, updateRangeDisplayForAmmo - private void setFieldOfFire(Mounted mounted) { + private void setFieldOfFire(WeaponMounted mounted) { // No field of fire without ClientGUI if (unitDisplay.getClientGUI() == null) { return; @@ -2038,7 +2039,7 @@ private void setFieldOfFire(Mounted mounted) { ClientGUI gui = unitDisplay.getClientGUI(); - WeaponType wtype = (WeaponType) mounted.getType(); + WeaponType wtype = mounted.getType(); int[][] ranges = new int[2][5]; ranges[0] = wtype.getRanges(mounted); @@ -2220,7 +2221,7 @@ private void setFieldOfFire(Mounted mounted) { unitDisplay.getClientGUI().getBoardView().setSensorRange(entity, entity.getPosition()); } - private String formatAmmo(Mounted m) { + private String formatAmmo(Mounted m) { StringBuffer sb = new StringBuffer(64); int ammoIndex = m.getDesc().indexOf(Messages.getString("MechDisplay.0")); int loc = m.getLocation(); @@ -2241,7 +2242,7 @@ private String formatAmmo(Mounted m) { return sb.toString(); } - private String formatBayWeapon(Mounted m) { + private String formatBayWeapon(WeaponMounted m) { StringBuffer sb = new StringBuffer(64); sb.append(m.getDesc()); return sb.toString(); @@ -2252,11 +2253,8 @@ private String formatBayWeapon(Mounted m) { * * @param mAmmo - the AmmoType of the weapon's loaded ammo. */ - private void updateRangeDisplayForAmmo(Mounted mAmmo) { - if (!(mAmmo.getType() instanceof AmmoType)) { - return; - } - AmmoType atype = (AmmoType) mAmmo.getType(); + private void updateRangeDisplayForAmmo(AmmoMounted mAmmo) { + AmmoType atype = mAmmo.getType(); // Only override the display for the various ATM and MML ammos if (atype.getAmmoType() == AmmoType.T_ATM) { if (atype.getMunitionType().contains(AmmoType.Munitions.M_EXTENDED_RANGE)) { @@ -2372,8 +2370,8 @@ private void updateRangeDisplayForAmmo(Mounted mAmmo) { onResize(); } // End private void updateRangeDisplayForAmmo( AmmoType ) - private void updateAttackValues(Mounted weapon, Mounted ammo) { - WeaponType wtype = (WeaponType) weapon.getType(); + private void updateAttackValues(WeaponMounted weapon, AmmoMounted ammo) { + WeaponType wtype = weapon.getType(); // update Attack Values and change range int avShort = wtype.getRoundShortAV(); int avMed = wtype.getRoundMedAV(); @@ -2383,7 +2381,7 @@ private void updateAttackValues(Mounted weapon, Mounted ammo) { // change range and attack values based upon ammo if (null != ammo) { - AmmoType atype = (AmmoType) ammo.getType(); + AmmoType atype = ammo.getType(); double[] changes = changeAttackValues(atype, avShort, avMed, avLong, avExt, maxr); avShort = (int) changes[0]; @@ -2579,10 +2577,10 @@ else if ((atype.getAmmoType() == AmmoType.T_LRM) } - private void compileWeaponBay(Mounted weapon, boolean isCapital) { + private void compileWeaponBay(WeaponMounted weapon, boolean isCapital) { - Vector bayWeapons = weapon.getBayWeapons(); - WeaponType wtype = (WeaponType) weapon.getType(); + List bayWeapons = weapon.getBayWeapons(); + WeaponType wtype = weapon.getType(); // set default values in case if statement stops wShortAVR.setText("---"); @@ -2602,7 +2600,7 @@ private void compileWeaponBay(Mounted weapon, boolean isCapital) { int maxr = WeaponType.RANGE_SHORT; for (int wId : bayWeapons) { - Mounted m = entity.getEquipment(wId); + WeaponMounted m = (WeaponMounted) entity.getEquipment(wId); if (!m.isBreached() && !m.isMissing() && !m.isDestroyed() @@ -2713,14 +2711,13 @@ public void valueChanged(ListSelectionEvent event) { if (currPanel instanceof FiringDisplay) { FiringDisplay firingDisplay = (FiringDisplay) currPanel; - Mounted mounted = null; - WeaponListModel weaponModel = (WeaponListModel) weaponList - .getModel(); + WeaponMounted mounted = null; + WeaponListModel weaponModel = (WeaponListModel) weaponList.getModel(); if (weaponList.getSelectedIndex() != -1) { mounted = weaponModel.getWeaponAt(weaponList .getSelectedIndex()); } - Mounted prevMounted = null; + WeaponMounted prevMounted = null; if ((event.getLastIndex() != -1) && (event.getLastIndex() < weaponModel.getSize())) { prevMounted = weaponModel.getWeaponAt(event.getLastIndex()); @@ -2775,11 +2772,10 @@ public void actionPerformed(ActionEvent ev) { if (weaponList.getSelectedIndex() == -1) { return; } - Mounted mWeap = ((WeaponListModel) weaponList.getModel()) - .getWeaponAt(n); - Mounted oldWeap = mWeap; - Mounted oldAmmo = mWeap.getLinked(); - Mounted mAmmo = vAmmo.get(m_chAmmo.getSelectedIndex()); + WeaponMounted mWeap = ((WeaponListModel) weaponList.getModel()).getWeaponAt(n); + WeaponMounted oldWeap = mWeap; + AmmoMounted oldAmmo = mWeap.getLinkedAmmo(); + AmmoMounted mAmmo = vAmmo.get(m_chAmmo.getSelectedIndex()); // if this is a weapon bay, then this is not what we want boolean isBay = false; if (mWeap.getType() instanceof BayWeapon) { @@ -2789,12 +2785,11 @@ public void actionPerformed(ActionEvent ev) { return; } // - Mounted sWeap = entity.getEquipment(mWeap.getBayWeapons() - .elementAt(n)); + Mounted sWeap = entity.getEquipment(mWeap.getBayWeapons().get(n)); // cycle through all weapons of the same type and load with // this ammo for (int wid : mWeap.getBayWeapons()) { - Mounted bWeap = entity.getEquipment(wid); + WeaponMounted bWeap = (WeaponMounted) entity.getEquipment(wid); // FIXME: Consider new AmmoType::equals / BombType::equals if (bWeap.getType().equals(sWeap.getType())) { entity.loadWeapon(bWeap, mAmmo); diff --git a/megamek/src/megamek/common/Aero.java b/megamek/src/megamek/common/Aero.java index 974545c8571..d5276bd1179 100644 --- a/megamek/src/megamek/common/Aero.java +++ b/megamek/src/megamek/common/Aero.java @@ -16,6 +16,7 @@ import megamek.client.ui.swing.calculationReport.CalculationReport; import megamek.common.cost.AeroCostCalculator; import megamek.common.enums.AimingMode; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.OptionsConstants; import megamek.common.planetaryconditions.PlanetaryConditions; import org.apache.logging.log4j.LogManager; @@ -1803,7 +1804,7 @@ public void addClanCase() { } if (explosiveFound) { try { - addEquipment(new Mounted(this, clCase), i, false); + addEquipment(Mounted.createMounted(this, clCase), i, false); } catch (LocationFullException ex) { // um, that's impossible. } @@ -2607,10 +2608,10 @@ public boolean isDmgHeavy() { return false; } - List weaponList = getTotalWeaponList(); + List weaponList = getTotalWeaponList(); int totalWeapons = weaponList.size(); int totalInoperable = 0; - for (Mounted weap : weaponList) { + for (WeaponMounted weap : weaponList) { if (weap.isCrippled()) { totalInoperable++; } @@ -2994,12 +2995,11 @@ public int getSpriteDrawPriority() { } @Override - public List getActiveAMS() { + public List getActiveAMS() { //Large craft use AMS and Point Defense bays - if ((this instanceof Dropship) || (this instanceof Jumpship)) { - - ArrayList ams = new ArrayList<>(); - for (Mounted weapon : getWeaponBayList()) { + if (isLargeCraft()) { + List ams = new ArrayList<>(); + for (WeaponMounted weapon : getWeaponBayList()) { // Skip anything that's not an AMS, AMS Bay or Point Defense Bay if (!weapon.getType().hasFlag(WeaponType.F_AMS) && !weapon.getType().hasFlag(WeaponType.F_AMSBAY) @@ -3022,8 +3022,8 @@ public List getActiveAMS() { // Make sure ammo is loaded for (int wId : weapon.getBayWeapons()) { - Mounted bayW = getEquipment(wId); - Mounted bayWAmmo = bayW.getLinked(); + Mounted bayW = getEquipment(wId); + Mounted bayWAmmo = bayW.getLinked(); if (!(weapon.getType().hasFlag(WeaponType.F_ENERGY)) && ((bayWAmmo == null) || (bayWAmmo.getUsableShotsLeft() == 0) || bayWAmmo.isDumping())) { diff --git a/megamek/src/megamek/common/AmmoType.java b/megamek/src/megamek/common/AmmoType.java index c47df1c7fb4..11c278dd8ff 100644 --- a/megamek/src/megamek/common/AmmoType.java +++ b/megamek/src/megamek/common/AmmoType.java @@ -22,6 +22,7 @@ import java.util.Set; import java.util.Vector; +import megamek.common.equipment.WeaponMounted; import org.apache.commons.lang.ArrayUtils; import megamek.common.options.OptionsConstants; @@ -14375,17 +14376,16 @@ public static boolean isAmmoValid(AmmoType ammoType, WeaponType weaponType) { * @return true/false - null arguments or linked ammo bin for the weapon result * in false */ - public static boolean canSwitchToAmmo(Mounted weapon, AmmoType otherAmmo) { + public static boolean canSwitchToAmmo(WeaponMounted weapon, AmmoType otherAmmo) { // no ammo switching if the weapon doesn't exist // or if it doesn't have an ammo bin // or the other ammo type doesn't exist - if ((weapon == null) || (weapon.getLinked() == null) - || (!(weapon.getLinked().getType() instanceof AmmoType)) + if ((weapon == null) || (weapon.getLinkedAmmo() == null) || (otherAmmo == null)) { return false; } - AmmoType currentAmmoType = (AmmoType) weapon.getLinked().getType(); + AmmoType currentAmmoType = weapon.getLinkedAmmo().getType(); // Ammo of the same type and rack size should be allowed boolean ammoOfSameType = currentAmmoType.equalsAmmoTypeOnly(otherAmmo) diff --git a/megamek/src/megamek/common/BattleArmor.java b/megamek/src/megamek/common/BattleArmor.java index ab81e73ce57..8677f0be8fe 100644 --- a/megamek/src/megamek/common/BattleArmor.java +++ b/megamek/src/megamek/common/BattleArmor.java @@ -17,6 +17,9 @@ import megamek.client.ui.swing.calculationReport.DummyCalculationReport; import megamek.common.cost.BattleArmorCostCalculator; import megamek.common.enums.AimingMode; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.MiscMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.OptionsConstants; import megamek.common.planetaryconditions.Atmosphere; import megamek.common.planetaryconditions.PlanetaryConditions; @@ -1238,7 +1241,7 @@ public int getRandomTrooper() { } @Override - public boolean loadWeapon(Mounted mounted, Mounted mountedAmmo) { + public boolean loadWeapon(WeaponMounted mounted, AmmoMounted mountedAmmo) { // BA must carry the ammo in same location as the weapon. // except for mine launcher mines // This allows for squad weapons and individual trooper weapons @@ -1252,7 +1255,7 @@ public boolean loadWeapon(Mounted mounted, Mounted mountedAmmo) { } @Override - public boolean loadWeaponWithSameAmmo(Mounted mounted, Mounted mountedAmmo) { + public boolean loadWeaponWithSameAmmo(WeaponMounted mounted, AmmoMounted mountedAmmo) { // BA must carry the ammo in same location as the weapon. // except for mine launcher mines // This allows for squad weapons and individual trooper weapons @@ -1268,7 +1271,7 @@ public boolean loadWeaponWithSameAmmo(Mounted mounted, Mounted mountedAmmo) { @Override public int getVibroClaws() { int claws = 0; - for (Mounted mounted : getMisc()) { + for (MiscMounted mounted : getMisc()) { if (mounted.getType().hasFlag(MiscType.F_VIBROCLAW)) { claws++; } diff --git a/megamek/src/megamek/common/BipedMech.java b/megamek/src/megamek/common/BipedMech.java index 3fc9674b50f..2203256a7c0 100644 --- a/megamek/src/megamek/common/BipedMech.java +++ b/megamek/src/megamek/common/BipedMech.java @@ -19,6 +19,7 @@ import java.util.ArrayList; import java.util.List; +import megamek.common.equipment.MiscMounted; import megamek.common.options.OptionsConstants; import megamek.common.planetaryconditions.PlanetaryConditions; @@ -575,10 +576,9 @@ public boolean hasActiveShield(int location) { continue; } - Mounted m = cs.getMount(); - EquipmentType type = m.getType(); - if ((type instanceof MiscType) && ((MiscType) type).isShield() && m.curMode().equals(MiscType.S_ACTIVE_SHIELD)) { - return m.getCurrentDamageCapacity(this, m.getLocation()) > 0; + Mounted m = cs.getMount(); + if ((m instanceof MiscMounted) && ((MiscMounted) m).getType().isShield() && m.curMode().equals(MiscType.S_ACTIVE_SHIELD)) { + return ((MiscMounted) m).getCurrentDamageCapacity(this, m.getLocation()) > 0; } } return false; @@ -645,10 +645,9 @@ public boolean hasPassiveShield(int location) { continue; } - Mounted m = cs.getMount(); - EquipmentType type = m.getType(); - if ((type instanceof MiscType) && ((MiscType) type).isShield() && m.curMode().equals(MiscType.S_PASSIVE_SHIELD)) { - return m.getCurrentDamageCapacity(this, m.getLocation()) > 0; + Mounted m = cs.getMount(); + if ((m instanceof MiscMounted) && ((MiscMounted) m).getType().isShield() && m.curMode().equals(MiscType.S_PASSIVE_SHIELD)) { + return ((MiscMounted) m).getCurrentDamageCapacity(this, m.getLocation()) > 0; } } return false; @@ -679,9 +678,8 @@ public boolean hasNoDefenseShield(int location) { continue; } - Mounted m = cs.getMount(); - EquipmentType type = m.getType(); - if ((type instanceof MiscType) && ((MiscType) type).isShield() && (m.curMode().equals(MiscType.S_NO_SHIELD) || isShutDown() || // if + Mounted m = cs.getMount(); + if ((m instanceof MiscMounted) && ((MiscMounted) m).getType().isShield() && (m.curMode().equals(MiscType.S_NO_SHIELD) || isShutDown() || // if // he // has // a @@ -692,7 +690,7 @@ public boolean hasNoDefenseShield(int location) { // defense mode getCrew().isKoThisRound() || getCrew() .isUnconscious())) { - return m.getCurrentDamageCapacity(this, m.getLocation()) > 0; + return ((MiscMounted) m).getCurrentDamageCapacity(this, m.getLocation()) > 0; } } return false; diff --git a/megamek/src/megamek/common/Compute.java b/megamek/src/megamek/common/Compute.java index 5f34e70277e..4586e2fe8d8 100644 --- a/megamek/src/megamek/common/Compute.java +++ b/megamek/src/megamek/common/Compute.java @@ -18,6 +18,8 @@ import megamek.common.MovePath.MoveStepType; import megamek.common.actions.*; import megamek.common.annotations.Nullable; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.enums.*; import megamek.common.options.OptionsConstants; import megamek.common.planetaryconditions.Atmosphere; @@ -1107,9 +1109,9 @@ public static ToHitData getImmobileMod(Targetable target, int aimingAt, AimingMo * * @return the modifiers */ - public static ToHitData getRangeMods(Game game, Entity ae, Mounted weapon, Mounted ammo, + public static ToHitData getRangeMods(Game game, Entity ae, WeaponMounted weapon, AmmoMounted ammo, Targetable target) { - WeaponType wtype = (WeaponType) weapon.getType(); + WeaponType wtype = weapon.getType(); int[] weaponRanges = wtype.getRanges(weapon, ammo); boolean isAttackerInfantry = (ae instanceof Infantry); boolean isAttackerBA = (ae instanceof BattleArmor); @@ -3118,7 +3120,7 @@ public static float getExpectedDamage(Game g, WeaponAttackAction waa, int infShootingStrength = 0; double infDamagePerTrooper = 0; - Mounted weapon = attacker.getEquipment(waa.getWeaponId()); + Mounted weapon = attacker.getEquipment(waa.getWeaponId()); Mounted lnk_guide; ToHitData hitData = waa.toHit(g, allECMInfo); @@ -3540,7 +3542,7 @@ public static double getAmmoAdjDamage(Game cgame, WeaponAttackAction atk) { Entity shooter, target; - Mounted fabin, best_bin; + AmmoMounted fabin, best_bin; AmmoType abin_type = new AmmoType(); AmmoType fabin_type = new AmmoType(); WeaponType wtype = new WeaponType(); @@ -3565,11 +3567,10 @@ public static double getAmmoAdjDamage(Game cgame, WeaponAttackAction atk) { fabin = null; best_bin = null; - for (Mounted abin : shooter.getAmmo()) { - if (shooter.loadWeapon(shooter.getEquipment(atk.getWeaponId()), - abin)) { + for (AmmoMounted abin : shooter.getAmmo()) { + if (shooter.loadWeapon((WeaponMounted) shooter.getEquipment(atk.getWeaponId()), abin)) { if (abin.getUsableShotsLeft() > 0) { - abin_type = (AmmoType) abin.getType(); + abin_type = abin.getType(); if (!AmmoType.canDeliverMinefield(abin_type)) { fabin = abin; fabin_type = (AmmoType) fabin.getType(); @@ -3582,9 +3583,8 @@ public static double getAmmoAdjDamage(Game cgame, WeaponAttackAction atk) { // To save processing time, lets see if we have more than one type of // bin // Thunder-type ammos and empty bins are excluded from the list - for (Mounted abin : shooter.getAmmo()) { - if (shooter.loadWeapon(shooter.getEquipment(atk.getWeaponId()), - abin)) { + for (AmmoMounted abin : shooter.getAmmo()) { + if (shooter.loadWeapon((WeaponMounted) shooter.getEquipment(atk.getWeaponId()), abin)) { if (abin.getUsableShotsLeft() > 0) { abin_type = (AmmoType) abin.getType(); if (!AmmoType.canDeliverMinefield(abin_type)) { @@ -3621,14 +3621,14 @@ public static double getAmmoAdjDamage(Game cgame, WeaponAttackAction atk) { best_bin = fabin; // For each valid ammo bin - for (Mounted abin : shooter.getAmmo()) { - if (shooter.loadWeapon(shooter.getEquipment(atk.getWeaponId()), abin)) { + for (AmmoMounted abin : shooter.getAmmo()) { + if (shooter.loadWeapon((WeaponMounted) shooter.getEquipment(atk.getWeaponId()), abin)) { if (abin.getUsableShotsLeft() > 0) { abin_type = (AmmoType) abin.getType(); if (!AmmoType.canDeliverMinefield(abin_type)) { // Load weapon with specified bin - shooter.loadWeapon(shooter.getEquipment(atk.getWeaponId()), abin); + shooter.loadWeapon((WeaponMounted) shooter.getEquipment(atk.getWeaponId()), abin); atk.setAmmoId(shooter.getEquipmentNum(abin)); atk.setAmmoMunitionType(abin_type.getMunitionType()); @@ -3812,7 +3812,7 @@ public static double getAmmoAdjDamage(Game cgame, WeaponAttackAction atk) { // Now that the best bin has been found, reload the weapon with // it - shooter.loadWeapon(shooter.getEquipment(atk.getWeaponId()), best_bin); + shooter.loadWeapon((WeaponMounted) shooter.getEquipment(atk.getWeaponId()), best_bin); atk.setAmmoId(shooter.getEquipmentNum(best_bin)); atk.setAmmoMunitionType(abin_type.getMunitionType()); } @@ -5627,7 +5627,7 @@ public static ToHitData getSpaceBombBaseToHit(Entity attacker, // must be in control if (a.isOutControlTotal()) { reason.append("the attacker is out of control"); - } else if (attacker.getBombs(AmmoType.F_SPACE_BOMB).size() < 1) { + } else if (attacker.getBombs(AmmoType.F_SPACE_BOMB).isEmpty()) { reason.append("the attacker has no useable bombs"); } else if (!rightFacing) { reason.append("the attacker is not facing the direction of travel"); @@ -6585,13 +6585,13 @@ public static int directBlowInfantryDamage(double damage, int mos, /** * @return the maximum damage that a set of weapons can generate. */ - public static int computeTotalDamage(List weaponList){ + public static int computeTotalDamage(List weaponList){ int totalDmg = 0; - for (Mounted weapon : weaponList) { + for (WeaponMounted weapon : weaponList) { if (!weapon.isBombMounted() && weapon.isCrippled()) { continue; } - WeaponType type = (WeaponType) weapon.getType(); + WeaponType type = weapon.getType(); if (type.getDamage() == WeaponType.DAMAGE_VARIABLE) { // Estimate rather than compute exact bay / trooper damage sum. totalDmg += type.getRackSize(); @@ -7036,11 +7036,11 @@ public static List getMountableUnits(Entity en, Coords pos, int elev, Ga } - public static boolean allowAimedShotWith(Mounted weapon, AimingMode aimingMode) { - WeaponType wtype = (WeaponType) weapon.getType(); + public static boolean allowAimedShotWith(WeaponMounted weapon, AimingMode aimingMode) { + WeaponType wtype = weapon.getType(); boolean isWeaponInfantry = wtype.hasFlag(WeaponType.F_INFANTRY); boolean usesAmmo = (wtype.getAmmoType() != AmmoType.T_NA) && !isWeaponInfantry; - Mounted ammo = usesAmmo ? weapon.getLinked() : null; + AmmoMounted ammo = usesAmmo ? weapon.getLinkedAmmo() : null; AmmoType atype = ammo == null ? null : (AmmoType) ammo.getType(); // Leg and swarm attacks can't be aimed. diff --git a/megamek/src/megamek/common/Dropship.java b/megamek/src/megamek/common/Dropship.java index 11b5c27f85f..d3bd1ecf9b9 100644 --- a/megamek/src/megamek/common/Dropship.java +++ b/megamek/src/megamek/common/Dropship.java @@ -13,6 +13,8 @@ import megamek.client.ui.swing.calculationReport.CalculationReport; import megamek.common.cost.DropShipCostCalculator; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.OptionsConstants; import megamek.common.planetaryconditions.Atmosphere; import megamek.common.planetaryconditions.PlanetaryConditions; @@ -394,17 +396,17 @@ public double getPriceMultiplier() { * need to check bay location before loading ammo */ @Override - public boolean loadWeapon(Mounted mounted, Mounted mountedAmmo) { + public boolean loadWeapon(WeaponMounted mounted, AmmoMounted mountedAmmo) { boolean success = false; - WeaponType wtype = (WeaponType) mounted.getType(); - AmmoType atype = (AmmoType) mountedAmmo.getType(); + WeaponType wtype = mounted.getType(); + AmmoType atype = mountedAmmo.getType(); if (mounted.getLocation() != mountedAmmo.getLocation()) { return success; } // for large craft, ammo must be in the same bay - Mounted bay = whichBay(getEquipmentNum(mounted)); + WeaponMounted bay = whichBay(getEquipmentNum(mounted)); if ((bay != null) && !bay.ammoInBay(getEquipmentNum(mountedAmmo))) { return success; } diff --git a/megamek/src/megamek/common/Entity.java b/megamek/src/megamek/common/Entity.java index 3f8467ad197..e44bb4083b6 100644 --- a/megamek/src/megamek/common/Entity.java +++ b/megamek/src/megamek/common/Entity.java @@ -27,7 +27,7 @@ import megamek.common.annotations.Nullable; import megamek.common.battlevalue.BVCalculator; import megamek.common.enums.*; -import megamek.common.equipment.ArmorType; +import megamek.common.equipment.*; import megamek.common.event.GameEntityChangeEvent; import megamek.common.force.Force; import megamek.common.icons.Camouflage; @@ -428,44 +428,44 @@ public abstract class Entity extends TurnOrdered implements Transporter, Targeta /** * A list of all mounted equipment. (Weapons, ammo, and misc) */ - protected ArrayList equipmentList = new ArrayList<>(); + protected List> equipmentList = new ArrayList<>(); /** * A list of all mounted weapons. This only includes regular weapons, not * bay mounts or grouped weapon mounts. */ - protected ArrayList weaponList = new ArrayList<>(); + protected List weaponList = new ArrayList<>(); /** * A list of all mounted weapon bays */ - protected ArrayList weaponBayList = new ArrayList<>(); + protected List weaponBayList = new ArrayList<>(); /** * A list of all mounted weapon groups */ - protected ArrayList weaponGroupList = new ArrayList<>(); + protected List weaponGroupList = new ArrayList<>(); /** * A list of every weapon mount, including bay mounts and weapon group * mounts */ - protected ArrayList totalWeaponList = new ArrayList<>(); + protected List totalWeaponList = new ArrayList<>(); /** * A list of all mounted ammo. */ - protected ArrayList ammoList = new ArrayList<>(); + protected List ammoList = new ArrayList<>(); /** * A list of all mounted bombs. */ - protected ArrayList bombList = new ArrayList<>(); + protected List bombList = new ArrayList<>(); /** * A list of all remaining equipment. */ - protected ArrayList miscList = new ArrayList<>(); + protected List miscList = new ArrayList<>(); protected ArrayList pendingINarcPods = new ArrayList<>(); protected ArrayList iNarcPods = new ArrayList<>(); @@ -898,13 +898,12 @@ protected boolean hasViableWeapons() { // Find any weapons with range of 6+ boolean hasRangeSixPlus = false; - List weaponList = getTotalWeaponList(); - for (Mounted weapon : weaponList) { + List weaponList = getTotalWeaponList(); + for (WeaponMounted weapon : weaponList) { if (weapon.isCrippled()) { continue; } - WeaponType type = (WeaponType) weapon.getType(); - if (type.getLongRange() >= 6) { + if (weapon.getType().getLongRange() >= 6) { hasRangeSixPlus = true; break; } @@ -917,7 +916,7 @@ protected boolean hasViableWeapons() { */ public void restore() { // restore all mounted equipments - for (Mounted mounted : equipmentList) { + for (Mounted mounted : equipmentList) { mounted.restore(); } @@ -1110,7 +1109,7 @@ public CompositeTechLevel factionTechLevel(int techFaction) { } CompositeTechLevel retVal = new CompositeTechLevel(this, techFaction); addSystemTechAdvancement(retVal); - for (Mounted m : getEquipment()) { + for (Mounted m : getEquipment()) { retVal.addComponent(m.getType()); if (m.isArmored()) { retVal.addComponent(TA_ARMORED_COMPONENT); @@ -1256,7 +1255,7 @@ public String getExtinctionRange() { */ public void recalculateTechAdvancement() { initTechAdvancement(); - for (Mounted m : getEquipment()) { + for (Mounted m : getEquipment()) { compositeTechLevel.addComponent(m.getType()); if (m.isArmored()) { compositeTechLevel.addComponent(TA_ARMORED_COMPONENT); @@ -2735,18 +2734,18 @@ public void setAlreadyTwisted(boolean value) { * also be unjammed if rapid-fire ACs is turned on. */ public boolean canUnjamRAC() { - for (Mounted mounted : getTotalWeaponList()) { - WeaponType wtype = (WeaponType) mounted.getType(); - if ((wtype.getAmmoType() == AmmoType.T_AC_ROTARY) + for (WeaponMounted mounted : getTotalWeaponList()) { + int ammotype = mounted.getType().getAmmoType(); + if ((ammotype == AmmoType.T_AC_ROTARY) && mounted.isJammed() && !mounted.isDestroyed()) { return true; } - if (((wtype.getAmmoType() == AmmoType.T_AC_ULTRA) - || (wtype.getAmmoType() == AmmoType.T_AC_ULTRA_THB) - || (wtype.getAmmoType() == AmmoType.T_AC) - || (wtype.getAmmoType() == AmmoType.T_LAC) - || (wtype.getAmmoType() == AmmoType.T_AC_IMP) - || (wtype.getAmmoType() == AmmoType.T_PAC)) + if (((ammotype == AmmoType.T_AC_ULTRA) + || (ammotype == AmmoType.T_AC_ULTRA_THB) + || (ammotype == AmmoType.T_AC) + || (ammotype == AmmoType.T_LAC) + || (ammotype == AmmoType.T_AC_IMP) + || (ammotype == AmmoType.T_PAC)) && mounted.isJammed() && !mounted.isDestroyed() && game.getOptions().booleanOption(OptionsConstants.ADVCOMBAT_UNJAM_UAC)) { @@ -3619,7 +3618,7 @@ && hasAbility(OptionsConstants.UNOFF_SOME_LIKE_IT_HOT)) { /** * Creates a new mount for this equipment and adds it in. */ - public Mounted addEquipment(EquipmentType etype, int loc) + public Mounted addEquipment(EquipmentType etype, int loc) throws LocationFullException { return addEquipment(etype, loc, false); } @@ -3627,7 +3626,7 @@ public Mounted addEquipment(EquipmentType etype, int loc) /** * Creates a new mount for this equipment and adds it in. */ - public Mounted addEquipment(EquipmentType etype, int loc, + public Mounted addEquipment(EquipmentType etype, int loc, boolean rearMounted) throws LocationFullException { return addEquipment(etype, loc, rearMounted, BattleArmor.MOUNT_LOC_NONE, false, false, false, false, false); @@ -3636,14 +3635,14 @@ public Mounted addEquipment(EquipmentType etype, int loc, /** * Creates a new mount for this equipment and adds it in. */ - public Mounted addEquipment(EquipmentType etype, int loc, + public Mounted addEquipment(EquipmentType etype, int loc, boolean rearMounted, int baMountLoc, boolean isArmored, boolean isTurreted) throws LocationFullException { return addEquipment(etype, loc, rearMounted, baMountLoc, isArmored, isTurreted, false, false, false); } - public Mounted addEquipment(EquipmentType etype, int loc, + public Mounted addEquipment(EquipmentType etype, int loc, boolean rearMounted, int baMountLoc, boolean isArmored, boolean isTurreted, boolean isSponsonTurreted) throws LocationFullException { @@ -3651,7 +3650,7 @@ public Mounted addEquipment(EquipmentType etype, int loc, isTurreted, isSponsonTurreted, false, false); } - public Mounted addEquipment(EquipmentType etype, int loc, + public Mounted addEquipment(EquipmentType etype, int loc, boolean rearMounted, int baMountLoc, boolean isArmored, boolean isTurreted, boolean isSponsonTurreted, boolean isPintleTurreted) throws LocationFullException { @@ -3659,11 +3658,11 @@ public Mounted addEquipment(EquipmentType etype, int loc, isTurreted, isSponsonTurreted, isPintleTurreted, false); } - public Mounted addEquipment(EquipmentType etype, int loc, + public Mounted addEquipment(EquipmentType etype, int loc, boolean rearMounted, int baMountLoc, boolean isArmored, boolean isTurreted, boolean isSponsonTurreted, boolean isPintleTurreted, boolean isOmniPodded) throws LocationFullException { - Mounted mounted = new Mounted(this, etype); + Mounted mounted = Mounted.createMounted(this, etype); mounted.setArmored(isArmored); mounted.setBaMountLoc(baMountLoc); mounted.setMechTurretMounted(isTurreted); @@ -3684,9 +3683,9 @@ public Mounted addEquipment(EquipmentType etype, int loc, * @return * @throws LocationFullException */ - public Mounted addEquipment(EquipmentType etype, int loc, + public Mounted addEquipment(EquipmentType etype, int loc, boolean rearMounted, int nAmmo) throws LocationFullException { - Mounted mounted = new Mounted(this, etype); + Mounted mounted = Mounted.createMounted(this, etype); addEquipment(mounted, loc, rearMounted, nAmmo); return mounted; @@ -3695,22 +3694,22 @@ public Mounted addEquipment(EquipmentType etype, int loc, /** * indicate whether this is a bomb mount */ - public Mounted addBomb(EquipmentType etype, int loc) + public Mounted addBomb(EquipmentType etype, int loc) throws LocationFullException { - Mounted mounted = new Mounted(this, etype); + Mounted mounted = Mounted.createMounted(this, etype); addBomb(mounted, loc); return mounted; } - protected void addBomb(Mounted mounted, int loc) + protected void addBomb(Mounted mounted, int loc) throws LocationFullException { mounted.setBombMounted(true); addEquipment(mounted, loc, false); } - public Mounted addWeaponGroup(EquipmentType etype, int loc) + public WeaponMounted addWeaponGroup(EquipmentType etype, int loc) throws LocationFullException { - Mounted mounted = new Mounted(this, etype); + WeaponMounted mounted = (WeaponMounted) Mounted.createMounted(this, etype); addEquipment(mounted, loc, false, true); return mounted; } @@ -3718,37 +3717,39 @@ public Mounted addWeaponGroup(EquipmentType etype, int loc) /** * indicate whether this is bodymounted for BAs */ - public Mounted addEquipment(EquipmentType etype, int loc, + public Mounted addEquipment(EquipmentType etype, int loc, boolean rearMounted, int baMountLoc, boolean dwpMounted) throws LocationFullException { - Mounted mounted = new Mounted(this, etype); + Mounted mounted = Mounted.createMounted(this, etype); mounted.setBaMountLoc(baMountLoc); mounted.setDWPMounted(dwpMounted); addEquipment(mounted, loc, rearMounted); return mounted; } - protected void addEquipment(Mounted mounted, int loc, boolean rearMounted, + protected void addEquipment(Mounted mounted, int loc, boolean rearMounted, int nAmmo) throws LocationFullException { - if ((mounted.getType() instanceof AmmoType) && (nAmmo > 1)) { + if ((mounted instanceof AmmoMounted) && (nAmmo > 1)) { mounted.setByShot(true); mounted.setShotsLeft(nAmmo); mounted.setOriginalShots(nAmmo); - double tonnage = Math.max(1, nAmmo / ((AmmoType) mounted.getType()).getShots()) * mounted.getTonnage(); - mounted.setAmmoCapacity(tonnage); + double tonnage = Math.max(1, nAmmo / ((AmmoMounted) mounted).getType().getShots()) * mounted.getTonnage(); + ((AmmoMounted) mounted).setAmmoCapacity(tonnage); } addEquipment(mounted, loc, rearMounted); } - protected void addEquipment(Mounted mounted, int loc, boolean rearMounted, + protected void addEquipment(Mounted mounted, int loc, boolean rearMounted, boolean isWeaponGroup) throws LocationFullException { - mounted.setWeaponGroup(true); + if (mounted instanceof WeaponMounted) { + mounted.setWeaponGroup(isWeaponGroup); + } addEquipment(mounted, loc, rearMounted); } - public void addEquipment(Mounted mounted, int loc, boolean rearMounted) + public void addEquipment(Mounted mounted, int loc, boolean rearMounted) throws LocationFullException { mounted.setLocation(loc, rearMounted); equipmentList.add(mounted); @@ -3759,14 +3760,14 @@ public void addEquipment(Mounted mounted, int loc, boolean rearMounted) } // add it to the proper sub-list - if (mounted.getType() instanceof WeaponType) { - totalWeaponList.add(mounted); + if (mounted instanceof WeaponMounted) { + totalWeaponList.add((WeaponMounted) mounted); if (mounted.isWeaponGroup()) { - weaponGroupList.add(mounted); + weaponGroupList.add((WeaponMounted) mounted); } else if (mounted.getType() instanceof BayWeapon) { - weaponBayList.add(mounted); + weaponBayList.add((WeaponMounted) mounted); } else { - weaponList.add(mounted); + weaponList.add((WeaponMounted) mounted); } if (mounted.getType().hasFlag(WeaponType.F_ARTILLERY)) { @@ -3780,18 +3781,18 @@ public void addEquipment(Mounted mounted, int loc, boolean rearMounted) addOneshotAmmo(mounted); } } - if (mounted.getType() instanceof AmmoType) { - ammoList.add(mounted); + if (mounted instanceof AmmoMounted) { + ammoList.add((AmmoMounted) mounted); } - if (mounted.getType() instanceof BombType) { - bombList.add(mounted); + if (mounted instanceof BombMounted) { + bombList.add((BombMounted) mounted); } - if (mounted.getType() instanceof MiscType) { - miscList.add(mounted); + if (mounted instanceof MiscMounted) { + miscList.add((MiscMounted) mounted); } } - private void addOneshotAmmo(Mounted mounted) throws LocationFullException { + private void addOneshotAmmo(Mounted mounted) throws LocationFullException { EquipmentType ammo; int shots; if (mounted.getType() instanceof InfantryWeapon) { @@ -3805,7 +3806,7 @@ private void addOneshotAmmo(Mounted mounted) throws LocationFullException { LogManager.getLogger().error("Equipment lookup failed for ammo for " + mounted.getName()); return; } - Mounted m = new Mounted(this, ammo); + Mounted m = Mounted.createMounted(this, ammo); m.setOmniPodMounted(mounted.isOmniPodMounted()); // BA pop-up mines can be fired individually and need a shot for each launcher in the squad. if (mounted.getType().hasFlag(WeaponType.F_BA_INDIVIDUAL)) { @@ -3819,7 +3820,7 @@ private void addOneshotAmmo(Mounted mounted) throws LocationFullException { // need to allow for two separate mounts. Some infantry weapons have alternate // inferno ammo, which will use the same mechanism but start with zero shots. if (mounted.getType().hasFlag(WeaponType.F_DOUBLE_ONESHOT)) { - Mounted m2 = new Mounted(this, m.getType()); + Mounted m2 = Mounted.createMounted(this, m.getType()); m2.setOmniPodMounted(mounted.isOmniPodMounted()); m2.setShotsLeft(shots); m2.setOriginalShots(shots); @@ -3827,7 +3828,7 @@ private void addOneshotAmmo(Mounted mounted) throws LocationFullException { addEquipment(m2, Entity.LOC_NONE, false); } else if ((mounted.getType() instanceof InfantryWeapon) && ((InfantryWeapon) mounted.getType()).hasInfernoAmmo()) { - Mounted m2 = new Mounted(this, EquipmentType.get(EquipmentTypeLookup.INFANTRY_INFERNO_AMMO)); + Mounted m2 = Mounted.createMounted(this, EquipmentType.get(EquipmentTypeLookup.INFANTRY_INFERNO_AMMO)); m2.setOmniPodMounted(mounted.isOmniPodMounted()); m2.setShotsLeft(0); m.setLinked(m2); @@ -3843,7 +3844,7 @@ public void addFailedEquipment(String s) { * Returns the equipment number of the specified equipment, or -1 if * equipment is not present. */ - public int getEquipmentNum(Mounted mounted) { + public int getEquipmentNum(Mounted mounted) { if (mounted != null) { return equipmentList.indexOf(mounted); } @@ -3853,14 +3854,14 @@ public int getEquipmentNum(Mounted mounted) { /** * Returns an enumeration of all equipment */ - public ArrayList getEquipment() { + public List> getEquipment() { return equipmentList; } /** * Returns the equipment, specified by number */ - public Mounted getEquipment(int index) { + public Mounted getEquipment(int index) { try { return equipmentList.get(index); } catch (IndexOutOfBoundsException ex) { @@ -3868,11 +3869,26 @@ public Mounted getEquipment(int index) { } } + public WeaponMounted getWeapon(int index) { + Mounted mounted = getEquipment(index); + return mounted instanceof WeaponMounted ? (WeaponMounted) mounted : null; + } + + public MiscMounted getMisc(int index) { + Mounted mounted = getEquipment(index); + return mounted instanceof MiscMounted ? (MiscMounted) mounted : null; + } + + public AmmoMounted getAmmo(int index) { + Mounted mounted = getEquipment(index); + return mounted instanceof AmmoMounted ? (AmmoMounted) mounted : null; + } + public EquipmentType getEquipmentType(CriticalSlot cs) { if (cs.getType() != CriticalSlot.TYPE_EQUIPMENT) { return null; } - Mounted m = cs.getMount(); + Mounted m = cs.getMount(); return m.getType(); } @@ -3886,7 +3902,7 @@ public Iterator getFailedEquipment() { public int getTotalAmmoOfType(EquipmentType et) { int totalShotsLeft = 0; - for (Mounted amounted : getAmmo()) { + for (AmmoMounted amounted : getAmmo()) { // FIXME: Consider new AmmoType::equals / BombType::equals if (amounted.getType().equals(et) && !amounted.isDumping()) { totalShotsLeft += amounted.getUsableShotsLeft(); @@ -3903,12 +3919,12 @@ public int getTotalAmmoOfType(EquipmentType et) { * @return the int count of the amount of shots of all * munitions available for the given weapon. */ - public int getTotalMunitionsOfType(Mounted weapon) { + public int getTotalMunitionsOfType(WeaponMounted weapon) { int totalShotsLeft = 0; // specifically don't count caseless munitions as being of the same type as non-caseless - for (Mounted amounted : getAmmo()) { - boolean canSwitchToAmmo = AmmoType.canSwitchToAmmo(weapon, (AmmoType) amounted.getType()); + for (AmmoMounted amounted : getAmmo()) { + boolean canSwitchToAmmo = AmmoType.canSwitchToAmmo(weapon, amounted.getType()); if (canSwitchToAmmo && !amounted.isDumping()) { totalShotsLeft += amounted.getUsableShotsLeft(); @@ -3928,7 +3944,7 @@ public int getTotalMunitionsOfType(Mounted weapon) { */ public abstract boolean isSecondaryArcWeapon(int weaponId); - public Iterator getWeapons() { + public Iterator getWeapons() { if (usesWeaponBays()) { return weaponBayList.iterator(); } @@ -3939,11 +3955,11 @@ public Iterator getWeapons() { return weaponList.iterator(); } - public ArrayList getIndividualWeaponList() { + public List getIndividualWeaponList() { return weaponList; } - public ArrayList getWeaponList() { + public List getWeaponList() { if (usesWeaponBays()) { return weaponBayList; } @@ -3954,16 +3970,16 @@ public ArrayList getWeaponList() { return weaponList; } - public List getTotalWeaponList() { + public List getTotalWeaponList() { // return full weapon list even bay mounts and weapon groups return totalWeaponList; } - public ArrayList getWeaponBayList() { + public List getWeaponBayList() { return weaponBayList; } - public ArrayList getWeaponGroupList() { + public List getWeaponGroupList() { return weaponGroupList; } @@ -3976,7 +3992,7 @@ public ArrayList getWeaponGroupList() { public int getFirstWeapon() { // Now phase appropriate, since we don't really care to select weapons // we can't use during this phase... do we? - for (Mounted mounted : getWeaponList()) { + for (WeaponMounted mounted : getWeaponList()) { // TAG only in the correct phase... if ((mounted.getType().hasFlag(WeaponType.F_TAG) && !getGame().getPhase().isOffboard()) || (!mounted.getType().hasFlag(WeaponType.F_TAG) && getGame().getPhase().isOffboard()) @@ -4026,7 +4042,7 @@ public boolean isWeaponValidForPhase(int weapNum) { * @param mounted * @return True if valid, else false */ - public boolean isWeaponValidForPhase(Mounted mounted) { + public boolean isWeaponValidForPhase(Mounted mounted) { // Start reached, now we can attempt to pick a weapon. if ((mounted != null) && (mounted.isReady()) @@ -4072,9 +4088,8 @@ public boolean isWeaponValidForPhase(Mounted mounted) { * Attempts to load all weapons with ammo */ public void loadAllWeapons() { - for (Mounted mounted : getTotalWeaponList()) { - WeaponType wtype = (WeaponType) mounted.getType(); - if (wtype.getAmmoType() != AmmoType.T_NA) { + for (WeaponMounted mounted : getTotalWeaponList()) { + if (mounted.getType().getAmmoType() != AmmoType.T_NA) { loadWeapon(mounted); } } @@ -4083,8 +4098,8 @@ public void loadAllWeapons() { /** * Tries to load the specified weapon with the first available ammo */ - public void loadWeapon(Mounted mounted) { - for (Mounted mountedAmmo : getAmmo()) { + public void loadWeapon(WeaponMounted mounted) { + for (AmmoMounted mountedAmmo : getAmmo()) { if (loadWeapon(mounted, mountedAmmo)) { break; } @@ -4101,8 +4116,8 @@ public void loadWeapon(Mounted mounted) { * If this unit is part of a train, also check the vehicles directly connected * to it for compatible ammo */ - public void loadWeaponWithSameAmmo(Mounted mounted) { - for (Mounted mountedAmmo : getAmmo()) { + public void loadWeaponWithSameAmmo(WeaponMounted mounted) { + for (AmmoMounted mountedAmmo : getAmmo()) { if (loadWeaponWithSameAmmo(mounted, mountedAmmo)) { return; } @@ -4111,7 +4126,7 @@ public void loadWeaponWithSameAmmo(Mounted mounted) { if (getTowedBy() != Entity.NONE) { Entity ahead = game.getEntity(getTowedBy()); if (ahead != null) { - for (Mounted towedByAmmo : ahead.getAmmo()) { + for (AmmoMounted towedByAmmo : ahead.getAmmo()) { if (loadWeaponWithSameAmmo(mounted, towedByAmmo)) { return; } @@ -4122,7 +4137,7 @@ public void loadWeaponWithSameAmmo(Mounted mounted) { if (getTowing() != Entity.NONE) { Entity behind = game.getEntity(getTowing()); if (behind != null) { - for (Mounted towingAmmo : behind.getAmmo()) { + for (AmmoMounted towingAmmo : behind.getAmmo()) { if (loadWeaponWithSameAmmo(mounted, towingAmmo)) { return; } @@ -4137,10 +4152,10 @@ public void loadWeaponWithSameAmmo(Mounted mounted) { * Tries to load the specified weapon with the specified ammo. Returns true * if successful, false otherwise. */ - public boolean loadWeapon(Mounted mounted, Mounted mountedAmmo) { + public boolean loadWeapon(WeaponMounted mounted, AmmoMounted mountedAmmo) { boolean success = false; - WeaponType wtype = (WeaponType) mounted.getType(); - AmmoType atype = (AmmoType) mountedAmmo.getType(); + WeaponType wtype = mounted.getType(); + AmmoType atype = mountedAmmo.getType(); if (mountedAmmo.isAmmoUsable() && !wtype.hasFlag(WeaponType.F_ONESHOT) && (atype.getAmmoType() == wtype.getAmmoType()) @@ -4151,7 +4166,7 @@ public boolean loadWeapon(Mounted mounted, Mounted mountedAmmo) { || (wtype.getAmmoType() == AmmoType.T_INFANTRY)) && (mountedAmmo.getLocation() == Entity.LOC_NONE)) { // Make sure this ammo is in the chain, then move it to the head. - for (Mounted current = mounted; current != null; current = current.getLinked()) { + for (Mounted current = mounted; current != null; current = current.getLinked()) { if (current == mountedAmmo) { current.getLinkedBy().setLinked(current.getLinked()); current.setLinked(mounted.getLinked()); @@ -4167,12 +4182,11 @@ public boolean loadWeapon(Mounted mounted, Mounted mountedAmmo) { * Tries to load the specified weapon with the specified ammo. Returns true * if successful, false otherwise. */ - public boolean loadWeaponWithSameAmmo(Mounted mounted, Mounted mountedAmmo) { - AmmoType atype = (AmmoType) mountedAmmo.getType(); - Mounted oldammo = mounted.getLinked(); + public boolean loadWeaponWithSameAmmo(WeaponMounted mounted, AmmoMounted mountedAmmo) { + AmmoType atype = mountedAmmo.getType(); + AmmoMounted oldammo = mounted.getLinkedAmmo(); - if ((oldammo != null) && (oldammo.getType() instanceof AmmoType) - && !oldammo.getType().equals(atype)) { + if ((oldammo != null) && !oldammo.getType().equals(atype)) { return false; } @@ -4214,7 +4228,7 @@ public boolean weaponFiredFrom(int loc) { return false; } - public ArrayList getAmmo() { + public List getAmmo() { return ammoList; } @@ -4222,14 +4236,13 @@ public ArrayList getAmmo() { * @param weapon we want to find available ammo for * @return an ArrayList containing _one_ Mounted ammo for each viable type */ - public ArrayList getAmmo(Mounted weapon) { - WeaponType wtype = (WeaponType) weapon.getType(); - Set etypes = new HashSet(); - ArrayList ammos = new ArrayList(); + public List getAmmo(WeaponMounted weapon) { + Set etypes = new HashSet<>(); + ArrayList ammos = new ArrayList<>(); // Only add one valid ammo to the list to reduce repeat calculations - for (Mounted ammo: ammoList) { - if (AmmoType.isAmmoValid(ammo, wtype)) { + for (AmmoMounted ammo: ammoList) { + if (AmmoType.isAmmoValid(ammo, weapon.getType())) { if (etypes.add(ammo.getType())) { ammos.add(ammo); } @@ -4238,17 +4251,18 @@ public ArrayList getAmmo(Mounted weapon) { // One entry per ammo type that is currently usable by this weapon. return ammos; } - public ArrayList getMisc() { + + public List getMisc() { return miscList; } - public List getBombs() { + public List getBombs() { return bombList; } - public Vector getBombs(BigInteger flag) { - Vector bombs = new Vector<>(); - for (Mounted bomb : getBombs()) { + public List getBombs(BigInteger flag) { + List bombs = new ArrayList<>(); + for (BombMounted bomb : getBombs()) { BombType btype = (BombType) bomb.getType(); if (!bomb.isInoperable() && (bomb.getUsableShotsLeft() > 0) && btype.hasFlag(flag)) { @@ -4262,11 +4276,11 @@ public Vector getBombs(BigInteger flag) { */ protected void resetBombAttacks() { // Remove all bomb attacks - List bombAttacksToRemove = new ArrayList<>(); + List bombAttacksToRemove = new ArrayList<>(); EquipmentType spaceBomb = EquipmentType.get(IBomber.SPACE_BOMB_ATTACK); EquipmentType altBomb = EquipmentType.get(IBomber.ALT_BOMB_ATTACK); EquipmentType diveBomb = EquipmentType.get(IBomber.DIVE_BOMB_ATTACK); - for (Mounted eq : equipmentList) { + for (WeaponMounted eq : totalWeaponList) { // FIXME: Consider new BombType::equals if (eq.getType().equals(spaceBomb) || eq.getType().equals(altBomb) || eq.getType().equals(diveBomb)) { @@ -4287,7 +4301,7 @@ protected void resetBombAttacks() { boolean foundSpaceBomb = false; int numGroundBombs = 0; - for (Mounted m : getBombs()) { + for (BombMounted m : getBombs()) { // Add the space bomb attack if (!foundSpaceBomb && game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_STRATOPS_SPACE_BOMB) @@ -4295,7 +4309,7 @@ protected void resetBombAttacks() { && isFighter() && game.getBoard().inSpace()) { try { - Mounted bomb = addEquipment(spaceBomb, m.getLocation(), false); + WeaponMounted bomb = (WeaponMounted) addEquipment(spaceBomb, m.getLocation(), false); if (hasETypeFlag(ETYPE_FIGHTER_SQUADRON)) { bomb.setWeaponGroup(true); weaponGroupList.add(bomb); @@ -4312,7 +4326,7 @@ && isFighter() && (getConversionMode() == LandAirMech.CONV_MODE_MECH))) { if (numGroundBombs < 1) { try { - Mounted bomb = addEquipment(diveBomb, m.getLocation(), false); + WeaponMounted bomb = (WeaponMounted) addEquipment(diveBomb, m.getLocation(), false); if (hasETypeFlag(ETYPE_FIGHTER_SQUADRON)) { bomb.setWeaponGroup(true); weaponGroupList.add(bomb); @@ -4324,7 +4338,7 @@ && isFighter() if ((numGroundBombs < 10) && isFighter()) { try { - Mounted bomb = addEquipment(altBomb, m.getLocation(), false); + WeaponMounted bomb = (WeaponMounted) addEquipment(altBomb, m.getLocation(), false); if (hasETypeFlag(ETYPE_FIGHTER_SQUADRON)) { bomb.setWeaponGroup(true); weaponGroupList.add(bomb); @@ -4343,7 +4357,7 @@ && isFighter() * for removing broken tree clubs. */ public void removeMisc(String toRemove) { - for (Mounted mounted : getMisc()) { + for (MiscMounted mounted : getMisc()) { if (mounted.getName().equals(toRemove)) { miscList.remove(mounted); equipmentList.remove(mounted); @@ -4352,24 +4366,12 @@ public void removeMisc(String toRemove) { } } - public void removeWeapon(String toRemove) { - for (Mounted mounted : getMisc()) { - if (mounted.getName().equals(toRemove)) { - weaponList.remove(mounted); - equipmentList.remove(mounted); - break; - } - } - } - /** * Clear all bombs and bomb attacks */ public void clearBombs() { bombList.clear(); - for (Iterator i = equipmentList.iterator(); i.hasNext(); ) { - Mounted m = i.next(); - if ((m.getType() instanceof BombType) + equipmentList.removeIf(m -> (m.getType() instanceof BombType) || (m.getType() instanceof DiveBombAttack) || (m.getType() instanceof SpaceBombAttack) || (m.getType() instanceof AltitudeBombAttack) @@ -4382,17 +4384,12 @@ public void clearBombs() { || (m.getType() instanceof ISLAAMissileWeapon) || (m.getType() instanceof CLLAAMissileWeapon) || (m.getType() instanceof BombArrowIV) - /*|| m.getType() instanceof CLBombArrowIV*/ - || (m.getType() instanceof CLBombTAG) - || (m.getType() instanceof ISBombTAG) - || (m.getType() instanceof BombISRL10) - || (m.getType() instanceof AlamoMissileWeapon)) { - i.remove(); - } - } - for (Iterator i = weaponList.iterator(); i.hasNext(); ) { - Mounted m = i.next(); - if ((m.getType() instanceof DiveBombAttack) + /*|| m.getType() instanceof CLBombArrowIV*/ + || (m.getType() instanceof CLBombTAG) + || (m.getType() instanceof ISBombTAG) + || (m.getType() instanceof BombISRL10) + || (m.getType() instanceof AlamoMissileWeapon)); + weaponList.removeIf(m -> (m.getType() instanceof DiveBombAttack) || (m.getType() instanceof SpaceBombAttack) || (m.getType() instanceof AltitudeBombAttack) || (m.getType() instanceof ISAAAMissileWeapon) @@ -4404,20 +4401,17 @@ public void clearBombs() { || (m.getType() instanceof ISLAAMissileWeapon) || (m.getType() instanceof CLLAAMissileWeapon) || (m.getType() instanceof BombArrowIV) - /*|| m.getType() instanceof CLBombArrowIV*/ - || (m.getType() instanceof CLBombTAG) - || (m.getType() instanceof ISBombTAG) - || (m.getType() instanceof BombISRL10) - || (m.getType() instanceof AlamoMissileWeapon)) { - i.remove(); - } - } + /*|| m.getType() instanceof CLBombArrowIV*/ + || (m.getType() instanceof CLBombTAG) + || (m.getType() instanceof ISBombTAG) + || (m.getType() instanceof BombISRL10) + || (m.getType() instanceof AlamoMissileWeapon)); ammoList.removeIf(m -> m.getType() instanceof BombType); } - public List getClubs() { - List rv = new ArrayList<>(); - for (Mounted m : getMisc()) { + public List getClubs() { + List rv = new ArrayList<>(); + for (MiscMounted m : getMisc()) { if (m.getType().hasFlag(MiscType.F_CLUB)) { rv.add(m); } @@ -4443,13 +4437,10 @@ public boolean hasWorkingMisc(BigInteger flag) { * @return true if at least one ready item. */ public boolean hasWorkingMisc(BigInteger flag, long secondary) { - for (Mounted m : miscList) { - if ((m.getType() instanceof MiscType) && m.isReady()) { - MiscType type = (MiscType) m.getType(); - if (type.hasFlag(flag) - && ((secondary == -1) || type.hasSubType(secondary))) { - return true; - } + for (MiscMounted m : miscList) { + if (m.isReady() && m.getType().hasFlag(flag) + && ((secondary == -1) || m.getType().hasSubType(secondary))) { + return true; } } return false; @@ -4459,7 +4450,7 @@ public boolean hasMisc(BigInteger flag) { return miscList.stream().anyMatch(misc -> misc.getType().hasFlag(flag)); } - public List getMiscEquipment(BigInteger flag) { + public List getMiscEquipment(BigInteger flag) { return miscList.stream() .filter(item -> item.getType().hasFlag(flag)) .collect(Collectors.toList()); @@ -4488,7 +4479,7 @@ public int countWorkingMisc(BigInteger flag) { public int countWorkingMisc(BigInteger flag, int location) { int count = 0; - OUTER: for (Mounted m : getMisc()) { + OUTER: for (MiscMounted m : getMisc()) { if (!m.isInoperable() && m.getType().hasFlag(flag) && ((location == -1) || (m.getLocation() == location))) { if (m.hasModes()) { @@ -4506,7 +4497,7 @@ public int countWorkingMisc(BigInteger flag, int location) { public int countWorkingMisc(String internalName, int location) { int count = 0; - OUTER: for (Mounted m : getMisc()) { + OUTER: for (MiscMounted m : getMisc()) { if (!m.isInoperable() && m.getType().getInternalName().equalsIgnoreCase(internalName) && ((location == -1) || (m.getLocation() == location))) { if (m.hasModes()) { @@ -4529,12 +4520,9 @@ public int countWorkingMisc(String internalName, int location) { * @return true if at least one ready item. */ public boolean hasWorkingMisc(String name) { - for (Mounted m : miscList) { - if ((m.getType() instanceof MiscType) && m.isReady()) { - MiscType type = (MiscType) m.getType(); - if (type.internalName.equalsIgnoreCase(name)) { - return true; - } + for (MiscMounted m : miscList) { + if (m.isReady() && m.getType().internalName.equalsIgnoreCase(name)) { + return true; } } return false; @@ -4555,7 +4543,7 @@ public boolean hasWorkingMisc(BigInteger flag, long secondary, int location) { CriticalSlot crit = getCritical(location, slot); if ((null != crit) && (crit.getType() == CriticalSlot.TYPE_EQUIPMENT)) { - Mounted mount = crit.getMount(); + Mounted mount = crit.getMount(); if (mount == null) { continue; } @@ -4588,13 +4576,10 @@ public boolean hasWorkingWeapon(BigInteger flag) { * @return true if at least one ready item. */ public boolean hasWorkingWeapon(BigInteger flag, long secondary) { - for (Mounted m : weaponList) { - if ((m.getType() instanceof WeaponType) && m.isReady()) { - WeaponType type = (WeaponType) m.getType(); - if (type.hasFlag(flag) - && ((secondary == -1) || type.hasSubType(secondary))) { - return true; - } + for (WeaponMounted m : weaponList) { + if (m.isReady() && m.getType().hasFlag(flag) + && ((secondary == -1) || m.getType().hasSubType(secondary))) { + return true; } } return false; @@ -4607,12 +4592,9 @@ public boolean hasWorkingWeapon(BigInteger flag, long secondary) { * @return true if at least one ready item. */ public boolean hasWorkingWeapon(String name) { - for (Mounted m : weaponList) { - if ((m.getType() instanceof WeaponType) && m.isReady()) { - WeaponType type = (WeaponType) m.getType(); - if (type.getInternalName().equalsIgnoreCase(name)) { - return true; - } + for (WeaponMounted m : weaponList) { + if (m.isReady() && m.getType().getInternalName().equalsIgnoreCase(name)) { + return true; } } return false; @@ -4633,7 +4615,7 @@ public boolean hasWorkingWeapon(BigInteger flag, int secondary, int location) { CriticalSlot crit = getCritical(location, slot); if ((null != crit) && (crit.getType() == CriticalSlot.TYPE_EQUIPMENT)) { - Mounted mount = crit.getMount(); + Mounted mount = crit.getMount(); if (mount == null) { continue; } @@ -4832,7 +4814,7 @@ public int getGyroType() { } public static Map getAllGyroCodeName() { - Map result = new HashMap(); + Map result = new HashMap<>(); result.put(Mech.GYRO_UNKNOWN, Mech.getGyroDisplayString(Mech.GYRO_UNKNOWN)); result.put(Mech.GYRO_STANDARD, Mech.getGyroDisplayString(Mech.GYRO_STANDARD)); @@ -4900,7 +4882,7 @@ public int getHitCriticals(int type, int index, int loc) { */ protected int critStateCount(int type, int index, int loc, Predicate slotState) { int stateAppliesCount = 0; - Mounted m = null; + Mounted m = null; if (type == CriticalSlot.TYPE_EQUIPMENT) { m = getEquipment(index); if (m == null) { @@ -4999,7 +4981,7 @@ public int getNumberOfCriticals(EquipmentType etype) { */ public int getNumberOf(EquipmentType etype) { int total = 0; - for (Mounted m : equipmentList) { + for (Mounted m : equipmentList) { if (m.getType().equals(etype)) { total++; } @@ -5186,10 +5168,8 @@ public int getActiveUMUCount() { return 0; } int count = 0; - for (Mounted m : getMisc()) { - EquipmentType type = m.getType(); - if ((type instanceof MiscType) && type.hasFlag(MiscType.F_UMU) - && !(m.isDestroyed() || m.isMissing() || m.isBreached())) { + for (MiscMounted m : getMisc()) { + if (m.getType().hasFlag(MiscType.F_UMU) && !(m.isDestroyed() || m.isMissing() || m.isBreached())) { count++; } } @@ -5206,9 +5186,8 @@ public int getAllUMUCount() { return 0; } int count = 0; - for (Mounted m : getMisc()) { - EquipmentType type = m.getType(); - if ((type instanceof MiscType) && type.hasFlag(MiscType.F_UMU)) { + for (MiscMounted m : getMisc()) { + if (m.getType().hasFlag(MiscType.F_UMU)) { count++; } } @@ -5235,16 +5214,14 @@ public boolean hasActiveECM(boolean stealth) { return false; } if (!isShutDown()) { - for (Mounted m : getMisc()) { - EquipmentType type = m.getType(); + for (MiscMounted m : getMisc()) { // EQ equipment does not count for stealth armor - if (stealth && type.hasFlag(MiscType.F_EW_EQUIPMENT)) { + if (stealth && m.getType().hasFlag(MiscType.F_EW_EQUIPMENT)) { continue; } // TacOps p. 100 Angle ECM can have 1 ECM and 1 ECCM at the same // time - if ((type instanceof MiscType) - && type.hasFlag(MiscType.F_ECM) + if (m.getType().hasFlag(MiscType.F_ECM) && (m.curMode().equals("ECM") || m.curMode().equals("ECM & ECCM") || m .curMode().equals("ECM & Ghost Targets"))) { @@ -5266,10 +5243,8 @@ public boolean hasActiveAngelECM() { } if (game.getOptions().booleanOption(OptionsConstants.ADVANCED_TACOPS_ANGEL_ECM) && !isShutDown()) { - for (Mounted m : getMisc()) { - EquipmentType type = m.getType(); - if ((type instanceof MiscType) - && type.hasFlag(MiscType.F_ANGEL_ECM) + for (MiscMounted m : getMisc()) { + if (m.getType().hasFlag(MiscType.F_ANGEL_ECM) && (m.curMode().equals("ECM") || m.curMode().equals("ECM & ECCM") || m .curMode().equals("ECM & Ghost Targets"))) { @@ -5290,10 +5265,8 @@ public boolean hasActiveNovaECM() { return false; } if (!isShutDown()) { - for (Mounted m : getMisc()) { - EquipmentType type = m.getType(); - if ((type instanceof MiscType) && type.hasFlag(MiscType.F_NOVA) - && m.curMode().equals("ECM")) { + for (MiscMounted m : getMisc()) { + if (m.getType().hasFlag(MiscType.F_NOVA) && m.curMode().equals("ECM")) { return !(m.isInoperable()); } } @@ -5326,20 +5299,18 @@ public boolean hasGhostTargets(boolean active) { return false; } boolean hasGhost = false; - for (Mounted m : getMisc()) { - EquipmentType type = m.getType(); + for (MiscMounted m : getMisc()) { + MiscType type = m.getType(); // TacOps p. 100 Angle ECM can have ECM/ECCM and Ghost Targets at // the same time - if ((type instanceof MiscType) - && type.hasFlag(MiscType.F_ECM) + if (type.hasFlag(MiscType.F_ECM) && (m.curMode().equals("Ghost Targets") || m.curMode().equals("ECM & Ghost Targets") || m .curMode().equals("ECCM & Ghost Targets")) && !(m.isInoperable() || getCrew().isUnconscious())) { hasGhost = true; } - if ((type instanceof MiscType) - && type.hasFlag(MiscType.F_COMMUNICATIONS) + if (type.hasFlag(MiscType.F_COMMUNICATIONS) && m.curMode().equals("Ghost Targets") && (getTotalCommGearTons() >= 7) && !(m.isInoperable() || getCrew().isUnconscious())) { @@ -5365,17 +5336,14 @@ public boolean hasActiveECCM() { } if ((game.getOptions().booleanOption(OptionsConstants.ADVANCED_TACOPS_ECCM) || game .getOptions().booleanOption(OptionsConstants.ADVAERORULES_STRATOPS_ECM)) && !isShutDown()) { - for (Mounted m : getMisc()) { - EquipmentType type = m.getType(); + for (MiscMounted m : getMisc()) { + MiscType type = m.getType(); // TacOps p. 100 Angle ECM can have 1 ECM and 1 ECCM at the same // time - if ((type instanceof MiscType) - && ((type.hasFlag(MiscType.F_ECM) && (m.curMode() - .equals("ECCM") - || m.curMode().equals("ECM & ECCM") || m - .curMode().equals("ECCM & Ghost Targets"))) || (type - .hasFlag(MiscType.F_COMMUNICATIONS) && m - .curMode().equals("ECCM")))) { + if (((type.hasFlag(MiscType.F_ECM) + && (m.curMode().equals("ECCM") || m.curMode().equals("ECM & ECCM") + || m.curMode().equals("ECCM & Ghost Targets"))) + || (type.hasFlag(MiscType.F_COMMUNICATIONS) && m.curMode().equals("ECCM")))) { return !m.isInoperable(); } } @@ -5395,10 +5363,9 @@ public boolean hasActiveAngelECCM() { if (game.getOptions().booleanOption(OptionsConstants.ADVANCED_TACOPS_ANGEL_ECM) && game.getOptions().booleanOption(OptionsConstants.ADVANCED_TACOPS_ECCM) && !isShutDown()) { - for (Mounted m : getMisc()) { + for (MiscMounted m : getMisc()) { EquipmentType type = m.getType(); - if ((type instanceof MiscType) - && type.hasFlag(MiscType.F_ANGEL_ECM) + if (m.getType().hasFlag(MiscType.F_ANGEL_ECM) && (m.curMode().equals("ECCM") || m.curMode().equals("ECM & ECCM") || m .curMode().equals("ECCM & Ghost Targets"))) { @@ -5428,9 +5395,9 @@ public int getECMRange() { } if (!isShutDown()) { - for (Mounted m : getMisc()) { - EquipmentType type = m.getType(); - if ((type instanceof MiscType) && type.hasFlag(MiscType.F_ECM) + for (MiscMounted m : getMisc()) { + MiscType type = m.getType(); + if (type.hasFlag(MiscType.F_ECM) && !m.isInoperable()) { if (type.hasFlag(MiscType.F_SINGLE_HEX_ECM)) { return 0; @@ -5472,14 +5439,12 @@ public boolean hasBAP(boolean checkECM) { if (isShutDown()) { return false; } - - for (Mounted m : getMisc()) { - EquipmentType type = m.getType(); - if ((type instanceof MiscType) && type.hasFlag(MiscType.F_BAP)) { + for (MiscMounted m : getMisc()) { + if (m.getType().hasFlag(MiscType.F_BAP)) { if (!m.isInoperable()) { // Beagle Isn't affected by normal ECM - if (type.getName().equals("Beagle Active Probe")) { + if (m.getType().getName().equals("Beagle Active Probe")) { return (game == null) || !checkECM || !ComputeECM.isAffectedByAngelECM(this, getPosition(), getPosition()); @@ -5549,9 +5514,9 @@ && isConventionalInfantry()) spaBonus = 1; } - for (Mounted m : getMisc()) { - EquipmentType type = m.getType(); - if ((type instanceof MiscType) && type.hasFlag(MiscType.F_BAP) && !m.isInoperable()) { + for (MiscMounted m : getMisc()) { + MiscType type = m.getType(); + if (type.hasFlag(MiscType.F_BAP) && !m.isInoperable()) { // Quirk bonus is only 2 if equipped with BAP if (quirkBonus > 0) { quirkBonus = 2; @@ -5602,9 +5567,8 @@ public boolean hasDroneOs() { * Returns wether or not this entity has a Targeting Computer. */ public boolean hasTargComp() { - for (Mounted m : getMisc()) { - if ((m.getType() instanceof MiscType) - && m.getType().hasFlag(MiscType.F_TARGCOMP)) { + for (MiscMounted m : getMisc()) { + if (m.getType().hasFlag(MiscType.F_TARGCOMP)) { return !m.isInoperable(); } } @@ -5625,9 +5589,8 @@ public boolean hasAimModeTargComp() { return true; } } - for (Mounted m : getMisc()) { - if ((m.getType() instanceof MiscType) - && m.getType().hasFlag(MiscType.F_TARGCOMP) + for (MiscMounted m : getMisc()) { + if (m.getType().hasFlag(MiscType.F_TARGCOMP) && m.curMode().equals("Aimed shot")) { return !m.isInoperable(); } @@ -5642,10 +5605,8 @@ public boolean hasC3S() { if (isShutDown() || isOffBoard()) { return false; } - for (Mounted m : getEquipment()) { - if ((m.getType() instanceof MiscType) - && (m.getType().hasFlag(MiscType.F_C3S) || m.getType() - .hasFlag(MiscType.F_C3SBS)) && !m.isInoperable()) { + for (MiscMounted m : getMisc()) { + if ((m.getType().hasFlag(MiscType.F_C3S) || m.getType().hasFlag(MiscType.F_C3SBS)) && !m.isInoperable()) { return true; } } @@ -5659,9 +5620,7 @@ public boolean hasC3S() { * @return True if the unit has CASE II */ public boolean hasCASEII() { - return getMisc().stream() - .filter(m -> m.getType() instanceof MiscType) - .anyMatch(m -> m.getType().hasFlag(MiscType.F_CASEII)); + return getMisc().stream().anyMatch(m -> m.getType().hasFlag(MiscType.F_CASEII)); } /** @@ -5674,7 +5633,6 @@ public boolean hasCASEII() { public boolean hasCASEII(int location) { return getMisc().stream() .filter(m -> m.getLocation() == location) - .filter(m -> m.getType() instanceof MiscType) .anyMatch(m -> m.getType().hasFlag(MiscType.F_CASEII)); } @@ -5688,7 +5646,7 @@ public boolean hasCASEII(int location) { * @return a boolean value indicating a present HarJel system */ public boolean hasHarJelIn(int location) { - for (Mounted mounted : getMisc()) { + for (MiscMounted mounted : getMisc()) { if ((mounted.getLocation() == location) && mounted.isReady() && (mounted.getType().hasFlag(MiscType.F_HARJEL))) { @@ -5702,10 +5660,10 @@ public boolean hasBoostedC3() { if (isShutDown() || isOffBoard()) { return false; } - for (Mounted m : getEquipment()) { - if ((m.getType().hasFlag(MiscType.F_C3SBS) || m.getType().hasFlag( - WeaponType.F_C3MBS)) - && !m.isInoperable()) { + for (Mounted m : getEquipment()) { + if (((m.getType() instanceof MiscType) && m.getType().hasFlag(MiscType.F_C3SBS)) + || ((m.getType() instanceof WeaponType) && m.getType().hasFlag(WeaponType.F_C3MBS)) + && !m.isInoperable()) { return true; } } @@ -5721,10 +5679,8 @@ public boolean hasC3M() { if (isShutDown() || isOffBoard()) { return false; } - for (Mounted m : getEquipment()) { - if ((m.getType() instanceof WeaponType) - && (m.getType().hasFlag(WeaponType.F_C3M) || m.getType() - .hasFlag(WeaponType.F_C3MBS)) && !m.isInoperable()) { + for (WeaponMounted m : getWeaponList()) { + if ((m.getType().hasFlag(WeaponType.F_C3M) || m.getType().hasFlag(WeaponType.F_C3MBS)) && !m.isInoperable()) { // If this unit is configured as a company commander, // and if this computer is the company master, then // this unit does not have a lance master computer. @@ -5746,9 +5702,9 @@ public boolean hasC3MM() { // Do we need to determine that there's no company command master? if (c3CompanyMasterIndex == LOC_DESTROYED) { - Iterator e = getEquipment().iterator(); + Iterator> e = getEquipment().iterator(); while ((c3CompanyMasterIndex == LOC_DESTROYED) && e.hasNext()) { - Mounted m = e.next(); + Mounted m = e.next(); if ((m.getType() instanceof WeaponType) && (m.getType().hasFlag(WeaponType.F_C3M) || m .getType().hasFlag(WeaponType.F_C3MBS)) @@ -5774,7 +5730,7 @@ public boolean hasC3MM() { } } - Mounted m = getEquipment(c3CompanyMasterIndex); + Mounted m = getEquipment(c3CompanyMasterIndex); if (!m.isDestroyed() && !m.isBreached()) { return true; } @@ -5799,10 +5755,8 @@ public boolean hasActiveNovaCEWS() { if (isShutDown() || isOffBoard()) { return false; } - for (Mounted m : getEquipment()) { - if ((m.getType() instanceof MiscType) - && m.getType().hasFlag(MiscType.F_NOVA) - && !m.isInoperable() && !m.curMode().equals("Off")) { + for (MiscMounted m : getMisc()) { + if (m.getType().hasFlag(MiscType.F_NOVA) && !m.isInoperable() && !m.curMode().equals("Off")) { return true; } } @@ -5810,10 +5764,8 @@ public boolean hasActiveNovaCEWS() { } public boolean hasNovaCEWS() { - for (Mounted m : getEquipment()) { - if ((m.getType() instanceof MiscType) - && m.getType().hasFlag(MiscType.F_NOVA) - && !m.isInoperable()) { + for (MiscMounted m : getMisc()) { + if (m.getType().hasFlag(MiscType.F_NOVA) && !m.isInoperable()) { return true; } } @@ -5824,9 +5776,8 @@ public boolean hasNavalC3() { if (isShutDown() || isOffBoard()) { return false; } - for (Mounted m : getEquipment()) { - if ((m.getType() instanceof MiscType) - && m.getType().hasFlag(MiscType.F_NAVAL_C3) && !m.isInoperable()) { + for (MiscMounted m : getMisc()) { + if (m.getType().hasFlag(MiscType.F_NAVAL_C3) && !m.isInoperable()) { return true; } } @@ -5837,9 +5788,8 @@ public boolean hasC3i() { if (isShutDown() || isOffBoard()) { return false; } - for (Mounted m : getEquipment()) { - if ((m.getType() instanceof MiscType) - && m.getType().hasFlag(MiscType.F_C3I) && !m.isInoperable()) { + for (MiscMounted m : getMisc()) { + if (m.getType().hasFlag(MiscType.F_C3I) && !m.isInoperable()) { return true; } } @@ -6317,7 +6267,7 @@ && getC3NetId().equals(e.getC3NetId())) { * Returns whether there is CASE protecting the location. */ public boolean locationHasCase(int loc) { - for (Mounted mounted : getMisc()) { + for (MiscMounted mounted : getMisc()) { if ((mounted.getLocation() == loc) && mounted.getType().hasFlag(MiscType.F_CASE)|(mounted.getType().hasFlag(MiscType.F_CASEP))) { return true; @@ -6334,7 +6284,7 @@ public boolean hasCase() { if (isClan()) { return true; } - for (Mounted mounted : getMisc()) { + for (MiscMounted mounted : getMisc()) { if (mounted.getType().hasFlag(MiscType.F_CASE)||(mounted.getType().hasFlag(MiscType.F_CASEP))) { return true; } @@ -6352,7 +6302,7 @@ public void hitAllCriticals(int loc, int slot) { for (int i = 0; i < getNumberOfCriticals(loc); i++) { CriticalSlot cs = getCritical(loc, i); if ((cs != null) && (cs.getType() == orig.getType())) { - Mounted csMount = cs.getMount(); + Mounted csMount = cs.getMount(); if ((csMount != null) && csMount.equals(orig.getMount())) { cs.setHit(true); } @@ -6427,7 +6377,7 @@ public void newRound(int roundNumber) { setAssaultDropInProgress(true); } - for (Mounted m : getEquipment()) { + for (Mounted m : getEquipment()) { m.newRound(roundNumber); } @@ -6524,7 +6474,7 @@ public void newRound(int roundNumber) { // Standard TSEMPs can fire every other round, so if we didn't fire last // round and the TSEMP isn't one-shot or repeating, reset it's fired state if (hasFiredTsemp()) { - for (Mounted m : getWeaponList()) { + for (WeaponMounted m : getWeaponList()) { if (m.getType().hasFlag(WeaponType.F_TSEMP) && !m.getType().hasFlag(WeaponType.F_ONESHOT)) { if (m.getType().hasFlag(WeaponType.F_REPEATING) || m.isTSEMPDowntime()) { @@ -6567,7 +6517,7 @@ public void newRound(int roundNumber) { */ public void applyDamage() { // mark all damaged equipment destroyed - for (Mounted mounted : getEquipment()) { + for (Mounted mounted : getEquipment()) { if (mounted.isHit()) { mounted.setDestroyed(true); } @@ -6628,7 +6578,7 @@ public void applyDamage() { */ public void reloadEmptyWeapons() { // try to reload weapons - for (Mounted mounted : getTotalWeaponList()) { + for (WeaponMounted mounted : getTotalWeaponList()) { WeaponType wtype = (WeaponType) mounted.getType(); if (wtype.getAmmoType() != AmmoType.T_NA) { @@ -6645,9 +6595,9 @@ public void reloadEmptyWeapons() { * * @return */ - public List getActiveAMS() { - ArrayList ams = new ArrayList<>(); - for (Mounted weapon : getWeaponList()) { + public List getActiveAMS() { + List ams = new ArrayList<>(); + for (WeaponMounted weapon : getWeaponList()) { // Skip anything that's not AMS if (!weapon.getType().hasFlag(WeaponType.F_AMS)) { continue; @@ -6667,11 +6617,11 @@ public List getActiveAMS() { // Make sure ammo is loaded boolean baAPDS = (this instanceof BattleArmor) && (weapon.getType().getInternalName().equals("ISBAAPDS")); - Mounted ammo = weapon.getLinked(); + AmmoMounted ammo = weapon.getLinkedAmmo(); if (!(weapon.getType().hasFlag(WeaponType.F_ENERGY)) && !baAPDS && ((ammo == null) || (ammo.getUsableShotsLeft() == 0) || ammo.isDumping())) { loadWeapon(weapon); - ammo = weapon.getLinked(); + ammo = weapon.getLinkedAmmo(); } // try again @@ -9292,8 +9242,8 @@ public boolean hasInfernoAmmo() { boolean found = false; // Walk through the unit's ammo, stop when we find a match. - for (Mounted amounted : getAmmo()) { - AmmoType atype = (AmmoType) amounted.getType(); + for (AmmoMounted amounted : getAmmo()) { + AmmoType atype = amounted.getType(); if (((atype.getAmmoType() == AmmoType.T_SRM) || (atype.getAmmoType() == AmmoType.T_SRM_IMP) || (atype.getAmmoType() == AmmoType.T_MML)) && (atype.getMunitionType().contains(AmmoType.Munitions.M_INFERNO)) && (amounted.getHittableShotsLeft() > 0)) { @@ -9478,7 +9428,7 @@ public String statusToString(int loc) { + getOInternal(loc) + "\n "; for (CriticalSlot cs : crits[loc]) { if (cs != null) { - Mounted mount = cs.getMount(); + Mounted mount = cs.getMount(); if (mount != null) { str += mount.getDesc() + "\n "; } @@ -10017,8 +9967,8 @@ public boolean isEligibleForOffboard() { if (isOffBoard() || isAssaultDropInProgress()) { return false; } - for (Mounted mounted : getWeaponList()) { - WeaponType wtype = (WeaponType) mounted.getType(); + for (WeaponMounted mounted : getWeaponList()) { + WeaponType wtype = mounted.getType(); if ((wtype != null) && (wtype.hasFlag(WeaponType.F_TAG) && mounted.isReady())) { return true; @@ -10172,8 +10122,8 @@ public boolean isEligibleForTargetingPhase() { if (isAssaultDropInProgress()) { return false; } - for (Mounted mounted : getWeaponList()) { - WeaponType wtype = (WeaponType) mounted.getType(); + for (WeaponMounted mounted : getWeaponList()) { + WeaponType wtype = mounted.getType(); if ((wtype != null) && (wtype.hasFlag(WeaponType.F_ARTILLERY))) { return true; } @@ -10414,7 +10364,7 @@ public boolean hasExternalSearchlight() { * @return */ public boolean hasSearchlight() { - for (Mounted m : getMisc()) { + for (MiscMounted m : getMisc()) { if (m.getType().hasFlag(MiscType.F_SEARCHLIGHT) && !m.isInoperable()) { return true; @@ -10437,7 +10387,7 @@ public void destroyOneSearchlight() { hasExternalSearchlight = false; } - for (Mounted m : getMisc()) { + for (MiscMounted m : getMisc()) { if (m.getType().hasFlag(MiscType.F_SEARCHLIGHT) && !m.isInoperable()) { m.setDestroyed(true); @@ -10792,7 +10742,7 @@ public int getStructureTechLevel() { return structureTechLevel; } - public void setWeaponHit(Mounted which) { + public void setWeaponHit(WeaponMounted which) { if (weaponList.contains(which)) { which.setHit(true); } @@ -10970,9 +10920,8 @@ public double getArmorWeight() { } public boolean hasTAG() { - for (Mounted m : getWeaponList()) { - WeaponType equip = (WeaponType) (m.getType()); - if ((equip != null) && (equip.hasFlag(WeaponType.F_TAG))) { + for (WeaponMounted m : getWeaponList()) { + if (m.getType().hasFlag(WeaponType.F_TAG)) { return true; } } @@ -11000,9 +10949,8 @@ public void setClimbMode(boolean state) { } public boolean usedTag() { - for (Mounted weapon : getWeaponList()) { - WeaponType wtype = (WeaponType) weapon.getType(); - if (weapon.isUsedThisRound() && wtype.hasFlag(WeaponType.F_TAG)) { + for (WeaponMounted weapon : getWeaponList()) { + if (weapon.isUsedThisRound() && weapon.getType().hasFlag(WeaponType.F_TAG)) { return true; } } @@ -11027,8 +10975,8 @@ public void setLayingMines(boolean laying) { } public boolean canLayMine() { - for (Mounted mounted : miscList) { - EquipmentType type = mounted.getType(); + for (MiscMounted mounted : getMisc()) { + MiscType type = mounted.getType(); if (!mounted.isMissing() && !isLayingMines() && (type.hasFlag(MiscType.F_MINE) || type.hasFlag(MiscType.F_VEHICLE_MINE_DISPENSER))) { return true; @@ -11502,7 +11450,7 @@ public void destroyLocation(int loc, boolean blownOff) { // some equipment is not present in critical slots // but is present in the location, so we'll need to look at it as well - for (Mounted mounted : getEquipment()) { + for (Mounted mounted : getEquipment()) { if (((mounted.getLocation() == loc) && mounted.getType().isHittable()) || (mounted.isSplit() && (mounted.getSecondLocation() == loc))) { if (blownOff) { @@ -11626,8 +11574,8 @@ public boolean isCommander() { return isCommander; } - public boolean hasLinkedMGA(Mounted mounted) { - for (Mounted m : getWeaponList()) { + public boolean hasLinkedMGA(Mounted mounted) { + for (WeaponMounted m : getWeaponList()) { if ((m.getLocation() == mounted.getLocation()) && m.getType().hasFlag(WeaponType.F_MGA) && !(m.isDestroyed() || m.isBreached()) @@ -11688,9 +11636,8 @@ public boolean usesWeaponBays() { * @param bayID * @return */ - public Mounted whichBay(int bayID) { - - for (Mounted m : getWeaponBayList()) { + public WeaponMounted whichBay(int bayID) { + for (WeaponMounted m : getWeaponBayList()) { for (int wId : m.getBayWeapons()) { // find the weapon and determine if it is there if (wId == bayID) { @@ -11710,14 +11657,14 @@ public Mounted whichBay(int bayID) { * @param rearMount * @return */ - public Mounted getFirstBay(WeaponType wtype, int loc, boolean rearMount) { + public WeaponMounted getFirstBay(WeaponType wtype, int loc, boolean rearMount) { int weapDamage = wtype.getRoundShortAV(); if (wtype.isCapital()) { weapDamage *= 10; } - for (Mounted m : getWeaponBayList()) { + for (WeaponMounted m : getWeaponBayList()) { BayWeapon bay = (BayWeapon) m.getType(); int damage = bay.getRoundShortAV() + weapDamage; if ((bay.getAtClass() == wtype.getAtClass()) @@ -11734,7 +11681,7 @@ public int getHeatInArc(int location, boolean rearMount) { int arcHeat = 0; - for (Mounted mounted : getTotalWeaponList()) { + for (WeaponMounted mounted : getTotalWeaponList()) { // is the weapon usable? if (mounted.isDestroyed() || mounted.isJammed()) { continue; @@ -11982,12 +11929,12 @@ public void setArcFired(int location, boolean rearMount) { * aeros */ public void setRapidFire() { - for (Mounted m : getTotalWeaponList()) { - WeaponType wtype = (WeaponType) m.getType(); - if (wtype.getAmmoType() == AmmoType.T_AC_ROTARY) { + for (WeaponMounted m : getTotalWeaponList()) { + int atype = m.getType().getAmmoType(); + if (atype == AmmoType.T_AC_ROTARY) { m.setMode("6-shot"); m.setModeSwitchable(false); - } else if (wtype.getAmmoType() == AmmoType.T_AC_ULTRA) { + } else if (atype == AmmoType.T_AC_ULTRA) { m.setMode("Ultra"); m.setModeSwitchable(false); } @@ -11999,9 +11946,8 @@ public void setRapidFire() { * first piece of appropriate equipment */ public void extendBlade(int loc) { - for (Mounted m : getEquipment()) { + for (MiscMounted m : getMisc()) { if ((m.getLocation() == loc) && !m.isDestroyed() && !m.isBreached() - && (m.getType() instanceof MiscType) && m.getType().hasFlag(MiscType.F_CLUB) && m.getType().hasSubType(MiscType.S_RETRACTABLE_BLADE)) { m.setMode("extended"); @@ -12022,7 +11968,7 @@ public void destroyRetractableBlade(int loc) { || (slot.getType() != CriticalSlot.TYPE_EQUIPMENT)) { continue; } - Mounted m = slot.getMount(); + Mounted m = slot.getMount(); if ((m.getLocation() == loc) && !m.isHit() && !m.isBreached() && (m.getType() instanceof MiscType) && m.getType().hasFlag(MiscType.F_CLUB) @@ -12085,12 +12031,12 @@ public void setGameOptions() { } } - for (Mounted mounted : getWeaponList()) { + for (WeaponMounted mounted : getWeaponList()) { mounted.adaptToGameOptions(game.getOptions()); mounted.setModesForMapType(); } - for (Mounted misc : getMisc()) { + for (MiscMounted misc : getMisc()) { if (misc.getType().hasFlag(MiscType.F_BAP) && (this instanceof Aero || this instanceof LandAirMech) && gameOpts.booleanOption(OptionsConstants.ADVAERORULES_STRATOPS_ECM)) { @@ -12254,10 +12200,9 @@ public boolean hasModularArmor() { } public boolean hasModularArmor(int loc) { - for (Mounted mount : this.getEquipment()) { + for (MiscMounted mount : getMisc()) { if ((loc == -1) || (mount.getLocation() == loc)) { - if (!mount.isDestroyed() && (mount.getType() instanceof MiscType) - && mount.getType().hasFlag(MiscType.F_MODULAR_ARMOR)) { + if (!mount.isDestroyed() && mount.getType().hasFlag(MiscType.F_MODULAR_ARMOR)) { return true; } } @@ -12271,23 +12216,19 @@ public int getDamageReductionFromModularArmor(HitData hit, int damage, Vector damage) { - mount.damageTaken += damage; + mount.takeDamage(damage); Report r = new Report(3535); r.subject = getId(); r.add(damage); @@ -12297,9 +12238,7 @@ public int getDamageReductionFromModularArmor(HitData hit, int damage, Vector ecmComparator; ecmComparator = new ECMInfo.ECCMComparator(); - for (Mounted m : getMisc()) { + for (MiscMounted m : getMisc()) { // Ignore if inoperable if (m.isInoperable()) { continue; @@ -12503,7 +12439,7 @@ public ECMInfo getECCMInfo() { ECMInfo bestInfo = null; Comparator ecmComparator; ecmComparator = new ECMInfo.ECCMComparator(); - for (Mounted m : getMisc()) { + for (MiscMounted m : getMisc()) { ECMInfo newInfo = null; if (m.getType().hasFlag(MiscType.F_COMMUNICATIONS) && m.curMode().equals("ECCM")) { @@ -12558,7 +12494,7 @@ public ECMInfo getECCMInfo() { */ public double getECMStrength() { int strength = 0; - for (Mounted m : getMisc()) { + for (MiscMounted m : getMisc()) { if (m.getType().hasFlag(MiscType.F_ANGEL_ECM)) { if (m.curMode().equals("ECM")) { strength = 2; @@ -12580,7 +12516,7 @@ public double getECMStrength() { */ public double getECCMStrength() { double strength = 0; - for (Mounted m : getMisc()) { + for (MiscMounted m : getMisc()) { if (m.getType().hasFlag(MiscType.F_COMMUNICATIONS)) { if ((getTotalCommGearTons() > 3) && (strength < 0.5)) { strength = 0.5; @@ -12615,7 +12551,7 @@ public double getECCMStrength() { */ public int getHQIniBonus() { int bonus = 0; - for (Mounted misc : getMisc()) { + for (MiscMounted misc : getMisc()) { if (misc.getType().hasFlag(MiscType.F_COMMUNICATIONS) && misc.curMode().equals("Default") && !misc.isInoperable()) { if (getTotalCommGearTons() >= 3) { @@ -12663,11 +12599,11 @@ public int getQuirkIniBonus() { * @param mammo * @return */ - public Mounted getBayByAmmo(Mounted mammo) { + public WeaponMounted getBayByAmmo(Mounted mammo) { - for (Mounted m : getWeaponBayList()) { + for (WeaponMounted m : getWeaponBayList()) { for (int bayAmmoId : m.getBayAmmo()) { - Mounted bayammo = getEquipment(bayAmmoId); + Mounted bayammo = getEquipment(bayAmmoId); if (bayammo == mammo) { return m; } @@ -12875,7 +12811,7 @@ public boolean hasArmoredChassis() { * @return */ public boolean hasEnvironmentalSealing() { - for (Mounted misc : miscList) { + for (MiscMounted misc : miscList) { if (misc.getType().hasFlag(MiscType.F_ENVIRONMENTAL_SEALING)) { return true; } @@ -13022,7 +12958,7 @@ public int countWeaponQuirks() { return count; } - for (Mounted m : getEquipment()) { + for (Mounted m : getEquipment()) { count += m.countQuirks(); } return count; @@ -13194,9 +13130,8 @@ public int[] getBombLoadout() { public int[] getBombLoadout(boolean internalOnly) { int[] loadout = new int[BombType.B_NUM]; - for (Mounted bomb : getBombs()) { - if ((bomb.getUsableShotsLeft() > 0) - && (bomb.getType() instanceof BombType)) { + for (BombMounted bomb : getBombs()) { + if ((bomb.getUsableShotsLeft() > 0)) { // Either count all bombs, or just internal bombs if (internalOnly && !bomb.isInternalBomb()) { continue; @@ -13236,11 +13171,9 @@ public Map getSecondaryPositions() { */ public boolean hasActiveBlueShield() { if (!isShutDown()) { - for (Mounted m : getMisc()) { + for (MiscMounted m : getMisc()) { EquipmentType type = m.getType(); - if ((type instanceof MiscType) - && type.hasFlag(MiscType.F_BLUE_SHIELD) - && m.curMode().equals("On")) { + if (type.hasFlag(MiscType.F_BLUE_SHIELD) && m.curMode().equals("On")) { return !(m.isDestroyed() || m.isMissing() || m.isBreached() || isShutDown()); } } @@ -13287,8 +13220,8 @@ public double getPowerAmplifierWeight() { // Otherwise, we need to iterate over our weapons, find out which of them // require amplification, and keep a running weight total of those. double total = 0.0; - for (Mounted m : getWeaponList()) { - WeaponType wt = (WeaponType) m.getType(); + for (WeaponMounted m : getWeaponList()) { + WeaponType wt = m.getType(); if ((wt.hasFlag(WeaponType.F_LASER) && (wt.getAmmoType() == AmmoType.T_NA)) || wt.hasFlag(WeaponType.F_PPC) || wt.hasFlag(WeaponType.F_PLASMA) @@ -13302,7 +13235,7 @@ public double getPowerAmplifierWeight() { total += m.getLinkedBy().getTonnage(); } } - for (Mounted m : getMisc()) { + for (MiscMounted m : getMisc()) { if (m.getType().hasFlag(MiscType.F_CLUB) && m.getType().hasSubType(MiscType.S_SPOT_WELDER)) { total += m.getTonnage(); } @@ -13615,7 +13548,7 @@ public boolean checkForMASCFailure(MovePath md, Vector vDesc, // If we failed before, the MASC was destroyed, and we wouldn't // have gotten here (hasActiveMASC would return false) if (!usedMASC) { - Mounted masc = getMASC(); + MiscMounted masc = getMASC(); bFailure = doMASCOrSuperchargerFailureCheckFor(masc, vDesc, vCriticals); usedMASC = true; return bFailure; @@ -13642,7 +13575,7 @@ public boolean checkForSuperchargerFailure(MovePath md, Vector vDesc, // If we failed before, the Supercharger was destroyed, and we wouldn't // have gotten here (hasActiveSupercharger would return false) if (!usedSupercharger) { - Mounted superCharger = getSuperCharger(); + MiscMounted superCharger = getSuperCharger(); bFailure = doMASCOrSuperchargerFailureCheckFor(superCharger, vDesc, vCriticals); usedSupercharger = true; return bFailure; @@ -13659,7 +13592,7 @@ public boolean checkForSuperchargerFailure(MovePath md, Vector vDesc, * @param vCriticals * @return */ - private boolean doMASCOrSuperchargerFailureCheckFor(Mounted masc, Vector vDesc, + private boolean doMASCOrSuperchargerFailureCheckFor(MiscMounted masc, Vector vDesc, HashMap> vCriticals) { if ((masc != null) && masc.curMode().equals("Armed")) { boolean bFailure = false; @@ -13826,9 +13759,9 @@ private boolean doMASCOrSuperchargerFailureCheckFor(Mounted masc, Vector * * @return */ - public Mounted getMASC() { - for (Mounted m : getMisc()) { - MiscType mtype = (MiscType) m.getType(); + public MiscMounted getMASC() { + for (MiscMounted m : getMisc()) { + MiscType mtype = m.getType(); if (mtype.hasFlag(MiscType.F_MASC) && m.isReady() && !mtype.hasSubType(MiscType.S_SUPERCHARGER) && !mtype.hasSubType(MiscType.S_JETBOOSTER)) { @@ -13843,11 +13776,11 @@ public Mounted getMASC() { * * @return */ - public Mounted getSuperCharger() { - for (Mounted m : getMisc()) { - MiscType mtype = (MiscType) m.getType(); + public MiscMounted getSuperCharger() { + for (MiscMounted m : getMisc()) { + MiscType mtype = m.getType(); if (mtype.hasFlag(MiscType.F_MASC) && m.isReady() - && mtype.hasSubType(MiscType.S_SUPERCHARGER)) { + && mtype.hasSubType(MiscType.S_SUPERCHARGER)) { return m; } } @@ -13861,12 +13794,11 @@ public Mounted getSuperCharger() { */ public int damagedJumpJets() { int jumpJets = 0; - for (Mounted mounted : getMisc()) { - EquipmentType etype = mounted.getType(); + for (MiscMounted mounted : getMisc()) { if (!mounted.isDestroyed()) { continue; } - if (etype.hasFlag(MiscType.F_JUMP_JET)) { + if (mounted.getType().hasFlag(MiscType.F_JUMP_JET)) { jumpJets++; } } @@ -14300,7 +14232,7 @@ public void loadQuirks(List quirks) { q, getChassis(), getModel(), q.getLocation(), q.getSlot())); continue; } - Mounted m = cs.getMount(); + Mounted m = cs.getMount(); if (m == null) { LogManager.getLogger().warn(String.format("%s failed for %s %s - Critical slot (%s-%s) is empty!", q, getChassis(), getModel(), q.getLocation(), q.getSlot())); @@ -14343,7 +14275,7 @@ public void loadQuirks(List quirks) { @Override public void newPhase(GamePhase phase) { - for (Mounted m : getEquipment()) { + for (Mounted m : getEquipment()) { m.newPhase(phase); } if (getCrew().isDoomed()) { @@ -14508,7 +14440,7 @@ public int damageSystem(int type, int slot, int loc, int hits) { if ((cs == null) || (cs.getType() != type)) { continue; } - Mounted m = null; + Mounted m = null; if (type == CriticalSlot.TYPE_EQUIPMENT) { m = getEquipment(slot); } @@ -14574,12 +14506,12 @@ public int getMaxWeaponRange(boolean targetIsAirborne) { maxRange = 1; } - for (Mounted weapon : getWeaponList()) { + for (WeaponMounted weapon : getWeaponList()) { if (!weapon.isReady()) { continue; } - WeaponType type = (WeaponType) weapon.getType(); + WeaponType type = weapon.getType(); int range; if (isAirborne()) { @@ -14653,7 +14585,7 @@ public int getASEWAffected() { } public boolean hasActivatedRadicalHS() { - for (Mounted m : getMisc()) { + for (MiscMounted m : getMisc()) { if (m.getType().hasFlag(MiscType.F_RADICAL_HEATSINK) && m.curMode().equals("On")) { return true; @@ -14663,7 +14595,7 @@ public boolean hasActivatedRadicalHS() { } public void deactivateRadicalHS() { - for (Mounted m : getMisc()) { + for (MiscMounted m : getMisc()) { if (m.getType().hasFlag(MiscType.F_RADICAL_HEATSINK)) { m.setMode("Off"); // Can only have one radical heat sink @@ -14723,7 +14655,7 @@ public void setWeaponSortOrder(WeaponSortOrder weaponSortOrder) { // and make the order the same as default (based on eqId) if (weaponSortOrder.isCustom() && (customWeaponOrder == null)) { customWeaponOrder = new HashMap<>(); - for (Mounted weapon : weaponList) { + for (WeaponMounted weapon : weaponList) { int eqId = getEquipmentNum(weapon); customWeaponOrder.put(eqId, eqId); } @@ -14739,7 +14671,7 @@ public void setCustomWeaponOrder(Map customWeapOrder) { this.customWeaponOrder = customWeapOrder; } - public int getCustomWeaponOrder(Mounted weapon) { + public int getCustomWeaponOrder(WeaponMounted weapon) { int eqId = getEquipmentNum(weapon); if (customWeaponOrder == null) { return eqId; @@ -14748,7 +14680,7 @@ public int getCustomWeaponOrder(Mounted weapon) { return Objects.requireNonNullElse(order, -1); } - public void setCustomWeaponOrder(Mounted weapon, int order) { + public void setCustomWeaponOrder(WeaponMounted weapon, int order) { setWeapOrderChanged(true); int eqId = getEquipmentNum(weapon); if (eqId == -1) { @@ -15728,9 +15660,8 @@ public MPBoosters getArmedMPBoosters() { public MPBoosters getMPBoosters(boolean onlyArmed) { boolean hasMASC = false; boolean hasSupercharger = false; - for (Mounted m : getEquipment()) { - if (!m.isInoperable() && (m.getType() instanceof MiscType) - && m.getType().hasFlag(MiscType.F_MASC) ) { + for (MiscMounted m : getMisc()) { + if (!m.isInoperable() && m.getType().hasFlag(MiscType.F_MASC) ) { // Supercharger is a subtype of MASC in MiscType if ( m.getType().hasSubType(MiscType.S_SUPERCHARGER)) { hasSupercharger = !onlyArmed || m.curMode().equals("Armed"); @@ -15832,7 +15763,7 @@ public UnitRole getRole() { * @param mounted the equipment to look for * @return the (first) slot number that holds the mounted or -1 if none can be found */ - public int slotNumber(Mounted mounted) { + public int slotNumber(Mounted mounted) { int location = mounted.getLocation(); if (location == Entity.LOC_NONE) { return -1; diff --git a/megamek/src/megamek/common/EntityListFile.java b/megamek/src/megamek/common/EntityListFile.java index 291f9b30d8a..2ffc16efe03 100644 --- a/megamek/src/megamek/common/EntityListFile.java +++ b/megamek/src/megamek/common/EntityListFile.java @@ -16,6 +16,7 @@ import megamek.MMConstants; import megamek.client.Client; import megamek.codeUtilities.StringUtility; +import megamek.common.equipment.WeaponMounted; import megamek.common.force.Force; import megamek.common.options.OptionsConstants; import megamek.common.options.PilotOptions; @@ -76,7 +77,7 @@ private static String formatArmor(int points) { * available to absorb additional critical hits. * @return a String describing the slot. */ - private static String formatSlot(String index, Mounted mount, boolean isHit, boolean isDestroyed, + private static String formatSlot(String index, Mounted mount, boolean isHit, boolean isDestroyed, boolean isRepairable, boolean isMissing, int indentLvl) { StringBuilder output = new StringBuilder(); @@ -259,7 +260,7 @@ public static String getLocString(Entity entity, int indentLvl) { } // - Map baySlotMap = new HashMap<>(); + Map baySlotMap = new HashMap<>(); // Walk through the slots in this location. for (int loop = 0; loop < entity.getNumberOfCriticals(loc); loop++) { @@ -284,7 +285,7 @@ public static String getLocString(Entity entity, int indentLvl) { } else { // Yup. If the equipment isn't a system, get it. - Mounted mount = null; + Mounted mount = null; if (CriticalSlot.TYPE_EQUIPMENT == slot.getType()) { mount = slot.getMount(); } @@ -293,7 +294,7 @@ public static String getLocString(Entity entity, int indentLvl) { // then let's make a note of it if (entity.usesWeaponBays() && (mount != null) && !mount.getBayAmmo().isEmpty()) { - baySlotMap.put(slot.getMount(), loop + 1); + baySlotMap.put((WeaponMounted) slot.getMount(), loop + 1); } if ((mount != null) && (mount.getType() instanceof BombType)) { @@ -346,7 +347,7 @@ else if (!isDestroyed && (mount != null) String bayIndex = ""; - for (Mounted bay : baySlotMap.keySet()) { + for (WeaponMounted bay : baySlotMap.keySet()) { if (bay.ammoInBay(entity.getEquipmentNum(mount))) { bayIndex = String.valueOf(baySlotMap.get(bay)); } diff --git a/megamek/src/megamek/common/FighterSquadron.java b/megamek/src/megamek/common/FighterSquadron.java index de9df11ee0f..4e1a206789a 100644 --- a/megamek/src/megamek/common/FighterSquadron.java +++ b/megamek/src/megamek/common/FighterSquadron.java @@ -22,6 +22,7 @@ import megamek.client.ui.swing.calculationReport.CalculationReport; import megamek.common.cost.CostCalculator; import megamek.common.enums.AimingMode; +import megamek.common.equipment.AmmoMounted; import megamek.common.options.OptionsConstants; import megamek.common.planetaryconditions.PlanetaryConditions; import org.apache.logging.log4j.LogManager; @@ -427,8 +428,8 @@ public void updateSkills() { } @Override - public ArrayList getAmmo() { - ArrayList allAmmo = new ArrayList<>(); + public List getAmmo() { + List allAmmo = new ArrayList<>(); getActiveSubEntities().forEach(fighter -> allAmmo.addAll(fighter.getAmmo())); return allAmmo; } diff --git a/megamek/src/megamek/common/IBomber.java b/megamek/src/megamek/common/IBomber.java index 202dbbcba44..faee94b8906 100644 --- a/megamek/src/megamek/common/IBomber.java +++ b/megamek/src/megamek/common/IBomber.java @@ -22,6 +22,7 @@ import java.util.List; import java.util.stream.IntStream; +import megamek.common.equipment.BombMounted; import megamek.common.options.OptionsConstants; /** @@ -152,7 +153,7 @@ default boolean isVTOLBombing() { } // For convenience - List getBombs(); + List getBombs(); /** * @@ -291,14 +292,14 @@ private void applyBombEquipment(int type, int loc, boolean internal){ * @param internal mounted internally or not. */ private void applyBombWeapons(int type, int loc, boolean internal){ - Mounted m; + Mounted m; try { EquipmentType et = EquipmentType.get(BombType.getBombWeaponName(type)); m = ((Entity) this).addBomb(et, loc); m.setInternalBomb(internal); // Add bomb itself as single-shot ammo. if (type != BombType.B_TAG) { - Mounted ammo = new Mounted((Entity) this, + Mounted ammo = Mounted.createMounted((Entity) this, EquipmentType.get(BombType.getBombInternalName(type))); ammo.setShotsLeft(1); ammo.setInternalBomb(internal); diff --git a/megamek/src/megamek/common/InfantryWeaponMounted.java b/megamek/src/megamek/common/InfantryWeaponMounted.java index 263c9f05941..d659582fb07 100644 --- a/megamek/src/megamek/common/InfantryWeaponMounted.java +++ b/megamek/src/megamek/common/InfantryWeaponMounted.java @@ -27,7 +27,7 @@ * This handles special features of both weapons. Infantry units that only have * a single weapon should use {@link Mounted}. */ -public class InfantryWeaponMounted extends Mounted { +public class InfantryWeaponMounted extends Mounted { transient private InfantryWeapon otherWeapon; private final String typeName; @@ -42,7 +42,7 @@ public class InfantryWeaponMounted extends Mounted { * @param rangeWeapon The weapon used to calculate range. * @param otherWeapon The other weapon */ - public InfantryWeaponMounted(Entity entity, EquipmentType rangeWeapon, InfantryWeapon otherWeapon) { + public InfantryWeaponMounted(Entity entity, InfantryWeapon rangeWeapon, InfantryWeapon otherWeapon) { super(entity, rangeWeapon); this.typeName = otherWeapon.getInternalName(); this.otherWeapon = otherWeapon; diff --git a/megamek/src/megamek/common/Jumpship.java b/megamek/src/megamek/common/Jumpship.java index 86a9402fe5d..c194abb42cd 100644 --- a/megamek/src/megamek/common/Jumpship.java +++ b/megamek/src/megamek/common/Jumpship.java @@ -13,7 +13,9 @@ import megamek.client.ui.swing.calculationReport.CalculationReport; import megamek.common.cost.JumpShipCostCalculator; +import megamek.common.equipment.AmmoMounted; import megamek.common.equipment.ArmorType; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.OptionsConstants; import java.util.ArrayList; @@ -1150,17 +1152,17 @@ public boolean doomedInAtmosphere() { * need to check bay location before loading ammo */ @Override - public boolean loadWeapon(Mounted mounted, Mounted mountedAmmo) { + public boolean loadWeapon(WeaponMounted mounted, AmmoMounted mountedAmmo) { boolean success = false; - WeaponType wtype = (WeaponType) mounted.getType(); - AmmoType atype = (AmmoType) mountedAmmo.getType(); + WeaponType wtype = mounted.getType(); + AmmoType atype = mountedAmmo.getType(); if (mounted.getLocation() != mountedAmmo.getLocation()) { return success; } // for large craft, ammo must be in the same ba - Mounted bay = whichBay(getEquipmentNum(mounted)); + WeaponMounted bay = whichBay(getEquipmentNum(mounted)); if ((bay != null) && !bay.ammoInBay(getEquipmentNum(mountedAmmo))) { return success; } diff --git a/megamek/src/megamek/common/LandAirMech.java b/megamek/src/megamek/common/LandAirMech.java index 805948d7537..6545c20e53d 100644 --- a/megamek/src/megamek/common/LandAirMech.java +++ b/megamek/src/megamek/common/LandAirMech.java @@ -14,6 +14,10 @@ package megamek.common; import megamek.common.enums.MPBoosters; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.BombMounted; +import megamek.common.equipment.MiscMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.OptionsConstants; import megamek.common.planetaryconditions.PlanetaryConditions; import org.apache.logging.log4j.LogManager; @@ -2048,18 +2052,18 @@ protected void addBomb(Mounted mounted, int loc) throws LocationFullException { mounted.setBombMounted(true); - if (mounted.getType() instanceof BombType) { - bombList.add(mounted); + if (mounted instanceof BombMounted) { + bombList.add((BombMounted) mounted); } - if (mounted.getType() instanceof WeaponType) { - totalWeaponList.add(mounted); - weaponList.add(mounted); + if (mounted instanceof WeaponMounted) { + totalWeaponList.add((WeaponMounted) mounted); + weaponList.add((WeaponMounted) mounted); if (mounted.getType().hasFlag(WeaponType.F_ARTILLERY)) { aTracker.addWeapon(mounted); } if (mounted.getType().hasFlag(WeaponType.F_ONESHOT) && (AmmoType.getOneshotAmmo(mounted) != null)) { - Mounted m = new Mounted(this, AmmoType.getOneshotAmmo(mounted)); + AmmoMounted m = (AmmoMounted) Mounted.createMounted(this, AmmoType.getOneshotAmmo(mounted)); m.setShotsLeft(1); mounted.setLinked(m); // Oneshot ammo will be identified by having a location @@ -2067,19 +2071,19 @@ protected void addBomb(Mounted mounted, int loc) throws LocationFullException { addEquipment(m, Entity.LOC_NONE, false); } } - if (mounted.getType() instanceof AmmoType) { - ammoList.add(mounted); + if (mounted instanceof AmmoMounted) { + ammoList.add((AmmoMounted) mounted); } - if (mounted.getType() instanceof MiscType) { - miscList.add(mounted); + if (mounted instanceof MiscMounted) { + miscList.add((MiscMounted) mounted); } equipmentList.add(mounted); } @Override - public Mounted addEquipment(EquipmentType etype, int loc, boolean rearMounted) throws LocationFullException { + public Mounted addEquipment(EquipmentType etype, int loc, boolean rearMounted) throws LocationFullException { if (etype instanceof BombType) { - Mounted mounted = new Mounted(this, etype); + Mounted mounted = Mounted.createMounted(this, etype); addBomb(mounted, loc); return mounted; } else { diff --git a/megamek/src/megamek/common/MULParser.java b/megamek/src/megamek/common/MULParser.java index 47392906877..88cd2c59585 100644 --- a/megamek/src/megamek/common/MULParser.java +++ b/megamek/src/megamek/common/MULParser.java @@ -17,6 +17,8 @@ import megamek.codeUtilities.StringUtility; import megamek.common.annotations.Nullable; import megamek.common.enums.Gender; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.GameOptions; import megamek.common.options.OptionsConstants; import megamek.common.weapons.infantry.InfantryWeapon; @@ -1624,13 +1626,13 @@ private int parseSlot(Element slotTag, Entity entity, int loc, int locAmmoCount) EquipmentType newLoad = EquipmentType.get(type); if (newLoad instanceof AmmoType) { int counter = -1; - Iterator ammo = entity.getAmmo() + Iterator ammo = entity.getAmmo() .iterator(); while (ammo.hasNext() && (counter < locAmmoCount)) { // Is this mounted in the current location? - Mounted mounted = ammo.next(); + AmmoMounted mounted = ammo.next(); if (mounted.getLocation() == loc) { // Increment the loop counter. @@ -1805,7 +1807,7 @@ private int parseSlot(Element slotTag, Entity entity, int loc, int locAmmoCount) mounted.setRapidfire(Boolean.parseBoolean(rfmg)); // Is the mounted a type of ammo? - if (mounted.getType() instanceof AmmoType) { + if (mounted instanceof AmmoMounted) { // Get the saved ammo load. EquipmentType newLoad = EquipmentType.get(type); if (newLoad instanceof AmmoType) { @@ -1831,23 +1833,23 @@ private int parseSlot(Element slotTag, Entity entity, int loc, int locAmmoCount) } else { // Change to the saved ammo type and shots. - mounted.changeAmmoType((AmmoType) newLoad); + ((AmmoMounted) mounted).changeAmmoType((AmmoType) newLoad); mounted.setShotsLeft(shotsVal); } // End have-good-shots-value try { double capVal = Double.parseDouble(capacity); - mounted.setAmmoCapacity(capVal); + ((AmmoMounted) mounted).setAmmoCapacity(capVal); } catch (NumberFormatException excep) { // Handled by the next if test. } if (capacity.equals(VALUE_NA)) { if (entity.hasETypeFlag(Entity.ETYPE_BATTLEARMOR) || entity.hasETypeFlag(Entity.ETYPE_PROTOMECH)) { - mounted.setAmmoCapacity(mounted.getOriginalShots() + ((AmmoMounted) mounted).setAmmoCapacity(mounted.getOriginalShots() * ((AmmoType) mounted.getType()).getKgPerShot() * 1000); } else { - mounted.setAmmoCapacity(mounted.getOriginalShots() + ((AmmoMounted) mounted).setAmmoCapacity(mounted.getOriginalShots() * mounted.getTonnage() / ((AmmoType) mounted.getType()).getShots()); } @@ -1893,8 +1895,7 @@ else if (!mounted.getType().getInternalName() // Make sure munition is a type of ammo. if (munType instanceof AmmoType) { // Change to the saved munition type. - mounted.getLinked().changeAmmoType( - (AmmoType) munType); + ((AmmoMounted) mounted.getLinked()).changeAmmoType((AmmoType) munType); } else { // Bad XML equipment. warning.append("XML file expects") @@ -2665,9 +2666,9 @@ private void addExtraAmmoToBay(Entity entity, int loc, String type, String bayIn // 3: add the ammo to a crit slot on the bay's location int bayCritIndex = Integer.parseInt(bayIndex); - Mounted bay = entity.getCritical(loc, bayCritIndex - 1).getMount(); + WeaponMounted bay = (WeaponMounted) entity.getCritical(loc, bayCritIndex - 1).getMount(); - Mounted ammo = new Mounted(entity, AmmoType.get(type)); + Mounted ammo = Mounted.createMounted(entity, AmmoType.get(type)); try { entity.addEquipment(ammo, loc, bay.isRearMounted()); diff --git a/megamek/src/megamek/common/Mech.java b/megamek/src/megamek/common/Mech.java index cc28068cdd0..bc63819d306 100644 --- a/megamek/src/megamek/common/Mech.java +++ b/megamek/src/megamek/common/Mech.java @@ -20,6 +20,7 @@ import megamek.common.cost.MekCostCalculator; import megamek.common.enums.AimingMode; import megamek.common.enums.MPBoosters; +import megamek.common.equipment.MiscMounted; import megamek.common.loaders.MtfFile; import megamek.common.options.IBasicOption; import megamek.common.options.IOption; @@ -1416,7 +1417,7 @@ public void addEngineSinks(String sinkName, int toAllocate) { for (int i = 0; i < toAllocate; i++) { try { - addEquipment(new Mounted(this, sinkType), Entity.LOC_NONE, false); + addEquipment(Mounted.createMounted(this, sinkType), Entity.LOC_NONE, false); } catch (LocationFullException ignored) { // um, that's impossible. } @@ -2743,7 +2744,7 @@ public void addClanCase() { } if (explosiveFound) { try { - addEquipment(new Mounted(this, clCase), i, false); + addEquipment(Mounted.createMounted(this, clCase), i, false); } catch (LocationFullException ex) { // um, that's impossible. } @@ -2765,8 +2766,8 @@ public Mounted addTargCompWithoutSlots(EquipmentType etype, int loc, boolean omn public Mounted addEquipment(EquipmentType etype, EquipmentType etype2, int loc, boolean omniPod, boolean armored) throws LocationFullException { - Mounted mounted = new Mounted(this, etype); - Mounted mounted2 = new Mounted(this, etype2); + Mounted mounted = Mounted.createMounted(this, etype); + Mounted mounted2 = Mounted.createMounted(this, etype2); mounted.setOmniPodMounted(omniPod); mounted2.setOmniPodMounted(omniPod); mounted.setArmored(armored); @@ -4358,7 +4359,7 @@ public String getMtf() { sb.append(newLine); sb.append(MtfFile.HEAT_SINKS).append(heatSinks()).append(" "); - Optional heatSink = getMisc().stream() + Optional heatSink = getMisc().stream() .filter(m -> m.getType().hasFlag(MiscType.F_HEAT_SINK) || m.getType().hasFlag(MiscType.F_DOUBLE_HEAT_SINK)) .map(Mounted::getType).findFirst(); @@ -5270,12 +5271,10 @@ private int getAbsorptionRate(int location, int damage) { continue; } - Mounted m = cs.getMount(); - - EquipmentType type = m.getType(); - if ((type instanceof MiscType) && ((MiscType) type).isShield()) { - rate -= m.getDamageAbsorption(this, m.getLocation()); - m.damageTaken++; + Mounted m = cs.getMount(); + if ((m instanceof MiscMounted) && ((MiscMounted) m).getType().isShield()) { + rate -= ((MiscMounted) m).getDamageAbsorption(this, m.getLocation()); + ((MiscMounted) m).takeDamage(1); return Math.max(0, rate); } } diff --git a/megamek/src/megamek/common/MechFileParser.java b/megamek/src/megamek/common/MechFileParser.java index 46650faa2b6..cdf159713bc 100644 --- a/megamek/src/megamek/common/MechFileParser.java +++ b/megamek/src/megamek/common/MechFileParser.java @@ -14,10 +14,12 @@ */ package megamek.common; +import megamek.common.equipment.WeaponMounted; import megamek.common.loaders.*; import megamek.common.util.BuildingBlock; import megamek.common.util.fileUtils.MegaMekFile; import megamek.common.verifier.TestInfantry; +import megamek.common.weapons.Weapon; import megamek.common.weapons.ppc.*; import org.apache.logging.log4j.LogManager; @@ -515,14 +517,14 @@ else if (m.getType().hasFlag(MiscType.F_APOLLO)) { } // Check the next piece of equipment. // Walk through the list of equipment. - for (Mounted m : ent.getMisc()) { + for (Mounted m : ent.getMisc()) { // Link PPC Capacitor to PPC it its location. if (m.getType().hasFlag(MiscType.F_PPC_CAPACITOR) && (m.getLinked() == null)) { // link up to a weapon in the same location - for (Mounted mWeapon : ent.getWeaponList()) { + for (Mounted mWeapon : ent.getWeaponList()) { WeaponType wtype = (WeaponType) mWeapon.getType(); //Handle weapon bays @@ -802,7 +804,7 @@ static void linkDumpers(Entity entity) { */ static void linkMGAs(Entity entity) { List usedMG = new ArrayList<>(); - for (Mounted mga : entity.getWeaponList()) { + for (WeaponMounted mga : entity.getWeaponList()) { if (mga.getType().hasFlag(WeaponType.F_MGA)) { // This may be called from MML after changing equipment location, so there // may be old data that needs to be cleared diff --git a/megamek/src/megamek/common/MechSummary.java b/megamek/src/megamek/common/MechSummary.java index 3c19ff1b5ac..26178623131 100644 --- a/megamek/src/megamek/common/MechSummary.java +++ b/megamek/src/megamek/common/MechSummary.java @@ -1043,11 +1043,11 @@ public void setFluffImage(String base64image) { * * @param mountedList A collection of Mounted equipment */ - public void setEquipment(List mountedList) + public void setEquipment(List> mountedList) { equipmentNames = new Vector<>(mountedList.size()); equipmentQuantities = new Vector<>(mountedList.size()); - for (Mounted mnt : mountedList) + for (Mounted mnt : mountedList) { // Ignore weapon groups, as they aren't actually real equipment if (mnt.isWeaponGroup()) { @@ -1086,7 +1086,7 @@ public String getQuirkNames() { public void setWeaponQuirkNames(Entity entity) { Set weaponQuirkNameList = new HashSet<>(); - for (Mounted mounted : entity.getEquipment()) { + for (Mounted mounted : entity.getEquipment()) { weaponQuirkNameList.addAll(mounted.getQuirks().getOptionsList().stream() .filter(IOption::booleanValue) .map(IOptionInfo::getDisplayableNameWithValue) diff --git a/megamek/src/megamek/common/MechView.java b/megamek/src/megamek/common/MechView.java index 0987889885d..e473ce72d86 100644 --- a/megamek/src/megamek/common/MechView.java +++ b/megamek/src/megamek/common/MechView.java @@ -857,7 +857,7 @@ private List getWeapons(boolean showDetail) { wpnTable.setColNames("Weapons ", " Loc ", " Heat ", entity.isOmni() ? " Omni " : ""); wpnTable.setJustification(TableElement.JUSTIFIED_LEFT, TableElement.JUSTIFIED_CENTER, TableElement.JUSTIFIED_CENTER, TableElement.JUSTIFIED_CENTER); - for (Mounted mounted : entity.getWeaponList()) { + for (Mounted mounted : entity.getWeaponList()) { String[] row = { mounted.getDesc() + quirkMarker(mounted), entity.joinLocationAbbr(mounted.allLocations(), 3), "", "" }; WeaponType wtype = (WeaponType) mounted.getType(); diff --git a/megamek/src/megamek/common/MiscType.java b/megamek/src/megamek/common/MiscType.java index fc0e2737f70..e4589479cfe 100644 --- a/megamek/src/megamek/common/MiscType.java +++ b/megamek/src/megamek/common/MiscType.java @@ -385,14 +385,13 @@ public class MiscType extends EquipmentType { public static final long S_ATMOSPHERIC_LIFEBOAT = 1L << 2; // New stuff for shields - protected int baseDamageAbsorptionRate = 0; - protected int baseDamageCapacity = 0; - protected int damageTaken = 0; + private int baseDamageAbsorptionRate = 0; + private int baseDamageCapacity = 0; protected boolean industrial = false; // New stuff for infantry kits - protected double damageDivisor = 1.0; + private double damageDivisor = 1.0; /** Creates new MiscType */ public MiscType() { @@ -2358,7 +2357,6 @@ public static MiscType createModularArmor() { misc.flags = misc.flags.or(F_MODULAR_ARMOR).or(F_MECH_EQUIPMENT).or(F_TANK_EQUIPMENT).or(F_FIGHTER_EQUIPMENT) .or(F_SUPPORT_TANK_EQUIPMENT).or(F_VTOL_EQUIPMENT); misc.bv = BV_VARIABLE; - misc.damageTaken = 0; misc.baseDamageAbsorptionRate = 10; misc.baseDamageCapacity = 10; misc.rulesRefs = "93, TO:AUE"; @@ -3657,7 +3655,6 @@ public static MiscType createISSmallShield() { misc.setInstantModeSwitch(true); String[] modes = { S_NO_SHIELD, S_ACTIVE_SHIELD, S_PASSIVE_SHIELD }; misc.setModes(modes); - misc.damageTaken = 0; misc.baseDamageAbsorptionRate = 3; misc.baseDamageCapacity = 11; misc.rulesRefs = "290, TO"; @@ -3686,7 +3683,6 @@ public static MiscType createISMediumShield() { misc.setInstantModeSwitch(true); String[] modes = { S_NO_SHIELD, S_ACTIVE_SHIELD, S_PASSIVE_SHIELD }; misc.setModes(modes); - misc.damageTaken = 0; misc.baseDamageAbsorptionRate = 5; misc.baseDamageCapacity = 18; misc.rulesRefs = "290, TO"; @@ -3715,7 +3711,6 @@ public static MiscType createISLargeShield() { misc.setInstantModeSwitch(true); String[] modes = { S_NO_SHIELD, S_ACTIVE_SHIELD, S_PASSIVE_SHIELD }; misc.setModes(modes); - misc.damageTaken = 0; misc.baseDamageAbsorptionRate = 7; misc.baseDamageCapacity = 25; misc.rulesRefs = "290, TO"; diff --git a/megamek/src/megamek/common/Mounted.java b/megamek/src/megamek/common/Mounted.java index 472425fe44c..56b9262d65a 100644 --- a/megamek/src/megamek/common/Mounted.java +++ b/megamek/src/megamek/common/Mounted.java @@ -16,6 +16,10 @@ import megamek.common.actions.WeaponAttackAction; import megamek.common.enums.GamePhase; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.BombMounted; +import megamek.common.equipment.MiscMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.GameOptions; import megamek.common.options.OptionsConstants; import megamek.common.options.WeaponQuirks; @@ -23,7 +27,7 @@ import megamek.common.weapons.Weapon; import megamek.common.weapons.WeaponHandler; import megamek.common.weapons.bayweapons.AmmoBayWeapon; -import megamek.common.weapons.gaussrifles.GaussWeapon; +import megamek.common.weapons.bayweapons.BayWeapon; import org.apache.logging.log4j.LogManager; import java.io.Serializable; @@ -35,7 +39,7 @@ * @author Ben * @since April 1, 2002, 1:29 PM */ -public class Mounted implements Serializable, RoundUpdated, PhaseUpdated { +public class Mounted implements Serializable, RoundUpdated, PhaseUpdated { private static final long serialVersionUID = 6438017987074691566L; private boolean usedThisRound = false; @@ -64,17 +68,17 @@ public class Mounted implements Serializable, RoundUpdated, PhaseUpdated { private int location; private boolean rearMounted; - private Mounted linked = null; // for ammo, or artemis - private Mounted linkedBy = null; // reverse link for convenience + private Mounted linked = null; // for ammo, or artemis + private Mounted linkedBy = null; // reverse link for convenience - private Mounted crossLinkedBy = null; // Weapons with crossLinked capacitors + private Mounted crossLinkedBy = null; // Weapons with crossLinked capacitors private int linkedBayId = -1; - private Entity entity; // what I'm mounted on + private final Entity entity; // what I'm mounted on private WeaponQuirks quirks = new WeaponQuirks(); - private transient EquipmentType type; + private transient T type; private String typeName; private double size = 1.0; @@ -86,13 +90,6 @@ public class Mounted implements Serializable, RoundUpdated, PhaseUpdated { private boolean m_bPendingDump; private boolean m_bDumping; - // A list of ids (equipment numbers) for the weapons and ammo linked to - // this bay (if the mounted is of the BayWeapon type) - // I can also use this for weapons of the same type on a capital fighter - // and now Machine Gun Arrays too! - private Vector bayWeapons = new Vector<>(); - private Vector bayAmmo = new Vector<>(); - // on capital fighters and squadrons some weapon mounts actually represent // multiple weapons of the same type // provide a boolean indicating this type of mount and the number of weapons @@ -112,10 +109,6 @@ public class Mounted implements Serializable, RoundUpdated, PhaseUpdated { private boolean bombMounted = false; private boolean isInternalBomb = false; - // mine type - private int mineType = MINE_NONE; - // vibrabomb mine setting - private int vibraSetting = 20; // These arrays are used to track individual missing modular components on BA for MHQ // in MM they probably shouldn't need to be touched. They are used to keep track of @@ -180,75 +173,40 @@ public class Mounted implements Serializable, RoundUpdated, PhaseUpdated { private boolean squadSupportWeapon; /** Creates new Mounted */ - public Mounted(Entity entity, EquipmentType type) { + protected Mounted(Entity entity, T type) { this.entity = entity; this.type = type; typeName = type.getInternalName(); - if (type instanceof AmmoType) { - shotsLeft = ((AmmoType) type).getShots(); - size = type.getTonnage(entity); - } - if ((type instanceof MiscType) && type.hasFlag(MiscType.F_MINE)) { - mineType = MINE_CONVENTIONAL; - // Used to keep track of the # of mines - shotsLeft = 1; - } - if ((type instanceof MiscType) && - type.hasFlag(MiscType.F_VEHICLE_MINE_DISPENSER)) { - mineType = MINE_CONVENTIONAL; - // Used to keep track of the # of mines - shotsLeft = 2; - } - if ((type instanceof MiscType) - && type.hasFlag(MiscType.F_SENSOR_DISPENSER)) { - setShotsLeft(type.hasFlag(MiscType.F_BA_EQUIPMENT) ? 6 : 30); - } - if ((type instanceof MiscType) - && ((((MiscType) type).isShield() || type - .hasFlag(MiscType.F_MODULAR_ARMOR)))) { - MiscType shield = (MiscType) type; - baseDamageAbsorptionRate = shield.baseDamageAbsorptionRate; - baseDamageCapacity = shield.baseDamageCapacity; - damageTaken = shield.damageTaken; - } - if ((type instanceof MiscType) - && type.hasFlag(MiscType.F_MINESWEEPER)) { - armorValue = 30; - } quirks.initialize(); } - /** - * Changing ammo loadouts allows updating AmmoTypes of existing bins. This - * is the only circumstance under which this should happen. - */ - - public void changeAmmoType(AmmoType at) { - if (!(type instanceof AmmoType)) { - LogManager.getLogger().warn("Attempted to change ammo type of non-ammo"); - return; - } - type = at; - typeName = at.getInternalName(); - if (location == Entity.LOC_NONE) { - // Oneshot launcher - shotsLeft = 1; + public static Mounted createMounted(Entity entity, EquipmentType type) { + if (type instanceof BayWeapon) { + return new WeaponMounted(entity, (WeaponType) type); + } else if (type instanceof WeaponType) { + return new WeaponMounted(entity, (WeaponType) type); + } else if (type instanceof BombType) { + return new BombMounted(entity, (BombType) type); + } else if (type instanceof AmmoType) { + return new AmmoMounted(entity, (AmmoType) type); + } else if (type instanceof MiscType) { + return new MiscMounted(entity, (MiscType) type); } else { - // Regular launcher - shotsLeft = at.getShots(); + return new Mounted<>(entity, type); } } /** * Restores the equipment from the name */ + @SuppressWarnings("unchecked") public void restore() { if (typeName == null) { typeName = type.getName(); } else { - type = EquipmentType.get(typeName); + type = (T) EquipmentType.get(typeName); } if (type == null) { @@ -256,8 +214,14 @@ public void restore() { } } - public EquipmentType getType() { - return (null != type) ? type : (type = EquipmentType.get(typeName)); + @SuppressWarnings("unchecked") + public T getType() { + return (null != type) ? type : (type = (T) EquipmentType.get(typeName)); + } + + protected void setType(T type) { + this.type = type; + this.typeName = type.getInternalName(); } public int getModesCount() { @@ -434,33 +398,12 @@ public String getShortName() { return type.getShortName(size); } + protected String getBaseDesc() { + return getType().getDesc(getSize()); + } + public String getDesc() { - StringBuffer desc; - switch (getMineType()) { - case MINE_CONVENTIONAL: - desc = new StringBuffer( - Messages.getString("Mounted.ConventionalMine")); - break; - case MINE_VIBRABOMB: - desc = new StringBuffer( - Messages.getString("Mounted.VibraBombMine")); - break; - case MINE_COMMAND_DETONATED: - desc = new StringBuffer( - Messages.getString("Mounted.CommandDetonatedMine")); - break; - case MINE_ACTIVE: - desc = new StringBuffer( - Messages.getString("Mounted.ActiveMine")); - break; - case MINE_INFERNO: - desc = new StringBuffer( - Messages.getString("Mounted.InfernoMine")); - break; - case -1: - default: - desc = new StringBuffer(getType().getDesc(getSize())); - } + StringBuilder desc = new StringBuilder(getBaseDesc()); if (isWeaponGroup()) { desc.append(" (").append(getNWeapons()).append(")"); } @@ -751,7 +694,7 @@ public void resetJam() { /** * The number of shots of ammunition currently stored in this Mounted - * irregardless of its operational status. Or in other words, the straight + * regardless of its operational status. Or in other words, the straight * value last set by {@link #setShotsLeft(int)}, even if this ammo slot is * no longer functional or indeed notionally no longer part of the unit * formerly carrying it. This is the 'general' base value that should be @@ -807,33 +750,6 @@ public void setShotsLeft(int shotsLeft) { this.shotsLeft = shotsLeft; } - /** - * Returns how many shots the weapon is using - */ - public int getCurrentShots() { - WeaponType wtype = (WeaponType) getType(); - int nShots = getNumShots(wtype, curMode(), false); - // sets number of shots for MG arrays - if (wtype.hasFlag(WeaponType.F_MGA)) { - nShots = 0; - for (int eqn : getBayWeapons()) { - Mounted m = entity.getEquipment(eqn); - if (null == m) { - continue; - } - if ((m.getLocation() == getLocation()) - && !m.isDestroyed() - && !m.isBreached() - && m.getType().hasFlag(WeaponType.F_MG) - && (((WeaponType) m.getType()).getRackSize() == ((WeaponType) getType()) - .getRackSize())) { - nShots++; - } - } - } - return nShots; - } - /** * Returns how many shots a weapon type would use. This can be used without * an instantiation of Mounted, which is useful for computing Aero heat. @@ -913,28 +829,6 @@ public void setSize(double size) { this.size = size; } - /** - * The capacity of an ammo bin may be different than the weight of the original shots - * in the case of AR10s due to variable missile weight. - * - * @return The capacity of a mounted ammo bin in tons. - * @deprecated Use {@link #getSize()} - */ - @Deprecated - public double getAmmoCapacity() { - return size; - } - - /** - * Sets the maximum tonnage of ammo for a mounted ammo bin. - * - * @param capacity The capacity of the bin in tons. - * @deprecated Use {@link #setSize(double)} - */ - @Deprecated - public void setAmmoCapacity(double capacity) { - size = capacity; - } public boolean isRapidfire() { return rapidfire; @@ -956,7 +850,7 @@ public boolean isHotLoaded() { boolean isHotLoaded = false; if (getType() instanceof WeaponType) { - Mounted link = getLinked(); + Mounted link = getLinked(); if ((link == null) || !(link.getType() instanceof AmmoType)) { return false; } @@ -999,16 +893,16 @@ && curMode().equals("HotLoad")) { public void setHotLoad(boolean hotload) { if (getType() instanceof WeaponType) { - Mounted link = getLinked(); + Mounted link = getLinked(); if ((link == null) || !(link.getType() instanceof AmmoType)) { return; } - if (((AmmoType) link.getType()).hasFlag(AmmoType.F_HOTLOAD)) { + if (link.getType().hasFlag(AmmoType.F_HOTLOAD)) { link.hotloaded = hotload; } } if (getType() instanceof AmmoType) { - if (((AmmoType) getType()).hasFlag(AmmoType.F_HOTLOAD)) { + if (getType().hasFlag(AmmoType.F_HOTLOAD)) { hotloaded = hotload; } } @@ -1143,33 +1037,33 @@ public List allLocations() { return locations; } - public Mounted getLinked() { + public Mounted getLinked() { return linked; } - public Mounted getLinkedBy() { + public Mounted getLinkedBy() { return linkedBy; } - public Mounted getCrossLinkedBy() { + public Mounted getCrossLinkedBy() { return crossLinkedBy; } - public void setLinked(Mounted linked) { + public void setLinked(Mounted linked) { this.linked = linked; if (linked != null) { linked.setLinkedBy(this); } } - public void setCrossLinked(Mounted linked) { + public void setCrossLinked(Mounted linked) { this.linked = linked; linked.setCrossLinkedBy(this); } // should only be called by setLinked(), or when dumping a DWP // in the case of a many-to-one relationship (like ammo) this is meaningless - public void setLinkedBy(Mounted linker) { + public void setLinkedBy(Mounted linker) { if ((linker != null) && (linker.getLinked() != this)) { // liar return; @@ -1178,7 +1072,7 @@ public void setLinkedBy(Mounted linker) { } // called by setCrossLinked() when using cross-linked capacitors. - public void setCrossLinkedBy(Mounted linker) { + public void setCrossLinkedBy(Mounted linker) { if ((linker != null) && (linker.getLinked() != this)) { // liar return; @@ -1223,94 +1117,6 @@ public void setSplit(boolean b) { } public int getExplosionDamage() { - if (type instanceof AmmoType) { - AmmoType atype = (AmmoType) type; - int rackSize = atype.getRackSize(); - int damagePerShot = atype.getDamagePerShot(); - // Anti-ship EW bomb does no damage but deals a 5-point explosion if LAM bomb bay is hit - if ((type instanceof BombType) - && (((BombType) type).getBombType() == BombType.B_ASEW)) { - damagePerShot = 5; - } - - //Capital missiles need a racksize for this - if (type.hasFlag(AmmoType.F_CAP_MISSILE)) { - rackSize = 1; - } - - //Screen launchers need a racksize. Damage is 15 per TW p251 - if (atype.getAmmoType() == AmmoType.T_SCREEN_LAUNCHER) { - rackSize = 1; - damagePerShot = 15; - } - - EnumSet mType = atype.getMunitionType(); - // both Dead-Fire and Tandem-charge SRM's do 3 points of damage per - // shot when critted - // Dead-Fire LRM's do 2 points of damage per shot when critted. - if ((mType.contains(AmmoType.Munitions.M_DEAD_FIRE)) - || (mType.contains(AmmoType.Munitions.M_TANDEM_CHARGE))) { - damagePerShot++; - } else if (atype.getAmmoType() == AmmoType.T_TASER) { - damagePerShot = 6; - } - - if (atype.getAmmoType() == AmmoType.T_MEK_MORTAR) { - if ((mType.contains(AmmoType.Munitions.M_AIRBURST)) - || (mType.contains(AmmoType.Munitions.M_FLARE)) - || (mType.contains(AmmoType.Munitions.M_SMOKE_WARHEAD))) { - damagePerShot = 1; - } else { - damagePerShot = 2; - } - } - - return damagePerShot * rackSize * shotsLeft; - } - - if (type instanceof WeaponType) { - WeaponType wtype = (WeaponType) type; - // TacOps Gauss Weapon rule p. 102 - if ((type instanceof GaussWeapon) && type.hasModes() - && curMode().equals("Powered Down")) { - return 0; - } - if ((isHotLoaded() || hasQuirk(OptionsConstants.QUIRK_WEAP_NEG_AMMO_FEED_PROBLEMS)) - && (getLinked() != null) && (getLinked().getUsableShotsLeft() > 0)) { - Mounted link = getLinked(); - AmmoType atype = ((AmmoType) link.getType()); - int damagePerShot = atype.getDamagePerShot(); - // Launchers with Dead-Fire missiles in them do an extra point of - // damage per shot when critted - if (atype.getMunitionType().contains(AmmoType.Munitions.M_DEAD_FIRE)) { - damagePerShot++; - } - - int damage = wtype.getRackSize() * damagePerShot; - return damage; - } - - if (wtype.hasFlag(WeaponType.F_PPC) && (hasChargedCapacitor() != 0)) { - if (isFired()) { - if (hasChargedCapacitor() == 2) { - return 15; - } - return 0; - } - if (hasChargedCapacitor() == 2) { - return 30; - } - return 15; - } - - if ((wtype.getAmmoType() == AmmoType.T_MPOD) && isFired()) { - return 0; - } - - return wtype.getExplosionDamage(); - - } - if (type instanceof MiscType) { MiscType mtype = (MiscType) type; if (mtype.hasFlag(MiscType.F_PPC_CAPACITOR)) { @@ -1421,6 +1227,14 @@ public boolean isCrippled() { return false; } + public List getBayWeapons() { + return Collections.emptyList(); + } + + public List getBayAmmo() { + return Collections.emptyList(); + } + /** * Returns false if this ammo should not be loaded. Checks if the ammo is * already destroyed or missing, is being dumped, has been breached, is @@ -1434,184 +1248,6 @@ public boolean isAmmoUsable() { return true; } - /** - * @return the type of mine this mounted is, or -1 if it isn't - * a mine - */ - public int getMineType() { - return mineType; - } - - /** - * set the type of mine this should be - * - * @param mineType - */ - public void setMineType(int mineType) { - this.mineType = mineType; - } - - /** - * set the vibrabomb sensitivity - * - * @param vibraSetting - * the int sensitivity to set - */ - public void setVibraSetting(int vibraSetting) { - this.vibraSetting = vibraSetting; - } - - /** - * get the vibrabomb sensitivity - * - * @return the int vibrabomb sensitity this mine is set to. - */ - public int getVibraSetting() { - return vibraSetting; - } - - public int getBaseDamageAbsorptionRate() { - return baseDamageAbsorptionRate; - } - - public int getBaseDamageCapacity() { - return baseDamageCapacity; - } - - /** - * Rules state that every time the shield takes a crit its damage absorption - * for each attack is reduced by 1. Also for every Arm actuator critted - * damage absorption is reduced by 1 and finally if the shoulder is hit the - * damage absorption is reduced by 2 making it possble to kill a shield - * before its gone through its full damage capacity. - * - * @param entity - * @param location - * @return - */ - public int getDamageAbsorption(Entity entity, int location) { - // Shields can only be used in arms so if you've got a shield in a - // location - // other then an arm your SOL --Torren. - if ((location != Mech.LOC_RARM) && (location != Mech.LOC_LARM)) { - return 0; - } - - int base = baseDamageAbsorptionRate; - - for (int slot = 0; slot < entity.getNumberOfCriticals(location); slot++) { - CriticalSlot cs = entity.getCritical(location, slot); - - if (cs == null) { - continue; - } - - if (cs.getType() != CriticalSlot.TYPE_EQUIPMENT) { - continue; - } - - Mounted m = cs.getMount(); - EquipmentType type = m.getType(); - if ((type instanceof MiscType) && ((MiscType) type).isShield()) { - if (cs.isDamaged()) { - base--; - } - } - } - - if (!entity.hasWorkingSystem(Mech.ACTUATOR_SHOULDER, location)) { - base -= 2; - } - - if (!entity.hasWorkingSystem(Mech.ACTUATOR_LOWER_ARM, location)) { - base--; - } - if (!entity.hasWorkingSystem(Mech.ACTUATOR_UPPER_ARM, location)) { - base--; - } - if (!entity.hasWorkingSystem(Mech.ACTUATOR_HAND, location)) { - base--; - } - - return Math.max(0, base); - } - - /** - * Rules say every time a shield is critted it loses 5 points from its - * Damage Capacity. basically count down from the top then subtract the - * amount of damage its already take. The damage capacity is used to - * determine if the shield is still viable. - * - * @param entity - * @param location - * @return damage capacity(no less then 0) - */ - public int getCurrentDamageCapacity(Entity entity, int location) { - // Shields can only be used in arms so if you've got a shield in a - // location - // other then an arm your SOL --Torren. - if ((location != Mech.LOC_RARM) && (location != Mech.LOC_LARM)) { - return 0; - } - - int base = baseDamageCapacity; - - for (int slot = 0; slot < entity.getNumberOfCriticals(location); slot++) { - CriticalSlot cs = entity.getCritical(location, slot); - - if (cs == null) { - continue; - } - - if (cs.getType() != CriticalSlot.TYPE_EQUIPMENT) { - continue; - } - - Mounted m = cs.getMount(); - EquipmentType type = m.getType(); - if ((type instanceof MiscType) && ((MiscType) type).isShield()) { - if (cs.isDamaged()) { - base -= 5; - } - } - } - if (!entity.hasWorkingSystem(Mech.ACTUATOR_SHOULDER, location)) { - base -= 2; - } - - if (!entity.hasWorkingSystem(Mech.ACTUATOR_LOWER_ARM, location)) { - base--; - } - if (!entity.hasWorkingSystem(Mech.ACTUATOR_UPPER_ARM, location)) { - base--; - } - if (!entity.hasWorkingSystem(Mech.ACTUATOR_HAND, location)) { - base--; - } - - return Math.max(0, base - damageTaken); - } - - public int getDamageTaken() { - return damageTaken; - } - - public void addWeaponToBay(int w) { - bayWeapons.add(w); - } - - public Vector getBayWeapons() { - return bayWeapons; - } - - public void addAmmoToBay(int a) { - bayAmmo.add(a); - } - - public Vector getBayAmmo() { - return bayAmmo; - } - public void setByShot(boolean b) { byShot = b; } @@ -1652,70 +1288,11 @@ public boolean isInternalBomb() { return isInternalBomb; } - // is ammo in the same bay as the weapon - public boolean ammoInBay(int mAmmoId) { - for (int nextAmmoId : bayAmmo) { - if (nextAmmoId == mAmmoId) { - return true; - } - } - return false; - } - /** * returns the heat for this weapon taking account of rapid-fire weapon * status */ public int getCurrentHeat() { - if (getType() instanceof WeaponType) { - WeaponType wtype = (WeaponType) getType(); - int heat = wtype.getHeat(); - - // AR10's have heat based upon the loaded missile - if (wtype.getName().equals("AR10")) { - AmmoType ammoType = (AmmoType) getLinked().getType(); - if (ammoType.hasFlag(AmmoType.F_AR10_BARRACUDA)) { - return 10; - } else if (ammoType.hasFlag(AmmoType.F_AR10_WHITE_SHARK)) { - return 15; - } else { // AmmoType.F_AR10_KILLER_WHALE - return 20; - } - } - - if (wtype.hasFlag(WeaponType.F_ENERGY) && wtype.hasModes()) { - heat = Compute.dialDownHeat(this, wtype); - } - // multiply by number of shots and number of weapons - heat = heat * getCurrentShots() * getNWeapons(); - if (hasQuirk(OptionsConstants.QUIRK_WEAP_POS_IMP_COOLING)) { - heat = Math.max(1, heat - 1); - } - if (hasQuirk(OptionsConstants.QUIRK_WEAP_NEG_POOR_COOLING)) { - heat += 1; - } - if (hasQuirk(OptionsConstants.QUIRK_WEAP_NEG_NO_COOLING)) { - heat += 2; - } - if (hasChargedCapacitor() == 2) { - heat += 10; - } - if (hasChargedCapacitor() == 1) { - heat += 5; - } - if ((getLinkedBy() != null) - && !getLinkedBy().isInoperable() - && (getLinkedBy().getType() instanceof MiscType) - && getLinkedBy().getType().hasFlag( - MiscType.F_LASER_INSULATOR)) { - heat -= 1; - if (heat == 0) { - heat++; - } - } - - return heat; - } return 0; } @@ -1992,49 +1569,16 @@ public void setBaMountLoc(int baMountLoc) { this.baMountLoc = baMountLoc; } - /** - * Returns true if this Mounted is a one-shot launcher of some kind - * otherwise returns false. - * - * @return - */ - public boolean isOneShotWeapon() { - return (getType() instanceof WeaponType) && getType().hasFlag(WeaponType.F_ONESHOT); - } - /** * Checks whether this mount is either one a one-shot weapon or ammo for a one-shot weapon. - * @return + * @return Whether the equipment is one-shot */ public boolean isOneShot() { - if (isOneShotWeapon()) { - return true; - } else if ((getType() instanceof AmmoType) && getLinkedBy() != null) { - // There should not be any circular references, but we should track where we've been just in case. - // Do a couple checks first to avoid instantiating a set unnecessarily. - Set checked = new HashSet<>(); - for (Mounted current = getLinkedBy(); current != null; current = current.getLinkedBy()) { - if (checked.contains(current)) { - return false; - } - if (current.isOneShotWeapon()) { - return true; - } - checked.add(current); - } - } return false; } - /** - * Check for whether this mount is linked by a one-shot weapon - * - * @return {@code true} if this is one-shot ammo - */ public boolean isOneShotAmmo() { - return (getType() instanceof AmmoType) - && (getLinkedBy() != null) - && getLinkedBy().isOneShot(); + return false; } public boolean isSquadSupportWeapon() { @@ -2162,6 +1706,10 @@ public void setSwitchedReason(int reason) { switchedReason = reason; } + protected List bayComponentsToString() { + return Collections.emptyList(); + } + @Override public String toString() { List locations = allLocations().stream().map(entity::getLocationAbbr).collect(Collectors.toList()); @@ -2184,14 +1732,7 @@ public String toString() { if (linkedBy != null) state.add("LinkedBy: [" + entity.getEquipment().indexOf(linkedBy) + "]"); if (crossLinkedBy != null) state.add("CrossLinkedBy: [" + entity.getEquipment().indexOf(crossLinkedBy) + "]"); if (linkedBayId != -1) state.add("LinkedBay: [" + linkedBayId + "]"); - if (!bayWeapons.isEmpty()) { - List bayWeaponIds = bayWeapons.stream().map(id -> "[" + id + "]").collect(Collectors.toList()); - state.add("Bay Weapons: " + String.join(", ", bayWeaponIds)); - } - if (!bayAmmo.isEmpty()) { - List bayAmmoIds = bayAmmo.stream().map(id -> "[" + id + "]").collect(Collectors.toList()); - state.add("Bay Ammo: " + String.join(", ", bayAmmoIds)); - } + state.addAll(bayComponentsToString()); if (type instanceof AmmoType) { state.add("Shots: " + shotsLeft); } diff --git a/megamek/src/megamek/common/Protomech.java b/megamek/src/megamek/common/Protomech.java index 7dd67aba45b..75d2612f432 100644 --- a/megamek/src/megamek/common/Protomech.java +++ b/megamek/src/megamek/common/Protomech.java @@ -16,6 +16,7 @@ import megamek.client.ui.swing.calculationReport.CalculationReport; import megamek.common.cost.ProtoMekCostCalculator; import megamek.common.enums.AimingMode; +import megamek.common.equipment.AmmoMounted; import megamek.common.equipment.ArmorType; import megamek.common.planetaryconditions.Atmosphere; import megamek.common.preference.PreferenceManager; @@ -858,17 +859,17 @@ public Mounted addEquipment(EquipmentType etype, int loc) } @Override - public Mounted addEquipment(EquipmentType etype, int loc, + public Mounted addEquipment(EquipmentType etype, int loc, boolean rearMounted) throws LocationFullException { - Mounted mounted = new Mounted(this, etype); + Mounted mounted = Mounted.createMounted(this, etype); addEquipment(mounted, loc, rearMounted, -1); return mounted; } @Override - public Mounted addEquipment(EquipmentType etype, int loc, + public Mounted addEquipment(EquipmentType etype, int loc, boolean rearMounted, int shots) throws LocationFullException { - Mounted mounted = new Mounted(this, etype); + Mounted mounted = Mounted.createMounted(this, etype); addEquipment(mounted, loc, rearMounted, shots); return mounted; @@ -878,14 +879,14 @@ public Mounted addEquipment(EquipmentType etype, int loc, * Mounts the specified weapon in the specified location. */ @Override - protected void addEquipment(Mounted mounted, int loc, boolean rearMounted, + protected void addEquipment(Mounted mounted, int loc, boolean rearMounted, int shots) throws LocationFullException { - if (mounted.getType() instanceof AmmoType) { + if (mounted instanceof AmmoMounted) { // Damn protomech ammo; nasty hack, should be cleaner if (-1 != shots) { mounted.setShotsLeft(shots); mounted.setOriginalShots(shots); - mounted.setAmmoCapacity(shots * ((AmmoType) mounted.getType()).getKgPerShot() / 1000); + ((AmmoMounted) mounted).setAmmoCapacity(shots * ((AmmoMounted) mounted).getType().getKgPerShot() / 1000); super.addEquipment(mounted, loc, rearMounted); return; } diff --git a/megamek/src/megamek/common/QuadVee.java b/megamek/src/megamek/common/QuadVee.java index f7430214f68..7d938ea6f57 100644 --- a/megamek/src/megamek/common/QuadVee.java +++ b/megamek/src/megamek/common/QuadVee.java @@ -19,6 +19,7 @@ package megamek.common; import megamek.common.enums.MPBoosters; +import megamek.common.equipment.MiscMounted; import megamek.common.options.OptionsConstants; import megamek.common.planetaryconditions.PlanetaryConditions; @@ -396,8 +397,8 @@ public int conversionCost() { } } } - for (Mounted m : getMisc()) { - if (m.getType() instanceof MiscType && m.getType().hasFlag(MiscType.F_TRACKS)) { + for (MiscMounted m : getMisc()) { + if (m.getType().hasFlag(MiscType.F_TRACKS)) { cost += m.getDamageTaken(); break; } diff --git a/megamek/src/megamek/common/SmallCraft.java b/megamek/src/megamek/common/SmallCraft.java index 45eb5df9b46..0b9360f395a 100644 --- a/megamek/src/megamek/common/SmallCraft.java +++ b/megamek/src/megamek/common/SmallCraft.java @@ -13,7 +13,9 @@ import megamek.client.ui.swing.calculationReport.CalculationReport; import megamek.common.cost.SmallCraftCostCalculator; +import megamek.common.equipment.AmmoMounted; import megamek.common.equipment.ArmorType; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.OptionsConstants; import java.util.HashMap; @@ -755,10 +757,10 @@ public double getBVTypeModifier() { * need to check bay location before loading ammo */ @Override - public boolean loadWeapon(Mounted mounted, Mounted mountedAmmo) { + public boolean loadWeapon(WeaponMounted mounted, AmmoMounted mountedAmmo) { boolean success = false; - WeaponType wtype = (WeaponType) mounted.getType(); - AmmoType atype = (AmmoType) mountedAmmo.getType(); + WeaponType wtype = mounted.getType(); + AmmoType atype = mountedAmmo.getType(); if (mounted.getLocation() != mountedAmmo.getLocation()) { return success; diff --git a/megamek/src/megamek/common/Tank.java b/megamek/src/megamek/common/Tank.java index e02fac897fc..b98440578ab 100644 --- a/megamek/src/megamek/common/Tank.java +++ b/megamek/src/megamek/common/Tank.java @@ -18,6 +18,7 @@ import megamek.common.enums.AimingMode; import megamek.common.enums.GamePhase; import megamek.common.enums.MPBoosters; +import megamek.common.equipment.AmmoMounted; import megamek.common.options.OptionsConstants; import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.common.weapons.flamers.VehicleFlamerWeapon; @@ -2420,12 +2421,12 @@ public int getFreeSlots() { // for ammo, each type of ammo takes one slots, regardless of // submunition type Set foundAmmo = new HashSet<>(); - for (Mounted ammo : getAmmo()) { + for (AmmoMounted ammo : getAmmo()) { // don't count oneshot ammo - if (ammo.isOneShotAmmo()) { + if (ammo.isOneShot()) { continue; } - AmmoType at = (AmmoType) ammo.getType(); + AmmoType at = ammo.getType(); if (!foundAmmo.contains(at.getAmmoType() + ":" + at.getRackSize())) { usedSlots++; foundAmmo.add(at.getAmmoType() + ":" + at.getRackSize()); diff --git a/megamek/src/megamek/common/TripodMech.java b/megamek/src/megamek/common/TripodMech.java index 28b661354ea..92ee039874d 100644 --- a/megamek/src/megamek/common/TripodMech.java +++ b/megamek/src/megamek/common/TripodMech.java @@ -20,6 +20,7 @@ import java.util.List; import megamek.common.enums.AimingMode; +import megamek.common.equipment.MiscMounted; import megamek.common.options.OptionsConstants; import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.common.preference.PreferenceManager; @@ -683,11 +684,10 @@ public boolean hasActiveShield(int location) { continue; } - Mounted m = cs.getMount(); - EquipmentType type = m.getType(); - if ((type instanceof MiscType) && ((MiscType) type).isShield() + Mounted m = cs.getMount(); + if ((m instanceof MiscMounted) && ((MiscMounted) m).getType().isShield() && m.curMode().equals(MiscType.S_ACTIVE_SHIELD)) { - return m.getCurrentDamageCapacity(this, m.getLocation()) > 0; + return ((MiscMounted) m).getCurrentDamageCapacity(this, m.getLocation()) > 0; } } return false; @@ -755,11 +755,10 @@ public boolean hasPassiveShield(int location) { continue; } - Mounted m = cs.getMount(); - EquipmentType type = m.getType(); - if ((type instanceof MiscType) && ((MiscType) type).isShield() + Mounted m = cs.getMount(); + if ((m instanceof MiscMounted) && ((MiscMounted) m).getType().isShield() && m.curMode().equals(MiscType.S_PASSIVE_SHIELD)) { - return m.getCurrentDamageCapacity(this, m.getLocation()) > 0; + return ((MiscMounted) m).getCurrentDamageCapacity(this, m.getLocation()) > 0; } } return false; @@ -790,10 +789,9 @@ public boolean hasNoDefenseShield(int location) { continue; } - Mounted m = cs.getMount(); - EquipmentType type = m.getType(); - if ((type instanceof MiscType) - && ((MiscType) type).isShield() + Mounted m = cs.getMount(); + if ((m instanceof MiscMounted) + && ((MiscMounted) m).getType().isShield() && (m.curMode().equals(MiscType.S_NO_SHIELD) || isShutDown() || // if // he @@ -806,7 +804,7 @@ public boolean hasNoDefenseShield(int location) { // defense mode getCrew().isKoThisRound() || getCrew() .isUnconscious())) { - return m.getCurrentDamageCapacity(this, m.getLocation()) > 0; + return ((MiscMounted) m).getCurrentDamageCapacity(this, m.getLocation()) > 0; } } return false; diff --git a/megamek/src/megamek/common/WeaponComparatorArc.java b/megamek/src/megamek/common/WeaponComparatorArc.java index 576830b7f3f..17f010f2203 100644 --- a/megamek/src/megamek/common/WeaponComparatorArc.java +++ b/megamek/src/megamek/common/WeaponComparatorArc.java @@ -14,6 +14,8 @@ */ package megamek.common; +import megamek.common.equipment.WeaponMounted; + import java.util.Comparator; /** @@ -22,50 +24,45 @@ * * @author arlith */ -public class WeaponComparatorArc implements Comparator { - private Entity entity; +public class WeaponComparatorArc implements Comparator { + private final Entity entity; public WeaponComparatorArc(Entity e) { entity = e; } @Override - public int compare(Mounted obj1, Mounted obj2) { - if (obj1.getType() instanceof WeaponType - && obj2.getType() instanceof WeaponType) { - int wnum1 = entity.getEquipmentNum(obj1); - int wnum2 = entity.getEquipmentNum(obj2); - WeaponType weap1 = (WeaponType) obj1.getType(); - WeaponType weap2 = (WeaponType) obj2.getType(); + public int compare(WeaponMounted obj1, WeaponMounted obj2) { + int wnum1 = entity.getEquipmentNum(obj1); + int wnum2 = entity.getEquipmentNum(obj2); + WeaponType weap1 = (WeaponType) obj1.getType(); + WeaponType weap2 = (WeaponType) obj2.getType(); - // Pick the weapon with the lowest arc - if (entity.getWeaponArc(wnum1) > entity.getWeaponArc(wnum2)) { - return 1; - } else if (entity.getWeaponArc(wnum1) < entity.getWeaponArc(wnum2)) { - return -1; - } else { - // Break ties with damage - // If types are equal, pick front facing first - if (weap1 == weap2) { - if (obj1.isRearMounted()) { - return -1; - } else if (obj2.isRearMounted()) { - return 1; - } else { - return 0; - } - } - // Pick the weapon with the highest damage - if (weap1.getDamage() > weap2.getDamage()) { - return 1; - } else if (weap1.getDamage() < weap2.getDamage()) { + // Pick the weapon with the lowest arc + if (entity.getWeaponArc(wnum1) > entity.getWeaponArc(wnum2)) { + return 1; + } else if (entity.getWeaponArc(wnum1) < entity.getWeaponArc(wnum2)) { + return -1; + } else { + // Break ties with damage + // If types are equal, pick front facing first + if (weap1 == weap2) { + if (obj1.isRearMounted()) { return -1; - } else { // Break ties with heat - return Integer.compare(weap1.getHeat(), weap2.getHeat()); + } else if (obj2.isRearMounted()) { + return 1; + } else { + return 0; } } + // Pick the weapon with the highest damage + if (weap1.getDamage() > weap2.getDamage()) { + return 1; + } else if (weap1.getDamage() < weap2.getDamage()) { + return -1; + } else { // Break ties with heat + return Integer.compare(weap1.getHeat(), weap2.getHeat()); + } } - - throw new ClassCastException("Passed Mounteds are not Weapons"); } } diff --git a/megamek/src/megamek/common/WeaponComparatorCustom.java b/megamek/src/megamek/common/WeaponComparatorCustom.java index 98952b8fe1b..5d32b138dc2 100644 --- a/megamek/src/megamek/common/WeaponComparatorCustom.java +++ b/megamek/src/megamek/common/WeaponComparatorCustom.java @@ -14,6 +14,8 @@ */ package megamek.common; +import megamek.common.equipment.WeaponMounted; + import java.util.Comparator; /** @@ -23,22 +25,18 @@ * * @author arlith */ -public class WeaponComparatorCustom implements Comparator { +public class WeaponComparatorCustom implements Comparator { - private Entity entity; + private final Entity entity; public WeaponComparatorCustom(Entity e) { entity = e; } @Override - public int compare(Mounted obj1, Mounted obj2) { - if (obj1.getType() instanceof WeaponType - && obj2.getType() instanceof WeaponType) { - int weapNum1 = entity.getCustomWeaponOrder(obj1); - int weapNum2 = entity.getCustomWeaponOrder(obj2); - return weapNum1 - weapNum2; - } - throw new ClassCastException("Passed Mounteds are not Weapons"); + public int compare(WeaponMounted obj1, WeaponMounted obj2) { + int weapNum1 = entity.getCustomWeaponOrder(obj1); + int weapNum2 = entity.getCustomWeaponOrder(obj2); + return weapNum1 - weapNum2; } } \ No newline at end of file diff --git a/megamek/src/megamek/common/WeaponComparatorDamage.java b/megamek/src/megamek/common/WeaponComparatorDamage.java index 76288d14d98..afab92a3d09 100644 --- a/megamek/src/megamek/common/WeaponComparatorDamage.java +++ b/megamek/src/megamek/common/WeaponComparatorDamage.java @@ -14,6 +14,8 @@ */ package megamek.common; +import megamek.common.equipment.WeaponMounted; + import java.util.Comparator; /** @@ -22,7 +24,7 @@ * * @author arlith */ -public class WeaponComparatorDamage implements Comparator { +public class WeaponComparatorDamage implements Comparator { /** * Value used to change order from ascending to descending. If descending, * value will be -1 and orders will be multiplied by -1. @@ -36,37 +38,33 @@ public WeaponComparatorDamage(boolean ascending) { } @Override - public int compare(Mounted obj1, Mounted obj2) { - if (obj1.getType() instanceof WeaponType - && obj2.getType() instanceof WeaponType) { - WeaponType weap1 = (WeaponType) obj1.getType(); - WeaponType weap2 = (WeaponType) obj2.getType(); - - // If types are equal, pick front facing first - if (weap1 == weap2) { - if (obj1.isRearMounted()) { - return -1 * ascending; - } else if (obj2.isRearMounted()) { - return ascending; - } else { - return 0; - } + public int compare(WeaponMounted obj1, WeaponMounted obj2) { + WeaponType weap1 = obj1.getType(); + WeaponType weap2 = obj2.getType(); + + // If types are equal, pick front facing first + if (weap1 == weap2) { + if (obj1.isRearMounted()) { + return -1 * ascending; + } else if (obj2.isRearMounted()) { + return ascending; + } else { + return 0; } - // Pick the weapon with the highest damage - if (weap1.getDamage() > weap2.getDamage()) { + } + // Pick the weapon with the highest damage + if (weap1.getDamage() > weap2.getDamage()) { + return ascending; + } else if (weap1.getDamage() < weap2.getDamage()) { + return -1 * ascending; + } else { // Break ties with heat + if (weap1.getHeat() > weap2.getHeat()) { return ascending; - } else if (weap1.getDamage() < weap2.getDamage()) { + } else if (weap1.getHeat() < weap2.getHeat()) { return -1 * ascending; - } else { // Break ties with heat - if (weap1.getHeat() > weap2.getHeat()) { - return ascending; - } else if (weap1.getHeat() < weap2.getHeat()) { - return -1 * ascending; - } else { - return 0; - } + } else { + return 0; } } - throw new ClassCastException("Passed Mounteds are not Weapons"); } } diff --git a/megamek/src/megamek/common/WeaponComparatorNum.java b/megamek/src/megamek/common/WeaponComparatorNum.java index 975db07d2c7..20e700aa53a 100644 --- a/megamek/src/megamek/common/WeaponComparatorNum.java +++ b/megamek/src/megamek/common/WeaponComparatorNum.java @@ -14,6 +14,8 @@ */ package megamek.common; +import megamek.common.equipment.WeaponMounted; + import java.util.Comparator; /** @@ -22,22 +24,18 @@ * * @author arlith */ -public class WeaponComparatorNum implements Comparator { +public class WeaponComparatorNum implements Comparator { - private Entity entity; + private final Entity entity; public WeaponComparatorNum(Entity e) { entity = e; } @Override - public int compare(Mounted obj1, Mounted obj2) { - if (obj1.getType() instanceof WeaponType - && obj2.getType() instanceof WeaponType) { - int weapNum1 = entity.getEquipmentNum(obj1); - int weapNum2 = entity.getEquipmentNum(obj2); - return weapNum1 - weapNum2; - } - throw new ClassCastException("Passed Mounteds are not Weapons"); + public int compare(WeaponMounted obj1, WeaponMounted obj2) { + int weapNum1 = entity.getEquipmentNum(obj1); + int weapNum2 = entity.getEquipmentNum(obj2); + return weapNum1 - weapNum2; } } \ No newline at end of file diff --git a/megamek/src/megamek/common/WeaponComparatorRange.java b/megamek/src/megamek/common/WeaponComparatorRange.java index 74dabbfe375..f003e404f20 100644 --- a/megamek/src/megamek/common/WeaponComparatorRange.java +++ b/megamek/src/megamek/common/WeaponComparatorRange.java @@ -14,6 +14,8 @@ */ package megamek.common; +import megamek.common.equipment.WeaponMounted; + import java.util.Comparator; /** @@ -21,7 +23,7 @@ * * @author arlith */ -public class WeaponComparatorRange implements Comparator { +public class WeaponComparatorRange implements Comparator { /** * Value used to change order from ascending to descending. If descending, @@ -36,42 +38,38 @@ public WeaponComparatorRange(boolean ascending) { } @Override - public int compare(Mounted obj1, Mounted obj2) { - if (obj1.getType() instanceof WeaponType - && obj2.getType() instanceof WeaponType) { - WeaponType weap1 = (WeaponType) obj1.getType(); - WeaponType weap2 = (WeaponType) obj2.getType(); - - // If types are equal, pick front facing first - if (weap1 == weap2) { - if (obj1.isRearMounted()) { - return -1 * ascending; - } else if (obj2.isRearMounted()) { - return ascending; - } else { - return 0; - } - } - int[] ranges1 = weap1.getRanges(obj1); - int[] ranges2 = weap2.getRanges(obj2); - // Start by comparing the short range brackets (*not* the minimum - // ranges at index 0), then work outwards from there as needed. - for (int r = 1; r < ranges1.length; r++) { - if (ranges1[r] < ranges2[r]) { - return -1 * ascending; - } else if (ranges1[r] > ranges2[r]) { - return ascending; - } - } - // If we get here, all ranges are equals, arbitrate with heat - if (weap1.getHeat() > weap2.getHeat()) { - return ascending; - } else if (weap1.getHeat() < weap2.getHeat()) { + public int compare(WeaponMounted obj1, WeaponMounted obj2) { + WeaponType weap1 = obj1.getType(); + WeaponType weap2 = obj2.getType(); + + // If types are equal, pick front facing first + if (weap1 == weap2) { + if (obj1.isRearMounted()) { return -1 * ascending; + } else if (obj2.isRearMounted()) { + return ascending; } else { return 0; } } - throw new ClassCastException("Passed Mounteds are not Weapons"); + int[] ranges1 = weap1.getRanges(obj1); + int[] ranges2 = weap2.getRanges(obj2); + // Start by comparing the short range brackets (*not* the minimum + // ranges at index 0), then work outwards from there as needed. + for (int r = 1; r < ranges1.length; r++) { + if (ranges1[r] < ranges2[r]) { + return -1 * ascending; + } else if (ranges1[r] > ranges2[r]) { + return ascending; + } + } + // If we get here, all ranges are equals, arbitrate with heat + if (weap1.getHeat() > weap2.getHeat()) { + return ascending; + } else if (weap1.getHeat() < weap2.getHeat()) { + return -1 * ascending; + } else { + return 0; + } } } diff --git a/megamek/src/megamek/common/WeaponType.java b/megamek/src/megamek/common/WeaponType.java index 620309a0866..43a3393d72c 100644 --- a/megamek/src/megamek/common/WeaponType.java +++ b/megamek/src/megamek/common/WeaponType.java @@ -17,6 +17,8 @@ import java.math.BigInteger; import megamek.common.alphaStrike.AlphaStrikeElement; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.weapons.AlamoMissileWeapon; import megamek.common.weapons.AltitudeBombAttack; import megamek.common.weapons.DiveBombAttack; @@ -607,20 +609,20 @@ public int getWExtremeRange() { return waterExtremeRange; } - public int getMaxRange(Mounted weapon) { + public int getMaxRange(WeaponMounted weapon) { if (weapon == null) { return getMaxRange(); } - return getMaxRange(weapon, weapon.getLinked()); + return getMaxRange(weapon, weapon.getLinkedAmmo()); } public int getMaxRange() { return maxRange; } - public int getMaxRange(Mounted weapon, Mounted ammo) { + public int getMaxRange(WeaponMounted weapon, AmmoMounted ammo) { if (getAmmoType() == AmmoType.T_ATM) { - AmmoType ammoType = (AmmoType) ammo.getType(); + AmmoType ammoType = ammo.getType(); if ((ammoType.getAmmoType() == AmmoType.T_ATM) && (ammoType.getMunitionType().contains(AmmoType.Munitions.M_EXTENDED_RANGE))) { return RANGE_EXT; @@ -630,7 +632,7 @@ public int getMaxRange(Mounted weapon, Mounted ammo) { } } if (getAmmoType() == AmmoType.T_MML) { - AmmoType ammoType = (AmmoType) ammo.getType(); + AmmoType ammoType = ammo.getType(); if (ammoType.hasFlag(AmmoType.F_MML_LRM) || (getAmmoType() == AmmoType.T_LRM_TORPEDO)) { return RANGE_LONG; } else { diff --git a/megamek/src/megamek/common/actions/ArtilleryAttackAction.java b/megamek/src/megamek/common/actions/ArtilleryAttackAction.java index 7b0c11ef0d6..7ab1633db47 100644 --- a/megamek/src/megamek/common/actions/ArtilleryAttackAction.java +++ b/megamek/src/megamek/common/actions/ArtilleryAttackAction.java @@ -51,10 +51,10 @@ public ArtilleryAttackAction(int entityId, int targetType, int targetId, distance = (int) Math.floor((double) distance / game.getPlanetaryConditions().getGravity()); EquipmentType eType = getEntity(game).getEquipment(weaponId).getType(); WeaponType wType = (WeaponType) eType; - Mounted mounted = getEntity(game).getEquipment(weaponId); + Mounted mounted = getEntity(game).getEquipment(weaponId); if (getEntity(game).usesWeaponBays() && wType.getAtClass() == WeaponType.CLASS_ARTILLERY) { for (int wId : game.getEntity(entityId).getEquipment(weaponId).getBayWeapons()) { - Mounted bayW = game.getEntity(entityId).getEquipment(wId); + Mounted bayW = game.getEntity(entityId).getEquipment(wId); WeaponType bayWType = ((WeaponType) bayW.getType()); if (bayWType.hasFlag(WeaponType.F_CRUISE_MISSILE)) { // See TO p181. Cruise missile flight time is (1 + (Mapsheets / 5, round down) diff --git a/megamek/src/megamek/common/actions/ClubAttackAction.java b/megamek/src/megamek/common/actions/ClubAttackAction.java index a913af0b80d..23dae2bd785 100644 --- a/megamek/src/megamek/common/actions/ClubAttackAction.java +++ b/megamek/src/megamek/common/actions/ClubAttackAction.java @@ -27,6 +27,7 @@ import megamek.common.TargetRoll; import megamek.common.Targetable; import megamek.common.ToHitData; +import megamek.common.equipment.MiscMounted; import megamek.common.options.OptionsConstants; import org.apache.logging.log4j.LogManager; @@ -39,14 +40,14 @@ */ public class ClubAttackAction extends PhysicalAttackAction { private static final long serialVersionUID = -8744665286254604559L; - private Mounted club; + private MiscMounted club; private int aiming; private boolean zweihandering; /** * Creates new ClubAttackAction */ - public ClubAttackAction(int entityId, int targetId, Mounted club, + public ClubAttackAction(int entityId, int targetId, MiscMounted club, int aimTable) { super(entityId, targetId); this.club = club; @@ -63,7 +64,7 @@ public ClubAttackAction(int entityId, int targetId, Mounted club, * @param zweihandering - a boolean indicating whether the attacker is zweihandering (using both hands) */ public ClubAttackAction(int entityId, int targetType, int targetId, - Mounted club, int aimTable, boolean zweihandering) { + MiscMounted club, int aimTable, boolean zweihandering) { super(entityId, targetType, targetId); this.club = club; aiming = aimTable; @@ -79,9 +80,9 @@ public ClubAttackAction(int entityId, int targetType, int targetId, * @param zweihandering - a boolean indicating whether the attacker is zweihandering (using both hands) * @return an integer of the damage dealt */ - public static int getDamageFor(Entity entity, Mounted club, + public static int getDamageFor(Entity entity, MiscMounted club, boolean targetInfantry, boolean zweihandering) { - MiscType mType = (MiscType) (club.getType()); + MiscType mType = club.getType(); int nDamage = (int) Math.floor(entity.getWeight() / 5.0); if (mType.hasSubType(MiscType.S_SWORD)) { nDamage = (int) (Math.ceil(entity.getWeight() / 10.0) + 1.0); @@ -562,11 +563,11 @@ public static ToHitData toHit(Game game, int attackerId, return toHit; } - public Mounted getClub() { + public MiscMounted getClub() { return club; } - public void setClub(Mounted club) { + public void setClub(MiscMounted club) { this.club = club; } diff --git a/megamek/src/megamek/common/actions/TeleMissileAttackAction.java b/megamek/src/megamek/common/actions/TeleMissileAttackAction.java index b55497ddb38..c5d56872b66 100644 --- a/megamek/src/megamek/common/actions/TeleMissileAttackAction.java +++ b/megamek/src/megamek/common/actions/TeleMissileAttackAction.java @@ -106,7 +106,7 @@ protected int getLargeCraftHeat(Entity e) { AttackHandler ah = i.nextElement(); WeaponAttackAction prevAttack = ah.getWaa(); if (prevAttack.getEntityId() == e.getId()) { - Mounted prevWeapon = e.getEquipment(prevAttack.getWeaponId()); + Mounted prevWeapon = e.getEquipment(prevAttack.getWeaponId()); for (int wId : prevWeapon.getBayWeapons()) { Mounted bayW = e.getEquipment(wId); totalheat += bayW.getCurrentHeat(); @@ -152,7 +152,7 @@ public int calcCounterAV(Game game, Targetable target) { // We need to know how much heat has been assigned to offensive weapons fire by the defender this round int weaponHeat = getLargeCraftHeat(entityTarget) + entityTarget.heatBuildup; if (null != lCounters) { - for (Mounted counter : lCounters) { + for (Mounted counter : lCounters) { // Point defenses only fire vs attacks against the arc they protect Entity pdEnt = counter.getEntity(); diff --git a/megamek/src/megamek/common/actions/WeaponAttackAction.java b/megamek/src/megamek/common/actions/WeaponAttackAction.java index 279d2ca1c14..578db1765f1 100644 --- a/megamek/src/megamek/common/actions/WeaponAttackAction.java +++ b/megamek/src/megamek/common/actions/WeaponAttackAction.java @@ -18,6 +18,8 @@ import megamek.client.ui.Messages; import megamek.common.*; import megamek.common.enums.AimingMode; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.OptionsConstants; import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.common.planetaryconditions.Wind; @@ -309,17 +311,11 @@ private static ToHitData toHitCalc(Game game, int attackerId, Targetable target, boolean isPointblankShot, List allECMInfo, boolean evenIfAlreadyFired, int ammoId) { final Entity ae = game.getEntity(attackerId); - final Mounted weapon = ae.getEquipment(weaponId); - final Mounted linkedAmmo = (ammoId == -1) ? weapon.getLinked() : ae.getEquipment(ammoId); + final WeaponMounted weapon = (WeaponMounted) ae.getEquipment(weaponId); + final AmmoMounted linkedAmmo = (ammoId == -1) ? weapon.getLinkedAmmo() : (AmmoMounted) ae.getEquipment(ammoId); final EquipmentType type = weapon.getType(); - // No need to process anything further if we're not using a weapon somehow - if (!(type instanceof WeaponType)) { - LogManager.getLogger().error("Trying to make a weapon attack with " + weapon.getName() + " which has type " + type.getName()); - return new ToHitData(TargetRoll.AUTOMATIC_FAIL, Messages.getString("WeaponAttackAction.NotAWeapon")); - } - if (target == null) { LogManager.getLogger().error(attackerId + "Attempting to attack null target"); return new ToHitData(TargetRoll.AUTOMATIC_FAIL, Messages.getString("MovementDisplay.NoTarget")); @@ -354,7 +350,7 @@ private static ToHitData toHitCalc(Game game, int attackerId, Targetable target, final boolean usesAmmo = (wtype.getAmmoType() != AmmoType.T_NA) && !isWeaponInfantry; - final Mounted ammo = usesAmmo ? linkedAmmo : null; + final AmmoMounted ammo = usesAmmo ? linkedAmmo : null; final AmmoType atype = ammo == null ? null : (AmmoType) ammo.getType(); @@ -465,8 +461,8 @@ private static ToHitData toHitCalc(Game game, int attackerId, Targetable target, if (ae.usesWeaponBays()) { for (int wId : weapon.getBayWeapons()) { - Mounted bayW = ae.getEquipment(wId); - Mounted bayWAmmo = bayW.getLinked(); + Mounted bayW = ae.getEquipment(wId); + Mounted bayWAmmo = bayW.getLinked(); if (bayWAmmo == null) { //At present, all weapons below using mLinker use ammo, so this won't be a problem @@ -932,7 +928,7 @@ public static ToHitData toHit(Game game, int attackerId, Targetable target) { */ private static String toHitIsImpossible(Game game, Entity ae, int attackerId, Targetable target, int ttype, LosEffects los, ToHitData losMods, ToHitData toHit, int distance, Entity spotter, - WeaponType wtype, Mounted weapon, int weaponId, AmmoType atype, Mounted ammo, EnumSet munition, + WeaponType wtype, WeaponMounted weapon, int weaponId, AmmoType atype, AmmoMounted ammo, EnumSet munition, boolean isArtilleryDirect, boolean isArtilleryFLAK, boolean isArtilleryIndirect, boolean isAttackerInfantry, boolean isBearingsOnlyMissile, boolean isCruiseMissile, boolean exchangeSwarmTarget, boolean isHoming, boolean isInferno, boolean isIndirect, boolean isStrafing, boolean isTAG, boolean targetInBuilding, @@ -1399,7 +1395,7 @@ private static String toHitIsImpossible(Game game, Entity ae, int attackerId, Ta // first check to see if there are any usable weapons boolean usable = false; for (int wId : weapon.getBayWeapons()) { - Mounted m = ae.getEquipment(wId); + Mounted m = ae.getEquipment(wId); WeaponType bayWType = ((WeaponType) m.getType()); boolean bayWUsesAmmo = (bayWType.getAmmoType() != AmmoType.T_NA); if (m.canFire()) { @@ -1437,7 +1433,7 @@ private static String toHitIsImpossible(Game game, Entity ae, int attackerId, Ta continue; } if ((prevAttack.getEntityId() == attackerId) && (weaponId != prevAttack.getWeaponId())) { - Mounted prevWeapon = ae.getEquipment(prevAttack.getWeaponId()); + Mounted prevWeapon = ae.getEquipment(prevAttack.getWeaponId()); if (prevWeapon != null) { int loc = prevWeapon.getLocation(); boolean rearMount = prevWeapon.isRearMounted(); @@ -1787,9 +1783,9 @@ private static String toHitIsImpossible(Game game, Entity ae, int attackerId, Ta if (ae.usesWeaponBays()) { //For Dropships for (int wId : weapon.getBayWeapons()) { - Mounted bayW = ae.getEquipment(wId); + Mounted bayW = ae.getEquipment(wId); // check the loaded ammo for the Arrow IV flag - Mounted bayWAmmo = bayW.getLinked(); + Mounted bayWAmmo = bayW.getLinked(); AmmoType bAType = (AmmoType) bayWAmmo.getType(); if (bAType.getAmmoType() != AmmoType.T_ARROW_IV) { return Messages.getString("WeaponAttackAction.OnlyArrowArty"); @@ -3566,7 +3562,7 @@ private static ToHitData compileAttackerToHitMods(Game game, Entity ae, Targetab private static ToHitData compileAeroAttackerToHitMods(Game game, Entity ae, Targetable target, int ttype, ToHitData toHit, int aimingAt, AimingMode aimingMode, int eistatus, - WeaponType wtype, Mounted weapon, + WeaponType wtype, Mounted weapon, AmmoType atype, EnumSet munition, boolean isArtilleryIndirect, boolean isFlakAttack, @@ -4014,7 +4010,7 @@ private static ToHitData compileTargetToHitMods(Game game, Entity ae, Targetable int ttype, LosEffects los, ToHitData toHit, int toSubtract, int aimingAt, AimingMode aimingMode, int distance, - WeaponType wtype, Mounted weapon, AmmoType atype, + WeaponType wtype, WeaponMounted weapon, AmmoType atype, EnumSet munition, boolean isArtilleryDirect, boolean isArtilleryIndirect, boolean isAttackerInfantry, @@ -4361,7 +4357,7 @@ else if ((atype != null) */ private static ToHitData compileTerrainAndLosToHitMods(Game game, Entity ae, Targetable target, int ttype, int aElev, int tElev, int targEl, int distance, LosEffects los, ToHitData toHit, ToHitData losMods, int toSubtract, int eistatus, - WeaponType wtype, Mounted weapon, int weaponId, AmmoType atype, Mounted ammo, EnumSet munition, boolean isAttackerInfantry, + WeaponType wtype, WeaponMounted weapon, int weaponId, AmmoType atype, AmmoMounted ammo, EnumSet munition, boolean isAttackerInfantry, boolean inSameBuilding, boolean isIndirect, boolean isPointBlankShot, boolean underWater) { if (ae == null || target == null) { // Can't handle these attacks without a valid attacker and target @@ -4911,7 +4907,7 @@ private static ToHitData handleSwarmSecondaryAttacks(Game game, Entity ae, Targe * @param srt Class that stores whether or not this WAA should return a special resolution */ private static ToHitData artilleryDirectToHit(Game game, Entity ae, Targetable target, int ttype, - ToHitData losMods, ToHitData toHit, WeaponType wtype, Mounted weapon, AmmoType atype, + ToHitData losMods, ToHitData toHit, WeaponType wtype, WeaponMounted weapon, AmmoType atype, boolean isArtilleryFLAK, boolean usesAmmo, SpecialResolutionTracker srt) { if (null == atype) { @@ -5077,7 +5073,7 @@ private static ToHitData artilleryIndirectToHit(Entity ae, Targetable target, * @param srt Class that stores whether or not this WAA should return a special resolution */ private static ToHitData handleArtilleryAttacks(Game game, Entity ae, Targetable target, int ttype, - ToHitData losMods, ToHitData toHit, WeaponType wtype, Mounted weapon, AmmoType atype, + ToHitData losMods, ToHitData toHit, WeaponType wtype, WeaponMounted weapon, AmmoType atype, boolean isArtilleryDirect, boolean isArtilleryFLAK, boolean isArtilleryIndirect, boolean isHoming, boolean usesAmmo, SpecialResolutionTracker srt) { Entity te = null; @@ -5184,7 +5180,7 @@ public static ToHitData processAttackerQuirks(ToHitData toHit, Entity ae, Target return toHit; } - public static ToHitData processAttackerSPAs(ToHitData toHit, Entity ae, Targetable target, Mounted weapon, Game game){ + public static ToHitData processAttackerSPAs(ToHitData toHit, Entity ae, Targetable target, WeaponMounted weapon, Game game){ PlanetaryConditions conditions = game.getPlanetaryConditions(); // blood stalker SPA diff --git a/megamek/src/megamek/common/alphaStrike/conversion/ASArcedDamageConverter.java b/megamek/src/megamek/common/alphaStrike/conversion/ASArcedDamageConverter.java index 44ed8e6cfce..9a7f68892b9 100644 --- a/megamek/src/megamek/common/alphaStrike/conversion/ASArcedDamageConverter.java +++ b/megamek/src/megamek/common/alphaStrike/conversion/ASArcedDamageConverter.java @@ -43,7 +43,7 @@ protected ASArcedDamageConverter(Entity entity, AlphaStrikeElement element, Calc } // Flatten the weaponlist as weapon bays are not relevant for AS conversion List flattenedWeaponList = new ArrayList<>(); - for (Mounted weapon : entity.getWeaponList()) { + for (Mounted weapon : entity.getWeaponList()) { if (weapon.getType() instanceof BayWeapon) { weapon.getBayWeapons().stream().map(entity::getEquipment).forEach(flattenedWeaponList::add); } else { diff --git a/megamek/src/megamek/common/alphaStrike/conversion/ASLargeAeroSpecialAbilityConverter.java b/megamek/src/megamek/common/alphaStrike/conversion/ASLargeAeroSpecialAbilityConverter.java index 81690e7421a..28b9bb45b6b 100644 --- a/megamek/src/megamek/common/alphaStrike/conversion/ASLargeAeroSpecialAbilityConverter.java +++ b/megamek/src/megamek/common/alphaStrike/conversion/ASLargeAeroSpecialAbilityConverter.java @@ -49,7 +49,7 @@ protected ASLargeAeroSpecialAbilityConverter(Entity entity, AlphaStrikeElement e @Override protected void processENE() { Arrays.fill(hasExplosiveArcComponent, false); - for (Mounted equipment : entity.getEquipment()) { + for (Mounted equipment : entity.getEquipment()) { processArcENE(equipment); if (equipment.getType() instanceof BayWeapon) { var bayEquipmentList = new ArrayList<>(equipment.getBayWeapons()); diff --git a/megamek/src/megamek/common/battlevalue/BVCalculator.java b/megamek/src/megamek/common/battlevalue/BVCalculator.java index f8744bbd42a..304c7e06f14 100644 --- a/megamek/src/megamek/common/battlevalue/BVCalculator.java +++ b/megamek/src/megamek/common/battlevalue/BVCalculator.java @@ -22,7 +22,10 @@ import megamek.client.ui.swing.calculationReport.DummyCalculationReport; import megamek.codeUtilities.MathUtility; import megamek.common.*; +import megamek.common.equipment.AmmoMounted; import megamek.common.equipment.ArmorType; +import megamek.common.equipment.MiscMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.OptionsConstants; import megamek.common.weapons.bayweapons.BayWeapon; @@ -345,7 +348,7 @@ protected void processArmor() { // Modular Armor int modularArmor = 0; - for (Mounted mounted : entity.getMisc()) { + for (MiscMounted mounted : entity.getMisc()) { if (mounted.getType().hasFlag(MiscType.F_MODULAR_ARMOR) && (mounted.getLocation() == loc)) { modularArmor += mounted.getBaseDamageCapacity() - mounted.getDamageTaken(); } @@ -733,15 +736,15 @@ protected double processWeapon(Mounted weapon, boolean showInReport, * @param addToOffensiveValue When true, will add the result to offensiveValue and show the result * @return The BV for this weapon */ - protected double processWeapon(Mounted weapon, boolean showInReport, + protected double processWeapon(Mounted weapon, boolean showInReport, boolean addToOffensiveValue, int weaponCount) { double weaponBV = weapon.getType().getBV(entity); // MG Arrays need to sum up their linked MGs if ((weapon.getType() instanceof WeaponType) && weapon.getType().hasFlag(WeaponType.F_MGA)) { double mgBV = 0; - for (int eqNum : weapon.getBayWeapons()) { - Mounted mg = entity.getEquipment(eqNum); + for (int eqNum : ((WeaponMounted) weapon).getBayWeapons()) { + Mounted mg = entity.getEquipment(eqNum); if ((mg != null) && (!mg.isDestroyed())) { mgBV += mg.getType().getBV(entity); } @@ -1033,13 +1036,13 @@ protected int offensiveSpeedFactorMP() { protected void processOffensiveTypeModifier() { } /** @return true when the given ammo (must be AmmoType) counts towards offensive ammo BV calculation. */ - protected boolean ammoCounts(Mounted ammo) { - AmmoType ammoType = (AmmoType) ammo.getType(); + protected boolean ammoCounts(AmmoMounted ammo) { + AmmoType ammoType = ammo.getType(); return (ammo.getUsableShotsLeft() > 0) && (ammoType.getAmmoType() != AmmoType.T_AMS) && (ammoType.getAmmoType() != AmmoType.T_APDS) && (ammoType.getAmmoType() != AmmoType.T_SCREEN_LAUNCHER) - && !ammo.isOneShotAmmo(); + && !ammo.isOneShot(); } /** Processes the sum of offensive and defensive battle rating and modifiers that affect this sum. */ @@ -1070,8 +1073,8 @@ protected void processSummarize() { } protected void assembleAmmo() { - for (Mounted ammo : entity.getAmmo()) { - AmmoType ammoType = (AmmoType) ammo.getType(); + for (AmmoMounted ammo : entity.getAmmo()) { + AmmoType ammoType = ammo.getType(); // don't count depleted ammo, AMS and oneshot ammo if (ammoCounts(ammo)) { @@ -1088,8 +1091,8 @@ protected void assembleAmmo() { } } - for (Mounted weapon : entity.getTotalWeaponList()) { - WeaponType wtype = (WeaponType) weapon.getType(); + for (WeaponMounted weapon : entity.getTotalWeaponList()) { + WeaponType wtype = weapon.getType(); if (weapon.isDestroyed() //|| wtype.hasFlag(WeaponType.F_AMS) || wtype.hasFlag(WeaponType.F_B_POD) || wtype.hasFlag(WeaponType.F_M_POD) diff --git a/megamek/src/megamek/common/battlevalue/BattleArmorBVCalculator.java b/megamek/src/megamek/common/battlevalue/BattleArmorBVCalculator.java index 37954290a6f..dc16721dd4d 100644 --- a/megamek/src/megamek/common/battlevalue/BattleArmorBVCalculator.java +++ b/megamek/src/megamek/common/battlevalue/BattleArmorBVCalculator.java @@ -21,6 +21,7 @@ import megamek.client.ui.swing.calculationReport.CalculationReport; import megamek.client.ui.swing.calculationReport.DummyCalculationReport; import megamek.common.*; +import megamek.common.equipment.AmmoMounted; import java.util.ArrayList; import java.util.HashSet; @@ -207,7 +208,7 @@ protected void processSummarize() { } @Override - protected boolean ammoCounts(Mounted ammo) { + protected boolean ammoCounts(AmmoMounted ammo) { return super.ammoCounts(ammo) && ((ammo.getLocation() == BattleArmor.LOC_SQUAD) || (ammo.getLocation() == currentTrooper)); } diff --git a/megamek/src/megamek/common/battlevalue/HeatTrackingBVCalculator.java b/megamek/src/megamek/common/battlevalue/HeatTrackingBVCalculator.java index 9896bde23b0..fa30410ee82 100644 --- a/megamek/src/megamek/common/battlevalue/HeatTrackingBVCalculator.java +++ b/megamek/src/megamek/common/battlevalue/HeatTrackingBVCalculator.java @@ -20,6 +20,7 @@ import megamek.common.*; import megamek.common.annotations.Nullable; +import megamek.common.equipment.WeaponMounted; import megamek.common.weapons.ppc.PPCWeapon; import megamek.common.weapons.prototypes.*; @@ -54,7 +55,7 @@ protected void processWeapons() { } List weaponRecords = new ArrayList<>(); - for (Mounted mounted : entity.getWeaponList()) { + for (WeaponMounted mounted : entity.getWeaponList()) { if (!countAsOffensiveWeapon(mounted)) { continue; } @@ -142,11 +143,11 @@ static class WeaponBvHeatRecord { return null; } - protected double weaponHeat(Mounted weapon) { + protected double weaponHeat(WeaponMounted weapon) { WeaponType wType = (WeaponType) weapon.getType(); double weaponHeat = wType.getHeat(); - if (weapon.isOneShotWeapon()) { + if (weapon.isOneShot()) { weaponHeat /= 4; } diff --git a/megamek/src/megamek/common/battlevalue/InfantryBVCalculator.java b/megamek/src/megamek/common/battlevalue/InfantryBVCalculator.java index 7a00a8a3913..052cb93d9a7 100644 --- a/megamek/src/megamek/common/battlevalue/InfantryBVCalculator.java +++ b/megamek/src/megamek/common/battlevalue/InfantryBVCalculator.java @@ -87,22 +87,22 @@ protected void processWeapons() { // Damage dealt by the troopers is averaged over primary and secondary weapons; therefore calculate // weapon damage at full strength and then multiply by the surviving trooper ratio if (primaryWeapon != null) { - Mounted primaryWeaponMounted = new Mounted(infantry, primaryWeapon); + Mounted primaryWeaponMounted = Mounted.createMounted(infantry, primaryWeapon); processWeapon(primaryWeaponMounted, true, true, primaryShooterCount); } if (secondaryWeapon != null) { - Mounted secondaryWeaponMounted = new Mounted(infantry, secondaryWeapon); + Mounted secondaryWeaponMounted = Mounted.createMounted(infantry, secondaryWeapon); processWeapon(secondaryWeaponMounted, true, true, secondaryShooterCount); } if (infantry.canMakeAntiMekAttacks()) { bvReport.addLine("Anti-Mek:", "", ""); if (primaryWeapon != null && !primaryWeapon.hasFlag(InfantryWeapon.F_INF_ARCHAIC)) { - Mounted primaryWeaponMounted = new Mounted(infantry, primaryWeapon); + Mounted primaryWeaponMounted = Mounted.createMounted(infantry, primaryWeapon); processWeapon(primaryWeaponMounted, true, true, primaryShooterCount); } if (secondaryWeapon != null && !secondaryWeapon.hasFlag(InfantryWeapon.F_INF_ARCHAIC)) { - Mounted secondaryWeaponMounted = new Mounted(infantry, secondaryWeapon); + Mounted secondaryWeaponMounted = Mounted.createMounted(infantry, secondaryWeapon); processWeapon(secondaryWeaponMounted, true, true, secondaryShooterCount); } } diff --git a/megamek/src/megamek/common/battlevalue/LargeAeroBVCalculator.java b/megamek/src/megamek/common/battlevalue/LargeAeroBVCalculator.java index 3511af07ff7..9c063003ff8 100644 --- a/megamek/src/megamek/common/battlevalue/LargeAeroBVCalculator.java +++ b/megamek/src/megamek/common/battlevalue/LargeAeroBVCalculator.java @@ -19,6 +19,8 @@ package megamek.common.battlevalue; import megamek.common.*; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.weapons.bayweapons.BayWeapon; import java.util.HashMap; @@ -39,7 +41,7 @@ public abstract class LargeAeroBVCalculator extends AeroBVCalculator { protected int nominalNoseLocation; protected int nominalLeftLocation; protected int nominalRightLocation; - protected final Map collectedWeapons = new HashMap<>(); + protected final Map collectedWeapons = new HashMap<>(); LargeAeroBVCalculator(Entity entity) { super(entity); @@ -58,8 +60,8 @@ protected boolean usesWeaponHeat() { @Override protected void assembleAmmo() { - for (Mounted ammo : entity.getAmmo()) { - AmmoType ammoType = (AmmoType) ammo.getType(); + for (AmmoMounted ammo : entity.getAmmo()) { + AmmoType ammoType = ammo.getType(); // don't count depleted ammo, AMS and oneshot ammo if (ammoCounts(ammo)) { @@ -222,9 +224,9 @@ protected boolean canBeSummed(Mounted weapon1, Mounted weapon2) { @Override protected void processWeapons() { - for (Mounted weapon : entity.getTotalWeaponList()) { + for (WeaponMounted weapon : entity.getTotalWeaponList()) { if (countAsOffensiveWeapon(weapon)) { - Mounted key = collectedWeapons.keySet().stream() + WeaponMounted key = collectedWeapons.keySet().stream() .filter(wp -> canBeSummed(weapon, wp)).findFirst().orElse(weapon); collectedWeapons.merge(key, 1, Integer::sum); } @@ -257,8 +259,8 @@ protected double processArc(final int bvNominalLocation) { bvReport.addEmptyLine(); bvReport.addLine(arcName(bvNominalLocation) + ":", "", ""); boolean arcEmpty = true; - for (Map.Entry weaponEntry : collectedWeapons.entrySet()) { - Mounted weapon = weaponEntry.getKey(); + for (Map.Entry weaponEntry : collectedWeapons.entrySet()) { + WeaponMounted weapon = weaponEntry.getKey(); if (isNominalArc(bvNominalLocation, weapon) && countAsOffensiveWeapon(weapon)) { arcHeat += weaponHeat(weapon) * weaponEntry.getValue(); processWeapon(weapon, true, true, weaponEntry.getValue()); diff --git a/megamek/src/megamek/common/battlevalue/WarShipBVCalculator.java b/megamek/src/megamek/common/battlevalue/WarShipBVCalculator.java index 99e9c3f1aeb..2119d08ab9e 100644 --- a/megamek/src/megamek/common/battlevalue/WarShipBVCalculator.java +++ b/megamek/src/megamek/common/battlevalue/WarShipBVCalculator.java @@ -19,6 +19,7 @@ package megamek.common.battlevalue; import megamek.common.*; +import megamek.common.equipment.WeaponMounted; import java.util.HashMap; import java.util.Map; @@ -128,9 +129,9 @@ protected void determineFront() { @Override protected void processWeapons() { - for (Mounted weapon : entity.getTotalWeaponList()) { + for (WeaponMounted weapon : entity.getTotalWeaponList()) { if (countAsOffensiveWeapon(weapon)) { - Mounted key = collectedWeapons.keySet().stream() + WeaponMounted key = collectedWeapons.keySet().stream() .filter(wp -> canBeSummed(weapon, wp)).findFirst().orElse(weapon); collectedWeapons.merge(key, 1, Integer::sum); } diff --git a/megamek/src/megamek/common/enums/WeaponSortOrder.java b/megamek/src/megamek/common/enums/WeaponSortOrder.java index aaa7331672e..9ffd8faf8e4 100644 --- a/megamek/src/megamek/common/enums/WeaponSortOrder.java +++ b/megamek/src/megamek/common/enums/WeaponSortOrder.java @@ -20,6 +20,7 @@ import megamek.MegaMek; import megamek.common.*; +import megamek.common.equipment.WeaponMounted; import org.apache.logging.log4j.LogManager; import java.util.Comparator; @@ -83,7 +84,7 @@ public boolean isCustom() { * @return the comparator for weapon sorting, or the default weapon sort comparator if the sort * order isn't handled yet. */ - public Comparator getWeaponSortComparator(final Entity entity) { + public Comparator getWeaponSortComparator(final Entity entity) { switch (this) { case DEFAULT: return new WeaponComparatorNum(entity); diff --git a/megamek/src/megamek/common/equipment/AmmoMounted.java b/megamek/src/megamek/common/equipment/AmmoMounted.java new file mode 100644 index 00000000000..9c606af9e2b --- /dev/null +++ b/megamek/src/megamek/common/equipment/AmmoMounted.java @@ -0,0 +1,129 @@ +/* + * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MegaMek. + * + * MegaMek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MegaMek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MegaMek. If not, see . + */ + +package megamek.common.equipment; + +import megamek.common.*; + +import java.util.EnumSet; +import java.util.HashSet; +import java.util.Set; + +public class AmmoMounted extends Mounted { + + public AmmoMounted(Entity entity, AmmoType type) { + super(entity, type); + + setShotsLeft(type.getShots()); + setSize(type.getTonnage(entity)); + } + + /** + * Change the type of ammo in this bin + * @param at The new ammo type + */ + public void changeAmmoType(AmmoType at) { + setType(at); + if (getLocation() == Entity.LOC_NONE) { + // Oneshot launcher + setShotsLeft(1); + } else { + // Regular launcher + setShotsLeft(at.getShots()); + } + } + + @Override + public int getExplosionDamage() { + int rackSize = getType().getRackSize(); + int damagePerShot = getType().getDamagePerShot(); + // Anti-ship EW bomb does no damage but deals a 5-point explosion if LAM bomb bay is hit + if ((getType() instanceof BombType) + && (((BombType) getType()).getBombType() == BombType.B_ASEW)) { + damagePerShot = 5; + } + + //Capital missiles need a racksize for this + if (getType().hasFlag(AmmoType.F_CAP_MISSILE)) { + rackSize = 1; + } + + //Screen launchers need a racksize. Damage is 15 per TW p251 + if (getType().getAmmoType() == AmmoType.T_SCREEN_LAUNCHER) { + rackSize = 1; + damagePerShot = 15; + } + + EnumSet mType = getType().getMunitionType(); + // both Dead-Fire and Tandem-charge SRM's do 3 points of damage per + // shot when critted + // Dead-Fire LRM's do 2 points of damage per shot when critted. + if ((mType.contains(AmmoType.Munitions.M_DEAD_FIRE)) + || (mType.contains(AmmoType.Munitions.M_TANDEM_CHARGE))) { + damagePerShot++; + } else if (getType().getAmmoType() == AmmoType.T_TASER) { + damagePerShot = 6; + } + + if (getType().getAmmoType() == AmmoType.T_MEK_MORTAR) { + if ((mType.contains(AmmoType.Munitions.M_AIRBURST)) + || (mType.contains(AmmoType.Munitions.M_FLARE)) + || (mType.contains(AmmoType.Munitions.M_SMOKE_WARHEAD))) { + damagePerShot = 1; + } else { + damagePerShot = 2; + } + } + + return damagePerShot * rackSize * getBaseShotsLeft(); + } + + /** + * Sets the capacity of the ammo bin. Used for units that allocate by shot rather than by ton. + * @param capacity The capacity of the ammo bin in tons. + */ + public void setAmmoCapacity(double capacity) { + // alias for setSize + setSize(capacity); + } + + @Override + public boolean isOneShot() { + if (getLinkedBy() != null) { + // There should not be any circular references, but we should track where we've been just in case. + // Do a couple checks first to avoid instantiating a set unnecessarily. + Set> checked = new HashSet<>(); + for (Mounted current = getLinkedBy(); current != null; current = current.getLinkedBy()) { + if (checked.contains(current)) { + return false; + } + if ((current.getType() instanceof WeaponType) && current.isOneShot()) { + return true; + } + checked.add(current); + } + } + return false; + } + + @Override + public boolean isOneShotAmmo() { + return isOneShot(); + } +} diff --git a/megamek/src/megamek/common/equipment/BombMounted.java b/megamek/src/megamek/common/equipment/BombMounted.java new file mode 100644 index 00000000000..df159ae0471 --- /dev/null +++ b/megamek/src/megamek/common/equipment/BombMounted.java @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MegaMek. + * + * MegaMek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MegaMek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MegaMek. If not, see . + */ + + +package megamek.common.equipment; + +import megamek.common.BombType; +import megamek.common.Entity; +import megamek.common.Mounted; + +public class BombMounted extends Mounted { + public BombMounted(Entity entity, BombType type) { + super(entity, type); + } +} diff --git a/megamek/src/megamek/common/equipment/MiscMounted.java b/megamek/src/megamek/common/equipment/MiscMounted.java new file mode 100644 index 00000000000..dda26a5e2b5 --- /dev/null +++ b/megamek/src/megamek/common/equipment/MiscMounted.java @@ -0,0 +1,253 @@ +/* + * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MegaMek. + * + * MegaMek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MegaMek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MegaMek. If not, see . + */ + +package megamek.common.equipment; + +import megamek.common.*; + +public class MiscMounted extends Mounted { + + public static final int MINE_NONE = -1; + public static final int MINE_CONVENTIONAL = 0; + public static final int MINE_VIBRABOMB = 1; + public static final int MINE_ACTIVE = 2; + public static final int MINE_INFERNO = 3; + public static final int MINE_EMP = 4; + public static final int MINE_COMMAND_DETONATED = 5; + + private int baseDamageAbsorptionRate = 0; + private int baseDamageCapacity = 0; + private int damageTaken = 0; + private int mineType = MINE_NONE; + private int vibraSetting = 20; + + public MiscMounted(Entity entity, MiscType type) { + super(entity, type); + + if (type.hasFlag(MiscType.F_MINE)) { + setMineType(MINE_CONVENTIONAL); + // Used to keep track of the # of mines + setShotsLeft(1); + } + if (type.hasFlag(MiscType.F_VEHICLE_MINE_DISPENSER)) { + setMineType(MINE_CONVENTIONAL); + // Used to keep track of the # of mines + setShotsLeft(2); + } + if (type.hasFlag(MiscType.F_SENSOR_DISPENSER)) { + setShotsLeft(type.hasFlag(MiscType.F_BA_EQUIPMENT) ? 6 : 30); + } + if (((type.isShield() || type.hasFlag(MiscType.F_MODULAR_ARMOR)))) { + baseDamageAbsorptionRate = type.getBaseDamageAbsorptionRate(); + baseDamageCapacity = type.getBaseDamageCapacity(); + } + if (type.hasFlag(MiscType.F_MINESWEEPER)) { + setArmorValue(30); + } + } + + public int getBaseDamageAbsorptionRate() { + return baseDamageAbsorptionRate; + } + + public int getBaseDamageCapacity() { + return baseDamageCapacity; + } + + + /** + * Rules state that every time the shield takes a crit its damage absorption + * for each attack is reduced by 1. Also for every Arm actuator critted + * damage absorption is reduced by 1 and finally if the shoulder is hit the + * damage absorption is reduced by 2 making it possble to kill a shield + * before its gone through its full damage capacity. + * + * @param entity Entity mounted the shield + * @param location The shield location index + * @return The shield's damage absorption value + */ + public int getDamageAbsorption(Entity entity, int location) { + // Shields can only be used in arms so if you've got a shield in a + // location + // other than an arm your SOL --Torren. + if ((location != Mech.LOC_RARM) && (location != Mech.LOC_LARM)) { + return 0; + } + + int base = baseDamageAbsorptionRate; + + for (int slot = 0; slot < entity.getNumberOfCriticals(location); slot++) { + CriticalSlot cs = entity.getCritical(location, slot); + + if (cs == null) { + continue; + } + + if (cs.getType() != CriticalSlot.TYPE_EQUIPMENT) { + continue; + } + + Mounted m = cs.getMount(); + EquipmentType type = m.getType(); + if ((type instanceof MiscType) && ((MiscType) type).isShield()) { + if (cs.isDamaged()) { + base--; + } + } + } + + if (!entity.hasWorkingSystem(Mech.ACTUATOR_SHOULDER, location)) { + base -= 2; + } + + if (!entity.hasWorkingSystem(Mech.ACTUATOR_LOWER_ARM, location)) { + base--; + } + if (!entity.hasWorkingSystem(Mech.ACTUATOR_UPPER_ARM, location)) { + base--; + } + if (!entity.hasWorkingSystem(Mech.ACTUATOR_HAND, location)) { + base--; + } + + return Math.max(0, base); + } + + /** + * Rules say every time a shield is critted it loses 5 points from its + * Damage Capacity. basically count down from the top then subtract the + * amount of damage its already take. The damage capacity is used to + * determine if the shield is still viable. + * + * @param entity The entity the shield is mounted on + * @param location The shield's location index + * @return damage capacity(no less than 0) + */ + public int getCurrentDamageCapacity(Entity entity, int location) { + // Shields can only be used in arms so if you've got a shield in a + // location + // other than an arm your SOL --Torren. + if ((location != Mech.LOC_RARM) && (location != Mech.LOC_LARM)) { + return 0; + } + + int base = baseDamageCapacity; + + for (int slot = 0; slot < entity.getNumberOfCriticals(location); slot++) { + CriticalSlot cs = entity.getCritical(location, slot); + + if (cs == null) { + continue; + } + + if (cs.getType() != CriticalSlot.TYPE_EQUIPMENT) { + continue; + } + + Mounted m = cs.getMount(); + EquipmentType type = m.getType(); + if ((type instanceof MiscType) && ((MiscType) type).isShield()) { + if (cs.isDamaged()) { + base -= 5; + } + } + } + if (!entity.hasWorkingSystem(Mech.ACTUATOR_SHOULDER, location)) { + base -= 2; + } + + if (!entity.hasWorkingSystem(Mech.ACTUATOR_LOWER_ARM, location)) { + base--; + } + if (!entity.hasWorkingSystem(Mech.ACTUATOR_UPPER_ARM, location)) { + base--; + } + if (!entity.hasWorkingSystem(Mech.ACTUATOR_HAND, location)) { + base--; + } + + return Math.max(0, base - damageTaken); + } + + public int getDamageTaken() { + return damageTaken; + } + + public void setDamageTaken(int damage) { + damageTaken = damage; + } + + public void takeDamage(int damage) { + damageTaken += damage; + } + /** + * @return the type of mine this mounted is, or -1 if it isn't + * a mine + */ + public int getMineType() { + return mineType; + } + + /** + * set the type of mine this should be + * + * @param mineType The mine type index + */ + public void setMineType(int mineType) { + this.mineType = mineType; + } + + /** + * set the vibrabomb sensitivity + * + * @param vibraSetting + * the int sensitivity to set + */ + public void setVibraSetting(int vibraSetting) { + this.vibraSetting = vibraSetting; + } + + /** + * get the vibrabomb sensitivity + * + * @return the int vibrabomb sensitity this mine is set to. + */ + public int getVibraSetting() { + return vibraSetting; + } + + @Override + public String getBaseDesc() { + switch (getMineType()) { + case MINE_CONVENTIONAL: + return Messages.getString("Mounted.ConventionalMine"); + case MINE_VIBRABOMB: + return Messages.getString("Mounted.VibraBombMine"); + case MINE_COMMAND_DETONATED: + return Messages.getString("Mounted.CommandDetonatedMine"); + case MINE_ACTIVE: + return Messages.getString("Mounted.ActiveMine"); + case MINE_INFERNO: + return Messages.getString("Mounted.InfernoMine"); + default: + return super.getBaseDesc(); + } + } + +} diff --git a/megamek/src/megamek/common/equipment/WeaponMounted.java b/megamek/src/megamek/common/equipment/WeaponMounted.java new file mode 100644 index 00000000000..a7afca97ec9 --- /dev/null +++ b/megamek/src/megamek/common/equipment/WeaponMounted.java @@ -0,0 +1,218 @@ +/* + * Copyright (c) 2024 - The MegaMek Team. All Rights Reserved. + * + * This file is part of MegaMek. + * + * MegaMek is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * MegaMek is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with MegaMek. If not, see . + */ + +package megamek.common.equipment; + +import megamek.common.*; +import megamek.common.options.OptionsConstants; +import megamek.common.weapons.gaussrifles.GaussWeapon; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +public class WeaponMounted extends Mounted { + + // A list of ids (equipment numbers) for the weapons and ammo linked to + // this bay (if the mounted is of the BayWeapon type) + // I can also use this for weapons of the same type on a capital fighter + // and now Machine Gun Arrays too! + private List bayWeapons = new ArrayList<>(); + private List bayAmmo = new ArrayList<>(); + + public WeaponMounted(Entity entity, WeaponType type) { + super(entity, type); + } + + @Override + public int getExplosionDamage() { + // TacOps Gauss Weapon rule p. 102 + if ((getType() instanceof GaussWeapon) && getType().hasModes() + && curMode().equals("Powered Down")) { + return 0; + } + if ((isHotLoaded() || hasQuirk(OptionsConstants.QUIRK_WEAP_NEG_AMMO_FEED_PROBLEMS)) + && (getLinked() != null) && (getLinked().getUsableShotsLeft() > 0)) { + Mounted link = getLinked(); + AmmoType atype = ((AmmoType) link.getType()); + int damagePerShot = atype.getDamagePerShot(); + // Launchers with Dead-Fire missiles in them do an extra point of + // damage per shot when critted + if (atype.getMunitionType().contains(AmmoType.Munitions.M_DEAD_FIRE)) { + damagePerShot++; + } + + return getType().getRackSize() * damagePerShot; + } + + if (getType().hasFlag(WeaponType.F_PPC) && (hasChargedCapacitor() != 0)) { + if (isFired()) { + if (hasChargedCapacitor() == 2) { + return 15; + } + return 0; + } + if (hasChargedCapacitor() == 2) { + return 30; + } + return 15; + } + + if ((getType().getAmmoType() == AmmoType.T_MPOD) && isFired()) { + return 0; + } + + return getType().getExplosionDamage(); + } + + @Override + public int getCurrentHeat() { + int heat = getType().getHeat(); + + // AR10's have heat based upon the loaded missile + if (getType().getName().equals("AR10")) { + AmmoType ammoType = (AmmoType) getLinked().getType(); + if (ammoType.hasFlag(AmmoType.F_AR10_BARRACUDA)) { + return 10; + } else if (ammoType.hasFlag(AmmoType.F_AR10_WHITE_SHARK)) { + return 15; + } else { // AmmoType.F_AR10_KILLER_WHALE + return 20; + } + } + + if (getType().hasFlag(WeaponType.F_ENERGY) && getType().hasModes()) { + heat = Compute.dialDownHeat(this, getType()); + } + // multiply by number of shots and number of weapons + heat = heat * getCurrentShots() * getNWeapons(); + if (hasQuirk(OptionsConstants.QUIRK_WEAP_POS_IMP_COOLING)) { + heat = Math.max(1, heat - 1); + } + if (hasQuirk(OptionsConstants.QUIRK_WEAP_NEG_POOR_COOLING)) { + heat += 1; + } + if (hasQuirk(OptionsConstants.QUIRK_WEAP_NEG_NO_COOLING)) { + heat += 2; + } + if (hasChargedCapacitor() == 2) { + heat += 10; + } + if (hasChargedCapacitor() == 1) { + heat += 5; + } + if ((getLinkedBy() != null) + && !getLinkedBy().isInoperable() + && (getLinkedBy().getType() instanceof MiscType) + && getLinkedBy().getType().hasFlag( + MiscType.F_LASER_INSULATOR)) { + heat -= 1; + if (heat == 0) { + heat++; + } + } + + return heat; + } + + /** + * @return The ammo currently linked by this weapon, or null if there is no linked ammo. + */ + public AmmoMounted getLinkedAmmo() { + return (getLinked() instanceof AmmoMounted) ? (AmmoMounted) getLinked() : null; + } + + /** + * Returns how many shots the weapon is using + */ + public int getCurrentShots() { + WeaponType wtype = (WeaponType) getType(); + int nShots = getNumShots(wtype, curMode(), false); + // sets number of shots for MG arrays + if (wtype.hasFlag(WeaponType.F_MGA)) { + nShots = 0; + for (int eqn : getBayWeapons()) { + Mounted m = getEntity().getEquipment(eqn); + if (null == m) { + continue; + } + if ((m.getLocation() == getLocation()) + && !m.isDestroyed() + && !m.isBreached() + && m.getType().hasFlag(WeaponType.F_MG) + && (((WeaponType) m.getType()).getRackSize() == ((WeaponType) getType()) + .getRackSize())) { + nShots++; + } + } + } + return nShots; + } + + @Override + public boolean isOneShot() { + return getType().hasFlag(WeaponType.F_ONESHOT); + } + + public void addWeaponToBay(int w) { + bayWeapons.add(w); + } + + @Override + public List getBayWeapons() { + return bayWeapons; + } + + public void addAmmoToBay(int a) { + bayAmmo.add(a); + } + + @Override + public List getBayAmmo() { + return bayAmmo; + } + + /** + * + * @param mAmmoId equipment number of ammo + * @return whether the ammo is in this weapon's bay + */ + public boolean ammoInBay(int mAmmoId) { + for (int nextAmmoId : bayAmmo) { + if (nextAmmoId == mAmmoId) { + return true; + } + } + return false; + } + + @Override + protected List bayComponentsToString() { + List list = new ArrayList<>(); + if (!bayWeapons.isEmpty()) { + List bayWeaponIds = bayWeapons.stream().map(id -> "[" + id + "]").collect(Collectors.toList()); + list.add("Bay Weapons: " + String.join(", ", bayWeaponIds)); + } + if (!bayAmmo.isEmpty()) { + List bayAmmoIds = bayAmmo.stream().map(id -> "[" + id + "]").collect(Collectors.toList()); + list.add("Bay Ammo: " + String.join(", ", bayAmmoIds)); + } + return list; + } +} diff --git a/megamek/src/megamek/common/loaders/BLKDropshipFile.java b/megamek/src/megamek/common/loaders/BLKDropshipFile.java index 36dc5aa6cc2..d612582726e 100644 --- a/megamek/src/megamek/common/loaders/BLKDropshipFile.java +++ b/megamek/src/megamek/common/loaders/BLKDropshipFile.java @@ -14,6 +14,7 @@ package megamek.common.loaders; import megamek.common.*; +import megamek.common.equipment.WeaponMounted; import megamek.common.util.BuildingBlock; /** @@ -232,7 +233,7 @@ protected void loadEquipment(Dropship a, String sName, int nLoc) boolean rearMount = false; int nAmmo = 1; // set up a new weapons bay mount - Mounted bayMount = null; + WeaponMounted bayMount = null; // set up a new bay type boolean newBay = false; double bayDamage = 0; @@ -306,8 +307,7 @@ protected void loadEquipment(Dropship a, String sName, int nLoc) WeaponType weap = (WeaponType) newmount.getType(); if (bayMount == null) { try { - bayMount = a.addEquipment(weap.getBayType(), - nLoc, rearMount); + bayMount = (WeaponMounted) a.addEquipment(weap.getBayType(), nLoc, rearMount); newBay = false; } catch (LocationFullException ex) { throw new EntityLoadingException( @@ -331,8 +331,7 @@ protected void loadEquipment(Dropship a, String sName, int nLoc) bayDamage += damage; } else { try { - bayMount = a.addEquipment(weap.getBayType(), - nLoc, rearMount); + bayMount = (WeaponMounted) a.addEquipment(weap.getBayType(), nLoc, rearMount); } catch (LocationFullException ex) { throw new EntityLoadingException( ex.getMessage()); diff --git a/megamek/src/megamek/common/loaders/BLKFile.java b/megamek/src/megamek/common/loaders/BLKFile.java index abacd3bd788..ee27673e60f 100644 --- a/megamek/src/megamek/common/loaders/BLKFile.java +++ b/megamek/src/megamek/common/loaders/BLKFile.java @@ -866,7 +866,7 @@ public static BuildingBlock getBlock(Entity t) { for (int i = 0; i < numLocs; i++) { eq.add(new Vector<>()); } - for (Mounted m : t.getEquipment()) { + for (Mounted m : t.getEquipment()) { // Ignore Mounteds that represent a WeaponGroup // BA anti-personnel weapons are written just after the mount if (m.isWeaponGroup() || m.isAPMMounted() || (m.getType() instanceof InfantryAttack)) { diff --git a/megamek/src/megamek/common/loaders/BLKInfantryFile.java b/megamek/src/megamek/common/loaders/BLKInfantryFile.java index 030076634e4..75cd6eb472f 100644 --- a/megamek/src/megamek/common/loaders/BLKInfantryFile.java +++ b/megamek/src/megamek/common/loaders/BLKInfantryFile.java @@ -100,11 +100,11 @@ public Entity getEntity() throws EntityLoadingException { Mounted m; try { if ((infantry.getSecondaryWeaponsPerSquad() > 1)) { - m = new InfantryWeaponMounted(infantry, stype, (InfantryWeapon) ptype); + m = new InfantryWeaponMounted(infantry, (InfantryWeapon) stype, (InfantryWeapon) ptype); } else if (stype != null) { - m = new InfantryWeaponMounted(infantry, ptype, (InfantryWeapon) stype); + m = new InfantryWeaponMounted(infantry, (InfantryWeapon) ptype, (InfantryWeapon) stype); } else { - m = new Mounted(infantry, ptype); + m = Mounted.createMounted(infantry, ptype); } } catch (ClassCastException ex) { throw new EntityLoadingException(ex.getMessage()); diff --git a/megamek/src/megamek/common/loaders/BLKJumpshipFile.java b/megamek/src/megamek/common/loaders/BLKJumpshipFile.java index fa0be091a2c..06f8c24ad69 100644 --- a/megamek/src/megamek/common/loaders/BLKJumpshipFile.java +++ b/megamek/src/megamek/common/loaders/BLKJumpshipFile.java @@ -14,6 +14,7 @@ package megamek.common.loaders; import megamek.common.*; +import megamek.common.equipment.WeaponMounted; import megamek.common.util.BuildingBlock; /** @@ -237,12 +238,12 @@ protected void loadEquipment(Jumpship a, String sName, int nLoc) throws EntityLo prefix = "IS "; } - boolean rearMount = false; - int nAmmo = 1; + boolean rearMount; + int nAmmo; // set up a new weapons bay mount - Mounted bayMount = null; + WeaponMounted bayMount = null; // set up a new bay type - boolean newBay = false; + boolean newBay; double bayDamage = 0; if (saEquip[0] != null) { for (String element : saEquip) { @@ -285,7 +286,7 @@ protected void loadEquipment(Jumpship a, String sName, int nLoc) throws EntityLo if (etype != null) { // first load the equipment - Mounted newmount; + Mounted newmount; try { if (nAmmo == 1) { newmount = a.addEquipment(etype, nLoc, rearMount); @@ -306,7 +307,7 @@ protected void loadEquipment(Jumpship a, String sName, int nLoc) throws EntityLo WeaponType weap = (WeaponType) newmount.getType(); if (bayMount == null) { try { - bayMount = a.addEquipment(weap.getBayType(), nLoc, rearMount); + bayMount = (WeaponMounted) a.addEquipment(weap.getBayType(), nLoc, rearMount); newBay = false; } catch (LocationFullException ex) { throw new EntityLoadingException(ex.getMessage()); @@ -323,7 +324,7 @@ protected void loadEquipment(Jumpship a, String sName, int nLoc) throws EntityLo bayDamage += damage; } else { try { - bayMount = a.addEquipment(weap.getBayType(), nLoc, rearMount); + bayMount = (WeaponMounted) a.addEquipment(weap.getBayType(), nLoc, rearMount); } catch (LocationFullException ex) { throw new EntityLoadingException(ex.getMessage()); } diff --git a/megamek/src/megamek/common/loaders/BLKSpaceStationFile.java b/megamek/src/megamek/common/loaders/BLKSpaceStationFile.java index ab5d8335282..47ceefedf21 100644 --- a/megamek/src/megamek/common/loaders/BLKSpaceStationFile.java +++ b/megamek/src/megamek/common/loaders/BLKSpaceStationFile.java @@ -14,6 +14,7 @@ package megamek.common.loaders; import megamek.common.*; +import megamek.common.equipment.WeaponMounted; import megamek.common.util.BuildingBlock; /** @@ -229,12 +230,12 @@ protected void loadEquipment(SpaceStation a, String sName, int nLoc) throws Enti prefix = "IS "; } - boolean rearMount = false; - int nAmmo = 1; + boolean rearMount; + int nAmmo; // set up a new weapons bay mount - Mounted bayMount = null; + WeaponMounted bayMount = null; // set up a new bay type - boolean newBay = false; + boolean newBay; double bayDamage = 0; if (saEquip[0] != null) { for (String element : saEquip) { @@ -277,7 +278,7 @@ protected void loadEquipment(SpaceStation a, String sName, int nLoc) throws Enti if (etype != null) { // first load the equipment - Mounted newmount; + Mounted newmount; try { if (nAmmo == 1) { newmount = a.addEquipment(etype, nLoc, rearMount); @@ -298,7 +299,7 @@ protected void loadEquipment(SpaceStation a, String sName, int nLoc) throws Enti WeaponType weap = (WeaponType) newmount.getType(); if (bayMount == null) { try { - bayMount = a.addEquipment(weap.getBayType(), nLoc, rearMount); + bayMount = (WeaponMounted) a.addEquipment(weap.getBayType(), nLoc, rearMount); newBay = false; } catch (LocationFullException ex) { throw new EntityLoadingException(ex.getMessage()); @@ -315,7 +316,7 @@ protected void loadEquipment(SpaceStation a, String sName, int nLoc) throws Enti bayDamage += damage; } else { try { - bayMount = a.addEquipment(weap.getBayType(), nLoc, rearMount); + bayMount = (WeaponMounted) a.addEquipment(weap.getBayType(), nLoc, rearMount); } catch (LocationFullException ex) { throw new EntityLoadingException(ex.getMessage()); } diff --git a/megamek/src/megamek/common/loaders/BLKWarshipFile.java b/megamek/src/megamek/common/loaders/BLKWarshipFile.java index a895f3a8bdf..b6603c747c8 100644 --- a/megamek/src/megamek/common/loaders/BLKWarshipFile.java +++ b/megamek/src/megamek/common/loaders/BLKWarshipFile.java @@ -14,6 +14,7 @@ package megamek.common.loaders; import megamek.common.*; +import megamek.common.equipment.WeaponMounted; import megamek.common.util.BuildingBlock; /** @@ -273,12 +274,12 @@ protected void loadEquipment(Entity en, String sName, int nLoc) throws EntityLoa prefix = "IS "; } - boolean rearMount = false; - int nAmmo = 1; + boolean rearMount; + int nAmmo; // set up a new weapons bay mount - Mounted bayMount = null; + WeaponMounted bayMount = null; // set up a new bay type - boolean newBay = false; + boolean newBay; double bayDamage = 0; if (saEquip[0] != null) { @@ -322,7 +323,7 @@ protected void loadEquipment(Entity en, String sName, int nLoc) throws EntityLoa if (etype != null) { // first load the equipment - Mounted newmount; + Mounted newmount; try { if (nAmmo == 1) { newmount = a.addEquipment(etype, nLoc, rearMount); @@ -343,7 +344,7 @@ protected void loadEquipment(Entity en, String sName, int nLoc) throws EntityLoa WeaponType weap = (WeaponType) newmount.getType(); if (bayMount == null) { try { - bayMount = a.addEquipment(weap.getBayType(), nLoc, rearMount); + bayMount = (WeaponMounted) a.addEquipment(weap.getBayType(), nLoc, rearMount); newBay = false; } catch (LocationFullException ex) { throw new EntityLoadingException(ex.getMessage()); @@ -359,7 +360,7 @@ protected void loadEquipment(Entity en, String sName, int nLoc) throws EntityLoa bayDamage += damage; } else { try { - bayMount = a.addEquipment(weap.getBayType(), nLoc, rearMount); + bayMount = (WeaponMounted) a.addEquipment(weap.getBayType(), nLoc, rearMount); } catch (LocationFullException ex) { throw new EntityLoadingException(ex.getMessage()); } diff --git a/megamek/src/megamek/common/loaders/HmpFile.java b/megamek/src/megamek/common/loaders/HmpFile.java index e41880e219d..a34d7f97c0d 100644 --- a/megamek/src/megamek/common/loaders/HmpFile.java +++ b/megamek/src/megamek/common/loaders/HmpFile.java @@ -694,7 +694,7 @@ private void setupCriticals(Mech mech, long[] criticals, int location) throws En } } else { // make a new one - m = new Mounted(mech, equipment); + m = Mounted.createMounted(mech, equipment); m.setFoundCrits(1); vSplitWeapons.addElement(m); } diff --git a/megamek/src/megamek/common/loaders/MtfFile.java b/megamek/src/megamek/common/loaders/MtfFile.java index 0ac5725b724..58997a523d8 100644 --- a/megamek/src/megamek/common/loaders/MtfFile.java +++ b/megamek/src/megamek/common/loaders/MtfFile.java @@ -842,7 +842,7 @@ private void parseCrits(Mech mech, int loc) throws EntityLoadingException { } } else { // make a new one - m = new Mounted(mech, etype); + m = Mounted.createMounted(mech, etype); m.setFoundCrits(1); m.setArmored(isArmored); m.setMechTurretMounted(isTurreted); diff --git a/megamek/src/megamek/common/loaders/TdbFile.java b/megamek/src/megamek/common/loaders/TdbFile.java index 4ec3f022e95..bf90390c573 100644 --- a/megamek/src/megamek/common/loaders/TdbFile.java +++ b/megamek/src/megamek/common/loaders/TdbFile.java @@ -396,7 +396,7 @@ private void parseCrits(Mech mech, int loc) throws EntityLoadingException { } } else { // make a new one - m = new Mounted(mech, etype); + m = Mounted.createMounted(mech, etype); m.setFoundCrits(1); vSplitWeapons.add(m); } diff --git a/megamek/src/megamek/common/scenario/ScenarioV1.java b/megamek/src/megamek/common/scenario/ScenarioV1.java index 04e212ea258..39c4363ff4b 100644 --- a/megamek/src/megamek/common/scenario/ScenarioV1.java +++ b/megamek/src/megamek/common/scenario/ScenarioV1.java @@ -23,6 +23,7 @@ import megamek.common.annotations.Nullable; import megamek.common.enums.GamePhase; import megamek.common.enums.Gender; +import megamek.common.equipment.AmmoMounted; import megamek.common.icons.Camouflage; import megamek.common.loaders.EntityLoadingException; import megamek.common.options.IOption; @@ -465,11 +466,11 @@ else if (chp.entity instanceof Tank) { if (sa.slot < sap.entity.getNumberOfCriticals(sa.loc)) { CriticalSlot cs = sap.entity.getCritical(sa.loc, sa.slot); if (cs != null) { - Mounted ammo = sap.entity.getCritical(sa.loc, sa.slot).getMount(); + AmmoMounted ammo = (AmmoMounted) sap.entity.getCritical(sa.loc, sa.slot).getMount(); if (ammo == null) { LogManager.getLogger().error(String.format("%s - invalid slot specified %d: %d", sap.entity.getShortName(), sa.loc, sa.slot + 1)); - } else if (ammo.getType() instanceof AmmoType) { + } else { AmmoType newAmmoType = getValidAmmoType(m.getGame(), ammo, sa.type); if (newAmmoType != null) { ammo.changeAmmoType(newAmmoType); diff --git a/megamek/src/megamek/common/templates/AeroTROView.java b/megamek/src/megamek/common/templates/AeroTROView.java index ff8c2048fb8..aa062601330 100644 --- a/megamek/src/megamek/common/templates/AeroTROView.java +++ b/megamek/src/megamek/common/templates/AeroTROView.java @@ -161,7 +161,7 @@ protected int addWeaponBays(String[][] arcSets) { return nameWidth; } - private Map createBayRow(Mounted bay) { + private Map createBayRow(Mounted bay) { final Map weaponCount = new HashMap<>(); int heat = 0; int srv = 0; diff --git a/megamek/src/megamek/common/verifier/TestAdvancedAerospace.java b/megamek/src/megamek/common/verifier/TestAdvancedAerospace.java index 98f028495f8..c5bc384ccd1 100644 --- a/megamek/src/megamek/common/verifier/TestAdvancedAerospace.java +++ b/megamek/src/megamek/common/verifier/TestAdvancedAerospace.java @@ -16,6 +16,7 @@ import megamek.common.*; import megamek.common.equipment.ArmorType; +import megamek.common.equipment.WeaponMounted; import megamek.common.util.StringUtil; import megamek.common.weapons.bayweapons.BayWeapon; import megamek.common.weapons.capitalweapons.ScreenLauncherWeapon; @@ -500,7 +501,7 @@ public StringBuffer printWeapon() { return super.printWeapon(); } StringBuffer buffer = new StringBuffer(); - for (Mounted m : getEntity().getWeaponBayList()) { + for (Mounted m : getEntity().getWeaponBayList()) { buffer.append(m.getName()).append(" ") .append(getLocationAbbr(m.getLocation())); if (m.isRearMounted()) { @@ -640,7 +641,7 @@ public boolean hasIllegalEquipmentCombinations(StringBuffer buff) { // Make sure all bays have at least one weapon and that there are at least // ten shots of ammo for each ammo-using weapon in the bay. - for (Mounted bay : vessel.getWeaponBayList()) { + for (Mounted bay : vessel.getWeaponBayList()) { if (bay.getBayWeapons().isEmpty()) { buff.append("Bay ").append(bay.getName()).append(" has no weapons\n"); illegal = true; @@ -648,8 +649,8 @@ public boolean hasIllegalEquipmentCombinations(StringBuffer buff) { Map ammoWeaponCount = new HashMap<>(); Map ammoTypeCount = new HashMap<>(); for (Integer wNum : bay.getBayWeapons()) { - final Mounted w = vessel.getEquipment(wNum); - if (w.isOneShotWeapon()) { + final Mounted w = vessel.getEquipment(wNum); + if (w.isOneShot()) { continue; } if (w.getType() instanceof WeaponType) { diff --git a/megamek/src/megamek/common/verifier/TestAero.java b/megamek/src/megamek/common/verifier/TestAero.java index 8bb4dec3865..88fcf89cc1b 100644 --- a/megamek/src/megamek/common/verifier/TestAero.java +++ b/megamek/src/megamek/common/verifier/TestAero.java @@ -17,6 +17,7 @@ import megamek.common.*; import megamek.common.annotations.Nullable; import megamek.common.equipment.ArmorType; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.OptionsConstants; import megamek.common.util.StringUtil; import megamek.common.weapons.bayweapons.BayWeapon; @@ -545,9 +546,9 @@ public boolean correctControlSystems(StringBuffer buff) { return true; } - public List checkCriticalSlotsForEquipment(Entity entity) { - List unallocated = new ArrayList<>(); - for (Mounted m : entity.getEquipment()) { + public List> checkCriticalSlotsForEquipment(Entity entity) { + List> unallocated = new ArrayList<>(); + for (Mounted m : entity.getEquipment()) { if ((m.getLocation() == Entity.LOC_NONE) && !m.isOneShotAmmo() && (m.getCriticals() > 0)) { unallocated.add(m); } @@ -567,7 +568,7 @@ public List checkCriticalSlotsForEquipment(Entity entity) { public boolean correctCriticals(StringBuffer buff) { boolean correct = true; - List unallocated = checkCriticalSlotsForEquipment(aero); + List> unallocated = checkCriticalSlotsForEquipment(aero); if (!unallocated.isEmpty()) { buff.append("Unallocated Equipment:\n"); for (Mounted mount : unallocated) { @@ -578,14 +579,14 @@ public boolean correctCriticals(StringBuffer buff) { int[] numWeapons = new int[aero.locations()]; int numBombs = 0; - for (Mounted m : aero.getWeaponList()) { + for (WeaponMounted m : aero.getWeaponList()) { if (m.getLocation() == Entity.LOC_NONE) { continue; } // Aeros can't use special munitions except for artemis, exceptions // LBX's must use clusters - WeaponType wt = (WeaponType) m.getType(); + WeaponType wt = m.getType(); boolean canHaveSpecialMunitions = ((wt.getAmmoType() == AmmoType.T_MML) || (wt.getAmmoType() == AmmoType.T_ATM) diff --git a/megamek/src/megamek/common/verifier/TestSmallCraft.java b/megamek/src/megamek/common/verifier/TestSmallCraft.java index eaae095f8ea..5bc0ea8f958 100644 --- a/megamek/src/megamek/common/verifier/TestSmallCraft.java +++ b/megamek/src/megamek/common/verifier/TestSmallCraft.java @@ -378,7 +378,7 @@ public StringBuffer printWeapon() { return super.printWeapon(); } StringBuffer buffer = new StringBuffer(); - for (Mounted m : getEntity().getWeaponBayList()) { + for (Mounted m : getEntity().getWeaponBayList()) { buffer.append(m.getName()).append(" ") .append(getLocationAbbr(m.getLocation())); if (m.isRearMounted()) { @@ -520,7 +520,7 @@ public boolean hasIllegalEquipmentCombinations(StringBuffer buff) { // For DropShips, make sure all bays have at least one weapon and that there are at least // ten shots of ammo for each ammo-using weapon in the bay. - for (Mounted bay : smallCraft.getWeaponBayList()) { + for (Mounted bay : smallCraft.getWeaponBayList()) { if (bay.getBayWeapons().isEmpty()) { buff.append("Bay ").append(bay.getName()).append(" has no weapons\n"); illegal = true; @@ -529,7 +529,7 @@ public boolean hasIllegalEquipmentCombinations(StringBuffer buff) { Map ammoTypeCount = new HashMap<>(); for (Integer wNum : bay.getBayWeapons()) { final Mounted w = smallCraft.getEquipment(wNum); - if (w.isOneShotWeapon()) { + if (w.isOneShot()) { continue; } if (w.getType() instanceof WeaponType) { @@ -541,7 +541,7 @@ public boolean hasIllegalEquipmentCombinations(StringBuffer buff) { } for (Integer aNum : bay.getBayAmmo()) { - final Mounted a = smallCraft.getEquipment(aNum); + final Mounted a = smallCraft.getEquipment(aNum); if (a.getType() instanceof AmmoType) { ammoTypeCount.merge(((AmmoType) a.getType()).getAmmoType(), a.getUsableShotsLeft(), Integer::sum); diff --git a/megamek/src/megamek/common/weapons/ACBayHandler.java b/megamek/src/megamek/common/weapons/ACBayHandler.java index 3ac1d8c4d5e..c22fca9741b 100644 --- a/megamek/src/megamek/common/weapons/ACBayHandler.java +++ b/megamek/src/megamek/common/weapons/ACBayHandler.java @@ -22,7 +22,9 @@ import megamek.common.ToHitData; import megamek.common.WeaponType; import megamek.common.actions.WeaponAttackAction; +import megamek.common.equipment.WeaponMounted; import megamek.server.GameManager; +import org.apache.logging.log4j.LogManager; /** * @author Jay Lawson @@ -49,8 +51,12 @@ public ACBayHandler(ToHitData t, WeaponAttackAction w, Game g, GameManager m) { @Override protected boolean doChecks(Vector vPhaseReport) { for (int wId : weapon.getBayWeapons()) { - Mounted bayW = ae.getEquipment(wId); - WeaponType bayWType = ((WeaponType) bayW.getType()); + WeaponMounted bayW = ae.getWeapon(wId); + if (bayW == null) { + LogManager.getLogger().error("Handler can't find the weapon!"); + return false; + } + WeaponType bayWType = bayW.getType(); int ammoUsed = bayW.getCurrentShots(); if (bayWType.getAmmoType() == AmmoType.T_AC_ROTARY) { boolean jams = false; diff --git a/megamek/src/megamek/common/weapons/AmmoBayWeaponHandler.java b/megamek/src/megamek/common/weapons/AmmoBayWeaponHandler.java index c86bab494d4..9832b6a04a2 100644 --- a/megamek/src/megamek/common/weapons/AmmoBayWeaponHandler.java +++ b/megamek/src/megamek/common/weapons/AmmoBayWeaponHandler.java @@ -20,8 +20,11 @@ import megamek.common.ToHitData; import megamek.common.WeaponType; import megamek.common.actions.WeaponAttackAction; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import megamek.server.GameManager; import megamek.server.Server; +import org.apache.logging.log4j.LogManager; /** * @author Jay Lawson @@ -61,20 +64,23 @@ protected int calcAttackValue() { int range = RangeType.rangeBracket(nRange, wtype.getATRanges(), true, false); for (int wId : weapon.getBayWeapons()) { - Mounted bayW = ae.getEquipment(wId); + WeaponMounted bayW = ae.getWeapon(wId); + if (bayW == null) { + LogManager.getLogger().error("Handler can't find the weapon!"); + return 0; + } // check the currently loaded ammo - Mounted bayWAmmo = bayW.getLinked(); + AmmoMounted bayWAmmo = bayW.getLinkedAmmo(); if (null == bayWAmmo || bayWAmmo.getUsableShotsLeft() < 1) { // try loading something else ae.loadWeaponWithSameAmmo(bayW); - bayWAmmo = bayW.getLinked(); + bayWAmmo = bayW.getLinkedAmmo(); } if (!bayW.isBreached() && !bayW.isDestroyed() && !bayW.isJammed() && bayWAmmo != null - && ae.getTotalAmmoOfType(bayWAmmo.getType()) >= bayW - .getCurrentShots()) { + && ae.getTotalAmmoOfType(bayWAmmo.getType()) >= bayW.getCurrentShots()) { WeaponType bayWType = ((WeaponType) bayW.getType()); // need to cycle through weapons and add av double current_av = 0; @@ -100,7 +106,7 @@ protected int calcAttackValue() { || bayWAmmo.getUsableShotsLeft() < 1) { // try loading something else ae.loadWeaponWithSameAmmo(bayW); - bayWAmmo = bayW.getLinked(); + bayWAmmo = bayW.getLinkedAmmo(); } if (null != bayWAmmo) { bayWAmmo.setShotsLeft(bayWAmmo.getBaseShotsLeft() - 1); diff --git a/megamek/src/megamek/common/weapons/AmmoWeapon.java b/megamek/src/megamek/common/weapons/AmmoWeapon.java index 2cdeb4d1113..ba063b217e1 100644 --- a/megamek/src/megamek/common/weapons/AmmoWeapon.java +++ b/megamek/src/megamek/common/weapons/AmmoWeapon.java @@ -18,6 +18,8 @@ import megamek.common.Mounted; import megamek.common.ToHitData; import megamek.common.actions.WeaponAttackAction; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import megamek.server.GameManager; import megamek.server.Server; @@ -50,11 +52,11 @@ public AttackHandler fire(WeaponAttackAction waa, Game game, GameManager manager protected void checkAmmo(WeaponAttackAction waa, Game g) { Entity ae = waa.getEntity(g); - Mounted weapon = ae.getEquipment(waa.getWeaponId()); - Mounted ammo = weapon.getLinked(); + WeaponMounted weapon = (WeaponMounted) ae.getEquipment(waa.getWeaponId()); + AmmoMounted ammo = weapon.getLinkedAmmo(); if (ammo == null || ammo.getUsableShotsLeft() < 1) { ae.loadWeaponWithSameAmmo(weapon); - ammo = weapon.getLinked(); + ammo = weapon.getLinkedAmmo(); // We need to make the WAA ammoId match the new ammo bin waa.setAmmoId(ae.getEquipmentNum(ammo)); } diff --git a/megamek/src/megamek/common/weapons/ArtilleryBayWeaponIndirectFireHandler.java b/megamek/src/megamek/common/weapons/ArtilleryBayWeaponIndirectFireHandler.java index 2d7c880a147..805fd7296c5 100644 --- a/megamek/src/megamek/common/weapons/ArtilleryBayWeaponIndirectFireHandler.java +++ b/megamek/src/megamek/common/weapons/ArtilleryBayWeaponIndirectFireHandler.java @@ -17,6 +17,8 @@ import megamek.common.actions.ArtilleryAttackAction; import megamek.common.actions.WeaponAttackAction; import megamek.common.enums.GamePhase; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.OptionsConstants; import megamek.server.GameManager; import org.apache.logging.log4j.LogManager; @@ -50,13 +52,19 @@ public boolean cares(final GamePhase phase) { protected void useAmmo() { nweaponsHit = weapon.getBayWeapons().size(); for (int wId : weapon.getBayWeapons()) { - Mounted bayW = ae.getEquipment(wId); + WeaponMounted bayW = ae.getWeapon(wId); + if (bayW == null) { + LogManager.getLogger().error("Handler can't find the weapon!"); + return; + } + // check the currently loaded ammo - Mounted bayWAmmo = bayW.getLinked(); + AmmoMounted bayWAmmo = bayW.getLinkedAmmo(); if (bayWAmmo == null) {// Can't happen. w/o legal ammo, the weapon // *shouldn't* fire. LogManager.getLogger().debug("Handler can't find any ammo! Oh no!"); + return; } int shots = bayW.getCurrentShots(); @@ -75,7 +83,7 @@ protected void useAmmo() { || bayWAmmo.getUsableShotsLeft() < 1) { // try loading something else ae.loadWeaponWithSameAmmo(bayW); - bayWAmmo = bayW.getLinked(); + bayWAmmo = bayW.getLinkedAmmo(); } if (null != bayWAmmo) { bayWAmmo.setShotsLeft(bayWAmmo.getBaseShotsLeft() - 1); diff --git a/megamek/src/megamek/common/weapons/CapitalMissileBayHandler.java b/megamek/src/megamek/common/weapons/CapitalMissileBayHandler.java index a0c662213f0..7ea6350085c 100644 --- a/megamek/src/megamek/common/weapons/CapitalMissileBayHandler.java +++ b/megamek/src/megamek/common/weapons/CapitalMissileBayHandler.java @@ -16,6 +16,8 @@ import megamek.common.*; import megamek.common.actions.WeaponAttackAction; import megamek.common.enums.GamePhase; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.OptionsConstants; import megamek.server.GameManager; import org.apache.logging.log4j.LogManager; @@ -268,20 +270,23 @@ protected int calcAttackValue() { int range = RangeType.rangeBracket(nRange, wtype.getATRanges(), true, false); for (int wId : weapon.getBayWeapons()) { - Mounted bayW = ae.getEquipment(wId); + WeaponMounted bayW = ae.getWeapon(wId); + if (bayW == null) { + LogManager.getLogger().error("Handler can't find the weapon!"); + return 0; + } // check the currently loaded ammo - Mounted bayWAmmo = bayW.getLinked(); + AmmoMounted bayWAmmo = bayW.getLinkedAmmo(); if (null == bayWAmmo || bayWAmmo.getUsableShotsLeft() < 1) { // try loading something else ae.loadWeaponWithSameAmmo(bayW); - bayWAmmo = bayW.getLinked(); + bayWAmmo = bayW.getLinkedAmmo(); } if (!bayW.isBreached() && !bayW.isDestroyed() && !bayW.isJammed() && bayWAmmo != null - && ae.getTotalAmmoOfType(bayWAmmo.getType()) >= bayW - .getCurrentShots()) { + && ae.getTotalAmmoOfType(bayWAmmo.getType()) >= bayW.getCurrentShots()) { WeaponType bayWType = ((WeaponType) bayW.getType()); // need to cycle through weapons and add av double current_av = 0; @@ -327,7 +332,7 @@ protected int calcAttackValue() { || bayWAmmo.getUsableShotsLeft() < 1) { // try loading something else ae.loadWeaponWithSameAmmo(bayW); - bayWAmmo = bayW.getLinked(); + bayWAmmo = bayW.getLinkedAmmo(); } if (null != bayWAmmo) { bayWAmmo.setShotsLeft(bayWAmmo.getBaseShotsLeft() - 1); diff --git a/megamek/src/megamek/common/weapons/CapitalMissileBearingsOnlyHandler.java b/megamek/src/megamek/common/weapons/CapitalMissileBearingsOnlyHandler.java index 0ffee4d1c4e..0c384ed41ca 100644 --- a/megamek/src/megamek/common/weapons/CapitalMissileBearingsOnlyHandler.java +++ b/megamek/src/megamek/common/weapons/CapitalMissileBearingsOnlyHandler.java @@ -17,6 +17,8 @@ import megamek.common.actions.ArtilleryAttackAction; import megamek.common.actions.WeaponAttackAction; import megamek.common.enums.GamePhase; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.OptionsConstants; import megamek.common.weapons.bayweapons.TeleOperatedMissileBayWeapon; import megamek.server.GameManager; @@ -44,7 +46,7 @@ public class CapitalMissileBearingsOnlyHandler extends AmmoBayWeaponHandler { || weapon.curMode().equals(Weapon.MODE_CAP_MISSILE_WAYPOINT_BEARING_EXT)); // Defined here so we can use it in multiple methods - Mounted bayWAmmo; + AmmoMounted bayWAmmo; int range; Coords targetCoords; @@ -66,9 +68,9 @@ public boolean cares(GamePhase phase) { protected void getMountedAmmo() { for (int wId : weapon.getBayWeapons()) { - Mounted bayW = ae.getEquipment(wId); + WeaponMounted bayW = ae.getWeapon(wId); // check the currently loaded ammo - bayWAmmo = bayW.getLinked(); + bayWAmmo = bayW.getLinkedAmmo(); if (bayWAmmo == null) {// Can't happen. w/o legal ammo, the weapon // *shouldn't* fire. @@ -80,14 +82,13 @@ protected void getMountedAmmo() { @Override protected void useAmmo() { getMountedAmmo(); - Mounted bayW = bayWAmmo.getLinkedBy(); + WeaponMounted bayW = (WeaponMounted) bayWAmmo.getLinkedBy(); int shots = (bayW.getCurrentShots() * weapon.getBayWeapons().size()); for (int i = 0; i < shots; i++) { - if (null == bayWAmmo - || bayWAmmo.getUsableShotsLeft() < 1) { + if ((null == bayWAmmo) || bayWAmmo.getUsableShotsLeft() < 1) { // try loading something else ae.loadWeaponWithSameAmmo(bayW); - bayWAmmo = bayW.getLinked(); + bayWAmmo = bayW.getLinkedAmmo(); } if (null != bayWAmmo) { bayWAmmo.setShotsLeft(bayWAmmo.getBaseShotsLeft() - 1); @@ -689,13 +690,13 @@ protected int calcAttackValue() { int range = RangeType.RANGE_EXTREME; for (int wId : weapon.getBayWeapons()) { - Mounted bayW = ae.getEquipment(wId); + WeaponMounted bayW = ae.getWeapon(wId); // check the currently loaded ammo - Mounted bayWAmmo = bayW.getLinked(); + AmmoMounted bayWAmmo = bayW.getLinkedAmmo(); if (null == bayWAmmo || bayWAmmo.getUsableShotsLeft() < 1) { // try loading something else ae.loadWeaponWithSameAmmo(bayW); - bayWAmmo = bayW.getLinked(); + bayWAmmo = bayW.getLinkedAmmo(); } if (!bayW.isBreached() && !bayW.isDestroyed() diff --git a/megamek/src/megamek/common/weapons/MissileBayWeaponHandler.java b/megamek/src/megamek/common/weapons/MissileBayWeaponHandler.java index 5a1a11e46fa..9e579ae46fc 100644 --- a/megamek/src/megamek/common/weapons/MissileBayWeaponHandler.java +++ b/megamek/src/megamek/common/weapons/MissileBayWeaponHandler.java @@ -31,6 +31,8 @@ import megamek.common.WeaponType; import megamek.common.actions.WeaponAttackAction; import megamek.common.enums.GamePhase; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.OptionsConstants; import megamek.server.GameManager; @@ -74,13 +76,13 @@ protected int calcAttackValue() { int range = RangeType.rangeBracket(nRange, wtype.getATRanges(), true, false); for (int wId : weapon.getBayWeapons()) { - Mounted bayW = ae.getEquipment(wId); + WeaponMounted bayW = ae.getWeapon(wId); // check the currently loaded ammo - Mounted bayWAmmo = bayW.getLinked(); + AmmoMounted bayWAmmo = bayW.getLinkedAmmo(); if (null == bayWAmmo || bayWAmmo.getUsableShotsLeft() < 1) { // try loading something else ae.loadWeaponWithSameAmmo(bayW); - bayWAmmo = bayW.getLinked(); + bayWAmmo = bayW.getLinkedAmmo(); } if (!bayW.isBreached() && !bayW.isDestroyed() @@ -115,7 +117,7 @@ protected int calcAttackValue() { || bayWAmmo.getUsableShotsLeft() < 1) { // try loading something else ae.loadWeaponWithSameAmmo(bayW); - bayWAmmo = bayW.getLinked(); + bayWAmmo = bayW.getLinkedAmmo(); } if (null != bayWAmmo) { bayWAmmo.setShotsLeft(bayWAmmo.getBaseShotsLeft() - 1); diff --git a/megamek/src/megamek/common/weapons/MissileWeaponHandler.java b/megamek/src/megamek/common/weapons/MissileWeaponHandler.java index fb204c06fd8..1d131c82d98 100644 --- a/megamek/src/megamek/common/weapons/MissileWeaponHandler.java +++ b/megamek/src/megamek/common/weapons/MissileWeaponHandler.java @@ -451,7 +451,7 @@ protected int getAMSHitsMod(Vector vPhaseReport) { ArrayList lCounters = waa.getCounterEquipment(); if (null != lCounters) { // resolve AMS counter-fire - for (Mounted counter : lCounters) { + for (Mounted counter : lCounters) { // Set up differences between different types of AMS boolean isAMS = counter.getType().hasFlag(WeaponType.F_AMS); boolean isAMSBay = counter.getType().hasFlag(WeaponType.F_AMSBAY); diff --git a/megamek/src/megamek/common/weapons/TeleMissileHandler.java b/megamek/src/megamek/common/weapons/TeleMissileHandler.java index 314fa469df0..d62348ba7ac 100644 --- a/megamek/src/megamek/common/weapons/TeleMissileHandler.java +++ b/megamek/src/megamek/common/weapons/TeleMissileHandler.java @@ -16,6 +16,8 @@ import megamek.common.*; import megamek.common.actions.WeaponAttackAction; import megamek.common.enums.GamePhase; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import megamek.server.GameManager; import org.apache.logging.log4j.LogManager; @@ -78,9 +80,9 @@ private int calcBayDamageAndHeat() { @Override protected void useAmmo() { for (int wId : weapon.getBayWeapons()) { - Mounted bayW = ae.getEquipment(wId); + WeaponMounted bayW = (WeaponMounted) ae.getEquipment(wId); // check the currently loaded ammo - Mounted bayWAmmo = bayW.getLinked(); + AmmoMounted bayWAmmo = bayW.getLinkedAmmo(); if (bayWAmmo == null) {// Can't happen. w/o legal ammo, the weapon // *shouldn't* fire. @@ -92,7 +94,7 @@ protected void useAmmo() { || bayWAmmo.getUsableShotsLeft() < 1) { // try loading something else ae.loadWeaponWithSameAmmo(bayW); - bayWAmmo = bayW.getLinked(); + bayWAmmo = bayW.getLinkedAmmo(); } if (null != bayWAmmo) { bayWAmmo.setShotsLeft(bayWAmmo.getBaseShotsLeft() - 1); diff --git a/megamek/src/megamek/common/weapons/WeaponHandler.java b/megamek/src/megamek/common/weapons/WeaponHandler.java index e48251c6026..8e5373745e4 100644 --- a/megamek/src/megamek/common/weapons/WeaponHandler.java +++ b/megamek/src/megamek/common/weapons/WeaponHandler.java @@ -20,6 +20,7 @@ import megamek.common.actions.WeaponAttackAction; import megamek.common.enums.AimingMode; import megamek.common.enums.GamePhase; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.OptionsConstants; import megamek.common.planetaryconditions.PlanetaryConditions; import megamek.server.GameManager; @@ -59,7 +60,7 @@ public class WeaponHandler implements AttackHandler, Serializable { protected WeaponType wtype; protected AmmoType atype; protected String typeName; - protected Mounted weapon; + protected WeaponMounted weapon; protected Entity ae; protected Targetable target; protected int subjectId; @@ -137,7 +138,7 @@ protected int getLargeCraftHeat(Entity e) { AttackHandler ah = i.nextElement(); WeaponAttackAction prevAttack = ah.getWaa(); if (prevAttack.getEntityId() == e.getId()) { - Mounted prevWeapon = e.getEquipment(prevAttack.getWeaponId()); + Mounted prevWeapon = e.getEquipment(prevAttack.getWeaponId()); for (int wId : prevWeapon.getBayWeapons()) { Mounted bayW = e.getEquipment(wId); totalheat += bayW.getCurrentHeat(); @@ -236,7 +237,7 @@ protected int calcCounterAV() { // We need to know how much heat has been assigned to offensive weapons fire by the defender this round int weaponHeat = getLargeCraftHeat(entityTarget) + entityTarget.heatBuildup; if (null != lCounters) { - for (Mounted counter : lCounters) { + for (Mounted counter : lCounters) { // Point defenses only fire vs attacks against the arc they protect Entity pdEnt = counter.getEntity(); boolean isInArc; @@ -1754,7 +1755,7 @@ public WeaponHandler(ToHitData t, WeaponAttackAction w, Game g, GameManager m) { waa = w; game = g; ae = game.getEntity(waa.getEntityId()); - weapon = ae.getEquipment(waa.getWeaponId()); + weapon = (WeaponMounted) ae.getEquipment(waa.getWeaponId()); wtype = (WeaponType) weapon.getType(); atype = (weapon.getLinked() != null) ? (AmmoType) weapon.getLinked().getType() : null; typeName = wtype.getInternalName(); @@ -1944,8 +1945,8 @@ public int checkLI(int nDamage, Entity entityTarget, Vector vPhaseReport return nDamage; } - weapon = ae.getEquipment(waa.getWeaponId()); - wtype = (WeaponType) weapon.getType(); + weapon = ae.getWeapon(waa.getWeaponId()); + wtype = weapon.getType(); if (!wtype.hasFlag(WeaponType.F_ENERGY)) { return nDamage; diff --git a/megamek/src/megamek/common/weapons/bayweapons/AmmoBayWeapon.java b/megamek/src/megamek/common/weapons/bayweapons/AmmoBayWeapon.java index 772acb0068f..a7fbe4b22b8 100644 --- a/megamek/src/megamek/common/weapons/bayweapons/AmmoBayWeapon.java +++ b/megamek/src/megamek/common/weapons/bayweapons/AmmoBayWeapon.java @@ -13,11 +13,10 @@ */ package megamek.common.weapons.bayweapons; -import megamek.common.Entity; -import megamek.common.Game; -import megamek.common.Mounted; -import megamek.common.ToHitData; +import megamek.common.*; import megamek.common.actions.WeaponAttackAction; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.weapons.AmmoBayWeaponHandler; import megamek.common.weapons.AttackHandler; import megamek.server.GameManager; @@ -46,13 +45,12 @@ public AttackHandler fire(WeaponAttackAction waa, Game game, GameManager manager protected void checkAmmo(WeaponAttackAction waa, Game g) { Entity ae = waa.getEntity(g); - Mounted m = ae.getEquipment(waa.getWeaponId()); - for (int wId : m.getBayWeapons()) { - Mounted weapon = ae.getEquipment(wId); - Mounted ammo = weapon.getLinked(); + WeaponMounted bay = ae.getWeapon(waa.getWeaponId()); + for (int wId : bay.getBayWeapons()) { + WeaponMounted weapon = ae.getWeapon(wId); + AmmoMounted ammo = weapon.getLinkedAmmo(); if (ammo == null || ammo.getUsableShotsLeft() < 1) { ae.loadWeaponWithSameAmmo(weapon); - ammo = weapon.getLinked(); } } } diff --git a/megamek/src/megamek/common/weapons/bayweapons/ArtilleryBayWeapon.java b/megamek/src/megamek/common/weapons/bayweapons/ArtilleryBayWeapon.java index 01d1644c504..69c3ccb8e68 100644 --- a/megamek/src/megamek/common/weapons/bayweapons/ArtilleryBayWeapon.java +++ b/megamek/src/megamek/common/weapons/bayweapons/ArtilleryBayWeapon.java @@ -56,7 +56,7 @@ protected AttackHandler getCorrectHandler(ToHitData toHit, WeaponAttackAction waa, Game game, GameManager manager) { Entity ae = game.getEntity(waa.getEntityId()); boolean useHoming = false; - for (int wId : ae.getEquipment(waa.getWeaponId()).getBayWeapons()) { + for (int wId : ((Mounted) ae.getEquipment(waa.getWeaponId())).getBayWeapons()) { Mounted bayW = ae.getEquipment(wId); // check the currently loaded ammo Mounted bayWAmmo = bayW.getLinked(); diff --git a/megamek/src/megamek/common/weapons/bayweapons/BayWeapon.java b/megamek/src/megamek/common/weapons/bayweapons/BayWeapon.java index 57bdf3aa454..7805fe9f134 100644 --- a/megamek/src/megamek/common/weapons/bayweapons/BayWeapon.java +++ b/megamek/src/megamek/common/weapons/bayweapons/BayWeapon.java @@ -15,6 +15,8 @@ import megamek.common.*; import megamek.common.actions.WeaponAttackAction; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.weapons.AttackHandler; import megamek.common.weapons.BayWeaponHandler; import megamek.common.weapons.Weapon; @@ -62,18 +64,18 @@ protected AttackHandler getCorrectHandler(ToHitData toHit, } @Override - public int getMaxRange(Mounted weapon) { + public int getMaxRange(WeaponMounted weapon) { return getMaxRange(weapon, null); } @Override - public int getMaxRange(Mounted weapon, Mounted ammo) { + public int getMaxRange(WeaponMounted weapon, AmmoMounted ammo) { int mrange = RANGE_SHORT; Entity ae = weapon.getEntity(); if (null != ae) { for (int wId : weapon.getBayWeapons()) { - Mounted bayW = ae.getEquipment(wId); - WeaponType bayWType = (WeaponType) bayW.getType(); + WeaponMounted bayW = (WeaponMounted) ae.getEquipment(wId); + WeaponType bayWType = bayW.getType(); if (bayWType.getMaxRange(bayW) > mrange) { mrange = bayWType.getMaxRange(bayW); } diff --git a/megamek/src/megamek/common/weapons/infantry/InfantryWeapon.java b/megamek/src/megamek/common/weapons/infantry/InfantryWeapon.java index 9ddc2c68ce8..d266d125e25 100644 --- a/megamek/src/megamek/common/weapons/infantry/InfantryWeapon.java +++ b/megamek/src/megamek/common/weapons/infantry/InfantryWeapon.java @@ -15,6 +15,8 @@ import megamek.common.*; import megamek.common.actions.WeaponAttackAction; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.GameOptions; import megamek.common.options.OptionsConstants; import megamek.common.weapons.AttackHandler; @@ -121,12 +123,12 @@ public int getRoundExtAV() { } @Override - public int getMaxRange(Mounted weapon) { + public int getMaxRange(WeaponMounted weapon) { return getMaxRange(weapon, null); } @Override - public int getMaxRange(Mounted weapon, Mounted ammo) { + public int getMaxRange(WeaponMounted weapon, AmmoMounted ammo) { for (int range = RangeType.RANGE_EXTREME; range >= RangeType.RANGE_SHORT; range--) { if (infantryRange * 3 > AIRBORNE_WEAPON_RANGES[range - 1]) { return range; diff --git a/megamek/src/megamek/server/GameManager.java b/megamek/src/megamek/server/GameManager.java index ddb76aee67c..e87f7f4230c 100644 --- a/megamek/src/megamek/server/GameManager.java +++ b/megamek/src/megamek/server/GameManager.java @@ -24,7 +24,7 @@ import megamek.common.annotations.Nullable; import megamek.common.containers.PlayerIDandList; import megamek.common.enums.*; -import megamek.common.equipment.ArmorType; +import megamek.common.equipment.*; import megamek.common.event.GameVictoryEvent; import megamek.common.force.Force; import megamek.common.force.Forces; @@ -23075,7 +23075,7 @@ public Vector damageEntity(Entity te, HitData hit, int damage, // If there are split weapons in this location, mark it // as hit, even if it took no criticals. - for (Mounted m : te.getWeaponList()) { + for (WeaponMounted m : te.getWeaponList()) { if (m.isSplit()) { if ((m.getLocation() == hit.getLocation()) || (m.getLocation() == nextHit @@ -25216,7 +25216,7 @@ private Vector applyAeroCritical(Aero aero, int loc, CriticalSlot cs, in } if (!weapons.isEmpty()) { - Mounted weapon = weapons.get(Compute.randomInt(weapons.size())); + Mounted weapon = weapons.get(Compute.randomInt(weapons.size())); // possibly check for an ammo explosion // don't allow ammo explosions on fighter squadrons if (game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_STRATOPS_AMMO_EXPLOSIONS) @@ -25681,7 +25681,7 @@ private void applyCargoCritical(Aero aero, int damageCaused, Vector repo r.subject = aero.getId(); r.addDesc(aero); reports.add(r); - for (Mounted bomb: ((IBomber) aero).getBombs()) { + for (BombMounted bomb: ((IBomber) aero).getBombs()) { damageBomb(bomb); } aero.applyDamage(); @@ -25690,13 +25690,13 @@ private void applyCargoCritical(Aero aero, int damageCaused, Vector repo // This will require firing an event to the End Phase to display a dialog; // for now just randomly dump bombs just like bots'. // TODO: fire event here to display dialog in end phase. - for (Mounted bomb:randomlySubSelectList(((IBomber) aero).getBombs(), bombsDestroyed)) { + for (BombMounted bomb : randomlySubSelectList(((IBomber) aero).getBombs(), bombsDestroyed)) { damageBomb(bomb); } aero.applyDamage(); } else { // This should always use the random method. - for (Mounted bomb:randomlySubSelectList(((IBomber) aero).getBombs(), bombsDestroyed)) { + for (BombMounted bomb:randomlySubSelectList(((IBomber) aero).getBombs(), bombsDestroyed)) { damageBomb(bomb); } aero.applyDamage(); @@ -25712,7 +25712,7 @@ private void applyCargoCritical(Aero aero, int damageCaused, Vector repo } } - private void damageBomb(Mounted bomb) { + private void damageBomb(BombMounted bomb) { bomb.setShotsLeft(0); bomb.setHit(true); if (bomb.getLinked() != null && (bomb.getLinked().getUsableShotsLeft() > 0)) { @@ -25721,8 +25721,8 @@ private void damageBomb(Mounted bomb) { } // Randomly select subset of Mounted items. - private ArrayList randomlySubSelectList(List list, int size) { - ArrayList subset = new ArrayList<>(); + private > List randomlySubSelectList(List list, int size) { + List subset = new ArrayList<>(); Random random_method = new Random(); for (int i = 0; i < size; i++) { subset.add(list.get(random_method.nextInt(list.size()))); @@ -28548,7 +28548,7 @@ private void resolveAmmoDumps() { } // also do DWP dumping if (entity instanceof BattleArmor) { - for (Mounted m : entity.getWeaponList()) { + for (WeaponMounted m : entity.getWeaponList()) { if (m.isDWPMounted() && m.isPendingDump()) { m.setMissing(true); r = new Report(5116); @@ -30093,27 +30093,17 @@ private void receiveEntityAmmoChange(Packet c, int connIndex) { } // Make sure that the entity has the given equipment. - Mounted mWeap = e.getEquipment(weaponId); - Mounted mAmmo = e.getEquipment(ammoId); - Mounted oldAmmo = (mWeap == null) ? null : mWeap.getLinked(); + WeaponMounted mWeap = (WeaponMounted) e.getEquipment(weaponId); + AmmoMounted mAmmo = (AmmoMounted) e.getEquipment(ammoId); + AmmoMounted oldAmmo = (mWeap == null) ? null : mWeap.getLinkedAmmo(); if (null == mAmmo) { LogManager.getLogger().error("Entity " + e.getDisplayName() + " does not have ammo #" + ammoId); return; } - if (!(mAmmo.getType() instanceof AmmoType)) { - LogManager.getLogger().error("Item #" + ammoId + " of entity " + e.getDisplayName() - + " is a " + mAmmo.getName() + " and not ammo."); - return; - } if (null == mWeap) { LogManager.getLogger().error("Entity " + e.getDisplayName() + " does not have weapon #" + weaponId); return; } - if (!(mWeap.getType() instanceof WeaponType)) { - LogManager.getLogger().error("Item #" + weaponId + " of entity " + e.getDisplayName() - + " is a " + mWeap.getName() + " and not a weapon."); - return; - } if (((WeaponType) mWeap.getType()).getAmmoType() == AmmoType.T_NA) { LogManager.getLogger().error("Item #" + weaponId + " of entity " + e.getDisplayName() + " is a " + mWeap.getName() + " and does not use ammo."); @@ -34776,27 +34766,27 @@ public Vector getAirborneVTOL(Team team) { * @param mineId an int pointing to the mine */ private void layMine(Entity entity, int mineId, Coords coords) { - Mounted mine = entity.getEquipment(mineId); + MiscMounted mine = (MiscMounted) entity.getEquipment(mineId); Report r; if (!mine.isMissing()) { int reportId = 0; switch (mine.getMineType()) { - case Mounted.MINE_CONVENTIONAL: + case MiscMounted.MINE_CONVENTIONAL: deliverThunderMinefield(coords, entity.getOwnerId(), 10, entity.getId()); reportId = 3500; break; - case Mounted.MINE_VIBRABOMB: + case MiscMounted.MINE_VIBRABOMB: deliverThunderVibraMinefield(coords, entity.getOwnerId(), 10, mine.getVibraSetting(), entity.getId()); reportId = 3505; break; - case Mounted.MINE_ACTIVE: + case MiscMounted.MINE_ACTIVE: deliverThunderActiveMinefield(coords, entity.getOwnerId(), 10, entity.getId()); reportId = 3510; break; - case Mounted.MINE_INFERNO: + case MiscMounted.MINE_INFERNO: deliverThunderInfernoMinefield(coords, entity.getOwnerId(), 10, entity.getId()); reportId = 3515; diff --git a/megamek/unittests/megamek/client/bot/princess/FireControlTest.java b/megamek/unittests/megamek/client/bot/princess/FireControlTest.java index 5f57f56e718..33c60bf112c 100644 --- a/megamek/unittests/megamek/client/bot/princess/FireControlTest.java +++ b/megamek/unittests/megamek/client/bot/princess/FireControlTest.java @@ -22,6 +22,8 @@ import megamek.client.bot.princess.PathRanker.PathRankerType; import megamek.codeUtilities.StringUtility; import megamek.common.*; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import megamek.common.options.GameOptions; import megamek.common.options.OptionsConstants; import megamek.common.options.PilotOptions; @@ -39,6 +41,7 @@ import java.math.BigInteger; import java.util.*; +import static java.util.Collections.emptyList; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; import static org.mockito.Mockito.*; @@ -52,65 +55,65 @@ public class FireControlTest { private static final int MOCK_TARGET_ID = 10; // AC5 - private Mounted mockWeaponAC5; + private WeaponMounted mockWeaponAC5; private WeaponType mockWeaponTypeAC5; @SuppressWarnings("FieldCanBeLocal") private AmmoType mockAmmoTypeAC5Std; - private Mounted mockAmmoAC5Std; + private AmmoMounted mockAmmoAC5Std; @SuppressWarnings("FieldCanBeLocal") private AmmoType mockAmmoTypeAC5Flak; - private Mounted mockAmmoAC5Flak; + private AmmoMounted mockAmmoAC5Flak; @SuppressWarnings("FieldCanBeLocal") private AmmoType mockAmmoTypeAC5Incendiary; - private Mounted mockAmmoAc5Incendiary; + private AmmoMounted mockAmmoAc5Incendiary; @SuppressWarnings("FieldCanBeLocal") private AmmoType mockAmmoTypeAc5Flechette; - private Mounted mockAmmoAc5Flechette; + private AmmoMounted mockAmmoAc5Flechette; private WeaponFireInfo mockAC5StdFireInfo; private WeaponFireInfo mockAC5IncendiaryFireInfo; private WeaponFireInfo mockAC5FlakFireInfo; // LB10X - private Mounted mockWeaponLB10X; + private WeaponMounted mockWeaponLB10X; private WeaponType mockLB10X; @SuppressWarnings("FieldCanBeLocal") private AmmoType mockAmmoTypeLB10XSlug; - private Mounted mockAmmoLB10XSlug; + private AmmoMounted mockAmmoLB10XSlug; @SuppressWarnings("FieldCanBeLocal") private AmmoType mockAmmoTypeLB10XCluster; - private Mounted mockAmmoLB10XCluster; + private AmmoMounted mockAmmoLB10XCluster; // MML - private Mounted mockWeaponMML5; + private WeaponMounted mockWeaponMML5; private WeaponType mockMML5; @SuppressWarnings("FieldCanBeLocal") private AmmoType mockAmmoTypeSRM5; - private Mounted mockAmmoSRM5; + private AmmoMounted mockAmmoSRM5; @SuppressWarnings("FieldCanBeLocal") private AmmoType mockAmmoTypeLRM5; - private Mounted mockAmmoLRM5; + private AmmoMounted mockAmmoLRM5; @SuppressWarnings("FieldCanBeLocal") private AmmoType mockAmmoTypeInferno5; - private Mounted mockAmmoInferno5; + private AmmoMounted mockAmmoInferno5; @SuppressWarnings("FieldCanBeLocal") private AmmoType mockAmmoTypeLrm5Frag; - private Mounted mockAmmoLrm5Frag; + private AmmoMounted mockAmmoLrm5Frag; // ATM - private Mounted mockAtm5Weapon; + private WeaponMounted mockAtm5Weapon; private WeaponType mockAtm5; @SuppressWarnings("FieldCanBeLocal") private AmmoType mockAmmoTypeAtm5He; - private Mounted mockAmmoAtm5He; + private AmmoMounted mockAmmoAtm5He; @SuppressWarnings("FieldCanBeLocal") private AmmoType mockAmmoTypeAtm5St; - private Mounted mockAmmoAtm5St; + private AmmoMounted mockAmmoAtm5St; @SuppressWarnings("FieldCanBeLocal") private AmmoType mockAmmoTypeAtm5Er; - private Mounted mockAmmoAtm5Er; + private AmmoMounted mockAmmoAtm5Er; @SuppressWarnings("FieldCanBeLocal") private AmmoType mockAmmoTypeAtm5Inferno; - private Mounted mockAmmoAtm5Inferno; + private AmmoMounted mockAmmoAtm5Inferno; private Entity mockTarget; private EntityState mockTargetState; @@ -132,10 +135,10 @@ public class FireControlTest { private Princess mockPrincess; - private ArrayList shooterWeapons; - private Mounted mockPPC; - private Mounted mockML; - private Mounted mockLRM5; + private ArrayList shooterWeapons; + private WeaponMounted mockPPC; + private WeaponMounted mockML; + private WeaponMounted mockLRM5; private WeaponFireInfo mockPPCFireInfo; private WeaponFireInfo mockMLFireInfo; private WeaponFireInfo mockLRMFireInfo; @@ -145,7 +148,7 @@ public class FireControlTest { private WeaponFireInfo mockLB10XSlugFireInfo; private WeaponFireInfo mockLB10XClusterFireInfo; - private Map testToHitThreshold; + private Map testToHitThreshold; private FireControl testFireControl; @@ -225,31 +228,31 @@ public void beforeEach() { // AC5 mockWeaponTypeAC5 = mock(WeaponType.class); - mockWeaponAC5 = mock(Mounted.class); + mockWeaponAC5 = mock(WeaponMounted.class); when(mockWeaponAC5.getType()).thenReturn(mockWeaponTypeAC5); when(mockWeaponTypeAC5.getAmmoType()).thenReturn(AmmoType.T_AC); mockAmmoTypeAC5Std = mock(AmmoType.class); when(mockAmmoTypeAC5Std.getAmmoType()).thenReturn(AmmoType.T_AC); when(mockAmmoTypeAC5Std.getMunitionType()).thenReturn(EnumSet.of(AmmoType.Munitions.M_STANDARD)); - mockAmmoAC5Std = mock(Mounted.class); + mockAmmoAC5Std = mock(AmmoMounted.class); when(mockAmmoAC5Std.getType()).thenReturn(mockAmmoTypeAC5Std); when(mockAmmoAC5Std.isAmmoUsable()).thenReturn(true); mockAmmoTypeAC5Flak = mock(AmmoType.class); when(mockAmmoTypeAC5Flak.getAmmoType()).thenReturn(AmmoType.T_AC); when(mockAmmoTypeAC5Flak.getMunitionType()).thenReturn(EnumSet.of(AmmoType.Munitions.M_FLAK)); - mockAmmoAC5Flak = mock(Mounted.class); + mockAmmoAC5Flak = mock(AmmoMounted.class); when(mockAmmoAC5Flak.getType()).thenReturn(mockAmmoTypeAC5Flak); when(mockAmmoAC5Flak.isAmmoUsable()).thenReturn(true); mockAmmoTypeAC5Incendiary = mock(AmmoType.class); when(mockAmmoTypeAC5Incendiary.getMunitionType()).thenReturn(EnumSet.of(AmmoType.Munitions.M_INCENDIARY_AC)); when(mockAmmoTypeAC5Incendiary.getAmmoType()).thenReturn(AmmoType.T_AC); - mockAmmoAc5Incendiary = mock(Mounted.class); + mockAmmoAc5Incendiary = mock(AmmoMounted.class); when(mockAmmoAc5Incendiary.getType()).thenReturn(mockAmmoTypeAC5Incendiary); when(mockAmmoAc5Incendiary.isAmmoUsable()).thenReturn(true); mockAmmoTypeAc5Flechette = mock(AmmoType.class); when(mockAmmoTypeAc5Flechette.getAmmoType()).thenReturn(AmmoType.T_AC); when(mockAmmoTypeAc5Flechette.getMunitionType()).thenReturn(EnumSet.of(AmmoType.Munitions.M_FLECHETTE)); - mockAmmoAc5Flechette = mock(Mounted.class); + mockAmmoAc5Flechette = mock(AmmoMounted.class); when(mockAmmoAc5Flechette.getType()).thenReturn(mockAmmoTypeAc5Flechette); when(mockAmmoAc5Flechette.isAmmoUsable()).thenReturn(true); @@ -282,40 +285,40 @@ public void beforeEach() { when(mockAC5FlakFireInfo.getExpectedDamage()).thenReturn(0.8333 * 3); // Std AC5 doReturn(mockAC5StdFireInfo).when(testFireControl).buildWeaponFireInfo(any(Entity.class), - any(EntityState.class), any(Targetable.class), any(EntityState.class), eq(mockWeaponAC5), any(Mounted.class), + any(EntityState.class), any(Targetable.class), any(EntityState.class), eq(mockWeaponAC5), any(AmmoMounted.class), any(Game.class), anyBoolean()); doReturn(mockAC5StdFireInfo).when(testFireControl).buildWeaponFireInfo(any(Entity.class), - any(MovePath.class), any(Targetable.class), any(EntityState.class), eq(mockWeaponAC5), any(Mounted.class), + any(MovePath.class), any(Targetable.class), any(EntityState.class), eq(mockWeaponAC5), any(AmmoMounted.class), any(Game.class), anyBoolean(), anyBoolean()); doReturn(mockAC5StdFireInfo).when(testFireControl).buildWeaponFireInfo(any(Entity.class), - any(Targetable.class), eq(mockWeaponAC5), any(Mounted.class), any(Game.class), anyBoolean()); + any(Targetable.class), eq(mockWeaponAC5), any(AmmoMounted.class), any(Game.class), anyBoolean()); // Incendiary AC5 doReturn(mockAC5IncendiaryFireInfo).when(testFireControl).buildWeaponFireInfo(any(Entity.class), - any(EntityState.class), any(Targetable.class), any(EntityState.class), eq(mockWeaponAC5), any(Mounted.class), + any(EntityState.class), any(Targetable.class), any(EntityState.class), eq(mockWeaponAC5), any(AmmoMounted.class), any(Game.class), anyBoolean()); doReturn(mockAC5IncendiaryFireInfo).when(testFireControl).buildWeaponFireInfo(any(Entity.class), - any(MovePath.class), any(Targetable.class), any(EntityState.class), eq(mockWeaponAC5), any(Mounted.class), + any(MovePath.class), any(Targetable.class), any(EntityState.class), eq(mockWeaponAC5), any(AmmoMounted.class), any(Game.class), anyBoolean(), anyBoolean()); doReturn(mockAC5IncendiaryFireInfo).when(testFireControl).buildWeaponFireInfo(any(Entity.class), - any(Targetable.class), eq(mockWeaponAC5), any(Mounted.class), any(Game.class), anyBoolean()); + any(Targetable.class), eq(mockWeaponAC5), any(AmmoMounted.class), any(Game.class), anyBoolean()); // Flak AC5 doReturn(mockAC5FlakFireInfo).when(testFireControl).buildWeaponFireInfo(any(Entity.class), - any(EntityState.class), any(Targetable.class), any(EntityState.class), eq(mockWeaponAC5), any(Mounted.class), + any(EntityState.class), any(Targetable.class), any(EntityState.class), eq(mockWeaponAC5), any(AmmoMounted.class), any(Game.class), anyBoolean()); doReturn(mockAC5FlakFireInfo).when(testFireControl).buildWeaponFireInfo(any(Entity.class), - any(MovePath.class), any(Targetable.class), any(EntityState.class), eq(mockWeaponAC5), any(Mounted.class), + any(MovePath.class), any(Targetable.class), any(EntityState.class), eq(mockWeaponAC5), any(AmmoMounted.class), any(Game.class), anyBoolean(), anyBoolean()); doReturn(mockAC5FlakFireInfo).when(testFireControl).buildWeaponFireInfo(any(Entity.class), - any(Targetable.class), eq(mockWeaponAC5), any(Mounted.class), any(Game.class), anyBoolean()); + any(Targetable.class), eq(mockWeaponAC5), any(AmmoMounted.class), any(Game.class), anyBoolean()); // LB10X mockLB10X = mock(WeaponType.class); mockAmmoTypeLB10XSlug = mock(AmmoType.class); - mockAmmoLB10XSlug = mock(Mounted.class); + mockAmmoLB10XSlug = mock(AmmoMounted.class); mockAmmoTypeLB10XCluster = mock(AmmoType.class); - mockAmmoLB10XCluster = mock(Mounted.class); - mockWeaponLB10X = mock(Mounted.class); + mockAmmoLB10XCluster = mock(AmmoMounted.class); + mockWeaponLB10X = mock(WeaponMounted.class); when(mockWeaponLB10X.getType()).thenReturn(mockLB10X); when(mockLB10X.getAmmoType()).thenReturn(AmmoType.T_AC_LBX); when(mockAmmoTypeLB10XSlug.getAmmoType()).thenReturn(AmmoType.T_AC_LBX); @@ -343,13 +346,13 @@ public void beforeEach() { // Firing Cluster ammo doReturn(mockLB10XClusterFireInfo).when(testFireControl).buildWeaponFireInfo(any(Entity.class), - any(EntityState.class), any(Targetable.class), any(EntityState.class), eq(mockWeaponLB10X), any(Mounted.class), + any(EntityState.class), any(Targetable.class), any(EntityState.class), eq(mockWeaponLB10X), any(AmmoMounted.class), any(Game.class), anyBoolean()); doReturn(mockLB10XClusterFireInfo).when(testFireControl).buildWeaponFireInfo(any(Entity.class), - any(MovePath.class), any(Targetable.class), any(EntityState.class), eq(mockWeaponLB10X), any(Mounted.class), + any(MovePath.class), any(Targetable.class), any(EntityState.class), eq(mockWeaponLB10X), any(AmmoMounted.class), any(Game.class), anyBoolean(), anyBoolean()); doReturn(mockLB10XClusterFireInfo).when(testFireControl).buildWeaponFireInfo(any(Entity.class), - any(Targetable.class), eq(mockWeaponLB10X), any(Mounted.class), any(Game.class), anyBoolean()); + any(Targetable.class), eq(mockWeaponLB10X), any(AmmoMounted.class), any(Game.class), anyBoolean()); // Firing Slug ammo doReturn(mockLB10XSlugFireInfo).when(testFireControl).buildWeaponFireInfo(any(Entity.class), @@ -365,14 +368,14 @@ public void beforeEach() { // MML mockMML5 = mock(MMLWeapon.class); mockAmmoTypeSRM5 = mock(AmmoType.class); - mockAmmoSRM5 = mock(Mounted.class); + mockAmmoSRM5 = mock(AmmoMounted.class); mockAmmoTypeLRM5 = mock(AmmoType.class); - mockAmmoLRM5 = mock(Mounted.class); + mockAmmoLRM5 = mock(AmmoMounted.class); mockAmmoTypeInferno5 = mock(AmmoType.class); - mockAmmoInferno5 = mock(Mounted.class); + mockAmmoInferno5 = mock(AmmoMounted.class); mockAmmoTypeLrm5Frag = mock(AmmoType.class); - mockAmmoLrm5Frag = mock(Mounted.class); - mockWeaponMML5 = mock(Mounted.class); + mockAmmoLrm5Frag = mock(AmmoMounted.class); + mockWeaponMML5 = mock(WeaponMounted.class); when(mockWeaponMML5.getType()).thenReturn(mockMML5); when(mockMML5.getAmmoType()).thenReturn(AmmoType.T_MML); when(mockAmmoTypeSRM5.getMunitionType()).thenReturn(EnumSet.of(AmmoType.Munitions.M_STANDARD)); @@ -413,16 +416,16 @@ public void beforeEach() { doReturn(true).when(mockAmmoTypeLrm5Frag).equalsAmmoTypeOnly(eq(mockAmmoTypeLrm5Frag)); // ATM - mockAtm5Weapon = mock(Mounted.class); + mockAtm5Weapon = mock(WeaponMounted.class); mockAtm5 = mock(ATMWeapon.class); mockAmmoTypeAtm5He = mock(AmmoType.class); - mockAmmoAtm5He = mock(Mounted.class); + mockAmmoAtm5He = mock(AmmoMounted.class); mockAmmoTypeAtm5St = mock(AmmoType.class); - mockAmmoAtm5St = mock(Mounted.class); + mockAmmoAtm5St = mock(AmmoMounted.class); mockAmmoTypeAtm5Er = mock(AmmoType.class); - mockAmmoAtm5Er = mock(Mounted.class); + mockAmmoAtm5Er = mock(AmmoMounted.class); mockAmmoTypeAtm5Inferno = mock(AmmoType.class); - mockAmmoAtm5Inferno = mock(Mounted.class); + mockAmmoAtm5Inferno = mock(AmmoMounted.class); when(mockAtm5Weapon.getType()).thenReturn(mockAtm5); when(mockAtm5.getAmmoType()).thenReturn(AmmoType.T_ATM); when(mockAtm5.getRackSize()).thenReturn(5); @@ -474,7 +477,7 @@ public void beforeEach() { when(mockEnergyWeaponType.getAmmoType()).thenReturn(AmmoType.T_NA); when(mockEnergyWeaponType.hasFlag(any())).thenReturn(false); when(mockEnergyWeaponType.hasModeType(anyString())).thenReturn(false); - mockPPC = mock(Mounted.class); + mockPPC = mock(WeaponMounted.class); when(mockPPC.getType()).thenReturn(mockEnergyWeaponType); shooterWeapons.add(mockPPC); mockPPCFireInfo = mock(WeaponFireInfo.class); @@ -491,7 +494,7 @@ public void beforeEach() { any(Targetable.class), eq(mockPPC), isNull(), any(Game.class), anyBoolean()); // buildWeaponFireInfo(shooter, target, weapon, null, game, false); - mockML = mock(Mounted.class); + mockML = mock(WeaponMounted.class); shooterWeapons.add(mockML); when(mockML.getType()).thenReturn(mockEnergyWeaponType); mockMLFireInfo = mock(WeaponFireInfo.class); @@ -505,20 +508,20 @@ public void beforeEach() { doReturn(mockMLFireInfo).when(testFireControl).buildWeaponFireInfo(any(Entity.class), any(Targetable.class), eq(mockML), isNull(), any(Game.class), anyBoolean()); - mockLRM5 = mock(Mounted.class); + mockLRM5 = mock(WeaponMounted.class); when(mockLRM5.getType()).thenReturn(mockWeaponType); - when(mockLRM5.getLinked()).thenReturn(mockAmmoLRM5); + when(mockLRM5.getLinkedAmmo()).thenReturn(mockAmmoLRM5); shooterWeapons.add(mockLRM5); mockLRMFireInfo = mock(WeaponFireInfo.class); when(mockLRMFireInfo.getProbabilityToHit()).thenReturn(0.6); doReturn(mockLRMFireInfo).when(testFireControl).buildWeaponFireInfo(any(Entity.class), - any(EntityState.class), any(Targetable.class), any(EntityState.class), eq(mockLRM5), any(Mounted.class), + any(EntityState.class), any(Targetable.class), any(EntityState.class), eq(mockLRM5), any(AmmoMounted.class), any(Game.class), anyBoolean()); doReturn(mockLRMFireInfo).when(testFireControl).buildWeaponFireInfo(any(Entity.class), - any(MovePath.class), any(Targetable.class), any(EntityState.class), eq(mockLRM5), any(Mounted.class), + any(MovePath.class), any(Targetable.class), any(EntityState.class), eq(mockLRM5), any(AmmoMounted.class), any(Game.class), anyBoolean(), anyBoolean()); doReturn(mockLRMFireInfo).when(testFireControl).buildWeaponFireInfo(any(Entity.class), - any(Targetable.class), eq(mockLRM5), any(Mounted.class), any(Game.class), anyBoolean()); + any(Targetable.class), eq(mockLRM5), any(AmmoMounted.class), any(Game.class), anyBoolean()); when(mockWeaponMML5.getType()).thenReturn(mockWeaponType); mockMMLFireInfo = mock(WeaponFireInfo.class); @@ -532,13 +535,13 @@ public void beforeEach() { // General doReturn(mockMMLFireInfo).when(testFireControl).buildWeaponFireInfo(any(Entity.class), - any(EntityState.class), any(Targetable.class), any(EntityState.class), eq(mockWeaponMML5), any(Mounted.class), + any(EntityState.class), any(Targetable.class), any(EntityState.class), eq(mockWeaponMML5), any(AmmoMounted.class), any(Game.class), anyBoolean()); doReturn(mockMMLFireInfo).when(testFireControl).buildWeaponFireInfo(any(Entity.class), - any(MovePath.class), any(Targetable.class), any(EntityState.class), eq(mockWeaponMML5), any(Mounted.class), + any(MovePath.class), any(Targetable.class), any(EntityState.class), eq(mockWeaponMML5), any(AmmoMounted.class), any(Game.class), anyBoolean(), anyBoolean()); doReturn(mockMMLFireInfo).when(testFireControl).buildWeaponFireInfo(any(Entity.class), - any(Targetable.class), eq(mockWeaponMML5), any(Mounted.class), any(Game.class), anyBoolean()); + any(Targetable.class), eq(mockWeaponMML5), any(AmmoMounted.class), any(Game.class), anyBoolean()); // Firing LRM5 ammo doReturn(mockMMLLRM5FireInfo).when(testFireControl).buildWeaponFireInfo(any(Entity.class), @@ -562,13 +565,13 @@ public void beforeEach() { // Mock the getAmmo(Mounted) call return value - ArrayList mockAmmoList = new ArrayList(); + List mockAmmoList = new ArrayList<>(); mockAmmoList.add(mockAmmoLRM5); mockAmmoList.add(mockAmmoSRM5); - when(mockShooter.getAmmo(any(Mounted.class))).thenReturn(mockAmmoList); + when(mockShooter.getAmmo(any(WeaponMounted.class))).thenReturn(mockAmmoList); testToHitThreshold = new HashMap<>(); - for (final Mounted weapon : mockShooter.getWeaponList()) { + for (final WeaponMounted weapon : mockShooter.getWeaponList()) { testToHitThreshold.put(weapon, 0.0); } } @@ -576,7 +579,7 @@ public void beforeEach() { @Test public void testGetHardTargetAmmo() { // Test an ammo list with only 1 bin of standard ammo. - List testAmmoList = new ArrayList<>(1); + List testAmmoList = new ArrayList<>(1); testAmmoList.add(mockAmmoAC5Std); final FireControl testFireControl = new FireControl(mockPrincess); assertEquals(mockAmmoAC5Std, testFireControl.getHardTargetAmmo(testAmmoList, mockWeaponTypeAC5, 5)); @@ -627,7 +630,7 @@ public void testGetHardTargetAmmo() { @Test public void testGetAntiAirAmmo() { // Test an ammo list with only 1 bin. - List testAmmoList = new ArrayList<>(2); + List testAmmoList = new ArrayList<>(2); testAmmoList.add(mockAmmoAC5Std); final FireControl testFireControl = new FireControl(mockPrincess); assertNull(testFireControl.getAntiAirAmmo(testAmmoList, mockWeaponTypeAC5, 5)); @@ -652,7 +655,7 @@ public void testGetAntiAirAmmo() { @Test public void testGetClusterAmmo() { // Test an ammo list with only 1 bin of cluster ammo. - List testAmmoList = new ArrayList<>(2); + List testAmmoList = new ArrayList<>(2); testAmmoList.add(mockAmmoLB10XCluster); FireControl testFireControl = new FireControl(mockPrincess); assertEquals(mockAmmoLB10XCluster, testFireControl.getClusterAmmo(testAmmoList, mockLB10X, 5)); @@ -673,7 +676,7 @@ public void testGetClusterAmmo() { @Test public void testGetHeatAmmo() { // Test an ammo list with only 1 bin of incendiary ammo. - List testAmmoList = new ArrayList<>(1); + List testAmmoList = new ArrayList<>(1); testAmmoList.add(mockAmmoAc5Incendiary); final FireControl testFireControl = new FireControl(mockPrincess); assertEquals(mockAmmoAc5Incendiary, testFireControl.getIncendiaryAmmo(testAmmoList, mockWeaponTypeAC5, @@ -710,7 +713,7 @@ public void testGetHeatAmmo() { @Test public void testGetAntiInfantryAmmo() { // Test an ammo list with only 1 bin of flechette ammo. - List testAmmoList = new ArrayList<>(1); + List testAmmoList = new ArrayList<>(1); testAmmoList.add(mockAmmoAc5Flechette); final FireControl testFireControl = new FireControl(mockPrincess); assertEquals(mockAmmoAc5Flechette, testFireControl.getAntiInfantryAmmo(testAmmoList, @@ -749,7 +752,7 @@ public void testGetAntiInfantryAmmo() { @Test public void testGetAntiVeeAmmo() { // Test an ammo list with only 1 bin of standard ammo. - List testAmmoList = new ArrayList<>(1); + List testAmmoList = new ArrayList<>(1); testAmmoList.add(mockAmmoAC5Std); FireControl testFireControl = new FireControl(mockPrincess); assertNull(testFireControl.getAntiVeeAmmo(testAmmoList, mockWeaponTypeAC5, 5, false)); @@ -790,7 +793,7 @@ public void testGetAntiVeeAmmo() { @Test public void testGetAtmAmmo() { // Test a list with just HE ammo. - List testAmmoList = new ArrayList<>(1); + List testAmmoList = new ArrayList<>(1); testAmmoList.add(mockAmmoAtm5He); final FireControl testFireControl = new FireControl(mockPrincess); assertEquals(mockAmmoAtm5He, testFireControl.getAtmAmmo(testAmmoList, 5, mockTargetState, false)); @@ -870,7 +873,7 @@ public void testGetAtmAmmo() { @Test public void testGetGeneralMmlAmmo() { // Test a list with just SRM ammo. - List testAmmoList = new ArrayList<>(1); + List testAmmoList = new ArrayList<>(1); testAmmoList.add(mockAmmoSRM5); final FireControl testFireControl = new FireControl(mockPrincess); assertEquals(mockAmmoSRM5, testFireControl.getGeneralMmlAmmo(testAmmoList, 6)); @@ -906,7 +909,7 @@ public void testGetPreferredAmmo() { when(mockCrew.getOptions()).thenReturn(mockOptions); when(mockOptions.booleanOption(anyString())).thenReturn(false); - final ArrayList testAmmoList = new ArrayList<>(5); + final ArrayList testAmmoList = new ArrayList<>(5); testAmmoList.add(mockAmmoAtm5He); testAmmoList.add(mockAmmoAtm5Er); testAmmoList.add(mockAmmoAtm5St); @@ -930,7 +933,7 @@ public void testGetPreferredAmmo() { // Test shooting an AC5 at a building. mockTarget = mock(BuildingTarget.class); when(mockTarget.getPosition()).thenReturn(new Coords(10, 15)); - when(mockWeaponAC5.getLinked()).thenReturn(mockAmmoAc5Incendiary); + when(mockWeaponAC5.getLinkedAmmo()).thenReturn(mockAmmoAc5Incendiary); assertEquals(mockAmmoAc5Incendiary, testFireControl.getPreferredAmmo(mockShooter, mockTarget, mockWeaponAC5)); // Test shooting an LBX at an airborne target. @@ -938,21 +941,21 @@ public void testGetPreferredAmmo() { when(((Entity) mockTarget).getArmorType(anyInt())).thenReturn(EquipmentType.T_ARMOR_STANDARD); when(mockTarget.getPosition()).thenReturn(new Coords(10, 15)); when(mockTarget.isAirborne()).thenReturn(true); - when(mockWeaponLB10X.getLinked()).thenReturn(mockAmmoLB10XCluster); + when(mockWeaponLB10X.getLinkedAmmo()).thenReturn(mockAmmoLB10XCluster); assertEquals(mockAmmoLB10XCluster, testFireControl.getPreferredAmmo(mockShooter, mockTarget, mockWeaponLB10X)); // Test shooting an LBX at a tank. mockTarget = mock(Tank.class); when(((Entity) mockTarget).getArmorType(anyInt())).thenReturn(EquipmentType.T_ARMOR_STANDARD); when(mockTarget.getPosition()).thenReturn(new Coords(10, 15)); - when(mockWeaponLB10X.getLinked()).thenReturn(mockAmmoLB10XCluster); + when(mockWeaponLB10X.getLinkedAmmo()).thenReturn(mockAmmoLB10XCluster); assertEquals(mockAmmoLB10XCluster, testFireControl.getPreferredAmmo(mockShooter, mockTarget, mockWeaponLB10X)); // Test shooting an AC at infantry. mockTarget = mock(Infantry.class); when(((Entity) mockTarget).getArmorType(anyInt())).thenReturn(EquipmentType.T_ARMOR_STANDARD); when(mockTarget.getPosition()).thenReturn(new Coords(10, 15)); - when(mockWeaponAC5.getLinked()).thenReturn(mockAmmoAc5Flechette); + when(mockWeaponAC5.getLinkedAmmo()).thenReturn(mockAmmoAc5Flechette); assertTrue( mockAmmoAc5Flechette.equals(testFireControl.getPreferredAmmo(mockShooter, mockTarget, mockWeaponAC5)) @@ -964,25 +967,25 @@ public void testGetPreferredAmmo() { when(((Entity) mockTarget).getArmorType(anyInt())).thenReturn(EquipmentType.T_ARMOR_STANDARD); when(mockTarget.getPosition()).thenReturn(new Coords(10, 15)); when(((Entity) mockTarget).getDamageLevel()).thenReturn(Entity.DMG_HEAVY); - when(mockWeaponLB10X.getLinked()).thenReturn(mockAmmoLB10XCluster); + when(mockWeaponLB10X.getLinkedAmmo()).thenReturn(mockAmmoLB10XCluster); assertEquals(mockAmmoLB10XCluster, testFireControl.getPreferredAmmo(mockShooter, mockTarget, mockWeaponLB10X)); // Test a hot target. when(((Entity) mockTarget).getDamageLevel()).thenReturn(Entity.DMG_LIGHT); when(((Entity) mockTarget).getHeat()).thenReturn(12); - when(mockWeaponMML5.getLinked()).thenReturn(mockAmmoInferno5); + when(mockWeaponMML5.getLinkedAmmo()).thenReturn(mockAmmoInferno5); assertEquals(mockAmmoInferno5, testFireControl.getPreferredAmmo(mockShooter, mockTarget, mockWeaponMML5)); when(((Entity) mockTarget).getArmorType(anyInt())).thenReturn(EquipmentType.T_ARMOR_HEAT_DISSIPATING); - when(mockWeaponMML5.getLinked()).thenReturn(mockAmmoSRM5); + when(mockWeaponMML5.getLinkedAmmo()).thenReturn(mockAmmoSRM5); assertEquals(mockAmmoSRM5, testFireControl.getPreferredAmmo(mockShooter, mockTarget, mockWeaponMML5)); when(((Entity) mockTarget).getArmorType(anyInt())).thenReturn(EquipmentType.T_ARMOR_STANDARD); // Test a normal target. when(((Entity) mockTarget).getHeat()).thenReturn(4); - when(mockWeaponAC5.getLinked()).thenReturn(mockAmmoAC5Std); + when(mockWeaponAC5.getLinkedAmmo()).thenReturn(mockAmmoAC5Std); assertEquals(mockAmmoAC5Std, testFireControl.getPreferredAmmo(mockShooter, mockTarget, mockWeaponAC5)); - when(mockWeaponMML5.getLinked()).thenReturn(mockAmmoSRM5); + when(mockWeaponMML5.getLinkedAmmo()).thenReturn(mockAmmoSRM5); assertEquals(mockAmmoSRM5, testFireControl.getPreferredAmmo(mockShooter, mockTarget, mockWeaponMML5)); } @@ -1617,7 +1620,7 @@ public void testGuessToHitModifierForWeapon() { when(mockTargetHex.containsTerrain(Terrains.WATER)).thenReturn(false); // todo test water final int MOCK_WEAPON_ID = 1; - final Mounted mockWeapon = mock(Mounted.class); + final WeaponMounted mockWeapon = mock(WeaponMounted.class); when(mockWeapon.canFire()).thenReturn(true); when(mockWeapon.getLocation()).thenReturn(Mech.LOC_RARM); when(mockShooter.getEquipmentNum(eq(mockWeapon))).thenReturn(MOCK_WEAPON_ID); @@ -1630,8 +1633,8 @@ public void testGuessToHitModifierForWeapon() { when(mockWeaponType.getMinimumRange()).thenReturn(3); when(mockWeaponType.hasFlag(eq(WeaponType.F_DIRECT_FIRE))).thenReturn(true); - final Mounted mockAmmo = mock(Mounted.class); - when(mockWeapon.getLinked()).thenReturn(mockAmmo); + final AmmoMounted mockAmmo = mock(AmmoMounted.class); + when(mockWeapon.getLinked()).thenReturn((Mounted) mockAmmo); when(mockAmmo.getUsableShotsLeft()).thenReturn(10); // Test the vanilla case. @@ -1918,18 +1921,18 @@ public void testGuessToHitModifierForWeapon() { when(mockAmmo.getUsableShotsLeft()).thenReturn(0); expected = new ToHitData(FireControl.TH_WEAP_NO_AMMO); assertToHitDataEquals(expected, testFireControl.guessToHitModifierForWeapon(mockShooter, - mockShooterState, mockTarget, mockTargetState, mockWeapon, mockWeapon.getLinked(), mockGame)); + mockShooterState, mockTarget, mockTargetState, mockWeapon, mockWeapon.getLinkedAmmo(), mockGame)); when(mockAmmo.getUsableShotsLeft()).thenReturn(10); - when(mockWeapon.getLinked()).thenReturn(null); + when(mockWeapon.getLinkedAmmo()).thenReturn(null); expected = new ToHitData(FireControl.TH_WEAP_NO_AMMO); assertToHitDataEquals(expected, testFireControl.guessToHitModifierForWeapon(mockShooter, - mockShooterState, mockTarget, mockTargetState, mockWeapon, mockWeapon.getLinked(), mockGame)); + mockShooterState, mockTarget, mockTargetState, mockWeapon, mockWeapon.getLinkedAmmo(), mockGame)); // Test a weapon that cannot fire. when(mockWeapon.canFire()).thenReturn(false); expected = new ToHitData(FireControl.TH_WEAP_CANNOT_FIRE); assertToHitDataEquals(expected, testFireControl.guessToHitModifierForWeapon(mockShooter, - mockShooterState, mockTarget, mockTargetState, mockWeapon, mockWeapon.getLinked(), mockGame)); + mockShooterState, mockTarget, mockTargetState, mockWeapon, mockWeapon.getLinkedAmmo(), mockGame)); } @Test @@ -1945,15 +1948,15 @@ public void testGuessAirToGroundStrikeToHitModifier() { doReturn(false).when(testFireControl).isTargetUnderFlightPath(eq(mockFlightPathBad), any(EntityState.class)); - final Mounted mockWeapon = mock(Mounted.class); + final WeaponMounted mockWeapon = mock(WeaponMounted.class); when(mockWeapon.canFire()).thenReturn(true); final WeaponType mockWeaponType = mock(WeaponType.class); when(mockWeapon.getType()).thenReturn(mockWeaponType); when(mockWeaponType.getAmmoType()).thenReturn(AmmoType.T_AC); - final Mounted mockAmmo = mock(Mounted.class); - when(mockWeapon.getLinked()).thenReturn(mockAmmo); + final AmmoMounted mockAmmo = mock(AmmoMounted.class); + when(mockWeapon.getLinkedAmmo()).thenReturn(mockAmmo); when(mockAmmo.getUsableShotsLeft()).thenReturn(10); final ConvFighter mockFighter = mock(ConvFighter.class); @@ -2346,7 +2349,7 @@ public void testGuessFullAirToGroundPlan() { FiringPlan expected; when(mockShooter.getPosition()).thenReturn(mockShooterCoords); when(mockShooter.isOffBoard()).thenReturn(false); - when(mockShooter.getBombs(any(BigInteger.class))).thenReturn(new Vector<>(0)); + when(mockShooter.getBombs(any(BigInteger.class))).thenReturn(emptyList()); when(mockTarget.getPosition()).thenReturn(mockTargetCoords); when(mockTarget.isOffBoard()).thenReturn(false); when(mockBoard.contains(eq(mockShooterCoords))).thenReturn(true); @@ -2379,7 +2382,7 @@ public void testGuessFullAirToGroundPlan() { mockTargetState, mockFlightPath, mockGame, true)); } - private void prepForFullFiringPlan(ArrayList wepList, ArrayList ammoList) { + private void prepForFullFiringPlan(List wepList, List ammoList) { when(mockShooter.getPosition()).thenReturn(mockShooterCoords); when(mockShooter.isOffBoard()).thenReturn(false); when(mockTarget.getPosition()).thenReturn(mockTargetCoords); @@ -2390,15 +2393,13 @@ private void prepForFullFiringPlan(ArrayList wepList, ArrayList mockAmmoList = new ArrayList(); - for (Mounted ammo: ammoList) { - mockAmmoList.add(ammo); - } + ArrayList mockAmmoList = new ArrayList<>(); + mockAmmoList.addAll(ammoList); when(mockShooter.getAmmo()).thenReturn(mockAmmoList); doNothing().when(testFireControl).calculateUtility(any(FiringPlan.class), anyInt(), anyBoolean()); @@ -2406,8 +2407,8 @@ private void prepForFullFiringPlan(ArrayList wepList, ArrayList wepList = new ArrayList(Arrays.asList(mockPPC, mockLRM5)); - ArrayList ammoList = new ArrayList(Arrays.asList(mockAmmoLRM5, mockAmmoSRM5)); + List wepList = new ArrayList<>(Arrays.asList(mockPPC, mockLRM5)); + List ammoList = new ArrayList<>(Arrays.asList(mockAmmoLRM5, mockAmmoSRM5)); prepForFullFiringPlan(wepList, ammoList); // Test the normal case. @@ -2443,8 +2444,8 @@ public void testGetFullFiringPlan() { @Test public void testChooseAppropriateMMLAmmoForLongRange() { - ArrayList wepList = new ArrayList(Arrays.asList(mockWeaponMML5)); - ArrayList ammoList = new ArrayList(Arrays.asList(mockAmmoSRM5, mockAmmoLRM5)); + List wepList = new ArrayList<>(Arrays.asList(mockWeaponMML5)); + List ammoList = new ArrayList<>(Arrays.asList(mockAmmoSRM5, mockAmmoLRM5)); prepForFullFiringPlan(wepList, ammoList); // Simulating longer-range engagement @@ -2458,8 +2459,8 @@ public void testChooseAppropriateMMLAmmoForLongRange() { @Test public void testChooseAppropriateMMLAmmoForShortRange() { - ArrayList wepList = new ArrayList(Arrays.asList(mockWeaponMML5)); - ArrayList ammoList = new ArrayList(Arrays.asList(mockAmmoLRM5, mockAmmoSRM5)); + List wepList = new ArrayList<>(Arrays.asList(mockWeaponMML5)); + List ammoList = new ArrayList<>(Arrays.asList(mockAmmoLRM5, mockAmmoSRM5)); prepForFullFiringPlan(wepList, ammoList); // Simulating closer-range engagement @@ -2476,8 +2477,8 @@ public void testChooseAppropriateMMLAmmoForShortRange() { @Test public void testChooseLBXAmmoForEngagingFlyer() { - ArrayList wepList = new ArrayList(Arrays.asList(mockWeaponLB10X)); - ArrayList ammoList = new ArrayList(Arrays.asList(mockAmmoLB10XSlug, mockAmmoLB10XCluster)); + ArrayList wepList = new ArrayList<>(Arrays.asList(mockWeaponLB10X)); + ArrayList ammoList = new ArrayList<>(Arrays.asList(mockAmmoLB10XSlug, mockAmmoLB10XCluster)); prepForFullFiringPlan(wepList, ammoList); // Should get the plan back with a Cluster shot @@ -2490,8 +2491,8 @@ public void testChooseLBXAmmoForEngagingFlyer() { @Test public void testChooseACAmmoForEngagingFlyer() { - ArrayList wepList = new ArrayList(Arrays.asList(mockWeaponAC5)); - ArrayList ammoList = new ArrayList(Arrays.asList( + ArrayList wepList = new ArrayList<>(Arrays.asList(mockWeaponAC5)); + ArrayList ammoList = new ArrayList<>(Arrays.asList( mockAmmoAC5Std, mockAmmoAc5Incendiary, mockAmmoAC5Flak )); prepForFullFiringPlan(wepList, ammoList); @@ -2540,7 +2541,7 @@ public void testCalcFiringPlansUnderHeat() { when(mockLRMFireInfo.getDebugDescription()).thenReturn("mock LRM"); alphaStrike.add(mockLRMFireInfo); - final Mounted mockMG = mock(Mounted.class); + final WeaponMounted mockMG = mock(WeaponMounted.class); shooterWeapons.add(mockMG); final WeaponFireInfo mockMGFireInfo = mock(WeaponFireInfo.class); when(mockMGFireInfo.getProbabilityToHit()).thenReturn(0.6); diff --git a/megamek/unittests/megamek/client/bot/princess/FiringPlanTest.java b/megamek/unittests/megamek/client/bot/princess/FiringPlanTest.java index 55f6b50a962..47c1ff71930 100644 --- a/megamek/unittests/megamek/client/bot/princess/FiringPlanTest.java +++ b/megamek/unittests/megamek/client/bot/princess/FiringPlanTest.java @@ -25,6 +25,8 @@ import megamek.common.WeaponType; import megamek.common.actions.EntityAction; import megamek.common.actions.WeaponAttackAction; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -50,7 +52,7 @@ public class FiringPlanTest { private static WeaponFireInfo mockWeaponFireInfoMG; private static WeaponAttackAction mockWeaponAttackActionMG; private static WeaponFireInfo mockWeaponFireInfoPPC; - private static Mounted mockPPC; + private static WeaponMounted mockPPC; private static WeaponAttackAction mockWeaponAttackActionPPC; private static WeaponFireInfo mockWeaponFireInfoERML; private static WeaponAttackAction mockWeaponAttackActionERML; @@ -65,21 +67,21 @@ public static void beforeAll() { mockWeaponFireInfoMG = mock(WeaponFireInfo.class); testFiringPlan.add(mockWeaponFireInfoMG); - Mounted mockMG = mock(Mounted.class); + WeaponMounted mockMG = mock(WeaponMounted.class); when(mockWeaponFireInfoMG.getWeapon()).thenReturn(mockMG); mockWeaponAttackActionMG = mock(WeaponAttackAction.class); when(mockWeaponFireInfoMG.getWeaponAttackAction()).thenReturn(mockWeaponAttackActionMG); mockWeaponFireInfoPPC = mock(WeaponFireInfo.class); testFiringPlan.add(mockWeaponFireInfoPPC); - mockPPC = mock(Mounted.class); + mockPPC = mock(WeaponMounted.class); when(mockWeaponFireInfoPPC.getWeapon()).thenReturn(mockPPC); mockWeaponAttackActionPPC = mock(WeaponAttackAction.class); when(mockWeaponFireInfoPPC.getWeaponAttackAction()).thenReturn(mockWeaponAttackActionPPC); mockWeaponFireInfoERML = mock(WeaponFireInfo.class); testFiringPlan.add(mockWeaponFireInfoERML); - Mounted mockERML = mock(Mounted.class); + WeaponMounted mockERML = mock(WeaponMounted.class); when(mockWeaponFireInfoERML.getWeapon()).thenReturn(mockERML); mockWeaponAttackActionERML = mock(WeaponAttackAction.class); when(mockWeaponFireInfoERML.getWeaponAttackAction()).thenReturn(mockWeaponAttackActionERML); @@ -175,7 +177,7 @@ public void testGetEntityActionVector() { @Test public void testSortPlan() { WeaponFireInfo mockInfoLL = mock(WeaponFireInfo.class); - Mounted mockLL = mock(Mounted.class); + WeaponMounted mockLL = mock(WeaponMounted.class); when(mockLL.getName()).thenReturn("LL"); when(mockLL.toString()).thenReturn("LL"); when(mockInfoLL.getWeapon()).thenReturn(mockLL); @@ -185,30 +187,30 @@ public void testSortPlan() { when(mockLL.getLinked()).thenReturn(null); WeaponFireInfo mockInfoLRM = mock(WeaponFireInfo.class); - Mounted mockLRM = mock(Mounted.class); + WeaponMounted mockLRM = mock(WeaponMounted.class); when(mockLRM.getName()).thenReturn("LRM"); when(mockLRM.toString()).thenReturn("LRM"); when(mockInfoLRM.getWeapon()).thenReturn(mockLRM); WeaponType mockTypeLRM = mock(WeaponType.class); when(mockLRM.getType()).thenReturn(mockTypeLRM); when(mockTypeLRM.getDamage()).thenReturn(WeaponType.DAMAGE_BY_CLUSTERTABLE); - Mounted mockAmmoLRM = mock(Mounted.class); - when(mockLRM.getLinked()).thenReturn(mockAmmoLRM); + AmmoMounted mockAmmoLRM = mock(AmmoMounted.class); + when(mockLRM.getLinkedAmmo()).thenReturn(mockAmmoLRM); AmmoType mockAmmoTypeLRM = mock(AmmoType.class); when(mockAmmoLRM.getType()).thenReturn(mockAmmoTypeLRM); when(mockAmmoTypeLRM.getMunitionType()).thenReturn(EnumSet.of(AmmoType.Munitions.M_STANDARD)); when(mockAmmoTypeLRM.getDamagePerShot()).thenReturn(1); WeaponFireInfo mockInfoLBX = mock(WeaponFireInfo.class); - Mounted mockLBX = mock(Mounted.class); + WeaponMounted mockLBX = mock(WeaponMounted.class); when(mockLBX.getName()).thenReturn("LBX"); when(mockLBX.toString()).thenReturn("LBX"); when(mockInfoLBX.getWeapon()).thenReturn(mockLBX); WeaponType mockTypeLBX = mock(WeaponType.class); when(mockLBX.getType()).thenReturn(mockTypeLBX); when(mockTypeLBX.getDamage()).thenReturn(10); - Mounted mockAmmoLBX = mock(Mounted.class); - when(mockLBX.getLinked()).thenReturn(mockAmmoLBX); + AmmoMounted mockAmmoLBX = mock(AmmoMounted.class); + when(mockLBX.getLinkedAmmo()).thenReturn(mockAmmoLBX); AmmoType mockAmmoTypeLBXCluster = mock(AmmoType.class); when(mockAmmoTypeLBXCluster.getMunitionType()).thenReturn(EnumSet.of(AmmoType.Munitions.M_CLUSTER)); when(mockAmmoTypeLBXCluster.getDamagePerShot()).thenReturn(1); @@ -217,15 +219,15 @@ public void testSortPlan() { when(mockAmmoTypeLBXSlug.getDamagePerShot()).thenReturn(1); WeaponFireInfo mockInfoSRM = mock(WeaponFireInfo.class); - Mounted mockSRM = mock(Mounted.class); + WeaponMounted mockSRM = mock(WeaponMounted.class); when(mockSRM.getName()).thenReturn("SRM"); when(mockSRM.toString()).thenReturn("SRM"); when(mockInfoSRM.getWeapon()).thenReturn(mockSRM); WeaponType mockTypeSRM = mock(WeaponType.class); when(mockSRM.getType()).thenReturn(mockTypeSRM); when(mockTypeSRM.getDamage()).thenReturn(WeaponType.DAMAGE_BY_CLUSTERTABLE); - Mounted mockAmmoSRM = mock(Mounted.class); - when(mockSRM.getLinked()).thenReturn(mockAmmoSRM); + AmmoMounted mockAmmoSRM = mock(AmmoMounted.class); + when(mockSRM.getLinkedAmmo()).thenReturn(mockAmmoSRM); AmmoType mockAmmoTypeSRM = mock(AmmoType.class); when(mockAmmoSRM.getType()).thenReturn(mockAmmoTypeSRM); when(mockAmmoTypeSRM.getMunitionType()).thenReturn(EnumSet.of(AmmoType.Munitions.M_STANDARD)); diff --git a/megamek/unittests/megamek/client/bot/princess/WeaponFireInfoTest.java b/megamek/unittests/megamek/client/bot/princess/WeaponFireInfoTest.java index 371721a5dca..672dc4c626e 100644 --- a/megamek/unittests/megamek/client/bot/princess/WeaponFireInfoTest.java +++ b/megamek/unittests/megamek/client/bot/princess/WeaponFireInfoTest.java @@ -21,6 +21,8 @@ import megamek.client.bot.princess.FireControl.FireControlType; import megamek.common.*; import megamek.common.actions.WeaponAttackAction; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.WeaponMounted; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -57,7 +59,7 @@ public class WeaponFireInfoTest { private static BipedMech mockTarget; private static EntityState mockTargetState; private static Game mockGame; - private static Mounted mockWeapon; + private static WeaponMounted mockWeapon; private static WeaponType mockWeaponType; private static WeaponAttackAction mockWeaponAttackAction; private static EquipmentMode mockEquipmentMode; @@ -79,7 +81,7 @@ public static void beforeAll() { mockFireControl = mock(FireControl.class); when(mockFireControl.guessToHitModifierForWeapon(any(Entity.class), any(EntityState.class), - any(Targetable.class), any(EntityState.class), any(Mounted.class), any(Mounted.class), any(Game.class))) + any(Targetable.class), any(EntityState.class), any(WeaponMounted.class), any(AmmoMounted.class), any(Game.class))) .thenReturn(mockToHitEight); mockPrincess = mock(Princess.class); @@ -108,7 +110,7 @@ public static void beforeAll() { when(mockTargetState.getPosition()).thenReturn(TARGET_COORDS_9); mockWeaponType = mock(WeaponType.class); - mockWeapon = mock(Mounted.class); + mockWeapon = mock(WeaponMounted.class); mockEquipmentMode = mock(EquipmentMode.class); when(mockWeapon.getType()).thenReturn(mockWeaponType); when(mockEquipmentMode.getName()).thenReturn(""); @@ -187,7 +189,7 @@ public void testInitDamage() { doReturn(mockToHitSix).when(testWeaponFireInfo).calcToHit(); doReturn(mockWeaponAttackAction).when(testWeaponFireInfo).buildWeaponAttackAction(); doReturn(expectedMaxDamage).when(testWeaponFireInfo).computeExpectedDamage(); - when(mockShooter.getEquipment(anyInt())).thenReturn(mockWeapon); + when(mockShooter.getEquipment(anyInt())).thenReturn((Mounted) mockWeapon); testWeaponFireInfo.initDamage(null, false, true, null); assertEquals(expectedMaxDamage, testWeaponFireInfo.getMaxDamage()); assertEquals(expectedProbabilityToHit, testWeaponFireInfo.getProbabilityToHit(), DELTA); diff --git a/megamek/unittests/megamek/common/AmmoTypeTest.java b/megamek/unittests/megamek/common/AmmoTypeTest.java index ee3640cecf1..715b0cac469 100644 --- a/megamek/unittests/megamek/common/AmmoTypeTest.java +++ b/megamek/unittests/megamek/common/AmmoTypeTest.java @@ -18,6 +18,9 @@ */ package megamek.common; +import megamek.common.equipment.AmmoMounted; +import megamek.common.equipment.MiscMounted; +import megamek.common.equipment.WeaponMounted; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; @@ -37,23 +40,23 @@ public class AmmoTypeTest { static WeaponType mockAC5 = mock(WeaponType.class); static AmmoType mockAC5AmmoType = mock(AmmoType.class); - static Mounted mockAmmoAC5 = mock(Mounted.class); - static Mounted mockAmmoAC5Empty = mock(Mounted.class); + static AmmoMounted mockAmmoAC5 = mock(AmmoMounted.class); + static AmmoMounted mockAmmoAC5Empty = mock(AmmoMounted.class); static AmmoType mockAC10AmmoType = mock(AmmoType.class); - static Mounted mockAmmoAC10 = mock(Mounted.class); + static AmmoMounted mockAmmoAC10 = mock(AmmoMounted.class); static WeaponType mockPPC = mock(WeaponType.class); static WeaponType mockSRM4 = mock(WeaponType.class); static AmmoType mockSRM4AmmoType = mock(AmmoType.class); - static Mounted mockAmmoSrm4 = mock(Mounted.class); + static AmmoMounted mockAmmoSrm4 = mock(AmmoMounted.class); static AmmoType mockSRM6AmmoType = mock(AmmoType.class); - static Mounted mockAmmoSrm6 = mock(Mounted.class); + static AmmoMounted mockAmmoSrm6 = mock(AmmoMounted.class); static AmmoType mockInferno4AmmoType = mock(AmmoType.class); - static Mounted mockAmmoInferno4 = mock(Mounted.class); + static AmmoMounted mockAmmoInferno4 = mock(AmmoMounted.class); static MiscType notAmmoType = mock(MiscType.class); - static Mounted mockNotAmmo = mock(Mounted.class); + static MiscMounted mockNotAmmo = mock(MiscMounted.class); @BeforeAll public static void beforeAll() { @@ -109,7 +112,7 @@ public void testIsAmmoValid() { assertFalse(AmmoType.isAmmoValid(mockAmmoAC5Empty, mockAC5)); // Test null ammo. - assertFalse(AmmoType.isAmmoValid((Mounted) null, mockAC5)); + assertFalse(AmmoType.isAmmoValid((AmmoMounted) null, mockAC5)); assertFalse(AmmoType.isAmmoValid((AmmoType) null, mockAC5)); // Test incompatible ammo. @@ -126,8 +129,8 @@ public void testIsAmmoValid() { @Test public void testCanSwitchToAmmo() { - Mounted mockWeapon = mock(Mounted.class); - when(mockWeapon.getLinked()).thenReturn(mockAmmoSrm4); + WeaponMounted mockWeapon = mock(WeaponMounted.class); + when(mockWeapon.getLinkedAmmo()).thenReturn(mockAmmoSrm4); assertTrue(AmmoType.canSwitchToAmmo(mockWeapon, mockInferno4AmmoType)); diff --git a/megamek/unittests/megamek/common/EntityTest.java b/megamek/unittests/megamek/common/EntityTest.java index 6c314a5f1c5..d47ab231450 100644 --- a/megamek/unittests/megamek/common/EntityTest.java +++ b/megamek/unittests/megamek/common/EntityTest.java @@ -22,11 +22,13 @@ import megamek.client.ui.swing.calculationReport.CalculationReport; import megamek.common.battlevalue.BVCalculator; +import megamek.common.equipment.WeaponMounted; import org.junit.jupiter.api.BeforeAll; import org.junit.jupiter.api.Test; import java.io.File; import java.util.ArrayList; +import java.util.List; import static org.junit.jupiter.api.Assertions.*; import static org.mockito.ArgumentMatchers.*; @@ -48,16 +50,19 @@ private Entity setupGunEmplacement() { any(CalculationReport.class))).thenCallRealMethod(); when(testEntity.getTotalArmor()).thenReturn(100); when(testEntity.getBARRating(anyInt())).thenCallRealMethod(); - ArrayList equipment = new ArrayList<>(2); + List> equipment = new ArrayList<>(2); + List weapons = new ArrayList<>(2); WeaponType ppcType = mock(WeaponType.class); when(ppcType.getBV(any(Entity.class))).thenReturn(50.0); - Mounted ppc = mock(Mounted.class); + WeaponMounted ppc = mock(WeaponMounted.class); when(ppc.getType()).thenReturn(ppcType); when(ppc.isDestroyed()).thenReturn(false); equipment.add(ppc); equipment.add(ppc); + weapons.add(ppc); + weapons.add(ppc); when(testEntity.getEquipment()).thenReturn(equipment); - when(testEntity.getWeaponList()).thenReturn(equipment); + when(testEntity.getWeaponList()).thenReturn(weapons); when(testEntity.getAmmo()).thenReturn(new ArrayList<>(0)); return testEntity; } diff --git a/megamek/unittests/megamek/common/WeaponTypeTest.java b/megamek/unittests/megamek/common/WeaponTypeTest.java index 0cbb4c9c97a..4f7b7a6acab 100644 --- a/megamek/unittests/megamek/common/WeaponTypeTest.java +++ b/megamek/unittests/megamek/common/WeaponTypeTest.java @@ -18,6 +18,7 @@ */ package megamek.common; +import megamek.common.equipment.WeaponMounted; import megamek.common.weapons.Weapon; import megamek.common.weapons.bayweapons.BayWeapon; import megamek.common.weapons.bayweapons.PPCBayWeapon; @@ -64,35 +65,35 @@ public void testArtemisCompatibleFlag() { } } - private Mounted setupBayWeapon(String name){ + private WeaponMounted setupBayWeapon(String name){ EquipmentType etype = EquipmentType.get(name); - Mounted weapon = new Mounted(mockEntity, etype); - Mounted bWeapon = new Mounted(mockEntity, ((WeaponType) weapon.getType()).getBayType()); + WeaponMounted weapon = new WeaponMounted(mockEntity, (WeaponType) etype); + WeaponMounted bWeapon = new WeaponMounted(mockEntity, (WeaponType) weapon.getType().getBayType()); bWeapon.addWeaponToBay(mockEntity.getEquipmentNum(weapon)); - when(mockEntity.getEquipment(anyInt())).thenReturn(weapon); + when(mockEntity.getEquipment(anyInt())).thenReturn((Mounted) weapon); return bWeapon; } @Test public void testWeaponBaysGetCorrectMaxRanges() { - Mounted ppcbay = setupBayWeapon("ISERPPC"); + WeaponMounted ppcbay = setupBayWeapon("ISERPPC"); WeaponType wtype = (WeaponType) ppcbay.getType(); assertEquals(RangeType.RANGE_LONG, wtype.getMaxRange(ppcbay)); - Mounted erplasbay = setupBayWeapon("CLERLargePulseLaser"); + WeaponMounted erplasbay = setupBayWeapon("CLERLargePulseLaser"); wtype = (WeaponType) erplasbay.getType(); assertEquals(RangeType.RANGE_LONG, wtype.getMaxRange(erplasbay )); - Mounted islplasbay = setupBayWeapon("ISLargePulseLaser"); + WeaponMounted islplasbay = setupBayWeapon("ISLargePulseLaser"); wtype = (WeaponType) islplasbay.getType(); assertEquals(RangeType.RANGE_MEDIUM, wtype.getMaxRange(islplasbay)); - Mounted ersmlasbay = setupBayWeapon("CLERSmallLaser"); + WeaponMounted ersmlasbay = setupBayWeapon("CLERSmallLaser"); wtype = (WeaponType) ersmlasbay.getType(); assertEquals(RangeType.RANGE_SHORT, wtype.getMaxRange(ersmlasbay)); - Mounted islgaussbay = setupBayWeapon("ISLightGaussRifle"); + WeaponMounted islgaussbay = setupBayWeapon("ISLightGaussRifle"); wtype = (WeaponType) islgaussbay .getType(); assertEquals(RangeType.RANGE_EXTREME, wtype.getMaxRange(islgaussbay )); } diff --git a/megamek/unittests/megamek/common/loaders/MtfFileTest.java b/megamek/unittests/megamek/common/loaders/MtfFileTest.java index 40a74caaa98..ebd6ae78e22 100644 --- a/megamek/unittests/megamek/common/loaders/MtfFileTest.java +++ b/megamek/unittests/megamek/common/loaders/MtfFileTest.java @@ -42,14 +42,14 @@ private MtfFile toMtfFile(Mech mech) throws EntityLoadingException { @Test public void testLoadEquipment() throws Exception { Mech mech = new BipedMech(); - Mounted mount = new Mounted(mech, EquipmentType.get("Medium Laser")); + Mounted mount = Mounted.createMounted(mech, EquipmentType.get("Medium Laser")); mount.setOmniPodMounted(true); mount.setMechTurretMounted(true); mount.setArmored(true); mech.addEquipment(mount, Mech.LOC_LT, true); MtfFile loader = toMtfFile(mech); - Mounted found = loader.getEntity().getCritical(Mech.LOC_LT, 0).getMount(); + Mounted found = loader.getEntity().getCritical(Mech.LOC_LT, 0).getMount(); assertEquals(mount.getType(), found.getType()); assertTrue(found.isRearMounted()); @@ -107,7 +107,7 @@ public void loadSuperheavyVariableSizeSlot() throws Exception { mech.setWeight(150.0); mech.setEngine(new Engine(300, Engine.NORMAL_ENGINE, 0)); EquipmentType commo = EquipmentType.get("CommsGear"); - Mounted mount = mech.addEquipment(commo, Mech.LOC_LT, false); + Mounted mount = mech.addEquipment(commo, Mech.LOC_LT, false); mount.setSize(varSize); MtfFile loader = toMtfFile(mech); @@ -127,7 +127,7 @@ public void ExceptionLoadSuperheavyVariableSizeSlot() throws Exception { mech.setWeight(150.0); mech.setEngine(new Engine(300, Engine.NORMAL_ENGINE, 0)); EquipmentType commo = EquipmentType.get("CommsGear"); - Mounted mount = mech.addEquipment(commo, Mech.LOC_LT, false); + Mounted mount = mech.addEquipment(commo, Mech.LOC_LT, false); mount.setSize(varSize); MtfFile loader = toMtfFile(mech); diff --git a/megamek/unittests/megamek/common/verifier/TestProtoMekTest.java b/megamek/unittests/megamek/common/verifier/TestProtoMekTest.java index 4e833051702..a29751ad11b 100644 --- a/megamek/unittests/megamek/common/verifier/TestProtoMekTest.java +++ b/megamek/unittests/megamek/common/verifier/TestProtoMekTest.java @@ -19,10 +19,12 @@ package megamek.common.verifier; import megamek.common.*; +import megamek.common.equipment.WeaponMounted; import megamek.common.verifier.TestEntity.Ceil; import org.junit.jupiter.api.Test; import java.util.ArrayList; +import java.util.List; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; @@ -43,7 +45,7 @@ private Protomech createGenericMockProtoMek() { return mockProtoMek; } - private TestEntityOption option = new TestEntityOption() { + private final TestEntityOption option = new TestEntityOption() { @Override public Ceil getWeightCeilingEngine() { return Ceil.KILO; @@ -306,9 +308,9 @@ public void testQuadGliderFails() { @Test public void testExcessiveSlots() { Protomech mockProtoMek = createGenericMockProtoMek(); - Mounted m = new Mounted(mockProtoMek, EquipmentType.get("CLERSmallLaser")); + Mounted m = Mounted.createMounted(mockProtoMek, EquipmentType.get("CLERSmallLaser")); m.setLocation(Protomech.LOC_TORSO); - ArrayList eqList = new ArrayList<>(); + List> eqList = new ArrayList<>(); eqList.add(m); when(mockProtoMek.getEquipment()).thenReturn(eqList); TestProtomech test = new TestProtomech(mockProtoMek, option, null); @@ -322,9 +324,9 @@ public void testExcessiveSlots() { public void testNoArmMountsForQuads() { Protomech mockProtoMek = createGenericMockProtoMek(); when(mockProtoMek.isQuad()).thenReturn(true); - Mounted m = new Mounted(mockProtoMek, EquipmentType.get("CLERSmallLaser")); + Mounted m = Mounted.createMounted(mockProtoMek, EquipmentType.get("CLERSmallLaser")); m.setLocation(Protomech.LOC_LARM); - ArrayList eqList = new ArrayList<>(); + List> eqList = new ArrayList<>(); eqList.add(m); when(mockProtoMek.getEquipment()).thenReturn(eqList); TestProtomech test = new TestProtomech(mockProtoMek, option, null); @@ -339,9 +341,9 @@ public void testEDPArmorTakesTorsoSlot() { when(mockProtoMek.locations()).thenReturn(Protomech.NUM_PMECH_LOCATIONS); when(mockProtoMek.getArmorType(anyInt())).thenReturn(EquipmentType.T_ARMOR_EDP); when(mockProtoMek.getArmorTechLevel(anyInt())).thenReturn(TechConstants.T_CLAN_EXPERIMENTAL); - Mounted m = new Mounted(mockProtoMek, EquipmentType.get("CLERSmallLaser")); + Mounted m = Mounted.createMounted(mockProtoMek, EquipmentType.get("CLERSmallLaser")); m.setLocation(Protomech.LOC_TORSO); - ArrayList eqList = new ArrayList<>(); + List> eqList = new ArrayList<>(); eqList.add(m); when(mockProtoMek.getEquipment()).thenReturn(eqList); TestProtomech test = new TestProtomech(mockProtoMek, option, null); @@ -354,8 +356,8 @@ public void testEDPArmorTakesTorsoSlot() { @Test public void testRearMountTorsoOnly() { Protomech mockProtoMek = createGenericMockProtoMek(); - Mounted m = new Mounted(mockProtoMek, EquipmentType.get("CLERSmallLaser")); - ArrayList eqList = new ArrayList<>(); + Mounted m = Mounted.createMounted(mockProtoMek, EquipmentType.get("CLERSmallLaser")); + List> eqList = new ArrayList<>(); eqList.add(m); when(mockProtoMek.getEquipment()).thenReturn(eqList); TestProtomech test = new TestProtomech(mockProtoMek, option, null); @@ -385,16 +387,18 @@ public void testIllegalArmor() { @Test public void testHeatSinkCount() { Protomech mockProtoMek = createGenericMockProtoMek(); - Mounted laser = new Mounted(mockProtoMek, EquipmentType.get("CLERSmallLaser")); + WeaponMounted laser = (WeaponMounted) Mounted.createMounted(mockProtoMek, EquipmentType.get("CLERSmallLaser")); laser.setLocation(Protomech.LOC_TORSO); - ArrayList eqList = new ArrayList<>(); + List> eqList = new ArrayList<>(); + List weaponList = new ArrayList<>(); eqList.add(laser); + weaponList.add(laser); when(mockProtoMek.getEquipment()).thenReturn(eqList); - when(mockProtoMek.getWeaponList()).thenReturn(eqList); + when(mockProtoMek.getWeaponList()).thenReturn(weaponList); TestProtomech test = new TestProtomech(mockProtoMek, option, null); assertEquals(test.getCountHeatSinks(), laser.getType().getHeat()); - eqList.add(new Mounted(mockProtoMek, EquipmentType.get("CLUltraAC5"))); + eqList.add(Mounted.createMounted(mockProtoMek, EquipmentType.get("CLUltraAC5"))); assertEquals(test.getCountHeatSinks(), laser.getType().getHeat()); } }