// ObjectDir.cpp: implementation of the CObjectDir class. // ////////////////////////////////////////////////////////////////////// #include "p4objects.h" LINK_ENTITY_TO_CLASS( object_dir, CObjectDir); void CObjectDir::Spawn() { Precache( ); SET_MODEL( ENT(pev), "models/dir/w_dir.mdl" ); UTIL_SetOrigin( pev, pev->origin ); target = (Vector)pev->origin; //by default, we're already where we want to be. UTIL_SetSize( pev, Vector(-20, -15, 38), Vector( 30, 4, 78) ); //collision box! level = 0; pev->movetype = MOVETYPE_FLY; // pev->sequence = LookupActivity (ACT_IDLE); // pev->frame = 0; // pev->framerate = 1; pev->solid = SOLID_BBOX; SetThink( Think ); SetTouch( Touch ); pev->nextthink = gpGlobals->time + 0.5; } void CObjectDir::Precache() { PRECACHE_MODEL("models/dir/w_dir.mdl"); } void CObjectDir :: Think( void ) { if (!IsInWorld()) { parent -> disown ( this ); UTIL_Remove( this ); return; } if (UTIL_VecUpdate( &(pev->origin), target )) { pev->nextthink = gpGlobals->time + 0.05; UTIL_SetSize( pev, Vector(-20, -15, 38), Vector( 30, 4, 78) ); //collision box! } else pev->nextthink = gpGlobals->time + 0.5; } void CObjectDir :: Touch( CBaseEntity* Thing ) { CBasePlayer *pl; CBaseEntity *be = CBaseEntity::Instance(Thing->pev->owner); if (Thing->IsPlayer()) pl = (CBasePlayer*) Thing; else if (be->IsPlayer()) pl = (CBasePlayer*) be; else return; if (pl->m_flNextP4Time > gpGlobals->time) return; if (Thing->IsExpand()) { Expand( pl ); pl->m_flNextP4Time = gpGlobals->time + 0.5; return; } if (Thing->IsLong()) { Long( pl ); pl->m_flNextP4Time = gpGlobals->time + 0.5; return; } pl->m_flNextP4Time = gpGlobals->time + 0.2; UTIL_PrintHud(pl, path.Text()); } void CObjectDir :: Long( CBasePlayer* pl ) { ClientDirUser ui; ui.changeflag = TRUE; ClientApi client; if (P4PORT.Length()) client.SetPort(P4PORT.Text()); 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; } char* args[3]; StrBuf changepath = StrBuf(); changepath.Append(path.Text()); changepath.Append("/..."); args[0] = "-m"; args[1] = "10"; args[2] = changepath.Text(); client.SetArgv(3, args); client.Run( "changes", &ui ); client.Final( &e ); if (e.GetSeverity()) { e.Fmt(&msg); UTIL_WarningHud(pl, msg.Text()); } UTIL_PrintHud( pl, ui.changes.Text()); } void CObjectDir :: Expand ( CBasePlayer* pl ) { if (level == 1) return; short sofar = 0; StrBuf hudmsg = StrBuf(); hudmsg.Append("Expanding directory "); hudmsg.Append(path.Text()); hudmsg.Append("..."); UTIL_PrintHud( pl, hudmsg.Text()); killKids(this); newLevel(1); parent->killKids(this); ClientDirUser ui; ui.changeflag = FALSE; ClientApi client; if (P4PORT.Length()) client.SetPort(P4PORT.Text()); 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; } StrBuf dirpath = StrBuf(); dirpath.Append(path.Text()); dirpath.Append("/*"); char* args[1]; args[0] = dirpath.Text(); client.SetArgv(1, args); client.Run( "dirs", &ui ); StrBuf dir = ui.dirs.SPop(); float xcoord = 1.0; CObjectDir *newdir; while (dir.Length() > 0) { if (sofar > MAXRESULTS) break; newdir = GetClassPtr( (CObjectDir *)NULL ); dirs.Append(newdir); newdir->pev->classname = MAKE_STRING("object_dir"); newdir->Spawn(); newdir->pev->origin = pev->origin; newdir->target = target - Vector(0,0,100); newdir->target.x -= xcoord*70; newdir->path = dir; newdir->parent = this; newdir->pev->nextthink = gpGlobals->time; dir = ui.dirs.SPop(); xcoord++; sofar++; } if (sofar > MAXRESULTS) { UTIL_WarningHud(pl, "Output truncated!"); return; } ClientFileUser fui; fui.logflag = FALSE; args[0] = dirpath.Text(); client.SetArgv(1, args); client.Run( "files", &fui ); client.Final( &e ); if (e.GetSeverity()) { StrBuf warn = StrBuf(); e.Fmt(&warn); UTIL_WarningHud(pl, warn.Text()); } StrBuf file = fui.files.SPop(); StrBuf ftype = fui.ftypes.SPop(); float ycoord = 1.0; CObjectFile *newfile; while (file.Length() > 0) { if (sofar > MAXRESULTS) break; newfile = GetClassPtr( (CObjectFile *)NULL ); files.Append(newfile); newfile->pev->classname = MAKE_STRING("object_file"); switch (*(ftype.Text())) { default: case 't': newfile->ftype = FTYPE_TEX; break; case 'b': newfile->ftype = FTYPE_BIN; break; case 'a': newfile->ftype = FTYPE_APP; break; case 's': newfile->ftype = FTYPE_SYM; break; } newfile->Spawn(); newfile->pev->origin = pev->origin; newfile->pev->angles = Vector(-1,-1,-1); newfile->target = target - Vector(0,0,100); newfile->target.y -= ycoord*60; newfile->path = file; newfile->parent = this; newfile->pev->nextthink = gpGlobals->time; file = fui.files.SPop(); ftype = fui.ftypes.SPop(); ycoord++; sofar++; } if (sofar > MAXRESULTS) UTIL_WarningHud(pl, "Output truncated!\n"); return; } void CObjectDir :: newLevel( short newlev ) { if (newlev > 0) { Vector parvec = parent->targvec(); target.x = parvec.x; target.y = parvec.y; } target.z += (newlev - level)*100; level = newlev; parent->newLevel(level+1); } void CObjectDir :: disown ( CBaseEntity *Target ) //this does the OPPOSITE of killKids!!! { dirs.EKill(Target); files.EKill(Target); return; } void CObjectDir :: killKids( CBaseEntity *Caller ) { bool callerFlag = false; CBaseEntity* kid = dirs.EPop(); while (kid != NULL) { if (kid == Caller) { callerFlag = TRUE; kid = dirs.EPop(); continue; } kid -> killKids(this); UTIL_Remove(kid); kid = dirs.EPop(); } if (callerFlag) dirs.Append(Caller); callerFlag = false; kid = files.EPop(); while (kid != NULL) { if (kid == Caller) { callerFlag = TRUE; kid = files.EPop(); continue; } kid -> killKids(this); UTIL_Remove(kid); kid = files.EPop(); } if (callerFlag) files.Append(Caller); } CObjectDir::CObjectDir() { } //CObjectDir::~CObjectDir() //{ //}
# | Change | User | Description | Committed | |
---|---|---|---|---|---|
#6 | 1689 | Sam Stafford |
Integrate 02.1 API and code cleanup to P4HL. Lots of work. Phew. |
||
#5 | 1024 | Sam Stafford |
Reworked entity creation in most cases - it's done one at a time now rather than all at once. This allows us to have more entities than the previous limit of 130, and also looks a little nicer. Folders and files now pop into existence instantly instead of sliding - makes navigation easier. Depots still slide because there typically aren't as many of them (okay, I might eventually make them pop too, but I'm tired now). Revisions slide because it looks really cool - like a waterfall pouring out of the file. The upper limit to entities is now due to the "visible entity packet" thing, which I'm certain I have no control over - it's as high as it can possibly be right now. |
||
#4 | 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. |
||
#3 | 1005 | Sam Stafford | Whoops, I lied - NOW text is the default in all cases. | ||
#2 | 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. |
||
#1 | 937 | Sam Stafford |
Renaming my guest directory to the more conventional sam_stafford. |
||
//guest/samwise/p4hl/src/dlls/ObjectDir.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. |