diff --git a/Core/GameEngine/CMakeLists.txt b/Core/GameEngine/CMakeLists.txt
index 56b8b90cfa..1a76d97095 100644
--- a/Core/GameEngine/CMakeLists.txt
+++ b/Core/GameEngine/CMakeLists.txt
@@ -112,6 +112,7 @@ set(GAMEENGINE_SRC
# Include/Common/StateMachine.h
# Include/Common/StatsCollector.h
# Include/Common/STLTypedefs.h
+ Include/Common/STLUtils.h
# Include/Common/StreamingArchiveFile.h
# Include/Common/SubsystemInterface.h
# Include/Common/SystemInfo.h
diff --git a/Core/GameEngine/Include/Common/STLUtils.h b/Core/GameEngine/Include/Common/STLUtils.h
new file mode 100644
index 0000000000..eef1a3a119
--- /dev/null
+++ b/Core/GameEngine/Include/Common/STLUtils.h
@@ -0,0 +1,61 @@
+/*
+** Command & Conquer Generals Zero Hour(tm)
+** Copyright 2025 TheSuperHackers
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+#pragma once
+
+#include
+#include
+
+namespace stl
+{
+
+// Finds first matching element in vector-like container and erases it.
+template
+bool find_and_erase(Container& container, const typename Container::value_type& value)
+{
+ typename Container::const_iterator it = container.begin();
+ for (; it != container.end(); ++it)
+ {
+ if (*it == value)
+ {
+ container.erase(it);
+ return true;
+ }
+ }
+ return false;
+}
+
+// Finds first matching element in vector-like container and removes it by swapping it with the last element.
+// This is generally faster than erasing from a vector, but will change the element sorting.
+template
+bool find_and_erase_unordered(Container& container, const typename Container::value_type& value)
+{
+ typename Container::iterator it = container.begin();
+ for (; it != container.end(); ++it)
+ {
+ if (*it == value)
+ {
+ *it = CPP_11(std::move)(container.back());
+ container.pop_back();
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace stl
diff --git a/Generals/Code/GameEngine/Include/Common/GameEngine.h b/Generals/Code/GameEngine/Include/Common/GameEngine.h
index 0b2ab9f613..174274ecb3 100644
--- a/Generals/Code/GameEngine/Include/Common/GameEngine.h
+++ b/Generals/Code/GameEngine/Include/Common/GameEngine.h
@@ -85,6 +85,8 @@ class GameEngine : public SubsystemInterface
protected:
+ virtual void resetSubsystems( void );
+
virtual FileSystem *createFileSystem( void ); ///< Factory for FileSystem classes
virtual LocalFileSystem *createLocalFileSystem( void ) = 0; ///< Factory for LocalFileSystem classes
virtual ArchiveFileSystem *createArchiveFileSystem( void ) = 0; ///< Factory for ArchiveFileSystem classes
diff --git a/Generals/Code/GameEngine/Include/Common/Radar.h b/Generals/Code/GameEngine/Include/Common/Radar.h
index 8fc78aa25d..d5ec171e08 100644
--- a/Generals/Code/GameEngine/Include/Common/Radar.h
+++ b/Generals/Code/GameEngine/Include/Common/Radar.h
@@ -190,9 +190,8 @@ class Radar : public Snapshot,
Bool tryEvent( RadarEventType event, const Coord3D *pos ); ///< try to make a "stealth" event
// adding and removing objects from the radar
- void addObject( Object *obj ); ///< add object to radar
- void removeObject( Object *obj ); ///< remove object from radar
- void examineObject( Object *obj ); ///< re-examine object and resort if needed
+ virtual bool addObject( Object *obj ); ///< add object to radar
+ virtual bool removeObject( Object *obj ); ///< remove object from radar
// radar options
void hide( Bool hide ) { m_radarHidden = hide; } ///< hide/unhide the radar
diff --git a/Generals/Code/GameEngine/Include/Common/STLTypedefs.h b/Generals/Code/GameEngine/Include/Common/STLTypedefs.h
index dc8c89c834..4e96da4b5b 100644
--- a/Generals/Code/GameEngine/Include/Common/STLTypedefs.h
+++ b/Generals/Code/GameEngine/Include/Common/STLTypedefs.h
@@ -58,6 +58,7 @@ class STLSpecialAlloc;
#include "Common/UnicodeString.h"
#include "Common/GameCommon.h"
#include "Common/GameMemory.h"
+#include "Common/STLUtils.h"
//-----------------------------------------------------------------------------
diff --git a/Generals/Code/GameEngine/Source/Common/GameEngine.cpp b/Generals/Code/GameEngine/Source/Common/GameEngine.cpp
index 4542419d92..f522ba5083 100644
--- a/Generals/Code/GameEngine/Source/Common/GameEngine.cpp
+++ b/Generals/Code/GameEngine/Source/Common/GameEngine.cpp
@@ -509,7 +509,8 @@ void GameEngine::init()
initDisabledMasks();
- TheSubsystemList->resetAll();
+ resetSubsystems();
+
HideControlBar();
} // end init
@@ -528,7 +529,7 @@ void GameEngine::reset( void )
if (TheGameLogic->isInMultiplayerGame())
deleteNetwork = true;
- TheSubsystemList->resetAll();
+ resetSubsystems();
if (deleteNetwork)
{
@@ -545,6 +546,16 @@ void GameEngine::reset( void )
}
}
+/// -----------------------------------------------------------------------------------------------
+void GameEngine::resetSubsystems( void )
+{
+ // TheSuperHackers @fix xezon 09/06/2025 Reset GameLogic first to purge all world objects early.
+ // This avoids potentially catastrophic issues when objects and subsystems have cross dependencies.
+ TheGameLogic->reset();
+
+ TheSubsystemList->resetAll();
+}
+
/// -----------------------------------------------------------------------------------------------
DECLARE_PERF_TIMER(GameEngine_update)
diff --git a/Generals/Code/GameEngine/Source/Common/System/Radar.cpp b/Generals/Code/GameEngine/Source/Common/System/Radar.cpp
index ee614b1518..e1943b53d4 100644
--- a/Generals/Code/GameEngine/Source/Common/System/Radar.cpp
+++ b/Generals/Code/GameEngine/Source/Common/System/Radar.cpp
@@ -394,13 +394,13 @@ void Radar::newMap( TerrainLogic *terrain )
/** Add an object to the radar list. The object will be sorted in the list to be grouped
* using it's radar priority */
//-------------------------------------------------------------------------------------------------
-void Radar::addObject( Object *obj )
+bool Radar::addObject( Object *obj )
{
// get the radar priority for this object
RadarPriorityType newPriority = obj->getRadarPriority();
if( isPriorityVisible( newPriority ) == FALSE )
- return;
+ return false;
// if this object is on the radar, remove it in favor of the new add
RadarObject **list;
@@ -544,6 +544,7 @@ void Radar::addObject( Object *obj )
} // end else
+ return true;
} // end addObject
//-------------------------------------------------------------------------------------------------
@@ -590,24 +591,24 @@ Bool Radar::deleteFromList( Object *obj, RadarObject **list )
//-------------------------------------------------------------------------------------------------
/** Remove an object from the radar, the object may reside in any list */
//-------------------------------------------------------------------------------------------------
-void Radar::removeObject( Object *obj )
+bool Radar::removeObject( Object *obj )
{
// sanity
if( obj->friend_getRadarData() == NULL )
- return;
+ return false;
if( deleteFromList( obj, &m_localObjectList ) == TRUE )
- return;
+ return true;
else if( deleteFromList( obj, &m_objectList ) == TRUE )
- return;
+ return true;
else
{
// sanity
DEBUG_ASSERTCRASH( 0, ("Radar: Tried to remove object '%s' which was not found\n",
obj->getTemplate()->getName().str()) );
-
+ return false;
} // end else
} // end removeObject
diff --git a/Generals/Code/GameEngineDevice/Include/W3DDevice/Common/W3DRadar.h b/Generals/Code/GameEngineDevice/Include/W3DDevice/Common/W3DRadar.h
index b60b0967e1..500ddd65b0 100644
--- a/Generals/Code/GameEngineDevice/Include/W3DDevice/Common/W3DRadar.h
+++ b/Generals/Code/GameEngineDevice/Include/W3DDevice/Common/W3DRadar.h
@@ -59,6 +59,9 @@ class W3DRadar : public Radar
virtual void update( void ); ///< subsystem update
virtual void reset( void ); ///< subsystem reset
+ virtual bool addObject( Object *obj ); ///< add object to radar
+ virtual bool removeObject( Object *obj ); ///< remove object from radar
+
virtual void newMap( TerrainLogic *terrain ); ///< reset radar for new map
void draw( Int pixelX, Int pixelY, Int width, Int height ); ///< draw the radar
@@ -80,7 +83,7 @@ class W3DRadar : public Radar
void drawViewBox( Int pixelX, Int pixelY, Int width, Int height ); ///< draw view box
void buildTerrainTexture( TerrainLogic *terrain ); ///< create the terrain texture of the radar
void drawIcons( Int pixelX, Int pixelY, Int width, Int height ); ///< draw all of the radar icons
- void renderObjectList( const RadarObject *listHead, TextureClass *texture, Bool calcHero = FALSE ); ///< render an object list to the texture
+ void renderObjectList( const RadarObject *listHead, TextureClass *texture ); ///< render an object list to the texture
void interpolateColorForHeight( RGBColor *color,
Real height,
Real hiZ,
@@ -118,7 +121,7 @@ class W3DRadar : public Radar
Real m_viewZoom; ///< camera zoom used for the view box we have
ICoord2D m_viewBox[ 4 ]; ///< radar cell points for the 4 corners of view box
- std::list m_cachedHeroPosList; //< cache of hero positions for drawing icons in radar overlay
+ std::vector m_cachedHeroObjectList; //< cache of hero objects for drawing icons in radar overlay
};
diff --git a/Generals/Code/GameEngineDevice/Source/W3DDevice/Common/System/W3DRadar.cpp b/Generals/Code/GameEngineDevice/Source/W3DDevice/Common/System/W3DRadar.cpp
index 55ed9ee9fe..01ebdc494c 100644
--- a/Generals/Code/GameEngineDevice/Source/W3DDevice/Common/System/W3DRadar.cpp
+++ b/Generals/Code/GameEngineDevice/Source/W3DDevice/Common/System/W3DRadar.cpp
@@ -608,10 +608,10 @@ void W3DRadar::drawEvents( Int pixelX, Int pixelY, Int width, Int height )
void W3DRadar::drawIcons( Int pixelX, Int pixelY, Int width, Int height )
{
// draw the hero icons
- std::list::const_iterator iter = m_cachedHeroPosList.begin();
- while (iter != m_cachedHeroPosList.end())
+ std::vector::const_iterator iter = m_cachedHeroObjectList.begin();
+ while (iter != m_cachedHeroObjectList.end())
{
- drawHeroIcon( pixelX, pixelY, width, height, (*iter) );
+ drawHeroIcon( pixelX, pixelY, width, height, (*iter)->getPosition() );
++iter;
}
}
@@ -619,7 +619,7 @@ void W3DRadar::drawIcons( Int pixelX, Int pixelY, Int width, Int height )
//-------------------------------------------------------------------------------------------------
/** Render an object list into the texture passed in */
//-------------------------------------------------------------------------------------------------
-void W3DRadar::renderObjectList( const RadarObject *listHead, TextureClass *texture, Bool calcHero )
+void W3DRadar::renderObjectList( const RadarObject *listHead, TextureClass *texture )
{
// sanity
@@ -637,12 +637,6 @@ void W3DRadar::renderObjectList( const RadarObject *listHead, TextureClass *text
if (player)
playerIndex=player->getPlayerIndex();
- if( calcHero )
- {
- // clear all entries from the cached hero object list
- m_cachedHeroPosList.clear();
- }
-
for( const RadarObject *rObj = listHead; rObj; rObj = rObj->friend_getNext() )
{
@@ -652,11 +646,6 @@ void W3DRadar::renderObjectList( const RadarObject *listHead, TextureClass *text
// get object
const Object *obj = rObj->friend_getObject();
- // cache hero object positions for drawing in icon layer
- if( calcHero && obj->isHero() )
- {
- m_cachedHeroPosList.push_back(obj->getPosition());
- }
Bool skip = FALSE;
// check for shrouded status
@@ -1001,6 +990,34 @@ void W3DRadar::update( void )
} // end update
+//-------------------------------------------------------------------------------------------------
+bool W3DRadar::addObject( Object *obj )
+{
+ if (Radar::addObject(obj))
+ {
+ if (obj->isHero())
+ {
+ m_cachedHeroObjectList.push_back(obj);
+ }
+ return true;
+ }
+ return false;
+}
+
+//-------------------------------------------------------------------------------------------------
+bool W3DRadar::removeObject( Object *obj )
+{
+ if (Radar::removeObject(obj))
+ {
+ if (obj->isHero())
+ {
+ stl::find_and_erase_unordered(m_cachedHeroObjectList, obj);
+ }
+ return true;
+ }
+ return false;
+}
+
//-------------------------------------------------------------------------------------------------
/** Reset the radar for the new map data being given to it */
//-------------------------------------------------------------------------------------------------
@@ -1416,7 +1433,7 @@ void W3DRadar::draw( Int pixelX, Int pixelY, Int width, Int height )
// rebuild the object overlay
renderObjectList( getObjectList(), m_overlayTexture );
- renderObjectList( getLocalObjectList(), m_overlayTexture, TRUE );
+ renderObjectList( getLocalObjectList(), m_overlayTexture );
} // end if
@@ -1475,7 +1492,7 @@ void W3DRadar::refreshTerrain( TerrainLogic *terrain )
/*
*
- void W3DRadar::renderObjectList( const RadarObject *listHead, TextureClass *texture, Bool calcHero )
+ void W3DRadar::renderObjectList( const RadarObject *listHead, TextureClass *texture )
{
// sanity
@@ -1495,12 +1512,6 @@ void W3DRadar::refreshTerrain( TerrainLogic *terrain )
UnsignedByte minAlpha = 8;
- if( calcHero )
- {
- // clear all entries from the cached hero object list
- m_cachedHeroPosList.clear();
- }
-
for( const RadarObject *rObj = listHead; rObj; rObj = rObj->friend_getNext() )
{
UnsignedByte h = (UnsignedByte)(rObj->isTemporarilyHidden());
@@ -1513,12 +1524,6 @@ void W3DRadar::refreshTerrain( TerrainLogic *terrain )
const Object *obj = rObj->friend_getObject();
UnsignedByte r = 1; // all decoys
- // cache hero object positions for drawing in icon layer
- if( calcHero && obj->isHero() )
- {
- m_cachedHeroPosList.push_back(obj->getPosition());
- }
-
// get the color we're going to draw in
UnsignedInt c = 0xfe000000;// this is a decoy
c |= (UnsignedInt)( obj->testStatus( OBJECT_STATUS_STEALTHED ) );//so is this
diff --git a/Generals/GameEngine/Include/Common/STLUtils.h b/Generals/GameEngine/Include/Common/STLUtils.h
new file mode 100644
index 0000000000..eef1a3a119
--- /dev/null
+++ b/Generals/GameEngine/Include/Common/STLUtils.h
@@ -0,0 +1,61 @@
+/*
+** Command & Conquer Generals Zero Hour(tm)
+** Copyright 2025 TheSuperHackers
+**
+** This program is free software: you can redistribute it and/or modify
+** it under the terms of the GNU General Public License as published by
+** the Free Software Foundation, either version 3 of the License, or
+** (at your option) any later version.
+**
+** This program is distributed in the hope that it will be useful,
+** but WITHOUT ANY WARRANTY; without even the implied warranty of
+** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+** GNU General Public License for more details.
+**
+** You should have received a copy of the GNU General Public License
+** along with this program. If not, see .
+*/
+
+#pragma once
+
+#include
+#include
+
+namespace stl
+{
+
+// Finds first matching element in vector-like container and erases it.
+template
+bool find_and_erase(Container& container, const typename Container::value_type& value)
+{
+ typename Container::const_iterator it = container.begin();
+ for (; it != container.end(); ++it)
+ {
+ if (*it == value)
+ {
+ container.erase(it);
+ return true;
+ }
+ }
+ return false;
+}
+
+// Finds first matching element in vector-like container and removes it by swapping it with the last element.
+// This is generally faster than erasing from a vector, but will change the element sorting.
+template
+bool find_and_erase_unordered(Container& container, const typename Container::value_type& value)
+{
+ typename Container::iterator it = container.begin();
+ for (; it != container.end(); ++it)
+ {
+ if (*it == value)
+ {
+ *it = CPP_11(std::move)(container.back());
+ container.pop_back();
+ return true;
+ }
+ }
+ return false;
+}
+
+} // namespace stl
diff --git a/GeneralsMD/Code/GameEngine/Include/Common/GameEngine.h b/GeneralsMD/Code/GameEngine/Include/Common/GameEngine.h
index 995817c7a2..02e9c39e4e 100644
--- a/GeneralsMD/Code/GameEngine/Include/Common/GameEngine.h
+++ b/GeneralsMD/Code/GameEngine/Include/Common/GameEngine.h
@@ -84,6 +84,8 @@ class GameEngine : public SubsystemInterface
protected:
+ virtual void resetSubsystems( void );
+
virtual FileSystem *createFileSystem( void ); ///< Factory for FileSystem classes
virtual LocalFileSystem *createLocalFileSystem( void ) = 0; ///< Factory for LocalFileSystem classes
virtual ArchiveFileSystem *createArchiveFileSystem( void ) = 0; ///< Factory for ArchiveFileSystem classes
diff --git a/GeneralsMD/Code/GameEngine/Include/Common/Radar.h b/GeneralsMD/Code/GameEngine/Include/Common/Radar.h
index 6f40897b07..6e4e4f21d3 100644
--- a/GeneralsMD/Code/GameEngine/Include/Common/Radar.h
+++ b/GeneralsMD/Code/GameEngine/Include/Common/Radar.h
@@ -190,9 +190,8 @@ class Radar : public Snapshot,
Bool tryEvent( RadarEventType event, const Coord3D *pos ); ///< try to make a "stealth" event
// adding and removing objects from the radar
- void addObject( Object *obj ); ///< add object to radar
- void removeObject( Object *obj ); ///< remove object from radar
- void examineObject( Object *obj ); ///< re-examine object and resort if needed
+ virtual bool addObject( Object *obj ); ///< add object to radar
+ virtual bool removeObject( Object *obj ); ///< remove object from radar
// radar options
void hide( Bool hide ) { m_radarHidden = hide; } ///< hide/unhide the radar
diff --git a/GeneralsMD/Code/GameEngine/Include/Common/STLTypedefs.h b/GeneralsMD/Code/GameEngine/Include/Common/STLTypedefs.h
index 59d006b0b6..374e7bb51b 100644
--- a/GeneralsMD/Code/GameEngine/Include/Common/STLTypedefs.h
+++ b/GeneralsMD/Code/GameEngine/Include/Common/STLTypedefs.h
@@ -58,6 +58,7 @@ class STLSpecialAlloc;
#include "Common/UnicodeString.h"
#include "Common/GameCommon.h"
#include "Common/GameMemory.h"
+#include "Common/STLUtils.h"
//-----------------------------------------------------------------------------
diff --git a/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp b/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp
index f95a046a49..c558886252 100644
--- a/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp
+++ b/GeneralsMD/Code/GameEngine/Source/Common/GameEngine.cpp
@@ -682,7 +682,8 @@ void GameEngine::init()
initDisabledMasks();
initDamageTypeFlags();
- TheSubsystemList->resetAll();
+ resetSubsystems();
+
HideControlBar();
} // end init
@@ -701,7 +702,7 @@ void GameEngine::reset( void )
if (TheGameLogic->isInMultiplayerGame())
deleteNetwork = true;
- TheSubsystemList->resetAll();
+ resetSubsystems();
if (deleteNetwork)
{
@@ -718,6 +719,16 @@ void GameEngine::reset( void )
}
}
+/// -----------------------------------------------------------------------------------------------
+void GameEngine::resetSubsystems( void )
+{
+ // TheSuperHackers @fix xezon 09/06/2025 Reset GameLogic first to purge all world objects early.
+ // This avoids potentially catastrophic issues when objects and subsystems have cross dependencies.
+ TheGameLogic->reset();
+
+ TheSubsystemList->resetAll();
+}
+
/// -----------------------------------------------------------------------------------------------
DECLARE_PERF_TIMER(GameEngine_update)
diff --git a/GeneralsMD/Code/GameEngine/Source/Common/System/Radar.cpp b/GeneralsMD/Code/GameEngine/Source/Common/System/Radar.cpp
index d5ba7a0797..69e3caf68f 100644
--- a/GeneralsMD/Code/GameEngine/Source/Common/System/Radar.cpp
+++ b/GeneralsMD/Code/GameEngine/Source/Common/System/Radar.cpp
@@ -397,13 +397,13 @@ void Radar::newMap( TerrainLogic *terrain )
/** Add an object to the radar list. The object will be sorted in the list to be grouped
* using it's radar priority */
//-------------------------------------------------------------------------------------------------
-void Radar::addObject( Object *obj )
+bool Radar::addObject( Object *obj )
{
// get the radar priority for this object
RadarPriorityType newPriority = obj->getRadarPriority();
if( isPriorityVisible( newPriority ) == FALSE )
- return;
+ return false;
// if this object is on the radar, remove it in favor of the new add
RadarObject **list;
@@ -547,6 +547,7 @@ void Radar::addObject( Object *obj )
} // end else
+ return true;
} // end addObject
//-------------------------------------------------------------------------------------------------
@@ -593,24 +594,24 @@ Bool Radar::deleteFromList( Object *obj, RadarObject **list )
//-------------------------------------------------------------------------------------------------
/** Remove an object from the radar, the object may reside in any list */
//-------------------------------------------------------------------------------------------------
-void Radar::removeObject( Object *obj )
+bool Radar::removeObject( Object *obj )
{
// sanity
if( obj->friend_getRadarData() == NULL )
- return;
+ return false;
if( deleteFromList( obj, &m_localObjectList ) == TRUE )
- return;
+ return true;
else if( deleteFromList( obj, &m_objectList ) == TRUE )
- return;
+ return true;
else
{
// sanity
DEBUG_ASSERTCRASH( 0, ("Radar: Tried to remove object '%s' which was not found\n",
obj->getTemplate()->getName().str()) );
-
+ return false;
} // end else
} // end removeObject
diff --git a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/Common/W3DRadar.h b/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/Common/W3DRadar.h
index fd1b2ff8e8..f94c6fbaf6 100644
--- a/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/Common/W3DRadar.h
+++ b/GeneralsMD/Code/GameEngineDevice/Include/W3DDevice/Common/W3DRadar.h
@@ -59,6 +59,9 @@ class W3DRadar : public Radar
virtual void update( void ); ///< subsystem update
virtual void reset( void ); ///< subsystem reset
+ virtual bool addObject( Object *obj ); ///< add object to radar
+ virtual bool removeObject( Object *obj ); ///< remove object from radar
+
virtual void newMap( TerrainLogic *terrain ); ///< reset radar for new map
void draw( Int pixelX, Int pixelY, Int width, Int height ); ///< draw the radar
@@ -80,7 +83,7 @@ class W3DRadar : public Radar
void drawViewBox( Int pixelX, Int pixelY, Int width, Int height ); ///< draw view box
void buildTerrainTexture( TerrainLogic *terrain ); ///< create the terrain texture of the radar
void drawIcons( Int pixelX, Int pixelY, Int width, Int height ); ///< draw all of the radar icons
- void renderObjectList( const RadarObject *listHead, TextureClass *texture, Bool calcHero = FALSE ); ///< render an object list to the texture
+ void renderObjectList( const RadarObject *listHead, TextureClass *texture ); ///< render an object list to the texture
void interpolateColorForHeight( RGBColor *color,
Real height,
Real hiZ,
@@ -118,7 +121,7 @@ class W3DRadar : public Radar
Real m_viewZoom; ///< camera zoom used for the view box we have
ICoord2D m_viewBox[ 4 ]; ///< radar cell points for the 4 corners of view box
- std::list m_cachedHeroPosList; //< cache of hero positions for drawing icons in radar overlay
+ std::vector m_cachedHeroObjectList; //< cache of hero objects for drawing icons in radar overlay
};
diff --git a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/Common/System/W3DRadar.cpp b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/Common/System/W3DRadar.cpp
index 83a97510fb..424b1e2f88 100644
--- a/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/Common/System/W3DRadar.cpp
+++ b/GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/Common/System/W3DRadar.cpp
@@ -606,10 +606,10 @@ void W3DRadar::drawEvents( Int pixelX, Int pixelY, Int width, Int height )
void W3DRadar::drawIcons( Int pixelX, Int pixelY, Int width, Int height )
{
// draw the hero icons
- std::list::const_iterator iter = m_cachedHeroPosList.begin();
- while (iter != m_cachedHeroPosList.end())
+ std::vector::const_iterator iter = m_cachedHeroObjectList.begin();
+ while (iter != m_cachedHeroObjectList.end())
{
- drawHeroIcon( pixelX, pixelY, width, height, (*iter) );
+ drawHeroIcon( pixelX, pixelY, width, height, (*iter)->getPosition() );
++iter;
}
}
@@ -617,7 +617,7 @@ void W3DRadar::drawIcons( Int pixelX, Int pixelY, Int width, Int height )
//-------------------------------------------------------------------------------------------------
/** Render an object list into the texture passed in */
//-------------------------------------------------------------------------------------------------
-void W3DRadar::renderObjectList( const RadarObject *listHead, TextureClass *texture, Bool calcHero )
+void W3DRadar::renderObjectList( const RadarObject *listHead, TextureClass *texture )
{
// sanity
@@ -635,12 +635,6 @@ void W3DRadar::renderObjectList( const RadarObject *listHead, TextureClass *text
if (player)
playerIndex=player->getPlayerIndex();
- if( calcHero )
- {
- // clear all entries from the cached hero object list
- m_cachedHeroPosList.clear();
- }
-
for( const RadarObject *rObj = listHead; rObj; rObj = rObj->friend_getNext() )
{
@@ -650,11 +644,6 @@ void W3DRadar::renderObjectList( const RadarObject *listHead, TextureClass *text
// get object
const Object *obj = rObj->friend_getObject();
- // cache hero object positions for drawing in icon layer
- if( calcHero && obj->isHero() )
- {
- m_cachedHeroPosList.push_back(obj->getPosition());
- }
Bool skip = FALSE;
// check for shrouded status
@@ -995,6 +984,34 @@ void W3DRadar::update( void )
} // end update
+//-------------------------------------------------------------------------------------------------
+bool W3DRadar::addObject( Object *obj )
+{
+ if (Radar::addObject(obj))
+ {
+ if (obj->isHero())
+ {
+ m_cachedHeroObjectList.push_back(obj);
+ }
+ return true;
+ }
+ return false;
+}
+
+//-------------------------------------------------------------------------------------------------
+bool W3DRadar::removeObject( Object *obj )
+{
+ if (Radar::removeObject(obj))
+ {
+ if (obj->isHero())
+ {
+ stl::find_and_erase_unordered(m_cachedHeroObjectList, obj);
+ }
+ return true;
+ }
+ return false;
+}
+
//-------------------------------------------------------------------------------------------------
/** Reset the radar for the new map data being given to it */
//-------------------------------------------------------------------------------------------------
@@ -1404,7 +1421,7 @@ void W3DRadar::draw( Int pixelX, Int pixelY, Int width, Int height )
// rebuild the object overlay
renderObjectList( getObjectList(), m_overlayTexture );
- renderObjectList( getLocalObjectList(), m_overlayTexture, TRUE );
+ renderObjectList( getLocalObjectList(), m_overlayTexture );
} // end if
@@ -1463,7 +1480,7 @@ void W3DRadar::refreshTerrain( TerrainLogic *terrain )
/*
*
- void W3DRadar::renderObjectList( const RadarObject *listHead, TextureClass *texture, Bool calcHero )
+ void W3DRadar::renderObjectList( const RadarObject *listHead, TextureClass *texture )
{
// sanity
@@ -1483,12 +1500,6 @@ void W3DRadar::refreshTerrain( TerrainLogic *terrain )
UnsignedByte minAlpha = 8;
- if( calcHero )
- {
- // clear all entries from the cached hero object list
- m_cachedHeroPosList.clear();
- }
-
for( const RadarObject *rObj = listHead; rObj; rObj = rObj->friend_getNext() )
{
UnsignedByte h = (UnsignedByte)(rObj->isTemporarilyHidden());
@@ -1501,12 +1512,6 @@ void W3DRadar::refreshTerrain( TerrainLogic *terrain )
const Object *obj = rObj->friend_getObject();
UnsignedByte r = 1; // all decoys
- // cache hero object positions for drawing in icon layer
- if( calcHero && obj->isHero() )
- {
- m_cachedHeroPosList.push_back(obj->getPosition());
- }
-
// get the color we're going to draw in
UnsignedInt c = 0xfe000000;// this is a decoy
c |= (UnsignedInt)( obj->testStatus( OBJECT_STATUS_STEALTHED ) );//so is this