What went wrong
WeaponHandler.getLargeCraftHeat reads the Heat by bay advanced aerospace option backwards, so turning the option on makes point defence heat accounting disagree with the firing validation that uses the same option.
The method sums the heat a large craft has already committed, to decide whether its point defences can still engage. It treats the option as off meaning by-bay:
// WeaponHandler.getLargeCraftHeat
if (!game.getOptions().booleanOption(OptionsConstants.ADVANCED_AERO_RULES_HEAT_BY_BAY)) {
totalHeat += prevWeapon.getHeatByBay();
} else {
// de-duplicated getHeatInArc(...) per arc
}
ComputeToHitIsImpossible uses the same option the other way round, and it is the code that decides whether a shot may be declared at all:
// ComputeToHitIsImpossible, three separate sites
if (game.getOptions().booleanOption(OptionsConstants.ADVANCED_AERO_RULES_HEAT_BY_BAY)) {
totalHeat += prevWeapon.getHeatByBay();
} else {
// de-duplicated getHeatInArc(...) per arc
}
What you expected instead
Both should count heat the same way for a given setting of the option. With Heat by bay enabled, both should sum getHeatByBay(). With it disabled, both should use the de-duplicated per-arc heat.
Steps to reproduce
Not reproduced in a running game. Found by reading, while fixing an unrelated crash in the same method (#8899, PR #8957).
To see it in play you would need a space game with Heat by bay enabled and a large craft with enough declared fire that the two methods disagree, then compare when firing is refused for heat against when point defences are allowed to engage.
Relevant log lines
None. This produces wrong numbers rather than an error.
MegaMek Suite Version
0.51.01
Operating System
Windows 11
Java Version
21.0.11
Notes
The option defaults to off, so the default path is unaffected. That is probably why this has gone unnoticed.
Flipping the condition changes when point defences may engage under that option, which is a rules behaviour change rather than a crash fix, so it was deliberately left alone in PR #8957 and raised separately here. Someone who knows the point defence rules should decide which of the two readings is correct before either side is changed.
What went wrong
WeaponHandler.getLargeCraftHeatreads the Heat by bay advanced aerospace option backwards, so turning the option on makes point defence heat accounting disagree with the firing validation that uses the same option.The method sums the heat a large craft has already committed, to decide whether its point defences can still engage. It treats the option as off meaning by-bay:
ComputeToHitIsImpossibleuses the same option the other way round, and it is the code that decides whether a shot may be declared at all:What you expected instead
Both should count heat the same way for a given setting of the option. With Heat by bay enabled, both should sum
getHeatByBay(). With it disabled, both should use the de-duplicated per-arc heat.Steps to reproduce
Not reproduced in a running game. Found by reading, while fixing an unrelated crash in the same method (#8899, PR #8957).
To see it in play you would need a space game with Heat by bay enabled and a large craft with enough declared fire that the two methods disagree, then compare when firing is refused for heat against when point defences are allowed to engage.
Relevant log lines
None. This produces wrong numbers rather than an error.
MegaMek Suite Version
0.51.01
Operating System
Windows 11
Java Version
21.0.11
Notes
The option defaults to off, so the default path is unaffected. That is probably why this has gone unnoticed.
Flipping the condition changes when point defences may engage under that option, which is a rules behaviour change rather than a crash fix, so it was deliberately left alone in PR #8957 and raised separately here. Someone who knows the point defence rules should decide which of the two readings is correct before either side is changed.