mirror of
https://github.com/1dot13/source.git
synced 2026-08-19 14:20:30 +02:00
Add Astars pathing to ingame options (#124)
* Enabled astars pathing * Add toggleable pathfinding choice to ingame options You can choose between original and A* pathfinding algorithms
This commit is contained in:
+62
-57
@@ -88,6 +88,11 @@
|
||||
#include "Map Screen Interface.h" // added by Flugente for SquadNames
|
||||
#include "Keys.h" // added by silversurfer for door handling from the side
|
||||
|
||||
#include "AIInternals.h"
|
||||
extern BOOLEAN gubWorldTileInLight[MAX_ALLOWED_WORLD_MAX];
|
||||
extern BOOLEAN gubIsCorpseThere[MAX_ALLOWED_WORLD_MAX];
|
||||
extern INT32 gubMerkCanSeeThisTile[MAX_ALLOWED_WORLD_MAX];
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// SANDRO - In this file, all APBPConstants[AP_CROUCH] and APBPConstants[AP_PRONE] were changed to GetAPsCrouch() and GetAPsProne()
|
||||
// On the bottom here, there are these functions made
|
||||
@@ -1365,74 +1370,74 @@ UINT32 UIHandleEndTurn( UI_EVENT *pUIEvent )
|
||||
SaveGame(SAVE__END_TURN_NUM, zString );
|
||||
}
|
||||
|
||||
// Flugente: this stuff is only ever used in AStar pathing and is a unnecessary waste of resources otherwise, so I'm putting an end to this
|
||||
#ifdef USE_ASTAR_PATHS
|
||||
////ddd enemy turn optimization
|
||||
if ( (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT ) )
|
||||
if (gGameSettings.fOptions[TOPTION_ALT_PATHFINDING])
|
||||
{
|
||||
memset( gubWorldTileInLight, FALSE, sizeof( gubWorldTileInLight ) );
|
||||
memset( gubIsCorpseThere, FALSE, sizeof( gubIsCorpseThere ) );
|
||||
memset( gubMerkCanSeeThisTile, FALSE, sizeof( gubMerkCanSeeThisTile ) );
|
||||
if ( (gTacticalStatus.uiFlags & TURNBASED) && (gTacticalStatus.uiFlags & INCOMBAT ) )
|
||||
{
|
||||
memset( gubWorldTileInLight, FALSE, sizeof( gubWorldTileInLight ) );
|
||||
memset( gubIsCorpseThere, FALSE, sizeof( gubIsCorpseThere ) );
|
||||
memset( gubMerkCanSeeThisTile, FALSE, sizeof( gubMerkCanSeeThisTile ) );
|
||||
|
||||
//sevenfm translated: unwinding of loop. When changing WORLD_MAX to another value will need some cleaning! dangerous code! ;)
|
||||
//sevenfm translated: unwinding of loop. When changing WORLD_MAX to another value will need some cleaning! dangerous code! ;)
|
||||
|
||||
// WANNE: We had a custom user map (Tixa, J9), where the following loop caused an unhandled exception.
|
||||
// The crash occurd at ~index 16000 when calling the method IsCorpseAtGridNo() ...
|
||||
// I don't know what causes it ...
|
||||
// Just try/catch (ugly, but works).
|
||||
__try
|
||||
{
|
||||
for(UINT32 i=0; i<(UINT32)WORLD_MAX; i+=4)
|
||||
{
|
||||
gubWorldTileInLight[i] = InLightAtNight(i, gpWorldLevelData[ i ].sHeight);
|
||||
gubIsCorpseThere[i] = IsCorpseAtGridNo( i, gpWorldLevelData[ i ].sHeight );
|
||||
gubWorldTileInLight[i+1] = InLightAtNight(i+1, gpWorldLevelData[ i+1 ].sHeight);
|
||||
gubIsCorpseThere[i+1] = IsCorpseAtGridNo( i+1, gpWorldLevelData[ i+1 ].sHeight );
|
||||
gubWorldTileInLight[i+2] = InLightAtNight(i+2, gpWorldLevelData[ i+2 ].sHeight);
|
||||
gubIsCorpseThere[i+2] = IsCorpseAtGridNo( i+2, gpWorldLevelData[ i+2 ].sHeight );
|
||||
gubWorldTileInLight[i+3] = InLightAtNight(i+3, gpWorldLevelData[ i+3 ].sHeight);
|
||||
gubIsCorpseThere[i+3] = IsCorpseAtGridNo( i+3, gpWorldLevelData[ i+3 ].sHeight );
|
||||
}
|
||||
}
|
||||
__except( EXCEPTION_EXECUTE_HANDLER )
|
||||
{
|
||||
// WANNE: Ignore, so the game can continue ...
|
||||
}
|
||||
|
||||
INT32 tcnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
|
||||
SOLDIERTYPE *tS;
|
||||
|
||||
INT16 sXOffset, sYOffset;
|
||||
INT32 sGridNo;
|
||||
UINT16 usSightLimit=0;
|
||||
|
||||
for ( tS = MercPtrs[ tcnt ]; tcnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ++tcnt, tS++ )
|
||||
{
|
||||
if ( tS->stats.bLife >= OKLIFE && tS->sGridNo != NOWHERE && tS->bInSector )
|
||||
// WANNE: We had a custom user map (Tixa, J9), where the following loop caused an unhandled exception.
|
||||
// The crash occurd at ~index 16000 when calling the method IsCorpseAtGridNo() ...
|
||||
// I don't know what causes it ...
|
||||
// Just try/catch (ugly, but works).
|
||||
__try
|
||||
{
|
||||
for(UINT32 i=0; i<(UINT32)WORLD_MAX; i+=4)
|
||||
{
|
||||
gubWorldTileInLight[i] = InLightAtNight(i, gpWorldLevelData[ i ].sHeight);
|
||||
gubIsCorpseThere[i] = IsCorpseAtGridNo( i, gpWorldLevelData[ i ].sHeight );
|
||||
gubWorldTileInLight[i+1] = InLightAtNight(i+1, gpWorldLevelData[ i+1 ].sHeight);
|
||||
gubIsCorpseThere[i+1] = IsCorpseAtGridNo( i+1, gpWorldLevelData[ i+1 ].sHeight );
|
||||
gubWorldTileInLight[i+2] = InLightAtNight(i+2, gpWorldLevelData[ i+2 ].sHeight);
|
||||
gubIsCorpseThere[i+2] = IsCorpseAtGridNo( i+2, gpWorldLevelData[ i+2 ].sHeight );
|
||||
gubWorldTileInLight[i+3] = InLightAtNight(i+3, gpWorldLevelData[ i+3 ].sHeight);
|
||||
gubIsCorpseThere[i+3] = IsCorpseAtGridNo( i+3, gpWorldLevelData[ i+3 ].sHeight );
|
||||
}
|
||||
}
|
||||
__except( EXCEPTION_EXECUTE_HANDLER )
|
||||
{
|
||||
//loop through all the gridnos that we are interested in
|
||||
for (sYOffset = -30; sYOffset <= 30; ++sYOffset)
|
||||
// WANNE: Ignore, so the game can continue ...
|
||||
}
|
||||
|
||||
INT32 tcnt = gTacticalStatus.Team[ gbPlayerNum ].bFirstID;
|
||||
SOLDIERTYPE *tS;
|
||||
|
||||
INT16 sXOffset, sYOffset;
|
||||
INT32 sGridNo;
|
||||
UINT16 usSightLimit=0;
|
||||
|
||||
for ( tS = MercPtrs[ tcnt ]; tcnt <= gTacticalStatus.Team[ gbPlayerNum ].bLastID; ++tcnt, tS++ )
|
||||
{
|
||||
if ( tS->stats.bLife >= OKLIFE && tS->sGridNo != NOWHERE && tS->bInSector )
|
||||
{
|
||||
for (sXOffset = -30; sXOffset <= 30; ++sXOffset)
|
||||
//loop through all the gridnos that we are interested in
|
||||
for (sYOffset = -30; sYOffset <= 30; ++sYOffset)
|
||||
{
|
||||
sGridNo = tS->sGridNo + sXOffset + (MAXCOL * sYOffset);
|
||||
|
||||
if ( sGridNo <= 0 || sGridNo >= WORLD_MAX )
|
||||
continue;
|
||||
|
||||
//usSightLimit = tS->GetMaxDistanceVisible(sGridNo, FALSE, CALC_FROM_WANTED_DIR);
|
||||
if(gubMerkCanSeeThisTile[sGridNo]==0)
|
||||
for (sXOffset = -30; sXOffset <= 30; ++sXOffset)
|
||||
{
|
||||
gubMerkCanSeeThisTile[sGridNo]=//SoldierToVirtualSoldierLineOfSightTest( tS, sGridNo, FALSE, ANIM_STAND, TRUE, usSightLimit );
|
||||
SoldierToVirtualSoldierLineOfSightTest( tS, sGridNo, tS->pathing.bLevel, ANIM_STAND, TRUE, CALC_FROM_WANTED_DIR);
|
||||
}
|
||||
}//fo
|
||||
}
|
||||
}//if
|
||||
sGridNo = tS->sGridNo + sXOffset + (MAXCOL * sYOffset);
|
||||
|
||||
if ( sGridNo <= 0 || sGridNo >= WORLD_MAX )
|
||||
continue;
|
||||
|
||||
//usSightLimit = tS->GetMaxDistanceVisible(sGridNo, FALSE, CALC_FROM_WANTED_DIR);
|
||||
if(gubMerkCanSeeThisTile[sGridNo]==0)
|
||||
{
|
||||
gubMerkCanSeeThisTile[sGridNo]=//SoldierToVirtualSoldierLineOfSightTest( tS, sGridNo, FALSE, ANIM_STAND, TRUE, usSightLimit );
|
||||
SoldierToVirtualSoldierLineOfSightTest( tS, sGridNo, tS->pathing.bLevel, ANIM_STAND, TRUE, CALC_FROM_WANTED_DIR);
|
||||
}
|
||||
}//fo
|
||||
}
|
||||
}//if
|
||||
}
|
||||
}
|
||||
}
|
||||
//ddd enemy turn optimization**
|
||||
#endif
|
||||
|
||||
// End our turn!
|
||||
if (is_server || !is_client)
|
||||
|
||||
@@ -10,12 +10,6 @@
|
||||
#define _PATHAI_H
|
||||
#include "isometric utils.h"
|
||||
|
||||
// WANNE: Please do not use ASTAR pathing,
|
||||
// because it is a HUGH PERFORMANCE KILLER on big maps!!
|
||||
//#define USE_ASTAR_PATHS
|
||||
|
||||
#ifdef USE_ASTAR_PATHS
|
||||
|
||||
namespace ASTAR {
|
||||
#include "BinaryHeap.hpp"
|
||||
#include <vector>
|
||||
@@ -188,8 +182,6 @@ private:
|
||||
|
||||
};//end namespace ASTAR
|
||||
|
||||
#endif// USE_ASTAR_PATHS
|
||||
|
||||
|
||||
BOOLEAN InitPathAI( void );
|
||||
void ShutDownPathAI( void );
|
||||
|
||||
+27
-29
@@ -49,12 +49,12 @@
|
||||
class OBJECTTYPE;
|
||||
class SOLDIERTYPE;
|
||||
|
||||
#ifdef USE_ASTAR_PATHS
|
||||
#include "BinaryHeap.hpp"
|
||||
#include "AIInternals.h"
|
||||
#include "opplist.h"
|
||||
#include "weapons.h"
|
||||
#endif
|
||||
extern BOOLEAN gubWorldTileInLight[MAX_ALLOWED_WORLD_MAX];
|
||||
extern BOOLEAN gubIsCorpseThere[MAX_ALLOWED_WORLD_MAX];
|
||||
extern INT32 gubMerkCanSeeThisTile[MAX_ALLOWED_WORLD_MAX];
|
||||
//#include "dnlprocesstalk.h"//dnl???
|
||||
|
||||
extern UINT16 gubAnimSurfaceIndex[ TOTALBODYTYPES ][ NUMANIMATIONSTATES ];
|
||||
@@ -454,9 +454,6 @@ UINT32 guiFailedPathChecks = 0;
|
||||
UINT32 guiUnsuccessfulPathChecks = 0;
|
||||
#endif
|
||||
|
||||
#ifdef USE_ASTAR_PATHS
|
||||
|
||||
|
||||
//ADB the extra cover feature is supposed to pick a path of the same distance as one calculated with the feature off,
|
||||
//but a safer path, usually farther away from an enemy or following behind some cover.
|
||||
//however it has not been tested and it may need some work, I haven't touched it in a while
|
||||
@@ -647,7 +644,7 @@ int AStarPathfinder::GetPath(SOLDIERTYPE *s ,
|
||||
fCloseGoodEnough = ( (fFlags & PATH_CLOSE_GOOD_ENOUGH) != 0);
|
||||
fConsiderPersonAtDestAsObstacle = (BOOLEAN)( fPathingForPlayer && fPathAroundPeople && !(fFlags & PATH_IGNORE_PERSON_AT_DEST) );
|
||||
|
||||
if ( fNonSwimmer && Water( dest ) )
|
||||
if ( fNonSwimmer && Water( dest, 0 ) )
|
||||
{
|
||||
DebugMsg( TOPIC_JA2, DBG_LEVEL_0, String( "ASTAR: path failed, water" ) );
|
||||
return( 0 );
|
||||
@@ -1390,7 +1387,7 @@ INT16 AStarPathfinder::CalcAP(int const terrainCost, UINT8 const direction)
|
||||
}
|
||||
|
||||
// Flugente: dragging someone
|
||||
if ( pSoldier->IsDraggingSomeone( ) )
|
||||
if ( pSoldier->IsDragging( false ) )
|
||||
{
|
||||
movementAPCost *= gItemSettings.fDragAPCostModifier;
|
||||
}
|
||||
@@ -2357,7 +2354,6 @@ bool AStarPathfinder::IsSomeoneInTheWay()
|
||||
return false;
|
||||
}
|
||||
|
||||
#endif//end ifdef USE_ASTAR_PATHS
|
||||
|
||||
INT8 RandomSkipListLevel( void )
|
||||
{
|
||||
@@ -2430,27 +2426,29 @@ INT32 FindBestPath(SOLDIERTYPE *s , INT32 sDestination, INT8 bLevel, INT16 usMov
|
||||
{
|
||||
s->sPlotSrcGrid = s->sGridNo;
|
||||
|
||||
#ifdef USE_ASTAR_PATHS
|
||||
//ddd
|
||||
CHAR8 errorBuf[511]; UINT32 b,e;
|
||||
b=GetJA2Clock();//return s->sGridNo+6;
|
||||
|
||||
int retVal = ASTAR::AStarPathfinder::GetInstance().GetPath(s, sDestination, bLevel, usMovementMode, bCopy, fFlags);
|
||||
|
||||
e=GetJA2Clock();sprintf(errorBuf, "timefind bestpath= %d",e-b );LiveMessage(errorBuf);
|
||||
|
||||
if (retVal || TileIsOutOfBounds(sDestination)) {
|
||||
return retVal;
|
||||
}
|
||||
else {
|
||||
DebugMsg( TOPIC_JA2, DBG_LEVEL_0, String( "ASTAR path failed!" ) );
|
||||
}
|
||||
|
||||
// if (TileIsOutOfBounds(sDestination))
|
||||
if (gGameSettings.fOptions[TOPTION_ALT_PATHFINDING])
|
||||
{
|
||||
return 0;
|
||||
CHAR8 errorBuf[511]; UINT32 b,e;
|
||||
b=GetJA2Clock();//return s->sGridNo+6;
|
||||
|
||||
int retVal = ASTAR::AStarPathfinder::GetInstance().GetPath(s, sDestination, bLevel, usMovementMode, bCopy, fFlags);
|
||||
|
||||
e=GetJA2Clock();sprintf(errorBuf, "timefind bestpath= %d",e-b );LiveMessage(errorBuf);
|
||||
|
||||
if (retVal || TileIsOutOfBounds(sDestination)) {
|
||||
return retVal;
|
||||
}
|
||||
else {
|
||||
DebugMsg( TOPIC_JA2, DBG_LEVEL_0, String( "ASTAR path failed!" ) );
|
||||
}
|
||||
|
||||
// if (TileIsOutOfBounds(sDestination))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
#else
|
||||
else
|
||||
{
|
||||
//__try
|
||||
//{
|
||||
INT32 iDestination = sDestination, iOrigination;
|
||||
@@ -4210,7 +4208,7 @@ ENDOFLOOP:
|
||||
//{
|
||||
// return (0);
|
||||
//}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void GlobalReachableTest( INT32 sStartGridNo )
|
||||
|
||||
Reference in New Issue
Block a user