Skip to content

Commit de13231

Browse files
committed
refactor(radar): Simplify function Radar::addObject (#1893)
1 parent a2c1d0e commit de13231

File tree

3 files changed

+127
-113
lines changed

3 files changed

+127
-113
lines changed

GeneralsMD/Code/GameEngine/Include/Common/Radar.h

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -196,8 +196,8 @@ class Radar : public Snapshot,
196196
Bool tryEvent( RadarEventType event, const Coord3D *pos ); ///< try to make a "stealth" event
197197

198198
// adding and removing objects from the radar
199-
virtual RadarObjectType addObject( Object *obj ); ///< add object to radar
200-
virtual RadarObjectType removeObject( Object *obj ); ///< remove object from radar
199+
virtual RadarObjectType addObject( Object *obj ); ///< add object to radar
200+
virtual RadarObjectType removeObject( Object *obj ); ///< remove object from radar
201201

202202
// radar options
203203
void hide( Int playerIndex, Bool hide ) { m_radarHidden[playerIndex] = hide; } ///< hide/show the radar
@@ -252,6 +252,9 @@ class Radar : public Snapshot,
252252
// search the object list for an object that maps to the given logical radar coordinates
253253
Object *searchListForRadarLocationMatch( RadarObject *listHead, ICoord2D *radarMatch );
254254

255+
void linkRadarObject( RadarObject *newObj, RadarObject **list );
256+
void assignObjectColorToRadarObject( RadarObject *radarObj, Object *obj );
257+
255258
Bool m_radarHidden[MAX_PLAYER_COUNT]; ///< true when radar is not visible
256259
Bool m_radarForceOn[MAX_PLAYER_COUNT]; ///< true when radar is forced to be on
257260
RadarObject *m_objectList; ///< list of objects in the radar

GeneralsMD/Code/GameEngine/Source/Common/System/Radar.cpp

Lines changed: 120 additions & 111 deletions
Original file line numberDiff line numberDiff line change
@@ -427,50 +427,7 @@ RadarObjectType Radar::addObject( Object *obj )
427427
newObj->friend_setObject( obj );
428428

429429
// set color for this object on the radar
430-
const Player *player = obj->getControllingPlayer();
431-
Player *clientPlayer = rts::getObservedOrLocalPlayer();
432-
Bool useIndicatorColor = true;
433-
434-
if( obj->isKindOf( KINDOF_DISGUISER ) )
435-
{
436-
//Because we have support for disguised units pretending to be units from another
437-
//team, we need to intercept it here and make sure it's rendered appropriately
438-
//based on which client is rendering it.
439-
StealthUpdate *update = obj->getStealth();
440-
if( update )
441-
{
442-
if( update->isDisguised() )
443-
{
444-
Player *disguisedPlayer = ThePlayerList->getNthPlayer( update->getDisguisedPlayerIndex() );
445-
if( player->getRelationship( clientPlayer->getDefaultTeam() ) != ALLIES && clientPlayer->isPlayerActive() )
446-
{
447-
//Neutrals and enemies will see this disguised unit as the team it's disguised as.
448-
player = disguisedPlayer;
449-
if( player )
450-
useIndicatorColor = false;
451-
}
452-
//Otherwise, the color will show up as the team it really belongs to (already set above).
453-
}
454-
}
455-
}
456-
457-
if( obj->getContain() )
458-
{
459-
// To handle Stealth garrison, ask containers what color they are drawing with to the local player.
460-
// Local is okay because radar display is not synced.
461-
player = obj->getContain()->getApparentControllingPlayer( clientPlayer );
462-
if( player )
463-
useIndicatorColor = false;
464-
}
465-
466-
if( useIndicatorColor || (player == NULL) )
467-
{
468-
newObj->setColor( obj->getIndicatorColor() );
469-
}
470-
else
471-
{
472-
newObj->setColor( player->getPlayerColor() );
473-
}
430+
assignObjectColorToRadarObject( newObj, obj );
474431

475432
// set a chunk of radar data in the object
476433
obj->friend_setRadarData( newObj );
@@ -492,73 +449,7 @@ RadarObjectType Radar::addObject( Object *obj )
492449
}
493450

