Add info_node and info_node_air support for navigation.
This commit is contained in:
@@ -609,3 +609,42 @@ template <class T> T * CreateClassPtr( T *a )
|
||||
return a;
|
||||
}
|
||||
|
||||
//
|
||||
// Converts a entvars_t * to a class pointer
|
||||
// It will allocate the class and entity
|
||||
// Use this for non-monsters entities
|
||||
//
|
||||
// WARNING: This does not check for free edicts!
|
||||
//
|
||||
template <class T> T * CreateNormalClassPtr( T *a )
|
||||
{
|
||||
entvars_t *pev = (entvars_t *)a;
|
||||
|
||||
if (pev != NULL)
|
||||
return NULL; // don't allocate if pointer already provided
|
||||
|
||||
// allocate entity...
|
||||
edict_t *temp_edict;
|
||||
int edict_index;
|
||||
|
||||
// allocate private data
|
||||
a = new T;
|
||||
|
||||
if ((temp_edict = a->CreateEntity("info_target")) == NULL)
|
||||
{
|
||||
(*g_engfuncs.pfnServerPrint)("[MONSTER] ERROR: NULL Ent in CreateNormalClassPtr!\n" );
|
||||
delete a;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
edict_index = (*g_engfuncs.pfnIndexOfEdict)(temp_edict);
|
||||
|
||||
// store the class pointer to the edict pev...
|
||||
pev = VARS(temp_edict);
|
||||
a->pev = pev;
|
||||
|
||||
// get the private data
|
||||
a = (T *)pev->euser4;
|
||||
|
||||
return a;
|
||||
}
|
||||
|
||||
@@ -48,6 +48,9 @@
|
||||
#include "decals.h"
|
||||
#include "shake.h"
|
||||
#include "skill.h"
|
||||
#include "nodes.h"
|
||||
|
||||
extern CGraph WorldGraph;
|
||||
|
||||
extern globalvars_t *gpGlobals;
|
||||
extern enginefuncs_t g_engfuncs;
|
||||
@@ -108,7 +111,12 @@ monster_type_t monster_types[]=
|
||||
// These are just names. But to keep it consistent
|
||||
// with the new KVD format, ensure these are exactly
|
||||
// like an actual, entity classname.
|
||||
"monster_alien_grunt", FALSE,
|
||||
|
||||
// We are going to use this as a list of what entities
|
||||
// can be spawned. Monsters should go first.
|
||||
// DO NOT ALTER THE ORDER OF ELEMENTS!
|
||||
|
||||
"monster_alien_grunt", FALSE, // Monsters
|
||||
"monster_apache", FALSE,
|
||||
"monster_barney", FALSE,
|
||||
"monster_bigmomma", FALSE,
|
||||
@@ -122,6 +130,8 @@ monster_type_t monster_types[]=
|
||||
"monster_scientist", FALSE,
|
||||
"monster_snark", FALSE,
|
||||
"monster_zombie", FALSE,
|
||||
"info_node", FALSE, // Nodes
|
||||
"info_node_air", FALSE,
|
||||
"", FALSE
|
||||
};
|
||||
|
||||
@@ -131,6 +141,9 @@ int monster_ents_used = 0;
|
||||
monster_spawnpoint_t monster_spawnpoint[MAX_MONSTERS];
|
||||
int monster_spawn_count = 0;
|
||||
|
||||
node_spawnpoint_t node_spawnpoint[MAX_NODES];
|
||||
int node_spawn_count = 0;
|
||||
|
||||
float check_respawn_time;
|
||||
|
||||
bool process_monster_cfg(void);
|
||||
@@ -779,6 +792,102 @@ void MonsterCommand(void)
|
||||
}
|
||||
}
|
||||
|
||||
void SpawnViewerCommand(void)
|
||||
{
|
||||
int index;
|
||||
|
||||
// debug command to spawn a node_viewer at a player's location
|
||||
if (CMD_ARGC() >= 2)
|
||||
{
|
||||
// check for a valid player name or index...
|
||||
const char *parg2 = CMD_ARGV(1);
|
||||
int player_index = -1;
|
||||
edict_t *pPlayer;
|
||||
const char *player_name;
|
||||
|
||||
if (*parg2 == '#') // player index
|
||||
{
|
||||
if (sscanf(&parg2[1], "%d", &player_index) != 1)
|
||||
player_index = -1;
|
||||
|
||||
if ((player_index < 1) || (player_index > gpGlobals->maxClients))
|
||||
{
|
||||
//META_CONS("[MONSTER] invalid player index! (%d to %d allowed)", 1, gpGlobals->maxClients);
|
||||
LOG_MESSAGE(PLID, "invalid player index! (%d to %d allowed)", 1, gpGlobals->maxClients);
|
||||
player_index = -1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (index = 1; index <= gpGlobals->maxClients; index++)
|
||||
{
|
||||
pPlayer = INDEXENT(index);
|
||||
|
||||
if (pPlayer && !pPlayer->free)
|
||||
{
|
||||
if (stricmp(STRING(pPlayer->v.netname), parg2) == 0)
|
||||
{
|
||||
player_index = index; // found the matching player name
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (player_index == -1)
|
||||
{
|
||||
//META_CONS("[MONSTER] can't find player named \"%s\"!", parg2);
|
||||
LOG_MESSAGE(PLID, "can't find player named \"%s\"!", parg2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (player_index != -1)
|
||||
{
|
||||
pPlayer = INDEXENT(player_index);
|
||||
|
||||
if ((pPlayer == NULL) || (pPlayer->free))
|
||||
{
|
||||
//META_CONS("[MONSTER] player index %d is not a valid player!", player_index);
|
||||
LOG_MESSAGE(PLID, "player index %d is not a valid player!", player_index);
|
||||
return;
|
||||
}
|
||||
|
||||
player_name = STRING(pPlayer->v.netname);
|
||||
|
||||
if (player_name[0] == 0)
|
||||
{
|
||||
//META_CONS("[MONSTER] player index %d is not a valid player!", player_index);
|
||||
LOG_MESSAGE(PLID, "player index %d is not a valid player!", player_index);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!UTIL_IsAlive(pPlayer))
|
||||
{
|
||||
//META_CONS("[MONSTER] player \"%s\" is not alive or is an observer!", player_name);
|
||||
LOG_MESSAGE(PLID, "player \"%s\" is not alive or is an observer!", player_name);
|
||||
return;
|
||||
}
|
||||
|
||||
Vector origin = pPlayer->v.origin;
|
||||
|
||||
CMBaseEntity *pViewer = CreateClassPtr((CNodeViewer *)NULL);
|
||||
if (pViewer == NULL)
|
||||
{
|
||||
//META_CONS("[MONSTER] ERROR: Error Creating Node!" );
|
||||
LOG_MESSAGE(PLID, "ERROR: Error Creating Viewer!");
|
||||
return;
|
||||
}
|
||||
|
||||
pViewer->pev->origin = origin;
|
||||
pViewer->Spawn();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
LOG_MESSAGE(PLID, "usage: node_viewer player_name | #player_index");
|
||||
LOG_MESSAGE(PLID, "spawns a node viewer at the player's location");
|
||||
}
|
||||
|
||||
void mmGameDLLInit( void )
|
||||
{
|
||||
@@ -810,6 +919,7 @@ int mmDispatchSpawn( edict_t *pent )
|
||||
world_precache();
|
||||
|
||||
monster_spawn_count = 0;
|
||||
node_spawn_count = 0;
|
||||
|
||||
monster_skill_init();
|
||||
|
||||
@@ -817,6 +927,31 @@ int mmDispatchSpawn( edict_t *pent )
|
||||
|
||||
process_monster_cfg();
|
||||
|
||||
// node support. -Giegue
|
||||
// init the WorldGraph.
|
||||
WorldGraph.InitGraph();
|
||||
|
||||
// make sure the .NOD file is newer than the .BSP file.
|
||||
if ( !WorldGraph.CheckNODFile ( ( char * )STRING( gpGlobals->mapname ) ) )
|
||||
{
|
||||
// NOD file is not present, or is older than the BSP file.
|
||||
WorldGraph.AllocNodes();
|
||||
}
|
||||
else
|
||||
{
|
||||
// Load the node graph for this level
|
||||
if ( !WorldGraph.FLoadGraph ( (char *)STRING( gpGlobals->mapname ) ) )
|
||||
{
|
||||
// couldn't load, so alloc and prepare to build a graph.
|
||||
ALERT ( at_console, "*Error opening .NOD file\n" );
|
||||
WorldGraph.AllocNodes();
|
||||
}
|
||||
else
|
||||
{
|
||||
ALERT ( at_console, "\n*Graph Loaded!\n" );
|
||||
}
|
||||
}
|
||||
|
||||
check_respawn_time = 0.0;
|
||||
|
||||
for (index = 0; index < MAX_MONSTER_ENTS; index++)
|
||||
@@ -851,6 +986,20 @@ void mmDispatchThink( edict_t *pent )
|
||||
}
|
||||
}
|
||||
|
||||
// Manually call think on these other entities
|
||||
if (FClassnameIs( pent, "testhull" ))
|
||||
{
|
||||
// Ensure you do think...
|
||||
CMBaseEntity::Instance(pent)->Think();
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
if (FClassnameIs( pent, "node_viewer" ))
|
||||
{
|
||||
CMBaseEntity::Instance(pent)->Think();
|
||||
RETURN_META(MRES_SUPERCEDE);
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
// HACKHACK -- this is a hack to keep the node graph entity from "touching" things (like triggers)
|
||||
@@ -899,6 +1048,7 @@ void mmServerActivate( edict_t *pEdictList, int edictCount, int clientMax )
|
||||
g_psv_gravity = CVAR_GET_POINTER( "sv_gravity" );
|
||||
|
||||
(g_engfuncs.pfnAddServerCommand)("monster", MonsterCommand);
|
||||
(g_engfuncs.pfnAddServerCommand)("node_viewer", SpawnViewerCommand);
|
||||
|
||||
for (index = 0; monster_types[index].name[0]; index++)
|
||||
{
|
||||
@@ -939,6 +1089,30 @@ void mmServerActivate( edict_t *pEdictList, int edictCount, int clientMax )
|
||||
|
||||
monster_ents_used = 0;
|
||||
|
||||
// spawn nodes
|
||||
for (index = 0; index < node_spawn_count; index++)
|
||||
{
|
||||
CMBaseEntity *pNode;
|
||||
pNode = CreateNormalClassPtr((CNodeEnt *)NULL);
|
||||
|
||||
if (pNode == NULL)
|
||||
{
|
||||
//META_CONS("[MONSTER] ERROR: Error Creating Node!" );
|
||||
LOG_MESSAGE(PLID, "ERROR: Error Creating Node!");
|
||||
}
|
||||
else
|
||||
{
|
||||
pNode->pev->origin = node_spawnpoint[index].origin;
|
||||
|
||||
if (node_spawnpoint[index].is_air_node)
|
||||
pNode->pev->classname = MAKE_STRING("info_node_air");
|
||||
else
|
||||
pNode->pev->classname = MAKE_STRING("info_node");
|
||||
|
||||
pNode->Spawn();
|
||||
}
|
||||
}
|
||||
|
||||
RETURN_META(MRES_IGNORED);
|
||||
}
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ extern cvar_t *dllapi_log;
|
||||
|
||||
extern monster_type_t monster_types[];
|
||||
extern int monster_spawn_count;
|
||||
|
||||
extern int node_spawn_count;
|
||||
|
||||
bool get_input(FILE *fp, char *input)
|
||||
{
|
||||
@@ -72,9 +72,11 @@ void scan_monster_cfg(FILE *fp)
|
||||
// Let's make a full rework of this. -Giegue
|
||||
char input[1024];
|
||||
float x, y, z;
|
||||
bool badent, monster, node;
|
||||
|
||||
while (get_input(fp, input))
|
||||
{
|
||||
badent = monster = node = FALSE;
|
||||
if (input[0] == '{')
|
||||
{
|
||||
// Proper start, initialize entity creation
|
||||
@@ -86,10 +88,83 @@ void scan_monster_cfg(FILE *fp)
|
||||
// It's the end of the entity structure?
|
||||
if (input[0] == '}')
|
||||
{
|
||||
// Done. Let's process the keyvalues.
|
||||
for (int i = 0; i < kvd_index; i++)
|
||||
// Check if the classname of whatever we want to spawn is valid.
|
||||
if (strcmp(data[kvd_index-1].key, "classname") == 0)
|
||||
{
|
||||
int mIndex;
|
||||
for (mIndex = 0; monster_types[mIndex].name[0]; mIndex++)
|
||||
{
|
||||
if (strcmp(data[kvd_index-1].value, monster_types[mIndex].name) == 0)
|
||||
{
|
||||
// Now that I think about it this looks slow and bad code >.>
|
||||
|
||||
// A match is found. What is this?
|
||||
if (strncmp(monster_types[mIndex].name, "monster", 7) == 0)
|
||||
{
|
||||
// It's a monster, add it to the list
|
||||
if (monster_spawn_count == MAX_MONSTERS)
|
||||
{
|
||||
// Ouch! Not enough room.
|
||||
LOG_MESSAGE(PLID, "ERROR: can't add monster, reached MAX_MONSTERS!"); // It will get spammy, sadly.
|
||||
badent = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
monster_spawnpoint[monster_spawn_count].monster = mIndex;
|
||||
monster_types[mIndex].need_to_precache = TRUE;
|
||||
monster = TRUE;
|
||||
}
|
||||
}
|
||||
else if (strcmp(monster_types[mIndex].name, "info_node") == 0)
|
||||
{
|
||||
// Normal node
|
||||
if (node_spawn_count == MAX_NODES)
|
||||
{
|
||||
// The map can't be THAT big can it?
|
||||
LOG_MESSAGE(PLID, "ERROR: can't add node, reached MAX_NODES!"); // zee spam bOi
|
||||
badent = TRUE;
|
||||
}
|
||||
else
|
||||
node = TRUE;
|
||||
}
|
||||
else if (strcmp(monster_types[mIndex].name, "info_node_air") == 0)
|
||||
{
|
||||
// Aerial node
|
||||
if (node_spawn_count == MAX_NODES)
|
||||
{
|
||||
// Ctrl+C --> Ctrl+V
|
||||
LOG_MESSAGE(PLID, "ERROR: can't add node, reached MAX_NODES!"); // poppo was here.
|
||||
badent = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
node_spawnpoint[node_spawn_count].is_air_node = TRUE;
|
||||
node = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (monster_types[mIndex].name[0] == 0)
|
||||
{
|
||||
LOG_MESSAGE(PLID, "ERROR: unknown classname: %s", input); // print conflictive line
|
||||
LOG_MESSAGE(PLID, "ERROR: nothing will spawn here!");
|
||||
badent = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// What are you doing?!
|
||||
LOG_MESSAGE(PLID, "ERROR: BAD ENTITY STRUCTURE! Last line was %s", input); // print conflictive line
|
||||
LOG_MESSAGE(PLID, "ERROR: nothing will spawn here!");
|
||||
badent = TRUE;
|
||||
}
|
||||
|
||||
if (!badent)
|
||||
{
|
||||
// Done. Let's process the keyvalues.
|
||||
for (int i = 0; i < (kvd_index-1); i++)
|
||||
{
|
||||
float x, y, z;
|
||||
// Any unknown keyvalue is ignored.
|
||||
// Any duplicate keyvalue is overwritten.
|
||||
|
||||
@@ -103,14 +178,25 @@ void scan_monster_cfg(FILE *fp)
|
||||
LOG_MESSAGE(PLID, "ERROR: entity will spawn at 0 0 0");
|
||||
x = y = z = 0;
|
||||
}
|
||||
if (monster)
|
||||
{
|
||||
monster_spawnpoint[monster_spawn_count].origin[0] = x;
|
||||
monster_spawnpoint[monster_spawn_count].origin[1] = y;
|
||||
monster_spawnpoint[monster_spawn_count].origin[2] = z;
|
||||
}
|
||||
else if (node)
|
||||
{
|
||||
node_spawnpoint[node_spawn_count].origin[0] = x;
|
||||
node_spawnpoint[node_spawn_count].origin[1] = y;
|
||||
node_spawnpoint[node_spawn_count].origin[2] = z;
|
||||
}
|
||||
}
|
||||
else if (strcmp(data[i].key, "delay") == 0)
|
||||
{
|
||||
// ToDo: Remove this keyvalue.
|
||||
// Monsters spawned directly should not respawn.
|
||||
if (monster)
|
||||
{
|
||||
if (sscanf(data[i].value, "%f", &x) != 1)
|
||||
{
|
||||
LOG_MESSAGE(PLID, "ERROR: invalid delay: %s", input); // print conflictive line
|
||||
@@ -121,7 +207,10 @@ void scan_monster_cfg(FILE *fp)
|
||||
}
|
||||
monster_spawnpoint[monster_spawn_count].delay = x;
|
||||
}
|
||||
}
|
||||
else if (strcmp(data[i].key, "angles") == 0)
|
||||
{
|
||||
if (monster)
|
||||
{
|
||||
if (sscanf(data[i].value, "%f %f %f", &x, &y, &z) != 3)
|
||||
{
|
||||
@@ -135,29 +224,21 @@ void scan_monster_cfg(FILE *fp)
|
||||
monster_spawnpoint[monster_spawn_count].angles[1] = y;
|
||||
monster_spawnpoint[monster_spawn_count].angles[2] = z;
|
||||
}
|
||||
else if (strcmp(data[i].key, "classname") == 0)
|
||||
{
|
||||
int mIndex;
|
||||
for (mIndex = 0; monster_types[mIndex].name[0]; mIndex++)
|
||||
{
|
||||
if (strcmp(data[i].value, monster_types[mIndex].name) == 0)
|
||||
{
|
||||
monster_spawnpoint[monster_spawn_count].monster = mIndex;
|
||||
monster_types[mIndex].need_to_precache = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (monster_types[mIndex].name[0] == 0)
|
||||
{
|
||||
LOG_MESSAGE(PLID, "ERROR: unknown classname: %s", input); // print conflictive line
|
||||
LOG_MESSAGE(PLID, "ERROR: nothing will spawn here!");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (monster)
|
||||
{
|
||||
// Init monster
|
||||
monster_spawnpoint[monster_spawn_count].respawn_time = gpGlobals->time + 0.1; // spawn (nearly) right away
|
||||
monster_spawnpoint[monster_spawn_count].need_to_respawn = TRUE;
|
||||
monster_spawn_count++;
|
||||
}
|
||||
else if (node)
|
||||
{
|
||||
// Increase node count
|
||||
node_spawn_count++;
|
||||
}
|
||||
|
||||
// Log on? Print all the entities that were added
|
||||
if (dllapi_log->value)
|
||||
@@ -166,8 +247,8 @@ void scan_monster_cfg(FILE *fp)
|
||||
// No, I'm not making this idiotproof. Classname should be the last KVD entry on an entity!
|
||||
LOG_CONSOLE(PLID, "[DEBUG] Added entity: %s", data[kvd_index-1].value);
|
||||
}
|
||||
}
|
||||
|
||||
monster_spawn_count++;
|
||||
free( data );
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -40,6 +40,18 @@ typedef struct {
|
||||
#define MAX_MONSTERS 100
|
||||
extern monster_spawnpoint_t monster_spawnpoint[MAX_MONSTERS];
|
||||
|
||||
// this is here to store if a node we want to spawn is an ordinary one, or a flying one
|
||||
typedef struct
|
||||
{
|
||||
Vector origin;
|
||||
bool is_air_node;
|
||||
} node_spawnpoint_t;
|
||||
|
||||
// nodes.cpp defines 1024 max nodes, but that amount is likely to trigger a
|
||||
// no free edicts crash if the server num_edicts is low. Increase if needed.
|
||||
#define MAX_NODES 256
|
||||
extern node_spawnpoint_t node_spawnpoint[MAX_NODES];
|
||||
|
||||
extern DLL_GLOBAL short g_sModelIndexFireball;// holds the index for the fireball
|
||||
extern DLL_GLOBAL short g_sModelIndexSmoke;// holds the index for the smoke cloud
|
||||
extern DLL_GLOBAL short g_sModelIndexWExplosion;// holds the index for the underwater explosion
|
||||
|
||||
@@ -1453,6 +1453,7 @@ void CTestHull :: Spawn( entvars_t *pevMasterNode )
|
||||
SET_MODEL(ENT(pev), "models/player.mdl");
|
||||
UTIL_SetSize(pev, VEC_HUMAN_HULL_MIN, VEC_HUMAN_HULL_MAX);
|
||||
|
||||
|
||||
pev->solid = SOLID_SLIDEBOX;
|
||||
pev->movetype = MOVETYPE_STEP;
|
||||
pev->effects = 0;
|
||||
@@ -1474,6 +1475,8 @@ void CTestHull :: Spawn( entvars_t *pevMasterNode )
|
||||
// UNDONE: Shouldn't we just use EF_NODRAW? This doesn't need to go to the client.
|
||||
pev->rendermode = kRenderTransTexture;
|
||||
pev->renderamt = 0;
|
||||
|
||||
pev->classname = MAKE_STRING("testhull");
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
@@ -1482,13 +1485,15 @@ void CTestHull :: Spawn( entvars_t *pevMasterNode )
|
||||
//=========================================================
|
||||
void CTestHull::DropDelay ( void )
|
||||
{
|
||||
UTIL_CenterPrintAll( "Node Graph out of Date. Rebuilding..." );
|
||||
// Do NOT uncomment or you'll get a "Tried to create a message with a bogus message type ( 0 )" crash!
|
||||
// Left here only because it's on the original HLSDK, and for comedy purposes. -Giegue
|
||||
//UTIL_CenterPrintAll( "Node Graph out of Date. Rebuilding..." );
|
||||
|
||||
UTIL_SetOrigin ( VARS(pev), WorldGraph.m_pNodes[ 0 ].m_vecOrigin );
|
||||
|
||||
SetThink ( &CTestHull::CallBuildNodeGraph );
|
||||
|
||||
pev->nextthink = gpGlobals->time + 1;
|
||||
pev->nextthink = gpGlobals->time + 2; // think called earlier, so add extra second. -Giegue
|
||||
}
|
||||
|
||||
//=========================================================
|
||||
@@ -1525,14 +1530,12 @@ void CNodeEnt :: Spawn( void )
|
||||
return;
|
||||
}
|
||||
|
||||
// Give time to the nodes to spawn and get added to the worldgraph,
|
||||
// TestHull is spawned after map start, not before. -Giegue
|
||||
/*if ( WorldGraph.m_cNodes == 0 )
|
||||
if ( WorldGraph.m_cNodes == 0 )
|
||||
{
|
||||
// this is the first node to spawn, spawn the test hull entity that builds and walks the node tree
|
||||
CTestHull *pHull = CreateClassPtr((CTestHull *)NULL);
|
||||
CTestHull *pHull = CreateNormalClassPtr((CTestHull *)NULL);
|
||||
pHull->Spawn( pev );
|
||||
}*/
|
||||
}
|
||||
|
||||
if ( WorldGraph.m_cNodes >= MAX_NODES )
|
||||
{
|
||||
@@ -2464,7 +2467,7 @@ int CGraph :: FLoadGraph ( char *szMapName )
|
||||
// Set the graph present flag, clear the pointers set flag
|
||||
//
|
||||
m_fGraphPresent = TRUE;
|
||||
m_fGraphPointersSet = FALSE;
|
||||
m_fGraphPointersSet = TRUE; // what if...?
|
||||
|
||||
FREE_FILE(aMemFile);
|
||||
|
||||
@@ -3472,26 +3475,6 @@ EnoughSaid:
|
||||
// to current location (typically the player). It then draws
|
||||
// as many connects as it can per frame, trying not to overflow the buffer
|
||||
//=========================================================
|
||||
class CNodeViewer : public CMBaseEntity
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
|
||||
int m_iBaseNode;
|
||||
int m_iDraw;
|
||||
int m_nVisited;
|
||||
int m_aFrom[128];
|
||||
int m_aTo[128];
|
||||
int m_iHull;
|
||||
int m_afNodeType;
|
||||
Vector m_vecColor;
|
||||
|
||||
void FindNodeConnections( int iNode );
|
||||
void AddNode( int iFrom, int iTo );
|
||||
void EXPORT DrawThink( void );
|
||||
|
||||
};
|
||||
|
||||
void CNodeViewer::Spawn( )
|
||||
{
|
||||
/*CNodeViewer *pViewer = CreateClassPtr((CNodeViewer *)NULL);
|
||||
@@ -3567,6 +3550,8 @@ void CNodeViewer::Spawn( )
|
||||
m_iDraw = 0;
|
||||
SetThink( &CNodeViewer::DrawThink );
|
||||
pev->nextthink = gpGlobals->time;
|
||||
|
||||
pev->classname = MAKE_STRING( "node_viewer" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -270,6 +270,29 @@ class CNodeEnt : public CMBaseEntity
|
||||
};
|
||||
|
||||
|
||||
//=========================================================
|
||||
// Node viewer
|
||||
//=========================================================
|
||||
class CNodeViewer : public CMBaseEntity
|
||||
{
|
||||
public:
|
||||
void Spawn( void );
|
||||
|
||||
int m_iBaseNode;
|
||||
int m_iDraw;
|
||||
int m_nVisited;
|
||||
int m_aFrom[128];
|
||||
int m_aTo[128];
|
||||
int m_iHull;
|
||||
int m_afNodeType;
|
||||
Vector m_vecColor;
|
||||
|
||||
void FindNodeConnections( int iNode );
|
||||
void AddNode( int iFrom, int iTo );
|
||||
void EXPORT DrawThink( void );
|
||||
|
||||
};
|
||||
|
||||
//=========================================================
|
||||
// CStack - last in, first out.
|
||||
//=========================================================
|
||||
|
||||
Reference in New Issue
Block a user