// 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;
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;
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. |
||