jediacademy/code/game/g_navigator.h
2013-04-04 17:35:38 -05:00

269 lines
No EOL
12 KiB
C++

////////////////////////////////////////////////////////////////////////////////////////
// RAVEN SOFTWARE - STAR WARS: JK II
// (c) 2002 Activision
//
//
//
// NAVIGATOR
// ---------
// This file provides an interface to two actor related systems:
// - Path Finding
// - Steering
//
//
//
////////////////////////////////////////////////////////////////////////////////////////
#ifndef __G_NAVIGATOR__
#define __G_NAVIGATOR__
#define USENEWNAVSYSTEM 1
#if !defined(RAVL_VEC_INC)
#include "..\Ravl\CVec.h"
#endif
////////////////////////////////////////////////////////////////////////////////////////
// The NAV Namespace
//
// This namespace provides the public interface to the NPC Navigation and Pathfinding
// system. This system is a bidirectional graph of nodes and weighted edges. Finding
// a path from one node to another is accomplished with A*, and cached internally for
// each actor who requests a path.
////////////////////////////////////////////////////////////////////////////////////////
namespace NAV
{
typedef int TNodeHandle;
typedef int TEdgeHandle;
enum EPointType
{
PT_NONE = 0,
PT_WAYNODE,
PT_COMBATNODE,
PT_GOALNODE,
PT_MAX
};
////////////////////////////////////////////////////////////////////////////////////
// Save, Load, Construct
////////////////////////////////////////////////////////////////////////////////////
bool LoadFromFile(const char *filename, int checksum);
bool TestEdge( TNodeHandle NodeA, TNodeHandle NodeB, qboolean IsDebugEdge );
bool LoadFromEntitiesAndSaveToFile(const char *filename, int checksum);
void SpawnedPoint(gentity_t* ent, EPointType type=PT_WAYNODE);
////////////////////////////////////////////////////////////////////////////////////
// Finding Nav Points
////////////////////////////////////////////////////////////////////////////////////
TNodeHandle GetNearestNode(gentity_t* ent, bool forceRecalcNow=false, NAV::TNodeHandle goal=0);
TNodeHandle GetNearestNode(const vec3_t& position, TNodeHandle previous=0, NAV::TNodeHandle goal=0, int ignoreEnt=ENTITYNUM_NONE, bool allowZOffset=false);
TNodeHandle ChooseRandomNeighbor(TNodeHandle NodeHandle);
TNodeHandle ChooseRandomNeighbor(TNodeHandle NodeHandle, const vec3_t& position, float maxDistance);
TNodeHandle ChooseClosestNeighbor(TNodeHandle NodeHandle, const vec3_t& position);
TNodeHandle ChooseFarthestNeighbor(TNodeHandle NodeHandle, const vec3_t& position);
TNodeHandle ChooseFarthestNeighbor(gentity_t* actor, const vec3_t& target, float maxSafeDot);
////////////////////////////////////////////////////////////////////////////////////
// Get The Location Of A Given Node Handle
////////////////////////////////////////////////////////////////////////////////////
const vec3_t& GetNodePosition(TNodeHandle NodeHandle);
void GetNodePosition(TNodeHandle NodeHandle, vec3_t& position);
////////////////////////////////////////////////////////////////////////////////////
// Testing Nearness
////////////////////////////////////////////////////////////////////////////////////
float EstimateCostToGoal(const vec3_t& position, TNodeHandle Goal);
float EstimateCostToGoal(TNodeHandle Start, TNodeHandle Goal);
bool OnSamePoint(gentity_t* actor, gentity_t* target);
bool OnNeighboringPoints(TNodeHandle A, TNodeHandle B);
bool OnNeighboringPoints(gentity_t* actor, gentity_t* target);
bool OnNeighboringPoints(gentity_t* actor, const vec3_t& position);
bool InSameRegion(gentity_t* actor, gentity_t* target);
bool InSameRegion(gentity_t* actor, const vec3_t& position);
bool InSameRegion(TNodeHandle A, TNodeHandle B);
bool InSafeRadius(CVec3 at, TNodeHandle atNode, TNodeHandle targetNode=0);
////////////////////////////////////////////////////////////////////////////////////
// Finding A Path
////////////////////////////////////////////////////////////////////////////////////
bool GoTo(gentity_t* actor, TNodeHandle target, float MaxDangerLevel=1.0f);
bool GoTo(gentity_t* actor, gentity_t* target, float MaxDangerLevel=1.0f);
bool GoTo(gentity_t* actor, const vec3_t& position, float MaxDangerLevel=1.0f);
bool FindPath(gentity_t* actor, TNodeHandle target, float MaxDangerLevel=1.0f);
bool FindPath(gentity_t* actor, gentity_t* target, float MaxDangerLevel=1.0f);
bool FindPath(gentity_t* actor, const vec3_t& position, float MaxDangerLevel=1.0f);
bool SafePathExists(const CVec3& start, const CVec3& stop, const CVec3& danger, float dangerDistSq);
bool HasPath(gentity_t* actor, TNodeHandle target=PT_NONE);
void ClearPath(gentity_t* actor);
bool UpdatePath(gentity_t* actor, TNodeHandle target=PT_NONE, float MaxDangerLevel=1.0f);
float PathDangerLevel(gentity_t* actor);
int PathNodesRemaining(gentity_t* actor);
const vec3_t& NextPosition(gentity_t* actor);
bool NextPosition(gentity_t* actor, CVec3& Position);
bool NextPosition(gentity_t* actor, CVec3& Position, float& SlowingRadius, bool& Fly, bool& Jump);
////////////////////////////////////////////////////////////////////////////////////
// Update One Or More Edges As A Result Of An Entity Getting Removed
////////////////////////////////////////////////////////////////////////////////////
void WayEdgesNowClear(gentity_t* ent);
////////////////////////////////////////////////////////////////////////////////////
// How Big Is The Given Ent
////////////////////////////////////////////////////////////////////////////////////
unsigned int ClassifyEntSize(gentity_t* ent);
void RegisterDangerSense(gentity_t* actor, int alertEventIndex);
void DecayDangerSenses();
////////////////////////////////////////////////////////////////////////////////////
// Debugging Information
////////////////////////////////////////////////////////////////////////////////////
void ShowDebugInfo(const vec3_t& PlayerPosition, TNodeHandle PlayerWaypoint);
void ShowStats();
void TeleportTo(gentity_t* actor, const char* pointName);
void TeleportTo(gentity_t* actor, int pointNum);
}
////////////////////////////////////////////////////////////////////////////////////////
// The STEER Namespace
//
// These functions allow access to the steering system.
//
// The Reset() and Finalize() functions MUST be called before and after any other steering
// operations. Beyond that, all other steering operations can be called in any order
// and any number of times. Once Finalize() is called, the results of all these
// operations will be summed up and applied as accelleration to the actor's velocity.
////////////////////////////////////////////////////////////////////////////////////////
namespace STEER
{
////////////////////////////////////////////////////////////////////////////////////
// Reset & Finalize
//
// Call these two operations before and after all other STEER operations. They
// clear out and setup the thrust vector for use by the entity.
////////////////////////////////////////////////////////////////////////////////////
void Activate(gentity_t* actor);
void DeActivate(gentity_t* actor, usercmd_t* ucmd);
bool Active(gentity_t* actor);
////////////////////////////////////////////////////////////////////////////////////
// Master Functions
////////////////////////////////////////////////////////////////////////////////////
bool GoTo(gentity_t* actor, gentity_t* target, float reachedRadius, bool avoidCollisions=true);
bool GoTo(gentity_t* actor, const vec3_t& position, float reachedRadius, bool avoidCollisions=true);
bool SafeToGoTo(gentity_t* actor, const vec3_t& targetPosition, int targetNode);
////////////////////////////////////////////////////////////////////////////////////
// Stop
//
// Slow down and come to a stop.
//
////////////////////////////////////////////////////////////////////////////////////
float Stop(gentity_t* actor, float weight=1.0f);
float MatchSpeed(gentity_t* actor, float speed, float weight=1.0f);
////////////////////////////////////////////////////////////////////////////////////
// Seek & Flee
//
// These two operations form the root of all steering. They do simple
// vector operations and add to the thrust vector.
////////////////////////////////////////////////////////////////////////////////////
float Seek(gentity_t* actor, const CVec3& pos, float slowingDistance=0.0f, float weight=1.0f, float desiredSpeed=0.0f);
float Flee(gentity_t* actor, const CVec3& pos, float weight=1.0f);
////////////////////////////////////////////////////////////////////////////////////
// Persue & Evade
//
// Slightly more complicated than Seek & Flee, these operations predict the position
// of the target entitiy.
////////////////////////////////////////////////////////////////////////////////////
float Persue(gentity_t* actor, gentity_t* target, float slowingDistance);
float Persue(gentity_t* actor, gentity_t* target, float slowingDistance, float offsetForward, float offsetRight=0.0f, float offsetUp=0.0f, bool relativeToTargetFacing=false);
float Evade(gentity_t* actor, gentity_t* target);
////////////////////////////////////////////////////////////////////////////////////
// Separation, Alignment, Cohesion
//
// These standard steering operations will apply thrust to achieve a group oriented
// position or direction.
////////////////////////////////////////////////////////////////////////////////////
float Separation(gentity_t* actor, float Scale=1.0f);
float Alignment(gentity_t* actor, float Scale=1.0f);
float Cohesion(gentity_t* actor, float Scale=1.0f);
////////////////////////////////////////////////////////////////////////////////////
// Wander & Path
//
// By far the most common way to alter a character's thrust, path maintaines motion
// along a navigational path (see NAV namespace), and a random wander path.
////////////////////////////////////////////////////////////////////////////////////
float Path(gentity_t* actor);
float Wander(gentity_t* actor);
float FollowLeader(gentity_t* actor, gentity_t* leader, float dist);
////////////////////////////////////////////////////////////////////////////////////
// Collision Avoidance
//
// Usually the last steering operation to call before finialization, this operation
// attempts to avoid collisions with nearby entities and architecture by thrusing
// away from them.
////////////////////////////////////////////////////////////////////////////////////
float AvoidCollisions(gentity_t* actor, gentity_t* leader=0);
gentity_t* SelectLeader(gentity_t* actor);
////////////////////////////////////////////////////////////////////////////////////
// Blocked
//
// This function records whether AI is blocked while the steering is active
////////////////////////////////////////////////////////////////////////////////////
void Blocked(gentity_t* actor, gentity_t* target);
void Blocked(gentity_t* actor, const vec3_t& target);
bool HasBeenBlockedFor(gentity_t* actor, int duration);
////////////////////////////////////////////////////////////////////////////////////
// Reached
//
// A quick function to see if a target location has been reached by an actor
////////////////////////////////////////////////////////////////////////////////////
bool Reached(gentity_t* actor, gentity_t* target, float targetRadius, bool flying=false);
bool Reached(gentity_t* actor, NAV::TNodeHandle target, float targetRadius, bool flying=false);
bool Reached(gentity_t* actor, const vec3_t& target, float targetRadius, bool flying=false);
}
#endif //__G_NAVIGATOR__