Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ class ContainModuleInterface
virtual const Object *friend_getRider() const = 0; ///< Damn. The draw order dependency bug for riders means that our draw module needs to cheat to get around it.
virtual Real getContainedItemsMass() const = 0;
virtual UnsignedInt getStealthUnitsContained() const = 0;
virtual UnsignedInt getHeroUnitsContained() const = 0;

virtual Bool calcBestGarrisonPosition( Coord3D *sourcePos, const Coord3D *targetPos ) = 0;
virtual Bool attemptBestFirePointPosition( Object *source, Weapon *weapon, Object *victim ) = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,7 @@ class OpenContain : public UpdateModule,
virtual const Object *friend_getRider() const{return NULL;} ///< Damn. The draw order dependency bug for riders means that our draw module needs to cheat to get around it.
virtual Real getContainedItemsMass() const;
virtual UnsignedInt getStealthUnitsContained() const { return m_stealthUnitsContained; }
virtual UnsignedInt getHeroUnitsContained() const { return m_heroUnitsContained; }

virtual PlayerMaskType getPlayerWhoEntered(void) const { return m_playerEnteredMask; }

Expand Down Expand Up @@ -238,6 +239,7 @@ class OpenContain : public UpdateModule,

ObjectEnterExitMap m_objectEnterExitInfo;
UnsignedInt m_stealthUnitsContained; ///< number of stealth units that can't be seen by enemy players.
UnsignedInt m_heroUnitsContained; ///< cached hero count
Int m_whichExitPath; ///< Cycles from 1 to n and is used only in modules whose data has numberOfExitPaths > 1.
UnsignedInt m_doorCloseCountdown; ///< When should I shut my door.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ OpenContain::OpenContain( Thing *thing, const ModuleData* moduleData ) : UpdateM
m_lastLoadSoundFrame = 0;
m_containListSize = 0;
m_stealthUnitsContained = 0;
m_heroUnitsContained = 0;
m_doorCloseCountdown = 0;

m_rallyPoint.zero();
Expand Down Expand Up @@ -352,6 +353,10 @@ void OpenContain::addToContainList( Object *rider )
{
m_stealthUnitsContained++;
}
if( rider->isKindOf( KINDOF_HERO ) )
{
m_heroUnitsContained++;
}
}

//-------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -542,6 +547,10 @@ void OpenContain::removeFromContainViaIterator( ContainedItemsList::iterator it,
}
}
}
if( rider->isKindOf( KINDOF_HERO ) && m_heroUnitsContained > 0 )
Copy link

Choose a reason for hiding this comment

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

Make the m_heroUnitsContained > 0 an assert, because we do not expect this to be 0 here, right?

{
m_heroUnitsContained--;
}


if (isEnclosingContainerFor( rider ))
Expand Down Expand Up @@ -620,7 +629,7 @@ void OpenContain::scatterToNearbyPosition(Object* rider)
}

//-------------------------------------------------------------------------------------------------
void OpenContain::onContaining( Object * /*rider*/ )
void OpenContain::onContaining( Object *rider )
{
// Play audio
if( m_loadSoundsEnabled )
Expand Down Expand Up @@ -1526,6 +1535,9 @@ void OpenContain::xfer( Xfer *xfer )
// stealth units contained
xfer->xferUnsignedInt( &m_stealthUnitsContained );

// hero units contained
xfer->xferUnsignedInt( &m_heroUnitsContained );
Copy link

Choose a reason for hiding this comment

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

This requires Xfer version increment. And version history documentation. Also needs to be put behind RETAIL_COMPATIBLE_XFER_SAVE. See other code that does it.

In RETAIL_COMPATIBLE_XFER_SAVE, the count needs to be restored by iterating hero objects like the original code did it.


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

Expand Down
16 changes: 2 additions & 14 deletions Generals/Code/GameEngine/Source/GameLogic/Object/Object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -593,25 +593,13 @@ Object::~Object()
}

//-------------------------------------------------------------------------------------------------
void localIsHero( Object *obj, void* userData )
{
Bool *hero = (Bool*)userData;

if( obj && obj->isKindOf( KINDOF_HERO ) )
{
*hero = TRUE;
}
}

