openmohaa/code/fgame/navigate.h
2023-07-05 20:52:55 +02:00

371 lines
10 KiB
C++

/*
===========================================================================
Copyright (C) 2015 the OpenMoHAA team
This file is part of OpenMoHAA source code.
OpenMoHAA source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.
OpenMoHAA source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with OpenMoHAA source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// navigate.h:
// Potentially could be an C++ implementation of the A* search algorithm, but
// is currently unfinished.
//
#ifndef __NAVIGATE_H__
#define __NAVIGATE_H__
#include "g_local.h"
#include "class.h"
#include "entity.h"
#include "stack.h"
#include "container.h"
#include "doors.h"
#include "sentient.h"
#include "../qcommon/qfiles.h"
extern Event EV_AI_SavePaths;
extern Event EV_AI_SaveNodes;
extern Event EV_AI_LoadNodes;
extern Event EV_AI_ClearNodes;
extern Event EV_AI_RecalcPaths;
extern Event EV_AI_CalcPath;
extern Event EV_AI_DisconnectPath;
extern cvar_t *ai_showroutes;
extern cvar_t *ai_showroutes_distance;
extern cvar_t *ai_shownodenums;
extern cvar_t *ai_shownode;
extern cvar_t *ai_showallnode;
extern cvar_t *ai_showpath;
extern cvar_t *ai_fallheight;
extern cvar_t *ai_debugpath;
extern cvar_t *ai_pathchecktime;
extern cvar_t *ai_pathcheckdist;
extern int ai_maxnode;
#define MAX_PATHCHECKSPERFRAME 4
extern int path_checksthisframe;
#define MAX_PATH_LENGTH 128 // should be more than plenty
#define NUM_PATHSPERNODE 48
class Path;
class PathNode;
#define NUM_WIDTH_VALUES 16
#define WIDTH_STEP 8
#define MAX_WIDTH ( WIDTH_STEP * NUM_WIDTH_VALUES )
#define MAX_HEIGHT 128
#define CHECK_PATH( path, width, height ) \
( ( ( ( width ) >= MAX_WIDTH ) || ( ( width ) < 0 ) ) ? false : \
( ( int )( path )->maxheight[ ( ( width ) / WIDTH_STEP ) - 1 ] < ( int )( height ) ) )
class pathway_ref {
public:
short int from;
short int to;
};
typedef struct {
byte numBlockers;
short int node;
short int fallheight;
float dist;
float dir[ 2 ];
float pos1[ 3 ];
float pos2[ 3 ];
} pathway_t;
class PathInfo {
public:
bool bAccurate;
float point[ 3 ];
float dist;
float dir[ 2 ];
public:
void Archive( Archiver& arc );
};
inline void PathInfo::Archive
(
Archiver& arc
)
{
arc.ArchiveBool( &bAccurate );
arc.ArchiveVec3( point );
arc.ArchiveFloat( &dist );
arc.ArchiveVec2( dir );
}
typedef enum { NOT_IN_LIST, IN_OPEN, IN_CLOSED } pathlist_t;
#define PATH_DONT_LINK 1
#define AI_DUCK 2
#define AI_COVER 4
#define AI_CONCEALMENT 8
#define AI_CORNER_LEFT 16
#define AI_CORNER_RIGHT 32
#define AI_SNIPER 64
#define AI_CRATE 128
#define AI_COVERFLAGS (AI_CRATE|AI_SNIPER|AI_CORNER_RIGHT|AI_CORNER_LEFT|AI_CONCEALMENT|AI_COVER)
#define AI_COVERFLAGS2 (AI_SNIPER|AI_CORNER_RIGHT|AI_CORNER_LEFT|AI_CONCEALMENT)
#define AI_COVERFLAGS3 (AI_SNIPER|AI_CORNER_RIGHT|AI_CORNER_LEFT|AI_CONCEALMENT|AI_DUCK|AI_CONCEALMENT)
#define AI_SNIPERFLAGS (AI_SNIPER|AI_CORNER_RIGHT|AI_CORNER_LEFT|AI_COVER)
#define AI_CRATEFLAGS (AI_CRATE|AI_CORNER_LEFT|AI_CORNER_RIGHT|AI_CONCEALMENT|AI_COVER|AI_DUCK)
#define AI_COVER_LEFT_FLAGS (AI_CRATE|AI_SNIPER|AI_CORNER_LEFT|AI_CONCEALMENT|AI_DUCK)
#define AI_COVER_RIGHT_FLAGS (AI_CRATE|AI_SNIPER|AI_CORNER_RIGHT|AI_CONCEALMENT|AI_DUCK)
#define AI_ALL (AI_DUCK|AI_COVER|AI_CONCEALMENT|AI_CORNER_LEFT|AI_CORNER_RIGHT|AI_SNIPER|AI_CRATE)
void DrawNode( int iNodeCount );
void DrawAllConnections( void );
class PathNode : public SimpleEntity
{
public:
int findCount;
pathway_t *Child;
int numChildren;
int virtualNumChildren;
float f;
float h;
float g;
class PathNode *Parent;
bool inopen;
PathNode *PrevNode;
PathNode *NextNode;
short int pathway;
vec_t *m_PathPos;
float dist;
float dir[ 2 ];
int nodeflags;
SafePtr<Entity> pLastClaimer;
int iAvailableTime;
int nodenum;
short int m_Depth;
friend class PathSearch;
friend void DrawAllConnections( void );
private:
void ConnectTo( PathNode *node );
void SetNodeFlags( Event *ev );
void Remove( Event *ev );
public:
CLASS_PROTOTYPE( PathNode );
void *operator new( size_t size );
void operator delete( void *ptr );
PathNode();
virtual ~PathNode();
void Archive( Archiver& arc ) override;
void ArchiveDynamic( Archiver& arc );
void ArchiveStatic( Archiver& arc );
bool CheckPathTo( PathNode *node );
void CheckPathToDefault( PathNode *node, pathway_t *pathway );
qboolean LadderTo( PathNode *node, pathway_t *pathway );
void DrawConnections( void );
void Claim( Entity *pClaimer );
void Relinquish( void );
Entity *GetClaimHolder( void ) const;
bool IsClaimedByOther( Entity *pPossibleClaimer ) const;
void MarkTemporarilyBad( void );
void ConnectChild( int i );
void DisconnectChild( int i );
const_str GetSpecialAttack( class Actor *pActor );
void IsTouching( Event *ev );
qboolean IsTouching( Entity *e1 );
void setOriginEvent( Vector org ) override;
};
typedef SafePtr<PathNode> PathNodePtr;
class nodeinfo {
public:
PathNode *pNode;
float fDistSquared;
};
#define PATHMAP_CELLSIZE 256
#define PATHMAP_GRIDSIZE ( MAX_MAP_BOUNDS * 2 / PATHMAP_CELLSIZE )
#define PATHMAP_NODES 128 // 128 - sizeof( int ) / sizeof( short )
#define MAX_PATHNODES 4096
class MapCell : public Class
{
private:
int numnodes;
short *nodes;
friend class PathSearch;
public:
MapCell();
~MapCell();
qboolean AddNode( PathNode *node );
int NumNodes( void );
};
class PathSearch : public Listener
{
friend class PathNode;
private:
static MapCell PathMap[ PATHMAP_GRIDSIZE ][ PATHMAP_GRIDSIZE ];
static PathNode *open;
static int findFrame;
static qboolean m_bNodesloaded;
static qboolean m_NodeCheckFailed;
static int m_LoadIndex;
public:
static PathNode *pathnodes[ 4096 ];
static int nodecount;
static float total_dist;
static const char *last_error;
private:
static void LoadAddToGrid( int x, int y );
static void LoadAddToGrid2( PathNode *node, int x, int y );
static void AddToGrid( PathNode *node, int x, int y );
static bool Connect( PathNode *node, int x, int y );
static int NodeCoordinate( float coord );
static int GridCoordinate( float coord );
static qboolean ArchiveSaveNodes( void );
static void ArchiveLoadNodes( void );
static void Init( void );
public:
CLASS_PROTOTYPE( PathSearch );
PathSearch();
virtual ~PathSearch();
static void ArchiveStaticLoad( Archiver& arc );
static void ArchiveStaticSave( Archiver& arc );
static bool ArchiveDynamic( Archiver& arc );
static void AddNode( PathNode *node );
static void Connect( PathNode *node );
static void UpdateNode( PathNode *node );
static MapCell *GetNodesInCell( int x, int y );
static MapCell *GetNodesInCell( float *pos );
static class PathNode *DebugNearestStartNode( float *pos, Entity *ent = NULL );
static class PathNode *NearestStartNode( float *pos, class SimpleActor *ent );
static class PathNode *NearestEndNode( float *pos );
static int DebugNearestNodeList( float *pos, PathNode **nodelist, int iMaxNodes );
static int DebugNearestNodeList2( float *pos, PathNode **nodelist, int iMaxNodes );
static void ShowNodes( void );
static void LoadNodes( void );
static void CreatePaths( void );
static void *AllocPathNode( void );
static void FreePathNode( void * );
static void ResetNodes( void );
static PathInfo *GeneratePath( PathInfo *path );
static PathInfo *GeneratePathNear( PathInfo *path );
static PathInfo *GeneratePathAway( PathInfo *path );
static class PathNode *GetSpawnNode( ClassDef *cls );
static int FindPath( float *start, float *end, Entity *ent, float maxPath, float *vLeashHome, float fLeashDistSquared, int fallheight );
static int FindPathAway( float *start, float *avoid, float *vPreferredDir, Entity *ent, float fMinSafeDist, float *vLeashHome, float fLeashDistSquared, int fallheight );
static int FindPathNear( float *start, float *end, Entity *ent, float maxPath, float fRadiusSquared, float *vLeashHome, float fLeashDistSquared, int fallheight );
static class PathNode *FindCornerNodeForWall( float *start, float *end, class SimpleActor *ent, float maxPath, float *plane );
static class PathNode *FindCornerNodeForExactPath( class SimpleActor *self, Sentient *enemy, float fMaxPath );
static int FindPotentialCover( class SimpleActor *pEnt, Vector& vPos, Entity *pEnemy, PathNode **ppFoundNodes, int iMaxFind );
static void PlayerCover( class Player *pPlayer );
static class PathNode *FindNearestCover( class SimpleActor *pEnt, Vector& vPos, Entity *pEnemy );
static class PathNode *FindNearestSniperNode( class SimpleActor *pEnt, Vector& vPos, Entity *pEnemy );
private:
static int NearestNodeSetup( vec3_t pos, MapCell *cell, int *nodes, vec3_t *deltas );
};
extern PathSearch PathManager;
PathNode *AI_FindNode( const char *name );
void AI_AddNode( PathNode *node );
void AI_RemoveNode( PathNode *node );
void AI_ResetNodes( void );
class AttractiveNode : public SimpleArchivedEntity
{
public:
int m_iPriority;
bool m_bUse;
float m_fMaxStayTime;
float m_fMaxDistance;
float m_fMaxDistanceSquared;
float m_fRespawnTime;
const_str m_csTeam;
int m_iTeam;
private:
// Container< SafePtr< Sentient > > m_pSentList;
public:
CLASS_PROTOTYPE( AttractiveNode );
AttractiveNode();
~AttractiveNode();
bool CheckTeam( Sentient *sent );
void setMaxDist( float dist );
void GetPriority( Event *ev );
void SetPriority( Event *ev );
void GetDistance( Event *ev );
void SetDistance( Event *ev );
void GetStayTime( Event *ev );
void SetStayTime( Event *ev );
void GetRespawnTime( Event *ev );
void SetRespawnTime( Event *ev );
void GetTeam( Event *ev );
void SetTeam( Event *ev );
void SetUse( Event *ev );
void Archive( Archiver& arc ) override;
};
typedef SafePtr< AttractiveNode > AttractiveNodePtr;
inline void AttractiveNode::Archive
(
Archiver& arc
)
{
arc.ArchiveInteger( &m_iPriority );
arc.ArchiveBool( &m_bUse );
arc.ArchiveFloat( &m_fMaxStayTime );
arc.ArchiveFloat( &m_fMaxDistanceSquared );
}
extern Container< AttractiveNode * > attractiveNodes;
#endif