Skip to content
20 changes: 16 additions & 4 deletions Generals/Code/GameEngine/Include/GameLogic/AI.h
Original file line number Diff line number Diff line change
Expand Up @@ -536,18 +536,30 @@ class AICommandInterface
aiDoCommand(&parms);
}

inline void aiFollowExitProductionPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource )
inline void aiFollowExitProductionPath( std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource )
{
AICommandParms parms(AICMD_FOLLOW_EXITPRODUCTION_PATH, cmdSource);
parms.m_coords = *path;
#if __cplusplus >= 201103L
parms.m_coords = std::move(*path);
#else
// TheSuperHackers @performance bobtista 23/11/2025 Use swap to emulate move semantics for VC6 compatibility
parms.m_coords.swap(*path);
path->clear();
#endif
parms.m_obj = ignoreObject;
aiDoCommand(&parms);
}

inline void aiFollowPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource )
inline void aiFollowPath( std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource )
{
AICommandParms parms(AICMD_FOLLOW_PATH, cmdSource);
parms.m_coords = *path;
#if __cplusplus >= 201103L
parms.m_coords = std::move(*path);
Copy link

Choose a reason for hiding this comment

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

Keep it simple and use swap even for c++11

Copy link

@Caball009 Caball009 Nov 25, 2025

Choose a reason for hiding this comment

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

Swap is unnecessary here and does not convey the intended operation: a single move operation; we don't care about the contents (if anything) of parms.m_coords.

Copy link

Choose a reason for hiding this comment

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

Yes but then we do not need all this #if __cplusplus >= 201103L stuff here.

Otherwise, create a "move" helper somewhere else that we use here, which does move in c++11 and swap in C++98.

Copy link
Author

Choose a reason for hiding this comment

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

Ok I added a helper to CppMacros.h

Copy link

Choose a reason for hiding this comment

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

Ok that works. I think CppMacros.h needs renaming to to cpp_compat.h later :-)

#else
// TheSuperHackers @performance bobtista 23/11/2025 Use swap to emulate move semantics for VC6 compatibility
parms.m_coords.swap(*path);
path->clear();
Copy link

Choose a reason for hiding this comment

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

This clear() is redundant. path will already be empty.

Choose a reason for hiding this comment

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

path will already be empty.

Why would it be?

Copy link

Choose a reason for hiding this comment

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

Because AICommandParms parms(...) is created with empty m_coords.

Choose a reason for hiding this comment

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

I think making the code clearer at a 'local' level can't hurt, but this is now probably a moot point with a swap / move helper function.

Copy link

Choose a reason for hiding this comment

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

You are not wrong, it is reasonable to make the intent clear, but in that case a comment would be better then instead of adding a redundant function call.

#endif
parms.m_obj = ignoreObject;
aiDoCommand(&parms);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class AIStateMachine : public StateMachine
virtual StateReturnType setState( StateID newStateID );