//-------------------------------------------------------------------------------------------------
// TheSuperHackers @performance bobtista 13/11/2025 Use cached hero count for O(1) lookup instead of O(n) iteration.
Bool Object::isHero() const
{
ContainModuleInterface *contain = getContain();
if( contain )
{
Bool heroInside = FALSE;
contain->iterateContained( localIsHero, (void*)(&heroInside), FALSE );
if( heroInside )
if( contain->getHeroUnitsContained() > 0 )
{
return TRUE;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ class ContainModuleInterface
virtual const Object *friend_getRider() const = 0; ///< Damn. The draw order dependency bug for riders means that our draw module needs to cheat to get around it.
virtual Real getContainedItemsMass() const = 0;
virtual UnsignedInt getStealthUnitsContained() const = 0;
virtual UnsignedInt getHeroUnitsContained() const = 0;

virtual Bool calcBestGarrisonPosition( Coord3D *sourcePos, const Coord3D *targetPos ) = 0;
virtual Bool attemptBestFirePointPosition( Object *source, Weapon *weapon, Object *victim ) = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ class OpenContain : public UpdateModule,
virtual const Object *friend_getRider() const{return NULL;} ///< Damn. The draw order dependency bug for riders means that our draw module needs to cheat to get around it.
virtual Real getContainedItemsMass() const;
virtual UnsignedInt getStealthUnitsContained() const { return m_stealthUnitsContained; }
virtual UnsignedInt getHeroUnitsContained() const { return m_heroUnitsContained; }

virtual PlayerMaskType getPlayerWhoEntered(void) const { return m_playerEnteredMask; }

Expand Down Expand Up @@ -259,6 +260,7 @@ class OpenContain : public UpdateModule,

ObjectEnterExitMap m_objectEnterExitInfo;
UnsignedInt m_stealthUnitsContained; ///< number of stealth units that can't be seen by enemy players.
UnsignedInt m_heroUnitsContained; ///< cached hero count
Int m_whichExitPath; ///< Cycles from 1 to n and is used only in modules whose data has numberOfExitPaths > 1.
UnsignedInt m_doorCloseCountdown; ///< When should I shut my door.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ OpenContain::OpenContain( Thing *thing, const ModuleData* moduleData ) : UpdateM
m_lastLoadSoundFrame = 0;
m_containListSize = 0;
m_stealthUnitsContained = 0;
m_heroUnitsContained = 0;
m_doorCloseCountdown = 0;

m_rallyPoint.zero();
Expand Down Expand Up @@ -374,6 +375,10 @@ void OpenContain::addToContainList( Object *rider )
{
m_stealthUnitsContained++;
}
if( rider->isKindOf( KINDOF_HERO ) )
{
m_heroUnitsContained++;
}
}

//-------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -660,6 +665,10 @@ void OpenContain::removeFromContainViaIterator( ContainedItemsList::iterator it,
}
}
}
if( rider->isKindOf( KINDOF_HERO ) && m_heroUnitsContained > 0 )
{
m_heroUnitsContained--;
}


if (isEnclosingContainerFor( rider ))
Expand Down Expand Up @@ -1751,6 +1760,9 @@ void OpenContain::xfer( Xfer *xfer )
// stealth units contained
xfer->xferUnsignedInt( &m_stealthUnitsContained );

// hero units contained
xfer->xferUnsignedInt( &m_heroUnitsContained );

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

Expand Down
15 changes: 2 additions & 13 deletions GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Object.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2042,25 +2042,14 @@ Bool Object::isNonFactionStructure(void) const
return isStructure() && !isFactionStructure();
}

void localIsHero( Object *obj, void* userData )
{
Bool *hero = (Bool*)userData;

if( obj && obj->isKindOf( KINDOF_HERO ) )
{
*hero = TRUE;
}
}

//-------------------------------------------------------------------------------------------------
// TheSuperHackers @performance bobtista 13/11/2025 Use cached hero count for O(1) lookup instead of O(n) iteration.
Bool Object::isHero(void) const
{
ContainModuleInterface *contain = getContain();
if( contain )
{
Bool heroInside = FALSE;
contain->iterateContained( localIsHero, (void*)(&heroInside), FALSE );
if( heroInside )
if( contain->getHeroUnitsContained() > 0 )
{
return TRUE;
}
Expand Down
Loading