bugfix: Modules now cease updating when disabled by non-whitelisted disabled types#2458
bugfix: Modules now cease updating when disabled by non-whitelisted disabled types#2458Stubbjax wants to merge 1 commit intoTheSuperHackers:mainfrom
Conversation
|
| Filename | Overview |
|---|---|
| Generals/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp | Adds #if RETAIL_COMPATIBLE_CRC guards replacing anyIntersectionWith with testForAll for the disabled-types check; the new condition correctly makes the whitelist exclusive (dis must be a subset of whitelisted types), matching the described bugfix intent. |
| GeneralsMD/Code/GameEngine/Source/GameLogic/System/GameLogic.cpp | Identical fix applied to the Zero Hour (GeneralsMD) variant of GameLogic.cpp; the same RETAIL_COMPATIBLE_CRC-guarded testForAll change is made in both the normal-update and sleepy-update loops. |
Flowchart
%%{init: {'theme': 'neutral'}}%%
flowchart TD
A[GameLogic::update - iterate update modules] --> B[dis = getDisabledFlags]
B --> C{dis has any bits set?}
C -- No disabled flags --> D[Run module update]
C -- Has disabled flags --> E{RETAIL_COMPATIBLE_CRC enabled?}
E -- Yes --> F[Old: dis.anyIntersectionWith whitelist]
E -- No --> G[New: whitelist.testForAll dis]
F -- Any bit in common --> D
F -- No overlap --> H[Skip update]
G -- dis is subset of whitelist --> D
G -- Any non-whitelisted bit found --> H
D --> I[u->update called]
H --> J[sleepLen = UPDATE_SLEEP_NONE]
Last reviewed commit: 5330787
43e4df1 to
5330787
Compare
Caball009
left a comment
There was a problem hiding this comment.
Before merging this I'd like to test if this code overlaps / conflicts with possible fixes for the gattling cannon barrels rotating despite insufficient energy.
|
Do we need to label this is Controversial? |
| // Previously, if the disabled mask had any bits in common with the disabled-types-to-process mask, | ||
| // the update would be processed. Now, if any *other* bits are set in the disabled mask, the update | ||
| // is no longer processed. | ||
| if (!dis.any() || u->getDisabledTypesToProcess().testForAll(dis)) |
There was a problem hiding this comment.
Is this certainly correct?
I would have expected:
const Bool isDisabled = dis.any() && dis.testForAny(u->getDisabledTypesToProcess());
if (!isDisabled)
...There was a problem hiding this comment.
The getDisabledTypesToProcess function returns the disabled statuses that do not block the module's update.
For example, BaseRegenerateUpdate::getDisabledTypesToProcess returns DISABLED_UNDERPOWERED. This means the module is allowed to continue performing its repair update even if the player has low power.
Similarly, PoisonedBehaviour::getDisabledTypesToProcess returns DISABLEDMASK_ALL because nothing should disable the poisoned update. This is highlighted by the accompanying comment "we should still poison disabled things".
The function serves as a whitelist of disabled types that do not affect the update of the respective module. Perhaps a better name would be getAllowedDisabledTypes or getIgnoredDisabledTypes.
There was a problem hiding this comment.
Ok got it. But why is this condition still correct then?
So what we need to test is: (dis & ~allowedDisabledTypes) == 0
Is u->getDisabledTypesToProcess().testForAll(dis) equivalent to that? It is so complicated to read. Can we write that easier?
Closes #147
This change fixes an issue where modules continue updating when disabled by a type that is not whitelisted.
For example, the stealth detector module has
DISABLED_HELDwhitelisted. This allows stealth detection to still run if an object is held, which in most cases is the result of containment (thoughCanDetectWhileContainedtypically blocks this). Any other disabling type is expected to shut the stealth detector down, such asDISABLED_EMPorDISABLED_SUBDUED. The problem is that the module only looks for whether theDISABLED_HELDbit is set and, if so, any other disabled type such asDISABLED_EMPis not considered.This can also be seen elsewhere, such as with powered USA base defences.
BaseRegenerateUpdatewhitelistsDISABLED_UNDERPOWERED. This means a Patriot Missile Battery will still repair itself when out of power. Conversely, if a Patriot Missile Battery is disabled by a Microwave Tank (DISABLED_SUBDUED), it will not repair itself. But if an underpowered Patriot Missile Battery is out of power and disabled by a Microwave Tank, then it will repair itself.Before
The EMP Patriot will not repair while subdued, but will while the power is also out
REPAIR.mp4
After
A disabled (including unmanned) Overlord's Gattling Cannon no longer detects stealth units
DISABLE_DETECTION.mp4