Skip to content

bugfix(radar): Show Hero Radar icons in Containers and Tunnels again#2189

Merged
xezon merged 2 commits intoTheSuperHackers:mainfrom
xezon:xezon/fix-hero-radar-icon-in-container
Feb 19, 2026
Merged

bugfix(radar): Show Hero Radar icons in Containers and Tunnels again#2189
xezon merged 2 commits intoTheSuperHackers:mainfrom
xezon:xezon/fix-hero-radar-icon-in-container

Conversation

@xezon
Copy link

@xezon xezon commented Jan 25, 2026

This change will show the Hero Radar icons in Containers and Tunnels again.

Previously we moved hero objects into its own radar object list, but this broke hero icons in containers, because containers are naturally not added in this hero objects list. This change returns to what the original did. Additionally the TunnelTracker also had the hero objects cache added, otherwise it did not work with tunnels.

TODO

  • Replicate in Generals

@xezon xezon added Bug Something is not working right, typically is user facing Minor Severity: Minor < Major < Critical < Blocker Gen Relates to Generals ZH Relates to Zero Hour ThisProject The issue was introduced by this project, or this task is specific to this project labels Jan 25, 2026
@greptile-apps
Copy link

greptile-apps bot commented Jan 26, 2026

Greptile Summary

Reverts the separate hero radar object list introduced in a previous fix, restoring the original architecture where containers with heroes inside can show hero icons on the radar.

Key changes:

  • Removed m_localHeroObjectList from Radar class and reverted to checking isHero() on objects in m_localObjectList
  • Added hero counting to TunnelTracker (previously missing) so tunnel containers can report contained heroes via getHeroUnitsContained()
  • Simplified xfer/save-load code by removing hero-specific versioning logic in OpenContain
  • Fixed minor typos ("emtpy" → "empty")

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The fix correctly addresses the root cause by reverting to the original architecture where containers check Object::isHero() (which includes hero-containing containers). The TunnelTracker additions properly mirror the existing OpenContain pattern. Changes are symmetric across Generals/GeneralsMD. Code is well-tested and follows established patterns.
  • No files require special attention

Important Files Changed

Filename Overview
Core/GameEngine/Source/Common/System/Radar.cpp Removed hero-specific list handling, cleaned up xfer version compatibility code, simplified object search logic
Core/GameEngineDevice/Source/W3DDevice/Common/System/W3DRadar.cpp Changed drawIcons to filter heroes from m_localObjectList instead of using separate hero list
Generals/Code/GameEngine/Source/Common/RTS/TunnelTracker.cpp Implemented hero counting in addToContainList, removeFromContain, and loadPostProcess methods
Generals/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp Removed hero-specific xfer versioning, simplified loadPostProcess to use addToContainList, fixed typos
GeneralsMD/Code/GameEngine/Source/Common/RTS/TunnelTracker.cpp Implemented hero counting in addToContainList, removeFromContain, and loadPostProcess (matches Generals)
GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp Removed hero-specific xfer versioning, simplified loadPostProcess, fixed typos (matches Generals)

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Radar Draw Icons] --> B{Iterate m_localObjectList}
    B --> C{Is obj->isHero?}
    C -->|No| B
    C -->|Yes| D{Check Hero Type}
    D -->|Direct Hero Unit| E[Draw Hero Icon at Unit Position]
    D -->|Container with Heroes| F{Check Container Type}
    F -->|OpenContain| G[m_heroUnitsContained > 0?]
    F -->|TunnelContain| H[TunnelTracker->getHeroUnitsContained > 0?]
    G -->|Yes| E
    H -->|Yes| E
    G -->|No| B
    H -->|No| B
    E --> B
    
    I[Add to Container] --> J[addToContainList]
    J --> K{Is KINDOF_HERO?}
    K -->|Yes| L[++m_heroUnitsContained]
    K -->|No| M[Done]
    L --> M
    
    N[Remove from Container] --> O{Is KINDOF_HERO?}
    O -->|Yes| P[--m_heroUnitsContained]
    O -->|No| Q[Done]
    P --> Q
Loading

Last reviewed commit: c91f654

@xezon
Copy link
Author

xezon commented Feb 19, 2026

Replicated in Generals with conflicts

D:\Projects\TheSuperHackers\GeneralsGameCode>FOR /F "delims=" %b IN ('git merge-base --fork-point main') DO git diff %b  1>changes.patch

D:\Projects\TheSuperHackers\GeneralsGameCode>git diff 2c26a90ad1b83033bdce238545131d32044c7ea2  1>changes.patch