494451
// link object to master list at the head of it's priority section
495-
if( *list == NULL )
496-
*list = newObj; // trivial case, an empty list
497-
else
498-
{
499-
RadarPriorityType prevPriority, currPriority;
500-
RadarObject *currObject, *prevObject, *nextObject;
501-
502-
prevObject = NULL;
503-
prevPriority = RADAR_PRIORITY_INVALID;
504-
for( currObject = *list; currObject; currObject = nextObject )
505-
{
506-
507-
// get the next object
508-
nextObject = currObject->friend_getNext();
509-
510-
// get the priority of this entry in the list (currPriority)
511-
currPriority = currObject->friend_getObject()->getRadarPriority();
512-
513-
//
514-
// if there is no previous object, or the previous priority is less than the
515-
// our new priority, and the current object in the list has a priority
516-
// higher than our equal to our own we need to be inserted here
517-
//
518-
if( (prevObject == NULL || prevPriority < newPriority ) &&
519-
(currPriority >= newPriority) )
520-
{
521-
522-
// insert into the list just ahead of currObject
523-
if( prevObject )
524-
{
525-
526-
// the new entry next points to what the previous one used to point to
527-
newObj->friend_setNext( prevObject->friend_getNext() );
528-
529-
// the previous one next now points to the new entry
530-
prevObject->friend_setNext( newObj );
531-
532-
}
533-
else
534-
{
535-
536-
// the new object next points to the current object
537-
newObj->friend_setNext( currObject );
538-
539-
// new list head is now newObj
540-
*list = newObj;
541-
542-
}
543-
544-
break; // exit for, stop the insert
545-
546-
}
547-
else if( nextObject == NULL )
548-
{
549-
550-
// at the end of the list, put object here
551-
currObject->friend_setNext( newObj );
552-
553-
}
554-
555-
// our current object is now the previous object
556-
prevObject = currObject;
557-
prevPriority = currPriority;
558-
559-
}
560-
561-
}
452+
linkRadarObject(newObj, list);
562453

563454
return objectType;
564455
}
@@ -1607,3 +1498,121 @@ Bool Radar::isPriorityVisible( RadarPriorityType priority )
16071498
}
16081499

