Skip to content

Commit aa36cd6

Browse files
authored
bugfix(rallypoint): Make healed units follow building rally point on exit (#1822)
1 parent b4b1cd7 commit aa36cd6

6 files changed

Lines changed: 84 additions & 4 deletions

File tree

Generals/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -925,8 +925,8 @@ void OpenContain::exitObjectViaDoor( Object *exitObj, ExitDoorType exitDoor )
925925
std::vector<Coord3D> exitPath;
926926
exitPath.push_back(endPosition);
927927
exitPath.push_back(endPosition); // Do it twice, in case units stack up due to brief flying. jba.
928-
if (m_rallyPointExists) {
929-
exitPath.push_back(m_rallyPoint);
928+
if (const Coord3D *rallyPoint = getRallyPoint()) {
929+
exitPath.push_back(*rallyPoint);
930930
}
931931

932932
if( ai )
@@ -1422,6 +1422,18 @@ const Coord3D *OpenContain::getRallyPoint() const
14221422
if (m_rallyPointExists)
14231423
return &m_rallyPoint;
14241424

1425+
#if !RETAIL_COMPATIBLE_CRC
1426+
// TheSuperHackers @bugfix arcticdolphin 02/03/2026 Use primary exit interface rally point if available.
1427+
if (getObject())
1428+
{
1429+
ExitInterface *primaryExit = getObject()->getObjectExitInterface();
1430+
if (primaryExit && primaryExit != static_cast<const ExitInterface *>(this))
1431+
{
1432+
return primaryExit->getRallyPoint();
1433+
}
1434+
}
1435+
#endif
1436+
14251437
return nullptr;
14261438
}
14271439

Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,6 +1032,20 @@ UpdateSleepTime ChinookAIUpdate::update()
10321032
// we're completely healed, so take off again
10331033
pp->setHealee(getObject(), false);
10341034
setMyState(TAKING_OFF, nullptr, nullptr, CMD_FROM_AI);
1035+
1036+
#if !RETAIL_COMPATIBLE_CRC
1037+
// TheSuperHackers @bugfix arcticdolphin 02/03/2026 Move healed Chinook to rally point if present.
1038+
if (Object *airfield = TheGameLogic->findObjectByID( m_airfieldForHealing ))
1039+
{
1040+
if (ExitInterface *exitInterface = airfield->getObjectExitInterface())
1041+
{
1042+
if (const Coord3D *rallyPoint = exitInterface->getRallyPoint())
1043+
{
1044+
aiMoveToPosition( rallyPoint, CMD_FROM_AI );
1045+
}
1046+
}
1047+
}
1048+
#endif
10351049
}
10361050
else
10371051
{

Generals/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1776,6 +1776,20 @@ UpdateSleepTime JetAIUpdate::update()
17761776
getStateMachine()->clear();
17771777
setLastCommandSource( CMD_FROM_AI );
17781778
getStateMachine()->setState( TAKING_OFF_AWAIT_CLEARANCE );
1779+
1780+
#if !RETAIL_COMPATIBLE_CRC
1781+
// TheSuperHackers @bugfix arcticdolphin 02/03/2026 Move healed helicopter to rally point if present.
1782+
if (Object *airfield = TheGameLogic->findObjectByID( jet->getProducerID() ))
1783+
{
1784+
if (ExitInterface *exitInterface = airfield->getObjectExitInterface())
1785+
{
1786+
if (const Coord3D *rallyPoint = exitInterface->getRallyPoint())
1787+
{
1788+
aiMoveToPosition( rallyPoint, CMD_FROM_AI );
1789+
}
1790+
}
1791+
}
1792+
#endif
17791793
}
17801794
else
17811795
{

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Contain/OpenContain.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1045,8 +1045,8 @@ void OpenContain::exitObjectViaDoor( Object *exitObj, ExitDoorType exitDoor )
10451045
std::vector<Coord3D> exitPath;
10461046
exitPath.push_back(endPosition);
10471047
exitPath.push_back(endPosition); // Do it twice, in case units stack up due to brief flying. jba.
1048-
if (m_rallyPointExists) {
1049-
exitPath.push_back(m_rallyPoint);
1048+
if (const Coord3D *rallyPoint = getRallyPoint()) {
1049+
exitPath.push_back(*rallyPoint);
10501050
}
10511051

10521052
if( ai )
@@ -1609,6 +1609,18 @@ const Coord3D *OpenContain::getRallyPoint() const
16091609
if (m_rallyPointExists)
16101610
return &m_rallyPoint;
16111611

1612+
#if !RETAIL_COMPATIBLE_CRC
1613+
// TheSuperHackers @bugfix arcticdolphin 02/03/2026 Use primary exit interface rally point if available.
1614+
if (getObject())
1615+
{
1616+
ExitInterface *primaryExit = getObject()->getObjectExitInterface();
1617+
if (primaryExit && primaryExit != static_cast<const ExitInterface *>(this))
1618+
{
1619+
return primaryExit->getRallyPoint();
1620+
}
1621+
}
1622+
#endif
1623+
16121624
return nullptr;
16131625
}
16141626

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/ChinookAIUpdate.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1094,6 +1094,20 @@ UpdateSleepTime ChinookAIUpdate::update()
10941094
// we're completely healed, so take off again
10951095
pp->setHealee(getObject(), false);
10961096
setMyState(TAKING_OFF, nullptr, nullptr, CMD_FROM_AI);
1097+
1098+
#if !RETAIL_COMPATIBLE_CRC
1099+
// TheSuperHackers @bugfix arcticdolphin 02/03/2026 Move healed Chinook to rally point if present.
1100+
if (Object *airfield = TheGameLogic->findObjectByID( m_airfieldForHealing ))
1101+
{
1102+
if (ExitInterface *exitInterface = airfield->getObjectExitInterface())
1103+
{
1104+
if (const Coord3D *rallyPoint = exitInterface->getRallyPoint())
1105+
{
1106+
aiMoveToPosition( rallyPoint, CMD_FROM_AI );
1107+
}
1108+
}
1109+
}
1110+
#endif
10971111
}
10981112
else
10991113
{

GeneralsMD/Code/GameEngine/Source/GameLogic/Object/Update/AIUpdate/JetAIUpdate.cpp

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1998,6 +1998,20 @@ UpdateSleepTime JetAIUpdate::update()
19981998
getStateMachine()->clear();
19991999
setLastCommandSource( CMD_FROM_AI );
20002000
getStateMachine()->setState( TAKING_OFF_AWAIT_CLEARANCE );
2001+
2002+
#if !RETAIL_COMPATIBLE_CRC
2003+
// TheSuperHackers @bugfix arcticdolphin 02/03/2026 Move healed helicopter to rally point if present.
2004+
if (Object *airfield = TheGameLogic->findObjectByID( jet->getProducerID() ))
2005+
{
2006+
if (ExitInterface *exitInterface = airfield->getObjectExitInterface())
2007+
{
2008+
if (const Coord3D *rallyPoint = exitInterface->getRallyPoint())
2009+
{
2010+
aiMoveToPosition( rallyPoint, CMD_FROM_AI );
2011+
}
2012+
}
2013+
}
2014+
#endif
20012015
}
20022016
else
20032017
{

0 commit comments

Comments
 (0)