D:\Projects\TheSuperHackers\GeneralsGameCode>git apply -p2 --directory=Generals --reject --whitespace=fix changes.patch
Checking patch Generals/GameEngine/Include/Common/Radar.h...
error: Generals/GameEngine/Include/Common/Radar.h: No such file or directory
Checking patch Generals/GameEngine/Source/Common/System/Radar.cpp...
error: Generals/GameEngine/Source/Common/System/Radar.cpp: No such file or directory
Checking patch Generals/GameEngineDevice/Source/W3DDevice/Common/System/W3DRadar.cpp...
error: Generals/GameEngineDevice/Source/W3DDevice/Common/System/W3DRadar.cpp: No such file or directory
Checking patch Generals/Code/GameEngine/Include/Common/TunnelTracker.h...
Checking patch Generals/Code/GameEngine/Include/GameLogic/Module/OpenContain.h...
Hunk #1 succeeded at 240 (offset -21 lines).
Checking patch Generals/Code/GameEngine/Include/GameLogic/Module/TunnelContain.h...
Hunk #1 succeeded at 106 (offset -6 lines).
Checking patch Generals/Code/GameEngine/Source/Common/RTS/TunnelTracker.cpp...
Hunk #2 succeeded at 187 (offset -1 lines).
Hunk #3 succeeded at 204 (offset -1 lines).
Hunk #4 succeeded at 444 (offset -1 lines).
Hunk #5 succeeded at 461 (offset -1 lines).
Checking patch Generals/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp...
Hunk #1 succeeded at 126 (offset -4 lines).
error: while searching for:
        * Version Info:
        * 1: Initial version
        * 2: Added m_passengerAllowedToFire
        * 3: TheSuperHackers @tweak Serialize hero units contained count
        */
// ------------------------------------------------------------------------------------------------
void OpenContain::xfer( Xfer *xfer )
{

        // version
#if RETAIL_COMPATIBLE_XFER_SAVE
        XferVersion currentVersion = 2;
#else
        XferVersion currentVersion = 3;
#endif
        XferVersion version = currentVersion;
        xfer->xferVersion( &version, currentVersion );
        m_xferVersion = version;

        // extend base class
        UpdateModule::xfer( xfer );

error: patch failed: Generals/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp:1681
Hunk #3 succeeded at 1493 (offset -220 lines).
error: while searching for:
        xfer->xferUnsignedInt( &m_lastLoadSoundFrame );

        // stealth units contained
        xfer->xferUnsignedInt( &m_stealthUnitsContained );

        // hero units contained
        if (version >= 3)
        {
                xfer->xferUnsignedInt( &m_heroUnitsContained );
        }

        // door close countdown
        xfer->xferUnsignedInt( &m_doorCloseCountdown );

        // conditionstate
        m_conditionState.xfer( xfer );

        // fire points

error: patch failed: Generals/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp:1769
Hunk #5 succeeded at 1602 (offset -214 lines).
Hunk #6 succeeded at 1653 (offset -221 lines).
Hunk #7 succeeded at 1674 (offset -221 lines).
error: while searching for:

        }

        if (m_xferVersion < 3)
        {
                // Restore hero count by iterating hero objects for old save versions
                m_heroUnitsContained = 0;
                for( ContainedItemsList::const_iterator it = m_containList.begin(); it != m_containList.end(); ++it )
                {
                        if( (*it)->isKindOf( KINDOF_HERO ) )
                        {
                                m_heroUnitsContained++;
                        }
                }
        }

        // sanity
        DEBUG_ASSERTCRASH( m_containListSize == m_containList.size(),
                                                                                 ("OpenContain::loadPostProcess - contain list count mismatch") );

error: patch failed: Generals/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp:1916
Checking patch Generals/Code/GameEngine/Source/GameLogic/Object/Contain/TunnelContain.cpp...
Hunk #1 succeeded at 228 (offset -77 lines).
Applied patch Generals/Code/GameEngine/Include/Common/TunnelTracker.h cleanly.
Applied patch Generals/Code/GameEngine/Include/GameLogic/Module/OpenContain.h cleanly.
Applied patch Generals/Code/GameEngine/Include/GameLogic/Module/TunnelContain.h cleanly.
Applied patch Generals/Code/GameEngine/Source/Common/RTS/TunnelTracker.cpp cleanly.
Applying patch Generals/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp with 3 rejects...
Hunk #1 applied cleanly.
Rejected hunk #2.
Hunk #3 applied cleanly.
Rejected hunk #4.
Hunk #5 applied cleanly.
Hunk #6 applied cleanly.
Hunk #7 applied cleanly.
Rejected hunk #8.
Applied patch Generals/Code/GameEngine/Source/GameLogic/Object/Contain/TunnelContain.cpp cleanly.

@xezon xezon merged commit e0691bf into TheSuperHackers:main Feb 19, 2026
25 checks passed
@xezon xezon deleted the xezon/fix-hero-radar-icon-in-container branch February 19, 2026 19:03
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 Gen Relates to Generals Minor Severity: Minor < Major < Critical < Blocker ThisProject The issue was introduced by this project, or this task is specific to this project ZH Relates to Zero Hour

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Radar hero icon is not shown on Radar when inside Tunnel

2 participants