Skip to content

bugfix: Sniper weapons can no longer fire upon empty Stinger Sites#2822

Open
Stubbjax wants to merge 2 commits into
TheSuperHackers:mainfrom
Stubbjax:fix-sniping-empty-stinger-sites
Open

bugfix: Sniper weapons can no longer fire upon empty Stinger Sites#2822
Stubbjax wants to merge 2 commits into
TheSuperHackers:mainfrom
Stubbjax:fix-sniping-empty-stinger-sites

Conversation

@Stubbjax

Copy link
Copy Markdown

Fixes #1590 from the patch repository

This change prevents sniper weapons from being able to fire upon empty Stinger Sites. Behaviour is now consistent with occupied / empty Fire Bases.

This change only applies to Zero Hour as the Generals implementation is different and it makes more sense to carry the fix there during the unification process.

Before

BEFORE_SNIPE.mp4

After

AFTER_SNIPE.mp4

@Stubbjax Stubbjax self-assigned this Jun 22, 2026
@Stubbjax Stubbjax added Bug Something is not working right, typically is user facing Minor Severity: Minor < Major < Critical < Blocker ZH Relates to Zero Hour NoRetail This fix or change is not applicable with Retail game compatibility labels Jun 22, 2026
@greptile-apps

greptile-apps Bot commented Jun 22, 2026

Copy link
Copy Markdown

Greptile Summary

Prevents sniper weapons from targeting empty Stinger Sites by extending the existing DAMAGE_SNIPER / KINDOF_STRUCTURE guard to also cover structures that use spawn-slave occupancy (no contain module) rather than garrison containment. The fix is Zero Hour-only and wrapped in #if !RETAIL_COMPATIBLE_CRC.

  • Adds getSlaveCount() as a pure virtual on SpawnBehaviorInterface (with an inline implementation in SpawnBehavior returning m_spawnCount), giving callers a clean API to query slave occupancy.
  • In Weapon.cpp, the new else branch checks spawnInterface->getSlaveCount() <= 0, which correctly handles both the all-dead state (0) and the never-yet-spawned sentinel value (0xffffffff → -1 in the signed Int field).

Confidence Score: 5/5

The change is safe to merge — it adds a narrow, well-guarded code path that only affects sniper damage estimation against structures with spawn-slave occupancy.

The <= 0 comparison correctly covers both the never-yet-spawned sentinel (0xffffffff → -1 in the signed Int field) and the all-soldiers-dead state (0), so the guard behaves correctly across the full lifecycle of a Stinger Site. The new virtual method is the sole addition to the interface, SpawnBehavior is its only implementor, and the fix is isolated behind #if !RETAIL_COMPATIBLE_CRC.

No files require special attention.

Important Files Changed

Filename Overview
GeneralsMD/Code/GameEngine/Include/GameLogic/Module/SpawnBehavior.h Adds pure virtual getSlaveCount() to SpawnBehaviorInterface and an inline implementation on SpawnBehavior that returns m_spawnCount; no other implementors exist so the change compiles cleanly.
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Weapon.cpp Adds an else branch to the DAMAGE_SNIPER / KINDOF_STRUCTURE guard: when no contain module is present, checks the spawn-behavior slave count and returns 0 if <= 0, correctly blocking sniper targeting of empty Stinger Sites (including the NONE_SPAWNED_YET sentinel of -1).

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["estimateWeaponTemplateDamage()"] --> B{"isKindOf STRUCTURE AND DAMAGE_SNIPER?"}
    B -->|No| Z[Continue normal evaluation]
    B -->|Yes| C{"getContain() not null?"}
    C -->|Yes| D{"getContainCount() == 0?"}
    D -->|Yes| E["return 0.0f - cannot target"]
    D -->|No| Z
    C -->|"No - new else branch"| F["getSpawnBehaviorInterface()"]
    F --> G{"spawnInterface not null?"}
    G -->|No| Z
    G -->|Yes| H{"getSlaveCount() <= 0?"}
    H -->|"Yes: -1=NONE_SPAWNED_YET or 0=all dead"| E
    H -->|No| Z
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A["estimateWeaponTemplateDamage()"] --> B{"isKindOf STRUCTURE AND DAMAGE_SNIPER?"}
    B -->|No| Z[Continue normal evaluation]
    B -->|Yes| C{"getContain() not null?"}
    C -->|Yes| D{"getContainCount() == 0?"}
    D -->|Yes| E["return 0.0f - cannot target"]
    D -->|No| Z
    C -->|"No - new else branch"| F["getSpawnBehaviorInterface()"]
    F --> G{"spawnInterface not null?"}
    G -->|No| Z
    G -->|Yes| H{"getSlaveCount() <= 0?"}
    H -->|"Yes: -1=NONE_SPAWNED_YET or 0=all dead"| E
    H -->|No| Z
Loading

Reviews (3): Last reviewed commit: "tweak: Cover unspawned states" | Re-trigger Greptile

Comment thread GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Weapon.cpp Outdated
Comment thread GeneralsMD/Code/GameEngine/Include/GameLogic/Module/SpawnBehavior.h Outdated
@Stubbjax Stubbjax force-pushed the fix-sniping-empty-stinger-sites branch from 3adccd8 to 290abfd Compare June 22, 2026 16:39
if ( victimObj->getContain()->getContainCount() == 0 )
return 0.0f;
}
#if !RETAIL_COMPATIBLE_CRC

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may also need a PRESERVE_SNIPER_STINGER_BEHAVIOR flag
The fix significantly increases the effectiveness of the sniper against GLA bases.
May need to be checked with The Comity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Bug Something is not working right, typically is user facing Minor Severity: Minor < Major < Critical < Blocker NoRetail This fix or change is not applicable with Retail game compatibility ZH Relates to Zero Hour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Sniper can shoot empty GLA Stinger Site, but not empty USA Firebase

4 participants