unify(pathfinder): Sanitize and merge AIPathfind and dependencies#2341
unify(pathfinder): Sanitize and merge AIPathfind and dependencies#2341Mauller wants to merge 11 commits intoTheSuperHackers:mainfrom
Conversation
…ghboringCells, safe merge
…State, safe merge
60286bd to
e20892a
Compare
|
| Filename | Overview |
|---|---|
| Generals/Code/GameEngine/Source/GameLogic/AI/AIPathfind.cpp | Major merge with conditionals, contains critical orphaned else compilation error at line 2810 |
| GeneralsMD/Code/GameEngine/Source/GameLogic/AI/AIPathfind.cpp | Cleaned up implementation with formatting improvements, safe merges from Generals |
| Generals/Code/GameEngine/Include/GameLogic/AIPathfind.h | Header merge with function signature changes, returns boolean from setTypeAsObstacle |
Last reviewed commit: 35a0d0a
e20892a to
180cc40
Compare
|
|
||
| Bool quickDoesPathExist( const LocomotorSet& locomotorSet, const Coord3D *from, const Coord3D *to ); ///< Can we build any path at all between the locations (terrain & buildings check - fast) | ||
| Bool clientSafeQuickDoesPathExist( const LocomotorSet& locomotorSet, const Coord3D *from, const Coord3D *to ); ///< Can we build any path at all between the locations (terrain & buildings check - fast) | ||
| Bool clientSafeQuickDoesPathExistForUI( const LocomotorSet& locomotorSet, const Coord3D *from, const Coord3D *to ); ///< Can we build any path at all between the locations (terrain onlyk - fast) |
There was a problem hiding this comment.
typo: onlyk should be only
| Bool clientSafeQuickDoesPathExistForUI( const LocomotorSet& locomotorSet, const Coord3D *from, const Coord3D *to ); ///< Can we build any path at all between the locations (terrain onlyk - fast) | |
| Bool clientSafeQuickDoesPathExistForUI( const LocomotorSet& locomotorSet, const Coord3D *from, const Coord3D *to ); ///< Can we build any path at all between the locations (terrain only - fast) |
Prompt To Fix With AI
This is a comment left during a code review.
Path: Generals/Code/GameEngine/Include/GameLogic/AIPathfind.h
Line: 667
Comment:
typo: `onlyk` should be `only`
```suggestion
Bool clientSafeQuickDoesPathExistForUI( const LocomotorSet& locomotorSet, const Coord3D *from, const Coord3D *to ); ///< Can we build any path at all between the locations (terrain only - fast)
```
How can I resolve this? If you propose a fix, please make it concise.| #if RTS_GENERALS | ||
| Bool m_needToCalculateZones; ///< True if terrain has changed. | ||
| #else | ||
| UnsignedInt m_nextFrameToCalculateZones; ///< WHen should I recalculate, next?. |
There was a problem hiding this comment.
typo: WHen should be When
| UnsignedInt m_nextFrameToCalculateZones; ///< WHen should I recalculate, next?. | |
| UnsignedInt m_nextFrameToCalculateZones; ///< When should I recalculate, next?. |
Prompt To Fix With AI
This is a comment left during a code review.
Path: Generals/Code/GameEngine/Include/GameLogic/AIPathfind.h
Line: 585
Comment:
typo: `WHen` should be `When`
```suggestion
UnsignedInt m_nextFrameToCalculateZones; ///< When should I recalculate, next?.
```
How can I resolve this? If you propose a fix, please make it concise.|
Had to fix a small dependency that i missed when building debug in generals |
| CELL_OBSTACLE = 0x04, ///< Occupied by a structure | ||
| CELL_BRIDGE_IMPASSABLE = 0x05, ///< Piece of a bridge that is impassable. | ||
| #if RTS_ZEROHOUR | ||
| CELL_IMPASSABLE = 0x06 ///< Just plain impassable except for aircraft. |
There was a problem hiding this comment.
These are not xfered I think. Would it be an issue if Generals uses 0x06 anyways?
There was a problem hiding this comment.
It's more of a map data issue, the map files also contain data on types of tiles that have been painted onto the map manually.
| { | ||
| #if RTS_GENERALS | ||
| DEBUG_ASSERTCRASH(m_info, ("Has to have info.")); | ||
| #else |
There was a problem hiding this comment.
If m_info is not initialized, this crashes in Generals when m_info->m_pos.x is called.
Therefore the 1.01 patch can be ported to Generals. Game would have crashed at this point anyways, so it will not mismatch.
| return; | ||
| } | ||
| } | ||
| #endif |
There was a problem hiding this comment.
I think this can be simplified to:
if (!ai->isDoingGroundMovement())
{
#if RTS_GENERALS
Bool isUnmannedHelicopter = false;
#else
// exception:sniped choppers are on ground
Bool isUnmannedHelicopter = ( obj->isKindOf( KINDOF_PRODUCED_AT_HELIPAD ) && obj->isDisabledByType( DISABLED_UNMANNED ) ) ;
#endif
if ( ! isUnmannedHelicopter )
{
updateAircraftGoal(obj, newGoalPos);
return;
}
}| // See if the goal is a valid destination. If not, accept closest cell. | ||
| if (closesetCell!=nullptr && !canPathThroughUnits && !checkDestination(obj, parentCell->getXIndex(), parentCell->getYIndex(), parentCell->getLayer(), radius, centerInCell)) { | ||
| #if RTS_GENERALS | ||
| break; |
There was a problem hiding this comment.
If you set foundGoal = true before the break then line 8767
Bool foundGoal = false;doesn't have to be in RTS_ZEROHOUR
and lines 8875-8882
// If we haven't already found the goal cell, continue examining. [8/25/2003]
if (!foundGoal) {
// Check to see if we can change layers in this cell.
checkChangeLayers(parentCell);
count += examineNeighboringCells(parentCell, goalCell, locomotorSet, isHuman, centerInCell, radius, startCellNdx, obj, NO_ATTACK);
}can also do without guards, simplifying the merge.
There was a problem hiding this comment.
Did you mean if i don't set foundGoal before the break, so it remains false? that way the code enters into the block with checkChangeLayers in the generals code like it original would have?
There was a problem hiding this comment.
made the change and no mismatching
| crusher, scanCell.x, scanCell.y, m_map)) { | ||
| PathfindCell *newCell = getCell(LAYER_GROUND, scanCell.x, scanCell.y); | ||
| #if RTS_GENERALS | ||
| if (newCell->hasInfo() && (newCell->getOpen() || newCell->getClosed())) return; // already looked at this one. |
There was a problem hiding this comment.
Is this a bug in Generals, where it should have been !newCell->hasInfo?
There was a problem hiding this comment.
There can be a behavioural difference here, since if newcell does not have info we won't return early in the generals version and instead we will allocate data for it further down before accessing it
There was a problem hiding this comment.
The call to GetZone also does not make use of m_info so it won't crash at this point.
| } | ||
| #endif | ||
| #if RTS_GENERALS | ||
| m_needToCalculateZones = false; |
| #else | ||
| if (zone >= m_maxZone) { | ||
| DEBUG_CRASH(("Invalid zone.")); | ||
| return UNINITIALIZED_ZONE; |
There was a problem hiding this comment.
UNINITIALIZED_ZONE equals 0. Code can be unified without guards.
| #else | ||
| m_zoneManager.updateZonesForModify(m_map, m_layers, cellBounds, m_extent); | ||
|
|
||
| Int i, j; |
| empty = false; | ||
| break; | ||
| #if RTS_ZEROHOUR | ||
| case PathfindCell::CELL_BRIDGE_IMPASSABLE: |
There was a problem hiding this comment.
CELL_BRIDGE_IMPASSABLE is a ZH state that does not get set in generals. It is safe to add this case without guards.
There was a problem hiding this comment.
yeah this should be fine, i left other code in some places in too for generals that considers CELL_BRIDGE_IMPASSABLE since i already merged the enumerations
| if (newObstacle != nullptr && newObstacle->isKindOf(KINDOF_AIRFIELD)) | ||
| #else | ||
| if (newObstacle != nullptr && newObstacle->isKindOf(KINDOF_FS_AIRFIELD)) | ||
| #endif |
There was a problem hiding this comment.
Probably cannot be unified due to enumeration order changes and the enumeration be within xfer?
There was a problem hiding this comment.
yes theres significant differences with KINDOF_AIRFIELD removed from zero hour
There was a problem hiding this comment.
i don't think these can be merged as i think they are baked into data
|
updated based on feedback |
| applyZone(r_thisCell, r_topCell, m_crusherZones, m_maxZone); | ||
| } | ||
| #else | ||
| else |
There was a problem hiding this comment.
orphaned else statement will cause compilation failure in RTS_ZEROHOUR build
The #if RTS_GENERALS branch (lines 2788-2808) contains independent if statements, not an if-else chain. When preprocessing switches to #else, this else keyword has no matching if statement.
Fix: change this to match the earlier pattern (line 2748) where the else comes after the closing brace of the type check if statement on line 2786
Prompt To Fix With AI
This is a comment left during a code review.
Path: Generals/Code/GameEngine/Source/GameLogic/AI/AIPathfind.cpp
Line: 2810
Comment:
orphaned `else` statement will cause compilation failure in RTS_ZEROHOUR build
The `#if RTS_GENERALS` branch (lines 2788-2808) contains independent `if` statements, not an if-else chain. When preprocessing switches to `#else`, this `else` keyword has no matching `if` statement.
Fix: change this to match the earlier pattern (line 2748) where the `else` comes after the closing brace of the type check `if` statement on line 2786
How can I resolve this? If you propose a fix, please make it concise.75d3750 to
35a0d0a
Compare
| applyZone(r_thisCell, r_topCell, m_crusherZones, m_maxZone); | ||
| } | ||
| #else | ||
| else |
There was a problem hiding this comment.
orphaned else - will cause RTS_ZEROHOUR build to fail
The #if RTS_GENERALS block (lines 2788-2808) contains independent if statements, not an if-else chain. When preprocessing removes this block for RTS_ZEROHOUR, this else has no matching if.
Fix: Move else to line 2787 after the closing brace, matching the pattern at line 2748
| else | |
| } | |
| else | |
| { | |
| #else |
Prompt To Fix With AI
This is a comment left during a code review.
Path: Generals/Code/GameEngine/Source/GameLogic/AI/AIPathfind.cpp
Line: 2810
Comment:
orphaned `else` - will cause RTS_ZEROHOUR build to fail
The `#if RTS_GENERALS` block (lines 2788-2808) contains independent `if` statements, not an if-else chain. When preprocessing removes this block for RTS_ZEROHOUR, this `else` has no matching `if`.
Fix: Move `else` to line 2787 after the closing brace, matching the pattern at line 2748
```suggestion
}
else
{
#else
```
How can I resolve this? If you propose a fix, please make it concise.
This PR merged Aipathfind.h and Aipathfind.cpp
The majority of the merge has required conditionals being placed throughout the code, this is due to significant changes between zero hour and generals making the function incompatible.
The majority of the merges are safe and distinct, either directly inherited from zero hour and into generals, or cleaned up from generals into zero hour.
The most involved the majority merge and refactor involves the functions within the PathfindZoneManager, as zero hour changes large portions of this code. The code itself was a mess and i reverted the implementation of parts of it from
whileback toforloops as used within generals to make the code easier to understand.Generals inherited some optimisations from zero hour within PathfindZoneManager but had to retain the original code in other places due to mismatches occuring.
Generals gained the boolean returning versions of the terrain object handling functions, although the generals code does not specifically use them. This was done as a cleaner merge.
Generals also gained some zero hour functions that now check for nulls.
Generals also gained some functional name changes from zero hour which required updating call sites.
Zero hour gained some debugging that was lost from generals and some cleaned up implementation and formatting.
EDIT: I also had to extend an enum in generals' AI.h due to debug changes merged back from zero hour.
I split the unification into commits to make reviewing it easier, the most strenuous commit is the third commit of the PathfindZoneManager. This is where a considerable amount of satinising and refactoring occurred between both implementations.