objectinfo.cpp #3

  • //
  • guest/
  • sam_stafford/
  • p4hl/
  • src/
  • dlls/
  • objectinfo.cpp
  • View
  • Commits
  • Open Download .zip Download (5 KB)
#include "p4objects.h"

LINK_ENTITY_TO_CLASS( object_info, CObjectInfo)

void CObjectInfo :: Spawn( ) 
{ 
	Precache( );
			
	SET_MODEL( ENT(pev), STRING(pev->model) );

	UTIL_SetOrigin( pev, pev->origin );
	target = (Vector)pev->origin;  //by default, we're already where we want to be.

	UTIL_SetSize( pev, Vector(-30, -30, 38), Vector(30, 30, 90) );  //collision box!

	level = 0;

	pev->movetype = MOVETYPE_FLY;
/* This is the animating code. */
	pev->sequence = LookupActivity (ACT_IDLE); //Use the ACT_IDLE sequence.
	pev->frame = 0; //Start on frame 0.
	pev->framerate = 1; //And set a framerate of 1.
/*                             */
	pev->solid = SOLID_BBOX; 

	SetThink( Think );
	SetTouch( Touch );

	pev->nextthink = gpGlobals->time + 0.8;
	nextRefreshTime = gpGlobals->time + 30;
} 

/* The object_info is the only one that's in the world when the map starts up, so we need
 * to precache everything, since the object_info will ultimately be spawning them later. */
void CObjectInfo :: Precache( ) 
	{ 
		/* Precache all the models, starting with this one. */
		PRECACHE_MODEL( "models/info/w_info.mdl" );
		PRECACHE_MODEL( "models/depot/w_depot.mdl" );
		PRECACHE_MODEL( "models/dir/w_dir.mdl" );
		PRECACHE_MODEL( "models/file/w_file.mdl");
		PRECACHE_MODEL( "models/rev/w_edit.mdl" );
		PRECACHE_MODEL( "models/rev/w_add.mdl" );
		PRECACHE_MODEL( "models/rev/w_delete.mdl" );
		PRECACHE_MODEL( "models/rev/w_integ.mdl" );
		/* Before I put this next bit of code in, the program would lag for three
		 * seconds the first time I accessed Perforce.  Now I have it in the precache 
		 * function so it's not as noticeable - still not sure exactly why it's slow
		 * the first time, though. */
		ClientLuser ui;
		ClientApi client;
		Error e;
		client.Init( &e );
		client.Run( "info", &ui );
		client.Final( &e );
} 

void CObjectInfo :: Think( void )
{
	if (!IsInWorld())
	{
		UTIL_Remove( this );
		return;
	}
	if (nextRefreshTime < gpGlobals->time) 
	{
		ClientLuser ui;
		ClientApi client;
		Error e;
		client.Init( &e );
		client.Run( "info", &ui );
		client.Final( &e );
		nextRefreshTime += 30;
	}
	if (UTIL_VecUpdate( &(pev->origin), target )) 
	{
		pev->nextthink = gpGlobals->time + 0.05;
		UTIL_SetSize( pev, Vector(-30, -30, 38), Vector(30, 30, 90) );  //collision box!
	}
	else pev->nextthink = gpGlobals->time + 0.5;
}

void CObjectInfo :: Touch( CBaseEntity* Player ) 
{
	CBasePlayer *pl;
	CBaseEntity *be = CBaseEntity::Instance(Player->pev->owner);

	if (Player->IsPlayer()) pl = (CBasePlayer*) Player;
	else if (be->IsPlayer()) pl = (CBasePlayer*) be;
	else return;
	if (pl->m_flNextP4Time > gpGlobals->time) return;

	if (Player->IsExpand()) {
		Expand( pl );
		return;
	}

	//after this point we just spit "p4 info" to player "pl".
			
	//run the command "p4 info"			
	ClientLuser ui;
	ClientApi client;
	Error e;
	StrBuf msg = StrBuf();

	client.Init( &e );
	if (e.GetSeverity()) {
		e.Fmt(&msg);
		UTIL_FatalHud(pl, msg.Text());
		pl->m_flNextP4Time = gpGlobals->time + 20.0; //20 second delay on connect error
		return;
	}

	client.Run( "info", &ui );

	client.Final( &e );
	if (e.GetSeverity()) {
		e.Fmt(&msg);
		UTIL_WarningHud(pl, msg.Text());
	}
	// Print contents of the message buffer
	UTIL_PrintHud( pl, ui.message.Text());
	pl->m_flNextP4Time = gpGlobals->time + 0.5; //0.5 second delay
}