/// @todo Rethink state parameter passing. Continuing in this fashion will have a pile of params in the machine (MSB)
void setGoalPath( const std::vector<Coord3D>* path );
void setGoalPath( std::vector<Coord3D>* path );
void addToGoalPath( const Coord3D *pathPoint );
const Coord3D *getGoalPathPosition( Int i ) const; ///< return path position at index "i"
Int getGoalPathSize() const { return m_goalPath.size(); }
Expand Down
4 changes: 2 additions & 2 deletions Generals/Code/GameEngine/Include/GameLogic/Module/AIUpdate.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ class AIUpdateInterface : public UpdateModule, public AICommandInterface
virtual void privateFollowWaypointPathAsTeam( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point
virtual void privateFollowWaypointPathExact( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point
virtual void privateFollowWaypointPathAsTeamExact( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point
virtual void privateFollowPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction );///< follow the path defined by the given array of points
virtual void privateFollowPath( std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction );///< follow the path defined by the given array of points
virtual void privateFollowPathAppend( const Coord3D *pos, CommandSourceType cmdSource );
virtual void privateAttackObject( Object *victim, Int maxShotsToFire, CommandSourceType cmdSource ); ///< attack given object
virtual void privateForceAttackObject( Object *victim, Int maxShotsToFire, CommandSourceType cmdSource ); ///< attack given object
Expand Down Expand Up @@ -338,7 +338,7 @@ class AIUpdateInterface : public UpdateModule, public AICommandInterface
virtual Bool isBusy() const;

virtual void onObjectCreated();
virtual void doQuickExit( const std::vector<Coord3D>* path ); ///< get out of this Object
virtual void doQuickExit( std::vector<Coord3D>* path ); ///< get out of this Object

virtual void aiDoCommand(const AICommandParms* parms);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ class JetAIUpdate : public AIUpdateInterface
Real friend_getMinHeight() const { return getJetAIUpdateModuleData()->m_minHeight; }
Real friend_getParkingOffset() const { return getJetAIUpdateModuleData()->m_parkingOffset; }
UnsignedInt friend_getTakeoffPause() const { return getJetAIUpdateModuleData()->m_takeoffPause; }
void friend_setGoalPath( const std::vector<Coord3D>* path ) { getStateMachine()->setGoalPath(path); }
void friend_setGoalPath( std::vector<Coord3D>* path ) { getStateMachine()->setGoalPath(path); }
void friend_setTakeoffInProgress(Bool v) { setFlag(TAKEOFF_IN_PROGRESS, v); }
void friend_setLandingInProgress(Bool v) { setFlag(LANDING_IN_PROGRESS, v); }
void friend_setTaxiInProgress(Bool v) { setFlag(TAXI_IN_PROGRESS, v); }
Expand All @@ -122,7 +122,7 @@ class JetAIUpdate : public AIUpdateInterface

virtual AIStateMachine* makeStateMachine();

virtual void privateFollowPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction );///< follow the path defined by the given array of points
virtual void privateFollowPath( std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction );///< follow the path defined by the given array of points
virtual void privateFollowPathAppend( const Coord3D *pos, CommandSourceType cmdSource );
virtual void privateEnter( Object *obj, CommandSourceType cmdSource ); ///< enter the given object
virtual void privateGetRepaired( Object *repairDepot, CommandSourceType cmdSource );///< get repaired at repair depot
Expand Down
11 changes: 9 additions & 2 deletions Generals/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -816,9 +816,16 @@ void AIStateMachine::loadPostProcess( void )
/**
* Define a simple path
*/
void AIStateMachine::setGoalPath( const std::vector<Coord3D>* path )
void AIStateMachine::setGoalPath( std::vector<Coord3D>* path )
{
m_goalPath = *path;
#if __cplusplus >= 201103L
m_goalPath = std::move(*path);
#else
// TheSuperHackers @performance bobtista 23/11/2025 Use swap to emulate move semantics for VC6 compatibility
// Swap transfers ownership without copying. Clear source to make intent explicit.
m_goalPath.swap(*path);
path->clear();
#endif
}

#ifdef STATE_MACHINE_DEBUG
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2619,13 +2619,13 @@ void AIUpdateInterface::aiDoCommand(const AICommandParms* parms)
privateFollowWaypointPathAsTeamExact(parms->m_waypoint, parms->m_cmdSource);
break;
case AICMD_FOLLOW_PATH:
privateFollowPath(&parms->m_coords, parms->m_obj, parms->m_cmdSource, FALSE);
privateFollowPath(&const_cast<AICommandParms*>(parms)->m_coords, parms->m_obj, parms->m_cmdSource, FALSE);
break;
case AICMD_FOLLOW_PATH_APPEND:
privateFollowPathAppend(&parms->m_pos, parms->m_cmdSource);
break;
case AICMD_FOLLOW_EXITPRODUCTION_PATH:
privateFollowPath(&parms->m_coords, parms->m_obj, parms->m_cmdSource, TRUE);
privateFollowPath(&const_cast<AICommandParms*>(parms)->m_coords, parms->m_obj, parms->m_cmdSource, TRUE);
break;
case AICMD_ATTACK_OBJECT:
privateAttackObject(parms->m_obj, parms->m_intValue, parms->m_cmdSource);
Expand Down Expand Up @@ -3240,7 +3240,7 @@ void AIUpdateInterface::privateFollowPathAppend( const Coord3D *pos, CommandSour
/**
* Follow the path defined by the given array of points
*/
void AIUpdateInterface::privateFollowPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction )
void AIUpdateInterface::privateFollowPath( std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction )
{
if (getObject()->isMobile() == FALSE)
return;
Expand Down Expand Up @@ -3681,7 +3681,7 @@ void AIUpdateInterface::privateExit( Object *objectToExit, CommandSourceType cmd
/**
* Get out of whatever it is inside of
*/
void AIUpdateInterface::doQuickExit( const std::vector<Coord3D>* path )
void AIUpdateInterface::doQuickExit( std::vector<Coord3D>* path )
{

Bool locked = getStateMachine()->isLocked();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2175,7 +2175,7 @@ Bool JetAIUpdate::getTreatAsAircraftForLocoDistToGoal() const
/**
* Follow the path defined by the given array of points
*/
void JetAIUpdate::privateFollowPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction )
void JetAIUpdate::privateFollowPath( std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction )
{
if (exitProduction)
{
Expand Down
20 changes: 16 additions & 4 deletions GeneralsMD/Code/GameEngine/Include/GameLogic/AI.h
Original file line number Diff line number Diff line change
Expand Up @@ -550,18 +550,30 @@ class AICommandInterface
aiDoCommand(&parms);
}

inline void aiFollowExitProductionPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource )
inline void aiFollowExitProductionPath( std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource )
{
AICommandParms parms(AICMD_FOLLOW_EXITPRODUCTION_PATH, cmdSource);
parms.m_coords = *path;
#if __cplusplus >= 201103L
parms.m_coords = std::move(*path);
#else
// TheSuperHackers @performance bobtista 23/11/2025 Use swap to emulate move semantics for VC6 compatibility
parms.m_coords.swap(*path);
path->clear();
#endif
parms.m_obj = ignoreObject;
aiDoCommand(&parms);
}

inline void aiFollowPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource )
inline void aiFollowPath( std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource )
{
AICommandParms parms(AICMD_FOLLOW_PATH, cmdSource);
parms.m_coords = *path;
#if __cplusplus >= 201103L
parms.m_coords = std::move(*path);
#else
// TheSuperHackers @performance bobtista 23/11/2025 Use swap to emulate move semantics for VC6 compatibility
parms.m_coords.swap(*path);
path->clear();
#endif
parms.m_obj = ignoreObject;
aiDoCommand(&parms);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ class AIStateMachine : public StateMachine
virtual StateReturnType setState( StateID newStateID );

/// @todo Rethink state parameter passing. Continuing in this fashion will have a pile of params in the machine (MSB)
void setGoalPath( const std::vector<Coord3D>* path );
void setGoalPath( std::vector<Coord3D>* path );
void addToGoalPath( const Coord3D *pathPoint );
const Coord3D *getGoalPathPosition( Int i ) const; ///< return path position at index "i"
Int getGoalPathSize() const { return m_goalPath.size(); }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ class AIUpdateInterface : public UpdateModule, public AICommandInterface
virtual void privateFollowWaypointPathAsTeam( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point
virtual void privateFollowWaypointPathExact( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point
virtual void privateFollowWaypointPathAsTeamExact( const Waypoint *way, CommandSourceType cmdSource );///< start following the path from the given point
virtual void privateFollowPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction );///< follow the path defined by the given array of points
virtual void privateFollowPath( std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction );///< follow the path defined by the given array of points
virtual void privateFollowPathAppend( const Coord3D *pos, CommandSourceType cmdSource );
virtual void privateAttackObject( Object *victim, Int maxShotsToFire, CommandSourceType cmdSource ); ///< attack given object
virtual void privateForceAttackObject( Object *victim, Int maxShotsToFire, CommandSourceType cmdSource ); ///< attack given object
Expand Down Expand Up @@ -351,7 +351,7 @@ class AIUpdateInterface : public UpdateModule, public AICommandInterface
virtual Bool isBusy() const;

virtual void onObjectCreated();
virtual void doQuickExit( const std::vector<Coord3D>* path ); ///< get out of this Object
virtual void doQuickExit( std::vector<Coord3D>* path ); ///< get out of this Object

virtual void aiDoCommand(const AICommandParms* parms);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ class JetAIUpdate : public AIUpdateInterface
Real friend_getMinHeight() const { return getJetAIUpdateModuleData()->m_minHeight; }
Real friend_getParkingOffset() const { return getJetAIUpdateModuleData()->m_parkingOffset; }
UnsignedInt friend_getTakeoffPause() const { return getJetAIUpdateModuleData()->m_takeoffPause; }
void friend_setGoalPath( const std::vector<Coord3D>* path ) { getStateMachine()->setGoalPath(path); }
void friend_setGoalPath( std::vector<Coord3D>* path ) { getStateMachine()->setGoalPath(path); }
void friend_setTakeoffInProgress(Bool v) { setFlag(TAKEOFF_IN_PROGRESS, v); }
void friend_setLandingInProgress(Bool v) { setFlag(LANDING_IN_PROGRESS, v); }
void friend_setTaxiInProgress(Bool v) { setFlag(TAXI_IN_PROGRESS, v); }
Expand All @@ -131,7 +131,7 @@ class JetAIUpdate : public AIUpdateInterface

virtual AIStateMachine* makeStateMachine();

virtual void privateFollowPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction );///< follow the path defined by the given array of points
virtual void privateFollowPath( std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction );///< follow the path defined by the given array of points
virtual void privateFollowPathAppend( const Coord3D *pos, CommandSourceType cmdSource );
virtual void privateEnter( Object *obj, CommandSourceType cmdSource ); ///< enter the given object
virtual void privateGetRepaired( Object *repairDepot, CommandSourceType cmdSource );///< get repaired at repair depot
Expand Down
11 changes: 9 additions & 2 deletions GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIStates.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -821,9 +821,16 @@ void AIStateMachine::loadPostProcess( void )
/**
* Define a simple path
*/
void AIStateMachine::setGoalPath( const std::vector<Coord3D>* path )
void AIStateMachine::setGoalPath( std::vector<Coord3D>* path )
{
m_goalPath = *path;
#if __cplusplus >= 201103L
m_goalPath = std::move(*path);
#else
// TheSuperHackers @performance bobtista 23/11/2025 Use swap to emulate move semantics for VC6 compatibility
// Swap transfers ownership without copying. Clear source to make intent explicit.
m_goalPath.swap(*path);
path->clear();
#endif
}

#ifdef STATE_MACHINE_DEBUG
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2681,13 +2681,13 @@ void AIUpdateInterface::aiDoCommand(const AICommandParms* parms)
privateFollowWaypointPathAsTeamExact(parms->m_waypoint, parms->m_cmdSource);
break;
case AICMD_FOLLOW_PATH:
privateFollowPath(&parms->m_coords, parms->m_obj, parms->m_cmdSource, FALSE);
privateFollowPath(&const_cast<AICommandParms*>(parms)->m_coords, parms->m_obj, parms->m_cmdSource, FALSE);
break;
case AICMD_FOLLOW_PATH_APPEND:
privateFollowPathAppend(&parms->m_pos, parms->m_cmdSource);
break;
case AICMD_FOLLOW_EXITPRODUCTION_PATH:
privateFollowPath(&parms->m_coords, parms->m_obj, parms->m_cmdSource, TRUE);
privateFollowPath(&const_cast<AICommandParms*>(parms)->m_coords, parms->m_obj, parms->m_cmdSource, TRUE);
break;
case AICMD_ATTACK_OBJECT:
privateAttackObject(parms->m_obj, parms->m_intValue, parms->m_cmdSource);
Expand Down Expand Up @@ -3381,7 +3381,7 @@ void AIUpdateInterface::privateFollowPathAppend( const Coord3D *pos, CommandSour
/**
* Follow the path defined by the given array of points
*/
void AIUpdateInterface::privateFollowPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction )
void AIUpdateInterface::privateFollowPath( std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction )
{
if (getObject()->isMobile() == FALSE)
return;
Expand Down Expand Up @@ -3873,7 +3873,7 @@ void AIUpdateInterface::privateExitInstantly( Object *objectToExit, CommandSourc
/**
* Get out of whatever it is inside of
*/
void AIUpdateInterface::doQuickExit( const std::vector<Coord3D>* path )
void AIUpdateInterface::doQuickExit( std::vector<Coord3D>* path )
{

Bool locked = getStateMachine()->isLocked();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2402,7 +2402,7 @@ Bool JetAIUpdate::getTreatAsAircraftForLocoDistToGoal() const
/**
* Follow the path defined by the given array of points
*/
void JetAIUpdate::privateFollowPath( const std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction )
void JetAIUpdate::privateFollowPath( std::vector<Coord3D>* path, Object *ignoreObject, CommandSourceType cmdSource, Bool exitProduction )
{
if (exitProduction)
{
Expand Down
Loading