16091500
}
1501+
1502+
// ------------------------------------------------------------------------------------------------
1503+
// ------------------------------------------------------------------------------------------------
1504+
void Radar::linkRadarObject( RadarObject *newObj, RadarObject **list )
1505+
{
1506+
if( *list == NULL )
1507+
{
1508+
// trivial case, an empty list
1509+
*list = newObj;
1510+
return;
1511+
}
1512+
1513+
RadarPriorityType newPriority = newObj->friend_getObject()->getRadarPriority();
1514+
RadarPriorityType prevPriority;
1515+
RadarPriorityType currPriority;
1516+
RadarObject *currObject;
1517+
RadarObject *prevObject;
1518+
RadarObject *nextObject;
1519+
1520+
DEBUG_ASSERTCRASH(newObj->friend_getNext() == NULL, "newObj->friend_getNext is not NULL");
1521+
1522+
prevObject = NULL;
1523+
prevPriority = RADAR_PRIORITY_INVALID;
1524+
for( currObject = *list; currObject; currObject = nextObject )
1525+
{
1526+
// get the next object
1527+
nextObject = currObject->friend_getNext();
1528+
1529+
// get the priority of this entry in the list (currPriority)
1530+
currPriority = currObject->friend_getObject()->getRadarPriority();
1531+
1532+
//
1533+
// if there is no previous object, or the previous priority is less than the
1534+
// our new priority, and the current object in the list has a priority
1535+
// higher than our equal to our own we need to be inserted here
1536+
//
1537+
if( (prevObject == NULL || prevPriority < newPriority ) && (currPriority >= newPriority) )
1538+
{
1539+
// insert into the list just ahead of currObject
1540+
if( prevObject )
1541+
{
1542+
// the new entry next points to what the previous one used to point to
1543+
newObj->friend_setNext( prevObject->friend_getNext() );
1544+
1545+
// the previous one next now points to the new entry
1546+
prevObject->friend_setNext( newObj );
1547+
}
1548+
else
1549+
{
1550+
// the new object next points to the current object
1551+
newObj->friend_setNext( currObject );
1552+
1553+
// new list head is now newObj
1554+
*list = newObj;
1555+
}
1556+
break;
1557+
}
1558+
else if( nextObject == NULL )
1559+
{
1560+
// at the end of the list, put object here
1561+
currObject->friend_setNext( newObj );
1562+
}
1563+
1564+
// our current object is now the previous object
1565+
prevObject = currObject;
1566+
prevPriority = currPriority;
1567+
}
1568+
}
1569+
1570+
// ------------------------------------------------------------------------------------------------
1571+
// ------------------------------------------------------------------------------------------------
1572+
void Radar::assignObjectColorToRadarObject( RadarObject *radarObj, Object *obj )
1573+
{
1574+
const Player *player = obj->getControllingPlayer();
1575+
Player *clientPlayer = rts::getObservedOrLocalPlayer();
1576+
Bool useIndicatorColor = true;
1577+
1578+
if( obj->isKindOf( KINDOF_DISGUISER ) )
1579+
{
1580+
//Because we have support for disguised units pretending to be units from another
1581+
//team, we need to intercept it here and make sure it's rendered appropriately
1582+
//based on which client is rendering it.
1583+
StealthUpdate *update = obj->getStealth();
1584+
if( update )
1585+
{
1586+
if( update->isDisguised() )
1587+
{
1588+
Player *disguisedPlayer = ThePlayerList->getNthPlayer( update->getDisguisedPlayerIndex() );
1589+
if( player->getRelationship( clientPlayer->getDefaultTeam() ) != ALLIES && clientPlayer->isPlayerActive() )
1590+
{
1591+
//Neutrals and enemies will see this disguised unit as the team it's disguised as.
1592+
player = disguisedPlayer;
1593+
if( player )
1594+
useIndicatorColor = false;
1595+
}
1596+
//Otherwise, the color will show up as the team it really belongs to (already set above).
1597+
}
1598+
}
1599+
}
1600+
1601+
if( obj->getContain() )
1602+
{
1603+
// To handle Stealth garrison, ask containers what color they are drawing with to the local player.
1604+
// Local is okay because radar display is not synced.
1605+
player = obj->getContain()->getApparentControllingPlayer( clientPlayer );
1606+
if( player )
1607+
useIndicatorColor = false;
1608+
}
1609+
1610+
if( useIndicatorColor || (player == NULL) )
1611+
{
1612+
radarObj->setColor( obj->getIndicatorColor() );
1613+
}
1614+
else
1615+
{
1616+
radarObj->setColor( player->getPlayerColor() );
1617+
}
1618+
}

GeneralsMD/Code/GameEngineDevice/Source/W3DDevice/Common/System/W3DRadar.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,6 +1018,8 @@ RadarObjectType W3DRadar::addObject( Object* obj )
10181018
}
10191019

10201020
//-------------------------------------------------------------------------------------------------
1021+
// TheSuperHackers @bugfix xezon 05/07/2025 Now removes the cached hero immediately because
1022+
// otherwise the object pointer could be dangling and used for a bit too long.
10211023
//-------------------------------------------------------------------------------------------------
10221024
RadarObjectType W3DRadar::removeObject( Object* obj )
10231025
{

0 commit comments

Comments
 (0)