void CObjectInfo :: Expand( CBasePlayer *pl)
{
	if (level == 1) return;
	UTIL_PrintHud( pl, "Expanding root node...\n");

	killKids(this);
	newLevel(1);

	ClientDepotUser ui;
	ui.specflag = FALSE;
	ClientApi client;
	Error e;

	client.Init( &e );
	if (e.GetSeverity()) {
		StrBuf msg = StrBuf();
		e.Fmt(&msg);
		UTIL_FatalHud(pl, msg.Text());
		pl->m_flNextP4Time = gpGlobals->time + 20.0;
		return;
	}

	client.Run( "depots", &ui );

	client.Final( &e );
	if (e.GetSeverity()) {
		StrBuf warn = StrBuf();
		e.Fmt(&warn);
		UTIL_WarningHud(pl, warn.Text());
	}

	StrBuf depot = ui.depots.SPop();
	if (depot.Length() == 0) depot.Append("depot");
	float ycoord = 0.0;

	CObjectDepot *newdepot;

	while (depot.Length() > 0)
	{
			newdepot = GetClassPtr( (CObjectDepot *)NULL );
			depots.Append(newdepot);
			newdepot->pev->classname = MAKE_STRING("object_depot");
			newdepot->Spawn();
			newdepot->pev->origin = pev->origin;
			newdepot->target = target - Vector(0,0,100);
			newdepot->target.y -= ycoord*100;
			newdepot->path = depot;
			newdepot->parent = this;
			newdepot->pev->nextthink = gpGlobals->time;
			depot = ui.depots.SPop();
			ycoord++;
	}
	return;
}

void CObjectInfo :: newLevel( short newlev)
{
	target.z += (newlev - level)*100;
	level = newlev;
}

void CObjectInfo :: disown( CBaseEntity *child)
{
	depots.EKill(child);
}

	void CObjectInfo :: killKids( CBaseEntity *Caller )
{
	BOOL callerFlag = FALSE;
	CBaseEntity* kid = depots.EPop();
	while (kid != NULL)
	{
		if (kid == Caller) 
		{
			callerFlag = TRUE;
			kid = depots.EPop();
			continue;
		}
		kid -> killKids(this);
		UTIL_Remove(kid);
		kid = depots.EPop();
	}
	if (callerFlag) depots.Append(Caller);
}
# Change User Description Committed
#6 1689 Sam Stafford Integrate 02.1 API and code cleanup to P4HL.
 Lots of work.  Phew.
#5 1007 Sam Stafford A stab at making P4HL a bit more accessible to Perforce novices.
During the Precache() phase of the P4HL objects, a "p4 info" is
executed.  If this returns any errors, odds are there's no server
there (I can't think of what other error "p4 info" would return).
If this happens, use "public.perforce.com:1666" as the new port
value for all future Perforce transactions during this session,
and send a message to the console explaining this.
#4 1003 Sam Stafford Different file types now displayed differently.
 Also flipped
around the file model so that its text doesn't look backwards
any more.
#3 986 Sam Stafford If no depots are listed by "p4 depots", assume that there is one depot
called "depot".
#2 971 Sam Stafford Have the ObjectInfo run a "p4 info" every 30 seconds.
#1 937 Sam Stafford Renaming my guest directory to the more conventional
sam_stafford.
//guest/samwise/p4hl/src/dlls/objectinfo.cpp
#1 936 Sam Stafford Adding P4HL to the public depot.
 See relnotes.txt for
installation instructions; all relevant files are under
p4hl/dist.

Source code is under p4hl/src in the form of a VC++ project.