jedi-academy/codemp/RMG/RM_Path.h

226 lines
6.4 KiB
C++

/************************************************************************************************
*
* Copyright (C) 2001-2002 Raven Software
*
* RM_Path.h
*
************************************************************************************************/
#pragma once
#if !defined(RM_PATH_H_INC)
#define RM_PATH_H_INC
#ifdef DEBUG_LINKING
#pragma message("...including RM_Path.h")
#endif
#if !defined(CM_RANDOMTERRAIN_H_INC)
#include "../qcommon/cm_randomterrain.h"
#endif
#include <string>
class CRMPathManager;
// directions you can proceed from cells
enum ERMDir
{
DIR_FIRST= 0,
DIR_N = 0,
DIR_NE,
DIR_E ,
DIR_SE,
DIR_S ,
DIR_SW,
DIR_W ,
DIR_NW,
DIR_MAX,
DIR_ALL = 255
};
#define HALF_DIR_MAX (DIR_MAX/2)
class CRMNode
{
private:
string mName; // name of node - "" if not used yet
vec3_t mPos; // where node is
int mPathID[DIR_MAX]; // path id's that lead from this node
bool mAreaPointPlaced; // false if no area point here yet.
int mFlattenHeight;
public:
CRMNode ( );
bool IsLocation() {return strlen(mName.c_str())>0;};
const char* GetName ( ) { return mName.c_str(); }
vec3_t& GetPos ( ) { return mPos; }
const float PathExist( const int dir) { return (mPathID[dir % DIR_MAX] != -1); };
const float GetPath ( const int dir) { return mPathID[dir % DIR_MAX]; };
bool AreaPoint() {return mAreaPointPlaced;};
void SetName ( const char* name ) { mName = name; }
void SetPos ( const vec3_t& v ) { VectorCopy ( v, mPos ); }
void SetPath( const int dir, const int id) { mPathID[dir % DIR_MAX] = id; };
void SetAreaPoint(bool ap) {mAreaPointPlaced = ap;};
void SetFlattenHeight(int flattenHeight) {mFlattenHeight = flattenHeight; }
int GetFlattenHeight() {return mFlattenHeight; }
};
typedef vector<CRMNode*> rmNodeVector_t;
// named spots on the map, should be placed into nodes
class CRMLoc
{
private:
string mName; // name of location
int mMinDepth;
int mMaxDepth;
int mMinPaths;
int mMaxPaths;
bool mPlaced; // location has been placed at a node
public:
CRMLoc (const char *name, const int min_depth, const int max_depth, const int min_paths =1, const int max_paths=1 )
: mMinDepth(min_depth), mMaxDepth(max_depth), mPlaced(false), mMinPaths(min_paths), mMaxPaths(max_paths)
{ mName = name; };
const char* GetName ( ) { return mName.c_str(); }
void SetName ( const char* name ) { mName = name; }
int MinDepth() {return mMinDepth;};
void SetMinDepth(const int deep) {mMinDepth = deep;};
int MaxDepth() {return mMaxDepth;};
void SetMaxDepth(const int deep) {mMaxDepth = deep;};
int MinPaths() {return mMinPaths;};
void SetMinPaths(const int paths) {mMinPaths = paths;};
int MaxPaths() {return mMaxPaths;};
void SetMaxPaths(const int paths) {mMaxPaths = paths;};
bool Placed() { return mPlaced; };
void SetPlaced(bool p) { mPlaced = p;};
};
typedef vector<CRMLoc*> rmLocVector_t;
// cells are used for figuring out node connections / paths
struct CRMCell
{
private:
int border;
int wall;
public:
CRMCell() { border = 0; wall = DIR_ALL; };
int Border() {return border;};
int Wall() {return wall;};
bool Border(const int dir) { return (border & (1<<dir))!=0; };
bool Wall(const int dir) { return (wall & (1<<dir))!=0; };
void SetBorder(const int dir) { border |= (1<<dir); };
void SetWall(const int dir) { wall |= (1<<dir); };
void RemoveWall(const int dir) { wall &= ~(1<<dir); };
};
typedef vector<CRMCell> rmCellVector_t;
class CRMPathManager
{
public:
int mXNodes; // number of nodes in the x dimension
int mYNodes; // number of nodes in the y dimension
private:
rmLocVector_t mLocations; // location, named spots to be placed at nodes
rmNodeVector_t mNodes; // nodes, spots on map that *may* be connected by paths
rmCellVector_t mCells; // array of cells for doing path generation
int mPathCount;
int mRiverCount;
int mMaxDepth; // deepest any location wants to be
int mDepth; // current depth
bool mCrossed; // used to indicate if paths crossed the imaginary diagonal that cuts symmetric maps in half
// path style
int mPathPoints;
float mPathMinWidth;
float mPathMaxWidth;
float mPathDepth;
float mPathDeviation;
float mPathBreadth;
// river style
int mRiverDepth;
int mRiverPoints;
float mRiverMinWidth;
float mRiverMaxWidth;
float mRiverBedDepth;
float mRiverDeviation;
float mRiverBreadth;
string mRiverBridge;
vec3_t mRiverPos;
static int neighbor_x[DIR_MAX];
static int neighbor_y[DIR_MAX];
CRandomTerrain* mTerrain;
public:
CRMPathManager ( CRandomTerrain* terrain );
~CRMPathManager ( );
void ClearCells (int x_nodes, int y_nodes);
bool CreateArray ( const int x_nodes, const int y_nodes );
CRMNode* FindNodeByName ( const char* name );
CRMNode* Node ( const int x, const int y ) {return mNodes[x + y*mXNodes];};
void CreateLocation ( const char* name, const int min_depth, int max_depth, const int min_paths =1, int max_paths =1 );
vec3_t& GetNodePos ( const int x, const int y ) { return mNodes[x + y*mXNodes]->GetPos(); };
void SetNodePos ( const int x, const int y, const vec3_t& pos) { mNodes[x + y*mXNodes]->SetPos(pos); };
int GetPathCount () {return mPathCount;};
int GetRiverCount () {return mRiverCount;};
float GetRiverDepth () {return mRiverBedDepth;};
float GetPathDepth () {return mPathDepth;};
const char *GetBridgeName () {return mRiverBridge.c_str();};
vec3_t& GetRiverPos ( const int x, const int y );
CRMCell& Cell ( const int x, const int y ) {return mCells[x + y*mXNodes];};
CRMCell& RiverCell ( const int x, const int y ) {return mCells[x + y*(mXNodes+1)];};
void PlaceLocation ( const int x, const int y );
void PathVisit ( const int x, const int y );
void RiverVisit ( const int x, const int y );
void SetPathStyle ( const int points = 10,
const float minwidth = 0.01f,
const float maxwidth = 0.05f,
const float depth = 0.3f,
const float deviation = 0.2f,
const float breadth = 5);
void SetRiverStyle ( const int depth = 5,
const int points = 10,
const float minwidth = 0.01,
const float maxwidth = 0.03,
const float beddepth = 0.0f,
const float deviation = 0.25f,
const float breadth = 7,
string bridge_name = "");
void GeneratePaths ( symmetry_t symmetric = SYMMETRY_NONE );
void GenerateRivers ( );
};
#endif