fix(spectregunship): Decouple gattling targeting logic from particle crc - #3055
fix(spectregunship): Decouple gattling targeting logic from particle crc#3055Okladnoj wants to merge 1 commit into
Conversation
6b305c3 to
d656c3f
Compare
d656c3f to
23cbbf0
Compare
Caball009
left a comment
There was a problem hiding this comment.
The title and description are no longer up-to-date, and provide inadequate rationale for this change. It's not at all clear to me why this change would be needed.
23cbbf0 to
53458d0
Compare
With RETAIL_COMPATIBLE_CRC=0 the headless dummy particle manager does not load particle system templates, so data->m_gattlingStrafeFXParticleSystem is null. The gattling targeting block was gated on that pointer, so a headless client skipped it and left m_gattlingTargetPosition and m_okToFireHowitzerCounter unchanged, diverging in logic crc from a graphical client; the howitzer GameLogicRandomValue calls then cascade the desync further. Run the targeting logic whenever the gattling is firing in the non-retail branch, independent of the template, and keep the template check only on the client-side particle creation. The original condition is preserved under RETAIL_COMPATIBLE_CRC so retail stays byte-identical even if an INI omits the particle template. Matches the pattern used in EMPUpdate, SpecialAbilityUpdate and TransitionDamageFX.
53458d0 to
d9eaaeb
Compare
|
@xezon @githubawn |
Caball009
left a comment
There was a problem hiding this comment.
The current description and change make a lot more sense to me. I checked with RETAIL_COMPATIBLE_CRC disabled and there's indeed a mismatch issue here for headless mode.
I have added two suggested changes that'll provide a cleaner overall change.
PS: The game uses "gattling" all over the place, but the actual spelling is "gatling".
| const ParticleSystemTemplate *tmp = data->m_gattlingStrafeFXParticleSystem; | ||
| // TheSuperHackers @fix The particle system is now decoupled from the logic crc | ||
| #if RETAIL_COMPATIBLE_CRC | ||
| if (tmp && gattling && gattling->testStatus( OBJECT_STATUS_IS_FIRING_WEAPON) ) | ||
| #else | ||
| if (gattling && gattling->testStatus( OBJECT_STATUS_IS_FIRING_WEAPON) ) | ||
| #endif |
There was a problem hiding this comment.
#if RETAIL_COMPATIBLE_CRC
// TheSuperHackers @fix The particle system is now decoupled from the logic crc
const ParticleSystemTemplate *tmp = data->m_gattlingStrafeFXParticleSystem;
if (tmp && gattling && gattling->testStatus( OBJECT_STATUS_IS_FIRING_WEAPON ))
#else
if ( gattling && gattling->testStatus( OBJECT_STATUS_IS_FIRING_WEAPON) )
#endif| // TheSuperHackers @fix The particle system is now decoupled from the logic crc | ||
| #if RETAIL_COMPATIBLE_CRC | ||
| if ( gunship->getShroudedStatus( localPlayer->getPlayerIndex() ) <= OBJECTSHROUD_PARTIAL_CLEAR ) | ||
| #else | ||
| if ( tmp && gunship->getShroudedStatus( localPlayer->getPlayerIndex() ) <= OBJECTSHROUD_PARTIAL_CLEAR ) | ||
| #endif |
There was a problem hiding this comment.
It's cleaner if you don't change this code and change this instead on line 662:
ParticleSystem *sys = TheParticleSystemManager->createParticleSystem(data->m_gattlingStrafeFXParticleSystem);createParticleSystem does a nullptr check on the ParticleSystemTemplate pointer.
|
I wonder if there are more cases like this that we overlooked. The retail compatible changes were checked pretty thoroughly with a lot replays, but that's less easy to do for non-retail. |
When the game logic was decoupled from the particle systems,
SpectreGunshipUpdatewas left coupled.The gattling targeting logic only ran when the particle template was present. In headless mode (
RETAIL_COMPATIBLE_CRC=0) the templates are not loaded, so the pointer is null and the block was skipped → the logic CRC of a headless client diverges from a graphical one.Decoupled following the same pattern as the neighboring fixes (marker
// TheSuperHackers @fix The particle system is now decoupled from the logic crc):Retail is preserved under
#if RETAIL_COMPATIBLE_CRC. Verified with a full deterministic replay (headless macOS ↔ Windows).