kingpin-sdk/gamesrc/G_NAV.H

330 lines
11 KiB
C
Raw Permalink Normal View History

2000-03-27 00:00:00 +00:00
// ==================================================================
//
// Character Navigation System (CNS)
//
// ==================================================================
// ==================================================================
// Defines
#define MAX_NODES 700
#define MAX_PARENT_NODES 128
#define MAX_VIS_NODES 15 // bound by file IO methods
#define MAX_CELLS_PER_NODE 4
#define MAX_MAP_AXIS 5000
#define CELL_AXIS_SUBDIVISION 32 // each axis is divided into segments, to form the cell grid
#define OPTIMIZE_NODES 2000 // check this many nodes per frame
// each node can ONLY be ONE of the following types
#define NODE_NORMAL 0
#define NODE_JUMP 1 // jump from this node
#define NODE_LANDING 2 // landing from a jump node
#define NODE_PLAT 4 // start riding a platform
#define NODE_TELEPORT 8 // move into a teleporter
#define NODE_BUTTON 16
// the following can exist in conjunction with others
#define NODE_DUCKING 32
// Visibility Tests
#define VIS_LINE 0
#define VIS_PARTIAL 1
#define VIS_FULL 2
// Route types (returned by NAV_Route_*())
#define ROUTE_NONE 0
#define ROUTE_INDIRECT 1
#define ROUTE_DIRECT 2
// Reachable tests
#define REACHABLE_THOROUGH 4
#define REACHABLE_AVERAGE 16
#define REACHABLE_POOR 32
// File I/O
#ifdef _WIN32
#define DIR_SLASH "\\"
#else
#define DIR_SLASH "/"
#endif
#define ROUTE_VERSION 4 // incremented each time file structure is changed, to allow automatic updating, if possible
#define ROUTE_SUBDIR "navdata"
#define ROUTE_EXT "nav"
// #define DUCKING_MAX_Z 4
#define DUCKING_MAX_Z 24 // as requested
// Not used anymore, characters have individual max_z values
//#define STANDING_MAX_Z 32
//ent->nav_data->flags
#define ND_STATIC 1 // this entity NEVER moves (items)
//ent->nav_build_data->flags
#define NBD_DUCK_NEWPATH 1 // set this whenever starting to duck while dropping nodes
#define NBD_JUMPING 2
#define NBD_SHOWPATH 4
//NAV_GetHidePos parameters
#define HIDEPOS_FURTHER -1
#define HIDEPOS_ANY 0
#define HIDEPOS_CLOSER 1
// ==================================================================
//#include "q_shared.h"
typedef struct node_s node_t;
typedef struct parent_node_s parent_node_t;
typedef struct cell_node_s cell_node_t;
// ==================================================================
// Node structures
//
// ..................................................................
// Routes
//
// This is where the actual route between 2 nodes is stored.
// This is the base of an array, where each item represents
// a path between the source node, and the destination
// (referenced by each array item).
typedef struct
{
short path; // Node to head for, to get to another node, -1 if no route
unsigned short dist; // route distance from this node, to the other node
} route_t;
// ..................................................................
// Parent (low-detail) nodes
//
// These are created, by merging a series of close-by (child) nodes
// into one parent node. These are only used for navigation
// of units that are not currently loaded into memory.
struct parent_node_s
{
vec3_t origin;
route_t routes[MAX_PARENT_NODES]; // Route data between this and all other parent nodes
};
// ..................................................................
// Child (high-detail) nodes
//
// The "normal" state of a node, used when traversing the active
// geometry.
struct node_s
{
short index; // index of this node in the "nodes" array
// SAVED DATA
float timestamp; // time node was created (used for node-creation code)
vec3_t origin; // position of node in active geometry
vec3_t jump_vel; // used for jump velocity
short node_type; // one of NODE_* constants (not flags)
short goal_index; // used for jump nodes, so we know which node to land on
byte waterlevel;
short yaw; // direction facing when node was dropped
byte cast_group; // set this when the node is dropped inside the territory of a specific gang
short visible_nodes[MAX_VIS_NODES]; // nodes that are visible and reachable from this node
short num_visible; // number of nodes visible from this node
route_t routes[MAX_NODES]; // Route data between this node and all other nodes
// Calculated/used at run-time
csurface_t *surface; // surface immediately below the node (used for visibility checking)
float ignore_time; // don't go for this node if level.time < ignore_time
edict_t *goal_ent; // used for trigger/platform/etc relationships
// used by NAV_GetHidePos() to speed things up
float last_sight_check;
qboolean last_sight_result;
};
// ..................................................................
// Cell nodes
//
// These are used, to keep track of which cells a node belongs to.
struct cell_node_s
{
node_t *node; // node that this cell_node is representing
cell_node_t *next; // next cell_node in the cell's list, NULL if end
};
// ..................................................................
// Active Unit-specific structure
//
// Stores all information relative to an ACTIVE unit (the unit currently
// being played.
//
// It is assumed that the eventual structures for inactive and active
// units will simply contain pointers to an active_node_data_t or an
// inactive_node_data_t, with one of them being NULL.
typedef struct
{
short node_count; // number of nodes currently in the unit
qboolean modified; // set if the node data has been modified, so saving will be required
// Main Node Array
//
// Used for references between nodes. Allows use
// of 16bit array indexes, instead of 32-pointers, which saves LOTS
// of memory.
//
// Nodes are allocated as they are added, since the actual nodes are
// the main source of memory useage.
node_t *nodes[MAX_NODES];
// Node Cells
//
// Contains a list of "cell_nodes", which represent a node being in a cell.
// Each node can have up to 4 "cell_nodes", which represent each cell that
// the node is within.
//
// "cell_nodes" are created dynamically, as each node is created, and assigned
// to a cell. These "cell_nodes" are then linked to their cell via a linked
// list, which starts with the array below.
cell_node_t *cells[CELL_AXIS_SUBDIVISION][CELL_AXIS_SUBDIVISION];
} active_node_data_t;
// ..................................................................
// Inactive Unit-specific structure
//
// Stores only the navigation data required for an inactive unit, which
// is MUCH less than an active unit.
//
// Note that area cell's aren't required here, since searches will be
// fast enough not to require them, considering the low number of
// parent nodes in an inactive unit (hence, low-detail nodes).
typedef struct
{
short node_count;
// Parent Node array
//
// Stores a pointer to all parent nodes in the inactive unit.
parent_node_t *parent_nodes[MAX_PARENT_NODES];
} inactive_unit_t;
// ..................................................................
// Navigational System data, used for entities
typedef struct
{
int flags; // changes the way the CNS handles the entity
short cache_node; // last successful closest node
float cache_node_time; // time of last cached node
float cache_valid_time; // time a cached node is deemed valid
short goal_index; // 1 + (index of the node to head for)
csurface_t *surface; // current surface standing on
} nav_data_t;
// ..................................................................
// Node Creation
typedef struct
{
int flags;
node_t *current_node; // last node dropped, or closest node
vec3_t old_org;
edict_t *old_groundentity;
float last_max_z; // used for ducking/standing
vec3_t ducking_org;
edict_t *jump_ent;
// debugging only
edict_t *debug_dest;
} nav_build_data_t;
// ==================================================================
// Navigation Specific variables
cvar_t *nav_dynamic;
cvar_t *nav_debug;
cvar_t *nav_optimize;
cvar_t *nav_aipath;
// ==================================================================
// Procedure Defines
// g_nav.c
void NAV_InitActiveNodes( active_node_data_t *active_node_data);
void NAV_PurgeActiveNodes( active_node_data_t *active_node_data);
node_t *NAV_CreateNode( edict_t *ent,
vec3_t origin,
vec3_t jump_vel,
short node_type,
short goal_index,
int waterlevel );
int NAV_OptimizeRoutes( active_node_data_t *active_node_data );
void NAV_CalculateVisible( active_node_data_t *active_node_data, node_t *node );
int NAV_CalculateRoutes ( active_node_data_t *active_node_data, node_t *node );
qboolean NAV_Visible( vec3_t src, vec3_t dest, int vis_type, int ducking );
qboolean NAV_Reachable( vec3_t src, vec3_t dest,
byte src_waterlevel, byte dest_waterlevel,
int ducking, int reachable_type );
qboolean NAV_ClearSight ( edict_t *self, vec3_t dest, edict_t *dest_ent );
void NAV_CalcNodeSurface( node_t *node );
node_t *NAV_GetClosestNode( edict_t *ent, int vis_type, int ignore_cached, qboolean away_from_enemy );
int NAV_Route_EntityToEntity( edict_t *src, node_t *current_node,
edict_t *dest, int vis_type, int check_all_nodes, route_t *route_out );
int NAV_Route_NodeToEntity( node_t *node,
edict_t *dest, int vis_type, route_t *route_out );
int NAV_Route_EntityToNode( edict_t *src, node_t *current_node,
node_t *dest_node, int vis_type, int check_all_nodes, int check_direct, route_t *route_out );
void NAV_EvaluateMove( edict_t *ent );
// g_nav_io.c
void NAV_WriteActiveNodes( active_node_data_t *active_node_data, char *unitname);
void NAV_WriteNode(FILE *f, active_node_data_t *active_node_data, node_t *node);
void NAV_ReadActiveNodes( active_node_data_t *active_node_data, char *unitname);
void NAV_ReadNode( FILE *f, active_node_data_t *active_node_data, node_t *node);
void NAV_FindGoalEnt( node_t *node );
void NAV_CalculateDistances(active_node_data_t *active_node_data);
int NAV_CalculateRouteDistance( active_node_data_t *active_node_data, node_t *src, node_t *dest );
// g_nav_cells.c
int NAV_GetCellIndexForAxis(float pos);
void NAV_AddNodeToCells(active_node_data_t *active_node_data, node_t *node);
// g_nav_misc.c
void NAV_DrawLine(vec3_t sorg, vec3_t dorg);
float NAV_Debug_DrawPath(edict_t *src, edict_t *dest);
void NAV_dprintf(char *fmt, ...);
void NAV_RebuildRoutes(active_node_data_t *node_data); // UNDER DEVELOPMENT!!
float *NAV_GetCombatPos( edict_t *ent, edict_t *enemy, qboolean melee );
float *NAV_GetHidePos( edict_t *ent, edict_t *enemy, int hidepos_type );
qboolean NAV_GetAvoidDirection( edict_t *ent, edict_t *avoid, vec3_t dir );
float *NAV_GetReachableNodeOutsideBounds( edict_t *ent, vec3_t bmins, vec3_t bmaxs );