objectinfo.cpp #2

  • //
  • 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();
			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.