Skip to content
Open
Show file tree
Hide file tree
Changes from 6 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
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);
#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 @@ -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);
Copy link

Choose a reason for hiding this comment

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

What is going on with the const_cast here? This looks dangerous. Can we get rid of it?

Copy link
Author

Choose a reason for hiding this comment

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

Yeah, it can be mutable. Another option maybe we change aiDoCommand to take non-const pointer, but that changes more stuff. I set it to mutable.

Copy link

Choose a reason for hiding this comment

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

That is not so elegant either.

The problem looks to be that AICommandParms is passed as const to aiDoCommand functions. I suspect we need another change and pass it as non const, UNLESS there is a very good reason why we cannot consume these structures.

This would also allow to optimize this call:

m_pendingCommand.store(*parms)

It currently creates a copy of the whole thing, instead of swapping/moving it.

Perhaps we need another change, refactoring aiDoCommand first, then optimize m_pendingCommand and this change.

Copy link
Author

Choose a reason for hiding this comment

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

#1924, and I used a script to replicate to generals :)

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