From f974aa886677b52b424ccf9fffb38bbffd90c5de Mon Sep 17 00:00:00 2001 From: psikomonkie <189469115+psikomonkie@users.noreply.github.com> Date: Sun, 15 Dec 2024 17:17:08 -0500 Subject: [PATCH 1/9] Issue 4259: Fixing Dropship Heat-by-Arc, updated Princess and forced grounded dropships to use individual weapons with heat-by-arc --- .../bot/princess/MultiTargetFireControl.java | 51 +++++++++++++++---- .../ui/swing/unitDisplay/WeaponPanel.java | 19 ++++--- megamek/src/megamek/common/Entity.java | 1 + .../common/actions/WeaponAttackAction.java | 50 +++++++++++------- .../megamek/common/weapons/WeaponHandler.java | 39 ++++++++++++-- 5 files changed, 117 insertions(+), 43 deletions(-) diff --git a/megamek/src/megamek/client/bot/princess/MultiTargetFireControl.java b/megamek/src/megamek/client/bot/princess/MultiTargetFireControl.java index 4b7e9736b58..7963399234a 100644 --- a/megamek/src/megamek/client/bot/princess/MultiTargetFireControl.java +++ b/megamek/src/megamek/client/bot/princess/MultiTargetFireControl.java @@ -26,6 +26,7 @@ import megamek.common.Entity; import megamek.common.Game; +import megamek.common.Mounted; import megamek.common.Targetable; import megamek.common.equipment.AmmoMounted; import megamek.common.equipment.WeaponMounted; @@ -259,6 +260,26 @@ FiringPlan calculatePerArcFiringPlan(Entity shooter, List shotLi // damage values by arc: arc #, arc damage Map arcDamage = new HashMap<>(); + int heatCapacity = shooter.getHeatCapacity(); + shooter.getWeapons(); + shooter.getWeaponList(); + logger.error(String.format("Weapons Length: %s", shooter.getWeaponList().size())); + for ( WeaponMounted weapon : shooter.getWeaponList()){ + + } + for ( WeaponMounted weapon : shooter.getWeaponList().stream().filter(Mounted::isUsedThisRound).toList()){ + logger.error(String.format("Weapon in list: %s", weapon.getName())); + int arc = weapon.isRearMounted() ? -shooter.getWeaponArc(weapon.getLocation()) : shooter.getWeaponArc(weapon.getLocation()); + if (!arcShots.containsKey(arc)) { + heatCapacity -= shooter.getHeatInArc(weapon.getLocation(), weapon.isRearMounted()); + arcShots.put(arc, new ArrayList<>()); + arcHeat.put(arc, 0); + arcDamage.put(arc, 1.0); + + logger.error(String.format("Arc: %s Heat: %s", arc, arcHeat.get(arc))); + } + } + // assemble the data we'll need to solve the backpack problem for (WeaponFireInfo shot : shotList) { int arc = shooter.getWeaponArc(shooter.getEquipmentNum(shot.getWeapon())); @@ -267,44 +288,51 @@ FiringPlan calculatePerArcFiringPlan(Entity shooter, List shotLi arc = -arc; } + logger.error(String.format("Shot: %s Rear: %s Arc: %s Raw arc: %s", shot.getWeapon().getName(), shot.getWeapon().isRearMounted(), arc,shooter.getWeaponArc(shooter.getEquipmentNum(shot.getWeapon())) )); + if (!arcShots.containsKey(arc)) { arcShots.put(arc, new ArrayList<>()); arcHeat.put(arc, shooter.getHeatInArc(shot.getWeapon().getLocation(), shot.getWeapon().isRearMounted())); arcDamage.put(arc, 0.0); + + logger.error(String.format("Arc: %s Heat: %s", arc, arcHeat.get(arc))); } arcShots.get(arc).add(shot); arcDamage.put(arc, arcDamage.get(arc) + shot.getExpectedDamage()); + logger.error(String.format("Arc: %s Damage: %s", arc, arcDamage.get(arc))); } // initialize the backpack Map>> arcBackpack = new HashMap<>(); - for (int x = 0; x < arcShots.keySet().size(); x++) { + for (int x = 0; x <= arcShots.keySet().size(); x++) { arcBackpack.put(x, new HashMap<>()); - for (int y = 0; y < shooter.getHeatCapacity(); y++) { + for (int y = 0; y <= heatCapacity; y++) { arcBackpack.get(x).put(y, new ArrayList<>()); } } - double[][] damageBackpack = new double[arcShots.keySet().size()][shooter.getHeatCapacity()]; + double[][] damageBackpack = new double[arcShots.keySet().size() + 1][heatCapacity + 1]; Integer[] arcHeatKeyArray = new Integer[arcHeat.keySet().size()]; System.arraycopy(arcHeat.keySet().toArray(), 0, arcHeatKeyArray, 0, arcHeat.keySet().size()); + logger.error(String.format("Heat Key Array Length: %s Attempted Output: %s", arcHeatKeyArray.length, arcHeatKeyArray)); + // now, we essentially solve the backpack problem, where the arcs are the items: // arc expected damage is the "value", and arc heat is the "weight", while the // backpack capacity is the unit's heat capacity. // while we're at it, we assemble the list of arcs fired for each cell - for (int arcIndex = 0; arcIndex < arcHeatKeyArray.length; arcIndex++) { - for (int heatIndex = 0; heatIndex < shooter.getHeatCapacity(); heatIndex++) { - int previousArc = arcIndex > 0 ? arcHeatKeyArray[arcIndex - 1] : 0; + for (int arcIndex = 0; arcIndex <= arcHeatKeyArray.length; arcIndex++) { + for (int heatIndex = 0; heatIndex <= heatCapacity; heatIndex++) { + int currentArc = arcIndex > 0 ? arcHeatKeyArray[arcIndex - 1] : 0; if (arcIndex == 0 || heatIndex == 0) { damageBackpack[arcIndex][heatIndex] = 0; - } else if (arcHeat.get(previousArc) <= heatIndex) { - int previousHeatIndex = heatIndex - arcHeat.get(previousArc); - double currentArcDamage = arcDamage.get(previousArc) + } else if (arcHeat.get(currentArc) <= heatIndex) { + int previousHeatIndex = heatIndex - arcHeat.get(currentArc); + double currentArcDamage = arcDamage.get(currentArc) + damageBackpack[arcIndex - 1][previousHeatIndex]; double accumulatedPreviousArcDamage = damageBackpack[arcIndex - 1][heatIndex]; @@ -315,7 +343,7 @@ FiringPlan calculatePerArcFiringPlan(Entity shooter, List shotLi // make sure we don't accidentally update the cell we're examining List appendedArcList = new ArrayList<>( arcBackpack.get(arcIndex - 1).get(previousHeatIndex)); - appendedArcList.add(previousArc); + appendedArcList.add(currentArc); arcBackpack.get(arcIndex).put(heatIndex, appendedArcList); } else { // we *can* add this arc to the list, but it won't take us past the damage @@ -336,7 +364,8 @@ FiringPlan calculatePerArcFiringPlan(Entity shooter, List shotLi // solution // unless there is no firing solution at all, in which case we skip this part if (!arcBackpack.isEmpty()) { - for (int arc : arcBackpack.get(arcBackpack.size() - 1).get(shooter.getHeatCapacity() - 1)) { + for (int arc : arcBackpack.get(arcBackpack.size() - 1).get(heatCapacity - 1)) { + logger.error(String.format("final arc: %s", arc)); retVal.addAll(arcShots.get(arc)); } } diff --git a/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java b/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java index db9153b3e45..7d05c009f53 100644 --- a/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java +++ b/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java @@ -1195,12 +1195,10 @@ public void displayMek(Entity en) { && game.getPhase().isFiring()) { hasFiredWeapons = true; // add heat from weapons fire to heat tracker - if (entity.usesWeaponBays()) { + if (entity.isLargeCraft()) { // if using bay heat option then don't add total arc if (game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY)) { - for (WeaponMounted weapon : mounted.getBayWeapons()) { - currentHeatBuildup += weapon.getCurrentHeat(); - } + currentHeatBuildup += mounted.getCurrentHeat(); } else { // check whether arc has fired int loc = mounted.getLocation(); @@ -1257,17 +1255,22 @@ public void displayMek(Entity en) { // change what is visible based on type if (entity.usesWeaponBays()) { - wArcHeatL.setVisible(true); - wArcHeatR.setVisible(true); m_chBayWeapon.setVisible(true); wBayWeapon.setVisible(true); } else { - wArcHeatL.setVisible(false); - wArcHeatR.setVisible(false); m_chBayWeapon.setVisible(false); wBayWeapon.setVisible(false); } + if (entity.isLargeCraft()) { + wArcHeatL.setVisible(true); + wArcHeatR.setVisible(true); + } + else { + wArcHeatL.setVisible(false); + wArcHeatR.setVisible(false); + } + wDamageTrooperL.setVisible(false); wDamageTrooperR.setVisible(false); wInfantryRange0L.setVisible(false); diff --git a/megamek/src/megamek/common/Entity.java b/megamek/src/megamek/common/Entity.java index 9ec423ce322..70e0808c493 100644 --- a/megamek/src/megamek/common/Entity.java +++ b/megamek/src/megamek/common/Entity.java @@ -11636,6 +11636,7 @@ public int getHeatInArc(int location, boolean rearMount) { if ((mounted.getLocation() == location) && (mounted.isRearMounted() == rearMount)) { arcHeat += mounted.getCurrentHeat(); + logger.error(String.format("Location: %s Rear Mount: %s Weapon: %s Heat: %s Arc Heat %s", location, rearMount, mounted.getName(), mounted.getCurrentHeat(), arcHeat)); } } return arcHeat; diff --git a/megamek/src/megamek/common/actions/WeaponAttackAction.java b/megamek/src/megamek/common/actions/WeaponAttackAction.java index 1876be5a9cc..42a7ee83390 100644 --- a/megamek/src/megamek/common/actions/WeaponAttackAction.java +++ b/megamek/src/megamek/common/actions/WeaponAttackAction.java @@ -1486,28 +1486,30 @@ private static String toHitIsImpossible(Game game, Entity ae, int attackerId, Ta // limit large craft to zero net heat and to heat by arc final int heatCapacity = ae.getHeatCapacity(); - if (ae.usesWeaponBays() && (weapon != null) && !weapon.getBayWeapons().isEmpty()) { + if (ae.isLargeCraft() && (weapon != null)) { int totalHeat = 0; - // first check to see if there are any usable weapons - boolean usable = false; - for (WeaponMounted m : weapon.getBayWeapons()) { - WeaponType bayWType = m.getType(); - boolean bayWUsesAmmo = (bayWType.getAmmoType() != AmmoType.T_NA); - if (m.canFire()) { - if (bayWUsesAmmo) { - if ((m.getLinked() != null) && (m.getLinked().getUsableShotsLeft() > 0)) { + // first check to see if there are any usable bay weapons + if (!weapon.getBayWeapons().isEmpty()) { + boolean usable = false; + for (WeaponMounted m : weapon.getBayWeapons()) { + WeaponType bayWType = m.getType(); + boolean bayWUsesAmmo = (bayWType.getAmmoType() != AmmoType.T_NA); + if (m.canFire()) { + if (bayWUsesAmmo) { + if ((m.getLinked() != null) && (m.getLinked().getUsableShotsLeft() > 0)) { + usable = true; + break; + } + } else { usable = true; break; } - } else { - usable = true; - break; } } - } - if (!usable) { - return Messages.getString("WeaponAttackAction.BayNotReady"); + if (!usable) { + return Messages.getString("WeaponAttackAction.BayNotReady"); + } } // create an array of booleans of locations @@ -1534,8 +1536,13 @@ private static String toHitIsImpossible(Game game, Entity ae, int attackerId, Ta int loc = prevWeapon.getLocation(); boolean rearMount = prevWeapon.isRearMounted(); if (game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY)) { - for (WeaponMounted bWeapon : prevWeapon.getBayWeapons()) { - totalHeat += bWeapon.getCurrentHeat(); + if (!weapon.getBayWeapons().isEmpty()) { + for (WeaponMounted bWeapon : prevWeapon.getBayWeapons()) { + totalHeat += bWeapon.getCurrentHeat(); + } + } + else { + totalHeat += prevWeapon.getCurrentHeat(); } } else { if (!rearMount) { @@ -1560,8 +1567,13 @@ private static String toHitIsImpossible(Game game, Entity ae, int attackerId, Ta int currentHeat = ae.getHeatInArc(loc, rearMount); if (game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY)) { currentHeat = 0; - for (WeaponMounted bWeapon : weapon.getBayWeapons()) { - currentHeat += bWeapon.getCurrentHeat(); + if (!weapon.getBayWeapons().isEmpty()) { + for (WeaponMounted bWeapon : weapon.getBayWeapons()) { + currentHeat += bWeapon.getCurrentHeat(); + } + } + else { + currentHeat += weapon.getCurrentHeat(); } } // check to see if this is currently the only arc being fired diff --git a/megamek/src/megamek/common/weapons/WeaponHandler.java b/megamek/src/megamek/common/weapons/WeaponHandler.java index dedba430824..bbad25266e0 100644 --- a/megamek/src/megamek/common/weapons/WeaponHandler.java +++ b/megamek/src/megamek/common/weapons/WeaponHandler.java @@ -153,7 +153,7 @@ public int getSalvoBonus() { * TeleMissile entity in the physical phase */ protected int getLargeCraftHeat(Entity e) { - int totalheat = 0; + int totalHeat = 0; if (e.hasETypeFlag(Entity.ETYPE_DROPSHIP) || e.hasETypeFlag(Entity.ETYPE_JUMPSHIP)) { if (e.usesWeaponBays()) { @@ -163,7 +163,35 @@ protected int getLargeCraftHeat(Entity e) { if (prevAttack.getEntityId() == e.getId()) { WeaponMounted prevWeapon = (WeaponMounted) e.getEquipment(prevAttack.getWeaponId()); for (WeaponMounted bayW : prevWeapon.getBayWeapons()) { - totalheat += bayW.getCurrentHeat(); + totalHeat += bayW.getCurrentHeat(); + } + } + } + } else if (!game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY)) { + // create an array of booleans of locations + boolean[] usedFrontArc = new boolean[ae.locations()]; + boolean[] usedRearArc = new boolean[ae.locations()]; + for (int i = 0; i < ae.locations(); i++) { + usedFrontArc[i] = false; + usedRearArc[i] = false; + } + for (Enumeration i = game.getAttacks(); i.hasMoreElements();) { + AttackHandler ah = i.nextElement(); + WeaponAttackAction prevAttack = ah.getWaa(); + if (prevAttack.getEntityId() == e.getId()) { + WeaponMounted prevWeapon = (WeaponMounted) e.getEquipment(prevAttack.getWeaponId()); + boolean rearMount = prevWeapon.isRearMounted(); + int loc = prevWeapon.getLocation(); + if (!rearMount) { + if (!usedFrontArc[loc]) { + totalHeat += ae.getHeatInArc(loc, rearMount); + usedFrontArc[loc] = true; + } + } else { + if (!usedRearArc[loc]) { + totalHeat += ae.getHeatInArc(loc, rearMount); + usedRearArc[loc] = true; + } } } } @@ -173,12 +201,12 @@ protected int getLargeCraftHeat(Entity e) { WeaponAttackAction prevAttack = ah.getWaa(); if (prevAttack.getEntityId() == e.getId()) { Mounted prevWeapon = e.getEquipment(prevAttack.getWeaponId()); - totalheat += prevWeapon.getCurrentHeat(); + totalHeat += prevWeapon.getCurrentHeat(); } } } } - return totalheat; + return totalHeat; } /** @@ -1903,12 +1931,13 @@ protected void addHeat() { return; } if (!(toHit.getValue() == TargetRoll.IMPOSSIBLE)) { - if (ae.usesWeaponBays() && !game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY)) { + if (ae.isLargeCraft() && !game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY)) { int loc = weapon.getLocation(); boolean rearMount = weapon.isRearMounted(); if (!ae.hasArcFired(loc, rearMount)) { ae.heatBuildup += ae.getHeatInArc(loc, rearMount); ae.setArcFired(loc, rearMount); + logger.error(String.format("Arc Heat: %s Buildup: %s", ae.getHeatInArc(loc, rearMount), ae.heatBuildup)); } } else { ae.heatBuildup += (weapon.getCurrentHeat()); From 1075861a75937de4d34ff395bf9ab243aab091c9 Mon Sep 17 00:00:00 2001 From: psikomonkie <189469115+psikomonkie@users.noreply.github.com> Date: Sun, 15 Dec 2024 17:17:08 -0500 Subject: [PATCH 2/9] Issue 4259: Fixing Dropship Heat-by-Arc, updated Princess and forced grounded dropships to use individual weapons with heat-by-arc --- .../bot/princess/MultiTargetFireControl.java | 51 +++++++++++++++---- .../ui/swing/unitDisplay/WeaponPanel.java | 19 ++++--- megamek/src/megamek/common/Entity.java | 1 + .../common/actions/WeaponAttackAction.java | 50 +++++++++++------- .../megamek/common/weapons/WeaponHandler.java | 39 ++++++++++++-- 5 files changed, 117 insertions(+), 43 deletions(-) diff --git a/megamek/src/megamek/client/bot/princess/MultiTargetFireControl.java b/megamek/src/megamek/client/bot/princess/MultiTargetFireControl.java index 4b7e9736b58..7963399234a 100644 --- a/megamek/src/megamek/client/bot/princess/MultiTargetFireControl.java +++ b/megamek/src/megamek/client/bot/princess/MultiTargetFireControl.java @@ -26,6 +26,7 @@ import megamek.common.Entity; import megamek.common.Game; +import megamek.common.Mounted; import megamek.common.Targetable; import megamek.common.equipment.AmmoMounted; import megamek.common.equipment.WeaponMounted; @@ -259,6 +260,26 @@ FiringPlan calculatePerArcFiringPlan(Entity shooter, List shotLi // damage values by arc: arc #, arc damage Map arcDamage = new HashMap<>(); + int heatCapacity = shooter.getHeatCapacity(); + shooter.getWeapons(); + shooter.getWeaponList(); + logger.error(String.format("Weapons Length: %s", shooter.getWeaponList().size())); + for ( WeaponMounted weapon : shooter.getWeaponList()){ + + } + for ( WeaponMounted weapon : shooter.getWeaponList().stream().filter(Mounted::isUsedThisRound).toList()){ + logger.error(String.format("Weapon in list: %s", weapon.getName())); + int arc = weapon.isRearMounted() ? -shooter.getWeaponArc(weapon.getLocation()) : shooter.getWeaponArc(weapon.getLocation()); + if (!arcShots.containsKey(arc)) { + heatCapacity -= shooter.getHeatInArc(weapon.getLocation(), weapon.isRearMounted()); + arcShots.put(arc, new ArrayList<>()); + arcHeat.put(arc, 0); + arcDamage.put(arc, 1.0); + + logger.error(String.format("Arc: %s Heat: %s", arc, arcHeat.get(arc))); + } + } + // assemble the data we'll need to solve the backpack problem for (WeaponFireInfo shot : shotList) { int arc = shooter.getWeaponArc(shooter.getEquipmentNum(shot.getWeapon())); @@ -267,44 +288,51 @@ FiringPlan calculatePerArcFiringPlan(Entity shooter, List shotLi arc = -arc; } + logger.error(String.format("Shot: %s Rear: %s Arc: %s Raw arc: %s", shot.getWeapon().getName(), shot.getWeapon().isRearMounted(), arc,shooter.getWeaponArc(shooter.getEquipmentNum(shot.getWeapon())) )); + if (!arcShots.containsKey(arc)) { arcShots.put(arc, new ArrayList<>()); arcHeat.put(arc, shooter.getHeatInArc(shot.getWeapon().getLocation(), shot.getWeapon().isRearMounted())); arcDamage.put(arc, 0.0); + + logger.error(String.format("Arc: %s Heat: %s", arc, arcHeat.get(arc))); } arcShots.get(arc).add(shot); arcDamage.put(arc, arcDamage.get(arc) + shot.getExpectedDamage()); + logger.error(String.format("Arc: %s Damage: %s", arc, arcDamage.get(arc))); } // initialize the backpack Map>> arcBackpack = new HashMap<>(); - for (int x = 0; x < arcShots.keySet().size(); x++) { + for (int x = 0; x <= arcShots.keySet().size(); x++) { arcBackpack.put(x, new HashMap<>()); - for (int y = 0; y < shooter.getHeatCapacity(); y++) { + for (int y = 0; y <= heatCapacity; y++) { arcBackpack.get(x).put(y, new ArrayList<>()); } } - double[][] damageBackpack = new double[arcShots.keySet().size()][shooter.getHeatCapacity()]; + double[][] damageBackpack = new double[arcShots.keySet().size() + 1][heatCapacity + 1]; Integer[] arcHeatKeyArray = new Integer[arcHeat.keySet().size()]; System.arraycopy(arcHeat.keySet().toArray(), 0, arcHeatKeyArray, 0, arcHeat.keySet().size()); + logger.error(String.format("Heat Key Array Length: %s Attempted Output: %s", arcHeatKeyArray.length, arcHeatKeyArray)); + // now, we essentially solve the backpack problem, where the arcs are the items: // arc expected damage is the "value", and arc heat is the "weight", while the // backpack capacity is the unit's heat capacity. // while we're at it, we assemble the list of arcs fired for each cell - for (int arcIndex = 0; arcIndex < arcHeatKeyArray.length; arcIndex++) { - for (int heatIndex = 0; heatIndex < shooter.getHeatCapacity(); heatIndex++) { - int previousArc = arcIndex > 0 ? arcHeatKeyArray[arcIndex - 1] : 0; + for (int arcIndex = 0; arcIndex <= arcHeatKeyArray.length; arcIndex++) { + for (int heatIndex = 0; heatIndex <= heatCapacity; heatIndex++) { + int currentArc = arcIndex > 0 ? arcHeatKeyArray[arcIndex - 1] : 0; if (arcIndex == 0 || heatIndex == 0) { damageBackpack[arcIndex][heatIndex] = 0; - } else if (arcHeat.get(previousArc) <= heatIndex) { - int previousHeatIndex = heatIndex - arcHeat.get(previousArc); - double currentArcDamage = arcDamage.get(previousArc) + } else if (arcHeat.get(currentArc) <= heatIndex) { + int previousHeatIndex = heatIndex - arcHeat.get(currentArc); + double currentArcDamage = arcDamage.get(currentArc) + damageBackpack[arcIndex - 1][previousHeatIndex]; double accumulatedPreviousArcDamage = damageBackpack[arcIndex - 1][heatIndex]; @@ -315,7 +343,7 @@ FiringPlan calculatePerArcFiringPlan(Entity shooter, List shotLi // make sure we don't accidentally update the cell we're examining List appendedArcList = new ArrayList<>( arcBackpack.get(arcIndex - 1).get(previousHeatIndex)); - appendedArcList.add(previousArc); + appendedArcList.add(currentArc); arcBackpack.get(arcIndex).put(heatIndex, appendedArcList); } else { // we *can* add this arc to the list, but it won't take us past the damage @@ -336,7 +364,8 @@ FiringPlan calculatePerArcFiringPlan(Entity shooter, List shotLi // solution // unless there is no firing solution at all, in which case we skip this part if (!arcBackpack.isEmpty()) { - for (int arc : arcBackpack.get(arcBackpack.size() - 1).get(shooter.getHeatCapacity() - 1)) { + for (int arc : arcBackpack.get(arcBackpack.size() - 1).get(heatCapacity - 1)) { + logger.error(String.format("final arc: %s", arc)); retVal.addAll(arcShots.get(arc)); } } diff --git a/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java b/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java index db9153b3e45..7d05c009f53 100644 --- a/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java +++ b/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java @@ -1195,12 +1195,10 @@ public void displayMek(Entity en) { && game.getPhase().isFiring()) { hasFiredWeapons = true; // add heat from weapons fire to heat tracker - if (entity.usesWeaponBays()) { + if (entity.isLargeCraft()) { // if using bay heat option then don't add total arc if (game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY)) { - for (WeaponMounted weapon : mounted.getBayWeapons()) { - currentHeatBuildup += weapon.getCurrentHeat(); - } + currentHeatBuildup += mounted.getCurrentHeat(); } else { // check whether arc has fired int loc = mounted.getLocation(); @@ -1257,17 +1255,22 @@ public void displayMek(Entity en) { // change what is visible based on type if (entity.usesWeaponBays()) { - wArcHeatL.setVisible(true); - wArcHeatR.setVisible(true); m_chBayWeapon.setVisible(true); wBayWeapon.setVisible(true); } else { - wArcHeatL.setVisible(false); - wArcHeatR.setVisible(false); m_chBayWeapon.setVisible(false); wBayWeapon.setVisible(false); } + if (entity.isLargeCraft()) { + wArcHeatL.setVisible(true); + wArcHeatR.setVisible(true); + } + else { + wArcHeatL.setVisible(false); + wArcHeatR.setVisible(false); + } + wDamageTrooperL.setVisible(false); wDamageTrooperR.setVisible(false); wInfantryRange0L.setVisible(false); diff --git a/megamek/src/megamek/common/Entity.java b/megamek/src/megamek/common/Entity.java index b5c25bfb492..e7da0f147b2 100644 --- a/megamek/src/megamek/common/Entity.java +++ b/megamek/src/megamek/common/Entity.java @@ -11631,6 +11631,7 @@ public int getHeatInArc(int location, boolean rearMount) { if ((mounted.getLocation() == location) && (mounted.isRearMounted() == rearMount)) { arcHeat += mounted.getCurrentHeat(); + logger.error(String.format("Location: %s Rear Mount: %s Weapon: %s Heat: %s Arc Heat %s", location, rearMount, mounted.getName(), mounted.getCurrentHeat(), arcHeat)); } } return arcHeat; diff --git a/megamek/src/megamek/common/actions/WeaponAttackAction.java b/megamek/src/megamek/common/actions/WeaponAttackAction.java index 1876be5a9cc..42a7ee83390 100644 --- a/megamek/src/megamek/common/actions/WeaponAttackAction.java +++ b/megamek/src/megamek/common/actions/WeaponAttackAction.java @@ -1486,28 +1486,30 @@ private static String toHitIsImpossible(Game game, Entity ae, int attackerId, Ta // limit large craft to zero net heat and to heat by arc final int heatCapacity = ae.getHeatCapacity(); - if (ae.usesWeaponBays() && (weapon != null) && !weapon.getBayWeapons().isEmpty()) { + if (ae.isLargeCraft() && (weapon != null)) { int totalHeat = 0; - // first check to see if there are any usable weapons - boolean usable = false; - for (WeaponMounted m : weapon.getBayWeapons()) { - WeaponType bayWType = m.getType(); - boolean bayWUsesAmmo = (bayWType.getAmmoType() != AmmoType.T_NA); - if (m.canFire()) { - if (bayWUsesAmmo) { - if ((m.getLinked() != null) && (m.getLinked().getUsableShotsLeft() > 0)) { + // first check to see if there are any usable bay weapons + if (!weapon.getBayWeapons().isEmpty()) { + boolean usable = false; + for (WeaponMounted m : weapon.getBayWeapons()) { + WeaponType bayWType = m.getType(); + boolean bayWUsesAmmo = (bayWType.getAmmoType() != AmmoType.T_NA); + if (m.canFire()) { + if (bayWUsesAmmo) { + if ((m.getLinked() != null) && (m.getLinked().getUsableShotsLeft() > 0)) { + usable = true; + break; + } + } else { usable = true; break; } - } else { - usable = true; - break; } } - } - if (!usable) { - return Messages.getString("WeaponAttackAction.BayNotReady"); + if (!usable) { + return Messages.getString("WeaponAttackAction.BayNotReady"); + } } // create an array of booleans of locations @@ -1534,8 +1536,13 @@ private static String toHitIsImpossible(Game game, Entity ae, int attackerId, Ta int loc = prevWeapon.getLocation(); boolean rearMount = prevWeapon.isRearMounted(); if (game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY)) { - for (WeaponMounted bWeapon : prevWeapon.getBayWeapons()) { - totalHeat += bWeapon.getCurrentHeat(); + if (!weapon.getBayWeapons().isEmpty()) { + for (WeaponMounted bWeapon : prevWeapon.getBayWeapons()) { + totalHeat += bWeapon.getCurrentHeat(); + } + } + else { + totalHeat += prevWeapon.getCurrentHeat(); } } else { if (!rearMount) { @@ -1560,8 +1567,13 @@ private static String toHitIsImpossible(Game game, Entity ae, int attackerId, Ta int currentHeat = ae.getHeatInArc(loc, rearMount); if (game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY)) { currentHeat = 0; - for (WeaponMounted bWeapon : weapon.getBayWeapons()) { - currentHeat += bWeapon.getCurrentHeat(); + if (!weapon.getBayWeapons().isEmpty()) { + for (WeaponMounted bWeapon : weapon.getBayWeapons()) { + currentHeat += bWeapon.getCurrentHeat(); + } + } + else { + currentHeat += weapon.getCurrentHeat(); } } // check to see if this is currently the only arc being fired diff --git a/megamek/src/megamek/common/weapons/WeaponHandler.java b/megamek/src/megamek/common/weapons/WeaponHandler.java index dedba430824..bbad25266e0 100644 --- a/megamek/src/megamek/common/weapons/WeaponHandler.java +++ b/megamek/src/megamek/common/weapons/WeaponHandler.java @@ -153,7 +153,7 @@ public int getSalvoBonus() { * TeleMissile entity in the physical phase */ protected int getLargeCraftHeat(Entity e) { - int totalheat = 0; + int totalHeat = 0; if (e.hasETypeFlag(Entity.ETYPE_DROPSHIP) || e.hasETypeFlag(Entity.ETYPE_JUMPSHIP)) { if (e.usesWeaponBays()) { @@ -163,7 +163,35 @@ protected int getLargeCraftHeat(Entity e) { if (prevAttack.getEntityId() == e.getId()) { WeaponMounted prevWeapon = (WeaponMounted) e.getEquipment(prevAttack.getWeaponId()); for (WeaponMounted bayW : prevWeapon.getBayWeapons()) { - totalheat += bayW.getCurrentHeat(); + totalHeat += bayW.getCurrentHeat(); + } + } + } + } else if (!game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY)) { + // create an array of booleans of locations + boolean[] usedFrontArc = new boolean[ae.locations()]; + boolean[] usedRearArc = new boolean[ae.locations()]; + for (int i = 0; i < ae.locations(); i++) { + usedFrontArc[i] = false; + usedRearArc[i] = false; + } + for (Enumeration i = game.getAttacks(); i.hasMoreElements();) { + AttackHandler ah = i.nextElement(); + WeaponAttackAction prevAttack = ah.getWaa(); + if (prevAttack.getEntityId() == e.getId()) { + WeaponMounted prevWeapon = (WeaponMounted) e.getEquipment(prevAttack.getWeaponId()); + boolean rearMount = prevWeapon.isRearMounted(); + int loc = prevWeapon.getLocation(); + if (!rearMount) { + if (!usedFrontArc[loc]) { + totalHeat += ae.getHeatInArc(loc, rearMount); + usedFrontArc[loc] = true; + } + } else { + if (!usedRearArc[loc]) { + totalHeat += ae.getHeatInArc(loc, rearMount); + usedRearArc[loc] = true; + } } } } @@ -173,12 +201,12 @@ protected int getLargeCraftHeat(Entity e) { WeaponAttackAction prevAttack = ah.getWaa(); if (prevAttack.getEntityId() == e.getId()) { Mounted prevWeapon = e.getEquipment(prevAttack.getWeaponId()); - totalheat += prevWeapon.getCurrentHeat(); + totalHeat += prevWeapon.getCurrentHeat(); } } } } - return totalheat; + return totalHeat; } /** @@ -1903,12 +1931,13 @@ protected void addHeat() { return; } if (!(toHit.getValue() == TargetRoll.IMPOSSIBLE)) { - if (ae.usesWeaponBays() && !game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY)) { + if (ae.isLargeCraft() && !game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY)) { int loc = weapon.getLocation(); boolean rearMount = weapon.isRearMounted(); if (!ae.hasArcFired(loc, rearMount)) { ae.heatBuildup += ae.getHeatInArc(loc, rearMount); ae.setArcFired(loc, rearMount); + logger.error(String.format("Arc Heat: %s Buildup: %s", ae.getHeatInArc(loc, rearMount), ae.heatBuildup)); } } else { ae.heatBuildup += (weapon.getCurrentHeat()); From 75f81dad5a26a07ad6d3e7d5367424c06f70be6e Mon Sep 17 00:00:00 2001 From: psikomonkie <189469115+psikomonkie@users.noreply.github.com> Date: Mon, 16 Dec 2024 12:56:25 -0500 Subject: [PATCH 3/9] Issue 4259: Fixing Dropship Heat-by-Arc for Players and Princess - Cleanup --- .../bot/princess/MultiTargetFireControl.java | 21 +---- .../ui/swing/unitDisplay/WeaponPanel.java | 2 +- megamek/src/megamek/common/Entity.java | 1 - .../common/actions/WeaponAttackAction.java | 18 +---- .../common/equipment/WeaponMounted.java | 14 ++++ .../megamek/common/weapons/WeaponHandler.java | 81 ++++++++----------- 6 files changed, 53 insertions(+), 84 deletions(-) diff --git a/megamek/src/megamek/client/bot/princess/MultiTargetFireControl.java b/megamek/src/megamek/client/bot/princess/MultiTargetFireControl.java index 7963399234a..b7dbfd3dd34 100644 --- a/megamek/src/megamek/client/bot/princess/MultiTargetFireControl.java +++ b/megamek/src/megamek/client/bot/princess/MultiTargetFireControl.java @@ -261,22 +261,15 @@ FiringPlan calculatePerArcFiringPlan(Entity shooter, List shotLi Map arcDamage = new HashMap<>(); int heatCapacity = shooter.getHeatCapacity(); - shooter.getWeapons(); - shooter.getWeaponList(); - logger.error(String.format("Weapons Length: %s", shooter.getWeaponList().size())); - for ( WeaponMounted weapon : shooter.getWeaponList()){ - - } - for ( WeaponMounted weapon : shooter.getWeaponList().stream().filter(Mounted::isUsedThisRound).toList()){ - logger.error(String.format("Weapon in list: %s", weapon.getName())); + // account for artillery fired during the Targeting (offboard) phase; we reduce the heat capacity and treat + // the arc's heat as 0 because this arc has already fired - so it can be included in the solution for "free" + for ( WeaponMounted weapon : shooter.getWeaponList().stream().filter(Mounted::isUsedThisRound).toList()) { int arc = weapon.isRearMounted() ? -shooter.getWeaponArc(weapon.getLocation()) : shooter.getWeaponArc(weapon.getLocation()); if (!arcShots.containsKey(arc)) { heatCapacity -= shooter.getHeatInArc(weapon.getLocation(), weapon.isRearMounted()); arcShots.put(arc, new ArrayList<>()); arcHeat.put(arc, 0); arcDamage.put(arc, 1.0); - - logger.error(String.format("Arc: %s Heat: %s", arc, arcHeat.get(arc))); } } @@ -288,20 +281,15 @@ FiringPlan calculatePerArcFiringPlan(Entity shooter, List shotLi arc = -arc; } - logger.error(String.format("Shot: %s Rear: %s Arc: %s Raw arc: %s", shot.getWeapon().getName(), shot.getWeapon().isRearMounted(), arc,shooter.getWeaponArc(shooter.getEquipmentNum(shot.getWeapon())) )); - if (!arcShots.containsKey(arc)) { arcShots.put(arc, new ArrayList<>()); arcHeat.put(arc, shooter.getHeatInArc(shot.getWeapon().getLocation(), shot.getWeapon().isRearMounted())); arcDamage.put(arc, 0.0); - - logger.error(String.format("Arc: %s Heat: %s", arc, arcHeat.get(arc))); } arcShots.get(arc).add(shot); arcDamage.put(arc, arcDamage.get(arc) + shot.getExpectedDamage()); - logger.error(String.format("Arc: %s Damage: %s", arc, arcDamage.get(arc))); } // initialize the backpack @@ -318,8 +306,6 @@ FiringPlan calculatePerArcFiringPlan(Entity shooter, List shotLi Integer[] arcHeatKeyArray = new Integer[arcHeat.keySet().size()]; System.arraycopy(arcHeat.keySet().toArray(), 0, arcHeatKeyArray, 0, arcHeat.keySet().size()); - logger.error(String.format("Heat Key Array Length: %s Attempted Output: %s", arcHeatKeyArray.length, arcHeatKeyArray)); - // now, we essentially solve the backpack problem, where the arcs are the items: // arc expected damage is the "value", and arc heat is the "weight", while the // backpack capacity is the unit's heat capacity. @@ -365,7 +351,6 @@ FiringPlan calculatePerArcFiringPlan(Entity shooter, List shotLi // unless there is no firing solution at all, in which case we skip this part if (!arcBackpack.isEmpty()) { for (int arc : arcBackpack.get(arcBackpack.size() - 1).get(heatCapacity - 1)) { - logger.error(String.format("final arc: %s", arc)); retVal.addAll(arcShots.get(arc)); } } diff --git a/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java b/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java index 7d05c009f53..057df443a34 100644 --- a/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java +++ b/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java @@ -1262,7 +1262,7 @@ public void displayMek(Entity en) { wBayWeapon.setVisible(false); } - if (entity.isLargeCraft()) { + if (entity.isLargeCraft() && !(game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY))) { wArcHeatL.setVisible(true); wArcHeatR.setVisible(true); } diff --git a/megamek/src/megamek/common/Entity.java b/megamek/src/megamek/common/Entity.java index e7da0f147b2..b5c25bfb492 100644 --- a/megamek/src/megamek/common/Entity.java +++ b/megamek/src/megamek/common/Entity.java @@ -11631,7 +11631,6 @@ public int getHeatInArc(int location, boolean rearMount) { if ((mounted.getLocation() == location) && (mounted.isRearMounted() == rearMount)) { arcHeat += mounted.getCurrentHeat(); - logger.error(String.format("Location: %s Rear Mount: %s Weapon: %s Heat: %s Arc Heat %s", location, rearMount, mounted.getName(), mounted.getCurrentHeat(), arcHeat)); } } return arcHeat; diff --git a/megamek/src/megamek/common/actions/WeaponAttackAction.java b/megamek/src/megamek/common/actions/WeaponAttackAction.java index 42a7ee83390..ad613c81fb6 100644 --- a/megamek/src/megamek/common/actions/WeaponAttackAction.java +++ b/megamek/src/megamek/common/actions/WeaponAttackAction.java @@ -1536,14 +1536,7 @@ private static String toHitIsImpossible(Game game, Entity ae, int attackerId, Ta int loc = prevWeapon.getLocation(); boolean rearMount = prevWeapon.isRearMounted(); if (game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY)) { - if (!weapon.getBayWeapons().isEmpty()) { - for (WeaponMounted bWeapon : prevWeapon.getBayWeapons()) { - totalHeat += bWeapon.getCurrentHeat(); - } - } - else { - totalHeat += prevWeapon.getCurrentHeat(); - } + totalHeat += prevWeapon.getHeatByBay(); } else { if (!rearMount) { if (!usedFrontArc[loc]) { @@ -1567,14 +1560,7 @@ private static String toHitIsImpossible(Game game, Entity ae, int attackerId, Ta int currentHeat = ae.getHeatInArc(loc, rearMount); if (game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY)) { currentHeat = 0; - if (!weapon.getBayWeapons().isEmpty()) { - for (WeaponMounted bWeapon : weapon.getBayWeapons()) { - currentHeat += bWeapon.getCurrentHeat(); - } - } - else { - currentHeat += weapon.getCurrentHeat(); - } + currentHeat += weapon.getHeatByBay(); } // check to see if this is currently the only arc being fired boolean onlyArc = true; diff --git a/megamek/src/megamek/common/equipment/WeaponMounted.java b/megamek/src/megamek/common/equipment/WeaponMounted.java index 5b5102d9bca..e705cae3fb2 100644 --- a/megamek/src/megamek/common/equipment/WeaponMounted.java +++ b/megamek/src/megamek/common/equipment/WeaponMounted.java @@ -372,4 +372,18 @@ && getType().getInternalName().equals("ISBAAPDS")) { return getType().getAmmoType() == AmmoType.T_APDS; } } + + /** + * @return The heat generated by the bay, or the heat of the individual weapon if it's not a bay + */ + public int getHeatByBay() { + int heat = 0; + if (!getBayWeapons().isEmpty()) { + heat = getBayWeapons().stream().mapToInt(WeaponMounted::getCurrentHeat).sum(); + } + else { + heat += getCurrentHeat(); + } + return heat; + } } diff --git a/megamek/src/megamek/common/weapons/WeaponHandler.java b/megamek/src/megamek/common/weapons/WeaponHandler.java index bbad25266e0..f48e475bca7 100644 --- a/megamek/src/megamek/common/weapons/WeaponHandler.java +++ b/megamek/src/megamek/common/weapons/WeaponHandler.java @@ -147,61 +147,46 @@ public int getSalvoBonus() { * during the round * Used to determine whether point defenses can engage. * - * @param e the entity you wish to get heat data from + * @param entity the entity you wish to get heat data from * @see TeleMissileAttackAction which contains a modified version of this to * work against a * TeleMissile entity in the physical phase */ - protected int getLargeCraftHeat(Entity e) { + protected int getLargeCraftHeat(Entity entity) { int totalHeat = 0; - if (e.hasETypeFlag(Entity.ETYPE_DROPSHIP) - || e.hasETypeFlag(Entity.ETYPE_JUMPSHIP)) { - if (e.usesWeaponBays()) { - for (Enumeration i = game.getAttacks(); i.hasMoreElements();) { - AttackHandler ah = i.nextElement(); - WeaponAttackAction prevAttack = ah.getWaa(); - if (prevAttack.getEntityId() == e.getId()) { - WeaponMounted prevWeapon = (WeaponMounted) e.getEquipment(prevAttack.getWeaponId()); - for (WeaponMounted bayW : prevWeapon.getBayWeapons()) { - totalHeat += bayW.getCurrentHeat(); - } + + if (!entity.isLargeCraft()) { + return totalHeat; + } + + for (Enumeration attack = game.getAttacks(); attack.hasMoreElements(); ) { + AttackHandler attackHandler = attack.nextElement(); + WeaponAttackAction prevAttack = attackHandler.getWaa(); + if (prevAttack.getEntityId() == entity.getId()) { + WeaponMounted prevWeapon = (WeaponMounted) entity.getEquipment(prevAttack.getWeaponId()); + if (!game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY)) { + totalHeat += prevWeapon.getHeatByBay(); + } else { + boolean rearMount = prevWeapon.isRearMounted(); + int loc = prevWeapon.getLocation(); + + // create an array of booleans of locations + boolean[] usedFrontArc = new boolean[ae.locations()]; + boolean[] usedRearArc = new boolean[ae.locations()]; + for (int i = 0; i < ae.locations(); i++) { + usedFrontArc[i] = false; + usedRearArc[i] = false; } - } - } else if (!game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY)) { - // create an array of booleans of locations - boolean[] usedFrontArc = new boolean[ae.locations()]; - boolean[] usedRearArc = new boolean[ae.locations()]; - for (int i = 0; i < ae.locations(); i++) { - usedFrontArc[i] = false; - usedRearArc[i] = false; - } - for (Enumeration i = game.getAttacks(); i.hasMoreElements();) { - AttackHandler ah = i.nextElement(); - WeaponAttackAction prevAttack = ah.getWaa(); - if (prevAttack.getEntityId() == e.getId()) { - WeaponMounted prevWeapon = (WeaponMounted) e.getEquipment(prevAttack.getWeaponId()); - boolean rearMount = prevWeapon.isRearMounted(); - int loc = prevWeapon.getLocation(); - if (!rearMount) { - if (!usedFrontArc[loc]) { - totalHeat += ae.getHeatInArc(loc, rearMount); - usedFrontArc[loc] = true; - } - } else { - if (!usedRearArc[loc]) { - totalHeat += ae.getHeatInArc(loc, rearMount); - usedRearArc[loc] = true; - } + if (!rearMount) { + if (!usedFrontArc[loc]) { + totalHeat += ae.getHeatInArc(loc, rearMount); + usedFrontArc[loc] = true; + } + } else { + if (!usedRearArc[loc]) { + totalHeat += ae.getHeatInArc(loc, rearMount); + usedRearArc[loc] = true; } - } - } - } else { - for (Enumeration i = game.getAttacks(); i.hasMoreElements();) { - AttackHandler ah = i.nextElement(); - WeaponAttackAction prevAttack = ah.getWaa(); - if (prevAttack.getEntityId() == e.getId()) { - Mounted prevWeapon = e.getEquipment(prevAttack.getWeaponId()); - totalHeat += prevWeapon.getCurrentHeat(); } } } From de8f1f269cf8878b27dec4762ab9221dde204c32 Mon Sep 17 00:00:00 2001 From: psikomonkie <189469115+psikomonkie@users.noreply.github.com> Date: Mon, 16 Dec 2024 13:37:10 -0500 Subject: [PATCH 4/9] Issue 4259: Fixing Dropship Heat-by-Arc for Players and Princess - Cleanup Loggers --- megamek/src/megamek/common/weapons/WeaponHandler.java | 1 - 1 file changed, 1 deletion(-) diff --git a/megamek/src/megamek/common/weapons/WeaponHandler.java b/megamek/src/megamek/common/weapons/WeaponHandler.java index f48e475bca7..eb14d0a62ae 100644 --- a/megamek/src/megamek/common/weapons/WeaponHandler.java +++ b/megamek/src/megamek/common/weapons/WeaponHandler.java @@ -1922,7 +1922,6 @@ protected void addHeat() { if (!ae.hasArcFired(loc, rearMount)) { ae.heatBuildup += ae.getHeatInArc(loc, rearMount); ae.setArcFired(loc, rearMount); - logger.error(String.format("Arc Heat: %s Buildup: %s", ae.getHeatInArc(loc, rearMount), ae.heatBuildup)); } } else { ae.heatBuildup += (weapon.getCurrentHeat()); From 07a727c73959e807e61c021b64e898025ec84f9c Mon Sep 17 00:00:00 2001 From: psikomonkie <189469115+psikomonkie@users.noreply.github.com> Date: Mon, 16 Dec 2024 13:46:17 -0500 Subject: [PATCH 5/9] Issue 4259: Fixing Dropship Heat-by-Arc for Players and Princess - Prevent dereferences variable error --- .../src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java b/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java index 057df443a34..d76e1746b37 100644 --- a/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java +++ b/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java @@ -1261,8 +1261,7 @@ public void displayMek(Entity en) { m_chBayWeapon.setVisible(false); wBayWeapon.setVisible(false); } - - if (entity.isLargeCraft() && !(game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY))) { + if (entity.isLargeCraft() && (game == null || !(game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY)))) { wArcHeatL.setVisible(true); wArcHeatR.setVisible(true); } From 11dd4d742926f3c869f0ad9885741187c0fc95e7 Mon Sep 17 00:00:00 2001 From: psikomonkie <189469115+psikomonkie@users.noreply.github.com> Date: Mon, 16 Dec 2024 13:53:08 -0500 Subject: [PATCH 6/9] Issue 4259: Fixing Dropship Heat-by-Arc for Players and Princess - currentHeatBuildup for bays should use getHeatByBay --- .../src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java b/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java index d76e1746b37..0f8babb2896 100644 --- a/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java +++ b/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java @@ -1198,7 +1198,7 @@ public void displayMek(Entity en) { if (entity.isLargeCraft()) { // if using bay heat option then don't add total arc if (game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY)) { - currentHeatBuildup += mounted.getCurrentHeat(); + currentHeatBuildup += mounted.getHeatByBay(); } else { // check whether arc has fired int loc = mounted.getLocation(); From d96d73a883d617f37d646424c87b13c00d626d15 Mon Sep 17 00:00:00 2001 From: psikomonkie <189469115+psikomonkie@users.noreply.github.com> Date: Mon, 16 Dec 2024 14:04:43 -0500 Subject: [PATCH 7/9] Issue 4259: Fixing Dropship Heat-by-Arc for Players and Princess - Code Scanning Fix --- megamek/src/megamek/common/actions/WeaponAttackAction.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/megamek/src/megamek/common/actions/WeaponAttackAction.java b/megamek/src/megamek/common/actions/WeaponAttackAction.java index ad613c81fb6..f8e40d3d808 100644 --- a/megamek/src/megamek/common/actions/WeaponAttackAction.java +++ b/megamek/src/megamek/common/actions/WeaponAttackAction.java @@ -1030,7 +1030,7 @@ private static String toHitIsImpossible(Game game, Entity ae, int attackerId, Ta } // are we bracing a location that's not where the weapon is located? - if (ae.isBracing() && (ae.braceLocation() != weapon.getLocation())) { + if (ae.isBracing() && weapon != null && (ae.braceLocation() != weapon.getLocation())) { return String.format(Messages.getString("WeaponAttackAction.BracingOtherLocation"), ae.getLocationName(ae.braceLocation()), ae.getLocationName(weapon.getLocation())); } From e568d81d4dd067de6a90105854d67d78db8e2475 Mon Sep 17 00:00:00 2001 From: psikomonkie <189469115+psikomonkie@users.noreply.github.com> Date: Tue, 17 Dec 2024 12:26:40 -0500 Subject: [PATCH 8/9] Issue 4259: Fixing Dropship Heat-by-Arc for Players and Princess - Ensure non-large craft with bays will work --- .../src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java | 2 +- megamek/src/megamek/common/weapons/WeaponHandler.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java b/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java index 0f8babb2896..79953321034 100644 --- a/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java +++ b/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java @@ -1217,7 +1217,7 @@ public void displayMek(Entity en) { } } else { if (!mounted.isBombMounted()) { - currentHeatBuildup += mounted.getCurrentHeat(); + currentHeatBuildup += mounted.getHeatByBay(); } } } diff --git a/megamek/src/megamek/common/weapons/WeaponHandler.java b/megamek/src/megamek/common/weapons/WeaponHandler.java index eb14d0a62ae..9ce40841629 100644 --- a/megamek/src/megamek/common/weapons/WeaponHandler.java +++ b/megamek/src/megamek/common/weapons/WeaponHandler.java @@ -1924,7 +1924,7 @@ protected void addHeat() { ae.setArcFired(loc, rearMount); } } else { - ae.heatBuildup += (weapon.getCurrentHeat()); + ae.heatBuildup += (weapon.getHeatByBay()); } } } From 6b9f1ee7b98ea4bcd7bc262c921765b9c2bb8309 Mon Sep 17 00:00:00 2001 From: psikomonkie <189469115+psikomonkie@users.noreply.github.com> Date: Tue, 17 Dec 2024 18:57:55 -0500 Subject: [PATCH 9/9] Issue 4259: Fixing Dropship Heat-by-Arc for Players and Princess - Improve Readability of statement --- .../client/ui/swing/unitDisplay/WeaponPanel.java | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java b/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java index 79953321034..b743562a3fc 100644 --- a/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java +++ b/megamek/src/megamek/client/ui/swing/unitDisplay/WeaponPanel.java @@ -1261,14 +1261,16 @@ public void displayMek(Entity en) { m_chBayWeapon.setVisible(false); wBayWeapon.setVisible(false); } - if (entity.isLargeCraft() && (game == null || !(game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY)))) { - wArcHeatL.setVisible(true); - wArcHeatR.setVisible(true); - } - else { + if ((!entity.isLargeCraft()) + || ((game != null) && (game.getOptions().booleanOption(OptionsConstants.ADVAERORULES_HEAT_BY_BAY)))){ wArcHeatL.setVisible(false); wArcHeatR.setVisible(false); } + else { + wArcHeatL.setVisible(true); + wArcHeatR.setVisible(true); + } + wDamageTrooperL.setVisible(false); wDamageTrooperR.setVisible(false);