diff --git a/megamek/src/megamek/client/bot/princess/FireControl.java b/megamek/src/megamek/client/bot/princess/FireControl.java index 60c7257cd35..a8f93ba77e9 100644 --- a/megamek/src/megamek/client/bot/princess/FireControl.java +++ b/megamek/src/megamek/client/bot/princess/FireControl.java @@ -2598,8 +2598,6 @@ FiringPlan getBestFiringPlan(final Entity shooter, ammoConservation); final FiringPlan plan = determineBestFiringPlan(parameters); - LogManager.getLogger().info(shooter.getDisplayName() + " at " + enemy - .getDisplayName() + " - Best Firing Plan: " + plan.getDebugDescription(true)); if ((null == bestPlan) || (plan.getUtility() > bestPlan.getUtility())) { bestPlan = plan; } @@ -3611,7 +3609,7 @@ private int switchMissileMode(Mounted weapon) { * @param wtype that uses ammo that is not tracked, or not actually ammo * @return true if wtype doesn't actually track ammo */ - private static boolean effectivelyAmmoless(WeaponType wtype) { + protected static boolean effectivelyAmmoless(WeaponType wtype) { List atypes = Arrays.asList( AmmoType.T_NA, AmmoType.T_INFANTRY diff --git a/megamek/src/megamek/client/bot/princess/MultiTargetFireControl.java b/megamek/src/megamek/client/bot/princess/MultiTargetFireControl.java index fada0fdab99..6e42bad4461 100644 --- a/megamek/src/megamek/client/bot/princess/MultiTargetFireControl.java +++ b/megamek/src/megamek/client/bot/princess/MultiTargetFireControl.java @@ -21,6 +21,7 @@ import megamek.common.*; import megamek.common.options.OptionsConstants; +import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; /** @@ -111,29 +112,39 @@ WeaponFireInfo getBestShot(Entity shooter, Mounted weapon) { WeaponFireInfo bestShot = null; for (Targetable target : getTargetableEnemyEntities(shooter, owner.getGame(), owner.getFireControlState())) { + WeaponFireInfo betterShot = null; final int ownerID = (target instanceof Entity) ? ((Entity) target).getOwnerId() : -1; if (owner.getHonorUtil().isEnemyBroken(target.getId(), ownerID, owner.getBehaviorSettings().isForcedWithdrawal())) { LogManager.getLogger().info(target.getDisplayName() + " is broken - ignoring"); continue; } - ArrayList ammos; - if (weapon.getBayWeapons().isEmpty()) { - ammos = shooter.getAmmo(weapon); + if (effectivelyAmmoless((WeaponType) weapon.getType())) { + betterShot = buildWeaponFireInfo(shooter, target, weapon, null, owner.getGame(), false); } else { - ammos = new ArrayList<>(); - ammos.add(null); - } + ArrayList ammos; + if (weapon.getBayWeapons().isEmpty()) { + ammos = shooter.getAmmo(weapon); + } else { + ammos = new ArrayList<>(); + ammos.add(null); + } - for (Mounted ammo: ammos) { - WeaponFireInfo shot = buildWeaponFireInfo(shooter, target, weapon, ammo, owner.getGame(), false); + for (Mounted 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 - if ((shot.getExpectedDamage() > 0) && - ((bestShot == null) || (shot.getExpectedDamage() > bestShot.getExpectedDamage()))) { - bestShot = shot; + // this is a better shot if it has a chance of doing damage and the damage is better than the previous best shot + if ((shot.getExpectedDamage() > 0) && + ((betterShot == null) || (shot.getExpectedDamage() > betterShot.getExpectedDamage()))) { + betterShot = shot; + } } } + // Now do the same comparison for the better shot of all these shots to determine the *best* shot + if ((betterShot != null && betterShot.getExpectedDamage() > 0) && + ((bestShot == null) || (betterShot.getExpectedDamage() > bestShot.getExpectedDamage()))) { + bestShot = betterShot; + } } return bestShot; @@ -176,7 +187,7 @@ void calculateUtility(final FiringPlan firingPlan, firingPlan.setUtility(utility); } - FiringPlan calculateFiringPlan(Entity shooter, List weaponList) { + protected FiringPlan calculateFiringPlan(Entity shooter, List weaponList) { FiringPlan retVal = new FiringPlan(); List shotList = new ArrayList<>(); @@ -199,7 +210,7 @@ FiringPlan calculateFiringPlan(Entity shooter, List weaponList) { retVal = calculateIndividualWeaponFiringPlan(shooter, shotList, shooterIsLarge); } - calculateUtility(retVal, calcHeatTolerance(shooter, shooter.isAero()), true); + calculateUtility(retVal, calcHeatTolerance(shooter, shooter.isAero()), shooter.isAero()); return retVal; } diff --git a/megamek/src/megamek/client/bot/princess/Princess.java b/megamek/src/megamek/client/bot/princess/Princess.java index f0a4804dbbb..eb12240b300 100644 --- a/megamek/src/megamek/client/bot/princess/Princess.java +++ b/megamek/src/megamek/client/bot/princess/Princess.java @@ -40,8 +40,10 @@ import megamek.common.util.StringUtil; import megamek.common.weapons.AmmoWeapon; import megamek.common.weapons.StopSwarmAttack; +import org.apache.commons.logging.impl.Log4JLogger; import org.apache.logging.log4j.Level; import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.io.File; import java.text.DecimalFormat; @@ -552,13 +554,14 @@ private int calculateTurretDeploymentValue(final Coords coords) { @Override protected void calculateFiringTurn() { final Entity shooter; + final Logger logger = LogManager.getLogger(); try { // get the first entity that can act this turn make sure weapons // are loaded shooter = getEntityToFire(fireControlState); } catch (Exception e) { // If we fail to get the shooter, literally nothing can be done. - LogManager.getLogger().error(e.getMessage(), e); + logger.error(e.getMessage(), e); return; } @@ -587,13 +590,13 @@ protected void calculateFiringTurn() { skipFiring = true; } } finally { - LogManager.getLogger().info(msg.toString()); + logger.info(msg.toString()); } } if (shooter.isHidden()) { skipFiring = true; - LogManager.getLogger().info("Hidden unit skips firing."); + logger.info("Hidden unit skips firing."); } // calculating a firing plan is somewhat expensive, so @@ -609,8 +612,11 @@ protected void calculateFiringTurn() { getFireControl(shooter).loadAmmo(shooter, plan); plan.sortPlan(); - LogManager.getLogger().info(shooter.getDisplayName() + " - Best Firing Plan: " + - plan.getDebugDescription(LogManager.getLogger().getLevel().isLessSpecificThan(Level.DEBUG))); + // Log info and debug at different levels + logger.info(shooter.getDisplayName() + " - Best Firing Plan: " + + plan.getDebugDescription(false)); + logger.debug(shooter.getDisplayName() + " - Detailed Best Firing Plan: " + + plan.getDebugDescription(true)); // Add expected damage from the chosen FiringPlan to the // damageMap for the target enemy. @@ -645,7 +651,7 @@ protected void calculateFiringTurn() { sendAttackData(shooter.getId(), actions); return; } else { - LogManager.getLogger().info("No best firing plan for " + shooter.getDisplayName()); + logger.info("No best firing plan for " + shooter.getDisplayName()); } } @@ -661,7 +667,7 @@ protected void calculateFiringTurn() { .findFirst() .orElse(null); if (stopSwarmWeapon == null) { - LogManager.getLogger().error("Failed to find a Stop Swarm Weapon while Swarming a unit, which should not be possible."); + logger.error("Failed to find a Stop Swarm Weapon while Swarming a unit, which should not be possible."); } else { miscPlan = new Vector<>(); miscPlan.add(new WeaponAttackAction(shooter.getId(), shooter.getSwarmTargetId(), @@ -698,7 +704,7 @@ protected void calculateFiringTurn() { sendAttackData(shooter.getId(), miscPlan); } catch (Exception e) { - LogManager.getLogger().error(e.getMessage(), e); + logger.error(e.getMessage(), e); // Don't lock up, just skip this entity. Vector fallback = new Vector<>(); sendAttackData(shooter.getId(), fallback);