void ProcessMenu(int value)
{
    switch(value)
    {
    case 1:
        useVertexShader = !useVertexShader;
        if (useVertexShader)
        {
            glutChangeToMenuEntry(1, "Toggle vertex shader (currently ON)", 1);
            glAttachShader(progObj, vShader);
        }
        else
        {
            glutChangeToMenuEntry(1, "Toggle vertex shader (currently OFF)", 1);
            glDetachShader(progObj, vShader);
        }

        Relink();
        break;

    case 2:
        useFragmentShader = !useFragmentShader;
        if (useFragmentShader)
        {
            glutChangeToMenuEntry(2, "Toggle fragment shader (currently ON)", 2);
            glAttachShader(progObj, fShader);
        }
        else
        {
            glutChangeToMenuEntry(2, "Toggle fragment shader (currently OFF)", 2);
            glDetachShader(progObj, fShader);
        }

        Relink();
        break;

    case 3:
        doBlink = !doBlink;
        if (doBlink)
        {
            glutChangeToMenuEntry(3, "Toggle flicker (currently ON)", 3);
        }
        else
        {
            glutChangeToMenuEntry(3, "Toggle flicker (currently OFF)", 3);
        }
        if (!doBlink && (flickerLocation != -1))
            glUniform1f(flickerLocation, 1.0f);
        break;

    default:
        break;
    }

    // Refresh the Window
    glutPostRedisplay();
}
	//=========================================================
	// Materialize - make a CWeaponCSBase visible and tangible
	//=========================================================
	void CWeaponCSBase::Materialize()
	{
		if ( m_fEffects & EF_NODRAW )
		{
			// changing from invisible state to visible.
			//Ken: Suppress the default sound
			//---
			if( g_pGameRules->IsMultiplayer() )
			{
				//EMIT_SOUND_DYN( ENT(pev), CHAN_WEAPON, "items/suitchargeok1.wav", 1, ATTN_NORM, 0, 150 );
			}

			//---
			m_fEffects &= ~EF_NODRAW;
			m_fEffects |= EF_MUZZLEFLASH;
		}

		AddSolidFlags( FSOLID_TRIGGER );

		Relink();
		//SetTouch( &CWeaponCSBase::DefaultTouch );

		//Ken: Leave guns & items lying around in single-player
		//---
		if( g_pGameRules->IsMultiplayer() ) 
		{
			SetThink (&CWeaponCSBase::SUB_Remove);
			SetNextThink( gpGlobals->curtime + 1 );
		}
		else
		{
			SetThink( NULL );
		}
	}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CGrenadeBugBait::Spawn( void )
{
	Precache();

	SetModel( GRENADE_MODEL );

	SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE );
	SetSolid( SOLID_BBOX ); 

	UTIL_SetSize( this, Vector( -2, -2, -2), Vector( 2, 2, 2 ) );
	Relink();

	SetTouch( BugBaitTouch );

	m_takedamage = DAMAGE_NO;

	m_pSporeTrail = NULL;

	/*
	m_pSporeTrail = SporeTrail::CreateSporeTrail();
	
	m_pSporeTrail->m_bEmit				= true;
	m_pSporeTrail->m_flSpawnRate		= 100.0f;
	m_pSporeTrail->m_flParticleLifetime	= 1.0f;
	m_pSporeTrail->m_flStartSize		= 1.0f;
	m_pSporeTrail->m_flEndSize			= 1.0f;
	m_pSporeTrail->m_flSpawnRadius		= 8.0f;

	m_pSporeTrail->m_vecEndColor		= Vector( 0, 0, 0 );
	*/
}
void CBaseTurret::Deploy(void)
{
	SetNextThink( gpGlobals->curtime + 0.1f );
	StudioFrameAdvance( );

	if ( m_Activity != ACT_TURRET_OPEN )
	{
		m_iOn = 1;
		SetActivity( (Activity)ACT_TURRET_OPEN );
		EmitSound( "NPC_Turret.Deploy" );

		m_OnDeploy.FireOutput(NULL, this);
	}

	if (m_fSequenceFinished)
	{
		Vector curmins, curmaxs;
		curmins = WorldAlignMins();
		curmaxs = WorldAlignMaxs();

		curmaxs.z = m_iDeployHeight;
		curmins.z = -m_iDeployHeight;

		SetCollisionBounds( curmins, curmaxs );

		Relink();

		SetActivity( (Activity)ACT_TURRET_OPEN_IDLE );

		m_flPlaybackRate = 0;
		SetThink(SearchThink);
	}

	m_flLastSight = gpGlobals->curtime + m_flMaxWait;
}
//-----------------------------------------------------------------------------
// Spawn
//-----------------------------------------------------------------------------
void CNPC_Eli :: Spawn()
{
	Precache();

	BaseClass::Spawn();

	SetModel( "models/eli.mdl" );

	SetHullType(HULL_HUMAN);
	SetHullSizeNormal();

	SetSolid( SOLID_BBOX );
	AddSolidFlags( FSOLID_NOT_STANDABLE );
	SetMoveType( MOVETYPE_STEP );
	SetBloodColor( BLOOD_COLOR_RED );
	m_iHealth			= 8;
	m_flFieldOfView		= 0.5;// indicates the width of this NPC's forward view cone ( as a dotproduct result )
	m_NPCState			= NPC_STATE_NONE;
	
	CapabilitiesAdd( bits_CAP_MOVE_GROUND | bits_CAP_OPEN_DOORS | bits_CAP_ANIMATEDFACE | bits_CAP_TURN_HEAD );

	NPCInit();

	Relink();
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CPlayer_Missile::InputActivate( inputdata_t &inputdata )
{
	// Make sure not already active
	if (m_bActive)
	{
		return;
	}

	BaseClass::InputActivate( inputdata );

	Vector origin = GetLocalOrigin();
	origin.z	+= 50;
	SetLocalOrigin( origin );
	RemoveSolidFlags( FSOLID_NOT_SOLID );
	Relink();

	// Using player angles to determine turning.  Initailze to 0,0,0
	CHL2_Player*	pPlayer		= (CHL2_Player*)UTIL_PlayerByIndex( 1 );

	Assert( pPlayer );

	pPlayer->SetLocalAngles( vec3_angle );	// Note: Set GetLocalAngles(), not pl.v_angle
	pPlayer->SnapEyeAngles( vec3_angle );				// Force reset
	pPlayer->SetFOV( 100 );

	engine->SetView( pPlayer->edict(), edict() );

	m_flStatic					= 0;
	SetThink(Launch);
	SetNextThink( gpGlobals->curtime + m_flLaunchDelay );
}
void CRagdollPropAttached::InitRagdollAttached( IPhysicsObject *pAttached, const Vector &forceVector, int forceBone, matrix3x4_t *pPrevBones, matrix3x4_t *pBoneToWorld, float dt, int collisionGroup, CBaseAnimating *pFollow, int boneIndexRoot, const Vector &boneLocalOrigin, int parentBoneAttach, const Vector &worldAttachOrigin )
{
	int ragdollAttachedIndex = 0;
	if ( parentBoneAttach > 0 )
	{
		studiohdr_t *pStudioHdr = GetModelPtr();
		mstudiobone_t *pBone = pStudioHdr->pBone( parentBoneAttach );
		ragdollAttachedIndex = pBone->physicsbone;
	}

	InitRagdoll( forceVector, forceBone, vec3_origin, pPrevBones, pBoneToWorld, dt, collisionGroup, false );
	
	IPhysicsObject *pRefObject = m_ragdoll.list[ragdollAttachedIndex].pObject;

	Vector attachmentPointRagdollSpace;
	pRefObject->WorldToLocal( attachmentPointRagdollSpace, worldAttachOrigin );

	constraint_ragdollparams_t constraint;
	constraint.Defaults();
	matrix3x4_t tmp, worldToAttached, worldToReference, constraintToWorld;

	Vector offsetWS;
	pAttached->LocalToWorld( offsetWS, boneLocalOrigin );

	AngleMatrix( QAngle(0, pFollow->GetAbsAngles().y, 0 ), offsetWS, constraintToWorld );

	constraint.axes[0].SetAxisFriction( -2, 2, 20 );
	constraint.axes[1].SetAxisFriction( 0, 0, 0 );
	constraint.axes[2].SetAxisFriction( -15, 15, 20 );
	
	pAttached->GetPositionMatrix( tmp );
	MatrixInvert( tmp, worldToAttached );

	pRefObject->GetPositionMatrix( tmp );
	MatrixInvert( tmp, worldToReference );

	ConcatTransforms( worldToReference, constraintToWorld, constraint.constraintToReference );
	ConcatTransforms( worldToAttached, constraintToWorld, constraint.constraintToAttached );

	// for now, just slam this to be the passed in value
	MatrixSetColumn( attachmentPointRagdollSpace, 3, constraint.constraintToReference );

	DisableCollisions( pAttached );
	m_pAttachConstraint = physenv->CreateRagdollConstraint( pRefObject, pAttached, m_ragdoll.pGroup, constraint );

	FollowEntity( pFollow );
	SetOwnerEntity( pFollow );
	RagdollActivate( m_ragdoll );

	Relink();
	m_boneIndexAttached = boneIndexRoot;
	m_ragdollAttachedObjectIndex = ragdollAttachedIndex;
	m_attachmentPointBoneSpace = boneLocalOrigin;
	
	Vector vTemp;
	MatrixGetColumn( constraint.constraintToReference, 3, vTemp );
	m_attachmentPointRagdollSpace = vTemp;
}
//-----------------------------------------------------------------------------
// Purpose: Attaches the flame to an entity and moves with it
// Input  : pTarget - target entity to attach to
//-----------------------------------------------------------------------------
void CEntityFlame::AttachToEntity( CBaseEntity *pTarget )
{
	// For networking to the client.
	m_hEntAttached = pTarget;

	// So our heat emitter follows the entity around on the server.
	SetParent( pTarget );
	Relink();
}
	TreeNode* Relink(TreeNode *root)
	{
		if(!root || (!root->left && !root->right))
			return root;
		TreeNode *left = root->left;
		TreeNode *right = root->right;
		root->left = NULL;
		if(left)
		{
			root->right = left;
			root = Relink(left);
		}
		if(right)
		{
			root->right = right;
			root = Relink(right);
		}
		return  root;
	}
void CBoneFollower::VPhysicsUpdate( IPhysicsObject *pPhysics )
{
	Vector origin;
	QAngle angles;

	pPhysics->GetPosition( &origin, &angles );

	SetAbsOrigin( origin );
	SetAbsAngles( angles );

	Relink();
}
void CBaseTurret::Retire(void)
{
	// make the turret level
	m_vecGoalAngles = GetAngles( );

	SetNextThink( gpGlobals->curtime + 0.1f );

	StudioFrameAdvance( );

	EyeOff( );

	if ( m_Activity != ACT_TURRET_CLOSE )
	{
		SetActivity( (Activity)ACT_TURRET_OPEN_IDLE );
		
		if (!MoveTurret())
		{
			SetActivity( (Activity)ACT_TURRET_CLOSE );
			EmitSound( "NPC_Turret.Retire" );

			m_OnRetire.FireOutput(NULL, this);
		}
	}
	else if (m_fSequenceFinished) 
	{	
		m_iOn = 0;
		m_flLastSight = 0;

		SetActivity( (Activity)ACT_TURRET_CLOSED_IDLE );

		Vector curmins, curmaxs;
		curmins = WorldAlignMins();
		curmaxs = WorldAlignMaxs();

		curmaxs.z = m_iRetractHeight;
		curmins.z = -m_iRetractHeight;

		SetCollisionBounds( curmins, curmaxs );
		Relink();

		if (m_iAutoStart)
		{
			SetThink(AutoSearchThink);		
			SetNextThink( gpGlobals->curtime + .1 );
		}
		else
		{
			SetThink(SUB_DoNothing);
		}
	}
}
void CRagdollPropAttached::Detach()
{
	StopFollowingEntity();
	SetOwnerEntity( NULL );
	SetAbsAngles( vec3_angle );
	SetMoveType( MOVETYPE_VPHYSICS );
	physenv->DestroyConstraint( m_pAttachConstraint );
	m_pAttachConstraint = NULL;

	// Go non-solid
	SetCollisionGroup( COLLISION_GROUP_DEBRIS );
	Relink();
	RecheckCollisionFilter();
}
Exemple #13
0
void Program::DoLink () {
    while (oldModList != nil) {
        InputFile* doomed = (InputFile*) oldModList;
        oldModList = (InputFile*)oldModList->nn;
        doomed->Unlink(oldModList);
        delete doomed;
    }
    Base* insertPoint = inf->nn;
    ctdt->Link(insertPoint);
    if (fullLink) {
        FullLink();
    } else {
        Relink();
    }
}
//-----------------------------------------------------------------------------
// Purpose: Spawn the object
//-----------------------------------------------------------------------------
void CExtinguisherCharger::Spawn( void )
{
	Precache();

	SetSolid( SOLID_BSP );
	SetMoveType( MOVETYPE_PUSH );

	UTIL_SetSize( this, EntitySpaceMins(), EntitySpaceMaxs() );
	SetModel( STRING( GetModelName() ) );
	Relink();

	m_bSoundOn = false;

	CreateVPhysics();
}
void CRecharge::Spawn()
{
	Precache( );

	SetSolid( SOLID_BSP );
	SetMoveType( MOVETYPE_PUSH );

	Relink();
	UTIL_SetSize(this, EntitySpaceMins(), EntitySpaceMaxs());
	SetModel( STRING( GetModelName() ) );
	m_iJuice = sk_suitcharger.GetFloat();
	SetTextureFrameIndex( 0 );

	CreateVPhysics();
}
void CRagdollProp::Spawn( void )
{
	Precache();
	SetModel( STRING( GetModelName() ) );

	Relink();

	matrix3x4_t pBoneToWorld[MAXSTUDIOBONES];
	BaseClass::SetupBones( pBoneToWorld, BONE_USED_BY_ANYTHING ); // FIXME: shouldn't this be a subset of the bones
	int collisionGroup = (m_spawnflags & SF_RAGDOLLPROP_DEBRIS) ? COLLISION_GROUP_DEBRIS : COLLISION_GROUP_NONE;
	InitRagdoll( vec3_origin, 0, vec3_origin, pBoneToWorld, pBoneToWorld, 0, collisionGroup, true );

	// only send data when physics moves this object
	NetworkStateManualMode( true );
	m_lastUpdateTickCount = 0;
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CPlayer_Missile::BlowUp(void)
{
	// Don't take damage any more
	m_takedamage	= DAMAGE_NO;

	// Mark as dead so won't be attacked
	m_lifeState = LIFE_DEAD;

	// Stop fly and launch sounds
	StopSound( "Player_Manhack.Fly" );
	StopSound( "Player_Manhack.Fire" );

	CPASFilter filter( GetAbsOrigin() );
	te->Explosion( filter, 0.0,
		&GetAbsOrigin(), 
		g_sModelIndexFireball,
		2.0, 
		15,
		TE_EXPLFLAG_NONE,
		m_flDamageRadius,
		m_flDamage );

	Vector vecForward = GetAbsVelocity();
	VectorNormalize(vecForward);
	trace_t		tr;
	UTIL_TraceLine ( GetAbsOrigin(), GetAbsOrigin() + 60*vecForward,  MASK_SOLID_BRUSHONLY, 
		this, COLLISION_GROUP_NONE, &tr);

	UTIL_DecalTrace( &tr, "Scorch" );

	UTIL_ScreenShake( GetAbsOrigin(), 25.0, 150.0, 1.0, 750, SHAKE_START );
	CSoundEnt::InsertSound ( SOUND_DANGER, GetAbsOrigin(), 1024, 3.0 );

	RadiusDamage ( CTakeDamageInfo( this, this, m_flDamage, DMG_BLAST ), GetAbsOrigin(), m_flDamageRadius, CLASS_NONE );

	SetThink(ExplodeThink);
	SetTouch(NULL);
	m_vBounceVel	= -0.2 * GetAbsVelocity();
	AddSolidFlags( FSOLID_NOT_SOLID );
	Relink();

	// Stop emitting smoke
	if(m_hSmokeTrail)
	{
		((SmokeTrail*)(CBaseEntity*)m_hSmokeTrail)->SetEmit(false);
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CPhysBox::Spawn( void )
{
	Precache();

	if ( HasSpawnFlags( SF_BREAK_TRIGGER_ONLY ) )
	{
		m_takedamage = DAMAGE_NO;
		AddSpawnFlags( SF_BREAK_DONT_TAKE_PHYSICS_DAMAGE );
	}
	else if ( m_iHealth == 0 )
	{
		m_takedamage = DAMAGE_EVENTS_ONLY;
		AddSpawnFlags( SF_BREAK_DONT_TAKE_PHYSICS_DAMAGE );
	}
	else
	{
		m_takedamage = DAMAGE_YES;
	}
  
	SetMoveType( MOVETYPE_NONE );
	SetSolid( SOLID_VPHYSICS );

	SetAbsVelocity( vec3_origin );
	SetModel( STRING( GetModelName() ) );
	Relink();
	SetSolid( SOLID_VPHYSICS );
	if ( HasSpawnFlags( SF_PHYSBOX_DEBRIS ) )
	{
		SetCollisionGroup( COLLISION_GROUP_DEBRIS );
	}

	CreateVPhysics();

	m_hCarryingPlayer = NULL;

	SetTouch( &CPhysBox::BreakTouch );
	if ( HasSpawnFlags( SF_BREAK_TRIGGER_ONLY ) )		// Only break on trigger
	{
		SetTouch( NULL );
	}

	if ( m_impactEnergyScale == 0 )
	{
		m_impactEnergyScale = 1.0;
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CPlayer_Missile::ControlDeactivate( void )
{
	BaseClass::ControlDeactivate();

	CHL2_Player*	pPlayer		= (CHL2_Player*)UTIL_PlayerByIndex( 1 );

	Assert( pPlayer );

	engine->SetView( pPlayer->edict(), pPlayer->edict() );

	pPlayer->m_Local.m_iHideHUD &= ~HIDEHUD_WEAPONS;

	SetAbsVelocity( vec3_origin );
	SetLocalAngles( m_vSpawnAng );
	SetLocalOrigin( m_vSpawnPos );
	m_fEffects		|= EF_NODRAW;
	Relink();
}
void CRagdollProp::CalcRagdollSize( void )
{
	Vector minbox, maxbox;

	ExtractBbox( GetSequence(), minbox, maxbox );
	SetCollisionBounds( minbox, maxbox );

	if ( m_ragdoll.list[0].pObject )
	{
		Vector rootPos, rootWorldPos;
		m_ragdoll.list[0].pObject->GetPosition( &rootWorldPos, NULL );
		WorldToEntitySpace( rootWorldPos, &rootPos );

		// BUGBUG: This doesn't work because the sequence doesn't necessarily include
		//		   the extrema of pose space.
		// An algorithm that should work correctly is to store a radius in each bone
		// Then walk the skeleton away from the root to each leaf, accumulating distance to parent
		// The node or leaf with the largest radius + Sum(dist to parent) is the ragdoll's radius
		// Next rev of the model file format, I'll add bone radius and fix this.
		Vector dist;
		const Vector &center = EntitySpaceCenter();
		int i;
		for ( i = 0; i < 3; i++ )
		{
			if ( rootPos[i] > center[i] )
			{
				dist[i] = rootPos[i] - EntitySpaceMins()[i];
			}
			else
			{
				dist[i] = EntitySpaceMaxs()[i] - rootPos[i];
			}
		}

		float radius = dist.Length();
		Vector curmins( -radius, -radius, -radius );
		Vector curmaxs( radius, radius, radius );
		SetCollisionBounds( curmins, curmaxs );
	}

	m_savedESMins = EntitySpaceMins();
	m_savedESMaxs = EntitySpaceMaxs();
	Relink();
}
void CStickyBomb::Spawn()
{
	m_hOperator = GetOwnerEntity();
	Precache();
	SetModel( STICKY_BOMB_MODEL );
	SetSolid( SOLID_BBOX );
	SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_CUSTOM );
	SetCollisionGroup( COLLISION_GROUP_NONE );
	m_takedamage = DAMAGE_NO;
	SetNextThink( TICK_NEVER_THINK );
	m_flAnimTime = gpGlobals->curtime;
	m_flPlaybackRate = 0.0;
	m_flCycle = 0;
	UTIL_SetSize( this, vec3_origin, vec3_origin );
	Relink();
	// no shadows, please.
	m_fEffects |= EF_NOSHADOW|EF_NORECEIVESHADOW;
	SetRenderColor( 255, 0, 0 );
}
Exemple #22
0
//------------------------------------------------------------------------------
// Purpose :
// Input   :
// Output  :
//------------------------------------------------------------------------------
void CNPC_LightStalk::Spawn( void )
{
    Precache();
    SetModel( LIGHTSTALK_MODEL );

    SetMoveType( MOVETYPE_NONE );
    SetSolid( SOLID_BBOX );
    AddSolidFlags( FSOLID_TRIGGER );

    UTIL_SetSize( this, Vector(-80,-80,0), Vector(80,80,32));
    Relink();
    SetActivity( ACT_IDLE );
    SetNextThink( gpGlobals->curtime + 0.1f );

    m_pGlow = CSprite::SpriteCreate( LIGHTSTALK_GLOW_SPRITE, GetLocalOrigin() + Vector(0,0,(WorldAlignMins().z+WorldAlignMaxs().z)*0.5), false );
    m_pGlow->SetTransparency( kRenderGlow, m_clrRender->r, m_clrRender->g, m_clrRender->b, m_clrRender->a, kRenderFxGlowShell );
    m_pGlow->SetScale( 1.0 );
    m_pGlow->SetAttachment( this, 1 );
    LightRise();
}
//=========================================================
// Spawn
//=========================================================
void CNPC_Gargantua::Spawn()
{
	Precache( );

	SetModel( "models/garg.mdl" );

	SetNavType(NAV_GROUND);
	SetSolid( SOLID_BBOX );
	AddSolidFlags( FSOLID_NOT_STANDABLE );
	SetMoveType( MOVETYPE_STEP );

	m_bloodColor		= BLOOD_COLOR_GREEN;
	m_iHealth			= sk_gargantua_health.GetFloat();
	SetViewOffset( Vector ( 0, 0, 96 ) );// taken from mdl file
	m_flFieldOfView		= -0.2;// width of forward view cone ( as a dotproduct result )
	m_NPCState			= NPC_STATE_NONE;

	CapabilitiesAdd( bits_CAP_MOVE_GROUND );
	CapabilitiesAdd( bits_CAP_INNATE_RANGE_ATTACK1 | bits_CAP_INNATE_MELEE_ATTACK1 | bits_CAP_INNATE_MELEE_ATTACK2 );

	SetHullType( HULL_WIDE_HUMAN );
	SetHullSizeNormal();

	m_pEyeGlow = CSprite::SpriteCreate( GARG_EYE_SPRITE_NAME, GetAbsOrigin(), FALSE );
	m_pEyeGlow->SetTransparency( kRenderGlow, 255, 255, 255, 0, kRenderFxNoDissipation );
	m_pEyeGlow->SetAttachment( this, 1 );
	EyeOff();

	m_seeTime = gpGlobals->curtime + 5;
	m_flameTime = gpGlobals->curtime + 2;
		
	NPCInit();

	BaseClass::Spawn();

	Relink();
}
	void CPlantedC4::Init( CCSPlayer *pevOwner, Vector vecStart, QAngle vecAngles )
	{
		SetMoveType( MOVETYPE_NONE );
		SetSolid( SOLID_BBOX );

		SetModel( PLANTED_C4_MODEL );	// Change this to c4 model

		SetCollisionBounds( Vector( 0, 0, 0 ), Vector( 8, 8, 8 ) );

		SetAbsOrigin( vecStart );
		SetAbsAngles( vecAngles );
		SetOwnerEntity( pevOwner );
		
		// Detonate in "time" seconds
		SetThink( &CPlantedC4::C4Think );
		//pGrenade->SetTouch( &CPlantedC4::C4Touch );

		SetNextThink( gpGlobals->curtime + 0.1f );
		
		m_flC4Blow = gpGlobals->curtime + c4timer.GetInt();

		m_flNextFreqInterval = c4timer.GetInt() / 4;
		m_flNextFreq = gpGlobals->curtime;
		m_flNextBeep = gpGlobals->curtime + 0.5;
		m_iCurWave = 0;
		m_sBeepName = NULL;

		m_flNextBlink = gpGlobals->curtime + BLINK_INTERVAL;
		m_flNextDefuse = 0;

		m_bStartDefuse = false;
		m_bJustBlew = false;
		SetFriction( 0.9 );

		Relink();
	}
//------------------------------------------------------------------------------
// Purpose : 
// Input   :
// Output  :
//------------------------------------------------------------------------------
void CNPC_CombineDropship::PrescheduleThink( void )
{
	BaseClass::PrescheduleThink();
	
	// keep track of think time deltas for burn calc below
	float dt = gpGlobals->curtime - m_flLastTime;
	m_flLastTime = gpGlobals->curtime;

	switch( m_iLandState )
	{
	case LANDING_NO:
		{
			if ( IsActivityFinished() && (GetActivity() != ACT_DROPSHIP_FLY_IDLE_EXAGG && GetActivity() != ACT_DROPSHIP_FLY_IDLE_CARGO) )
			{
				if ( m_hContainer )
				{
					SetIdealActivity( (Activity)ACT_DROPSHIP_FLY_IDLE_CARGO );
				}
				else
				{
					SetIdealActivity( (Activity)ACT_DROPSHIP_FLY_IDLE_EXAGG );
				}
			}

			DoRotorWash();
		}
		break;

	case LANDING_LEVEL_OUT:
		{
			// Approach the drop point
			Vector vecToTarget = (GetDesiredPosition() - GetAbsOrigin());
			float flDistance = vecToTarget.Length();

			// If we're slowing, make it look like we're slowing
			/*
			if ( IsActivityFinished() && GetActivity() != ACT_DROPSHIP_DESCEND_IDLE )
			{
				SetActivity( (Activity)ACT_DROPSHIP_DESCEND_IDLE );
			}
			*/

			// Are we there yet?
			float flSpeed = GetAbsVelocity().Length();
			if ( flDistance < 70 && flSpeed < 100 )
			{
				m_flLandingSpeed = flSpeed;
				m_iLandState = LANDING_DESCEND;
				// save off current angles so we can work them out over time
				QAngle angles = GetLocalAngles();
				m_existPitch = angles.x;
				m_existRoll = angles.z;

			}

			DoRotorWash();
		}
		break;

	case LANDING_DESCEND:
		{
			float	flAltitude;

			SetLocalAngularVelocity( vec3_angle );

			// Ensure we land on the drop point
			Vector vecToTarget = (GetDesiredPosition() - GetAbsOrigin());
			float flDistance = vecToTarget.Length();
			float flRampedSpeed = m_flLandingSpeed * (flDistance / 70);
			Vector vecVelocity = (flRampedSpeed / flDistance) * vecToTarget;
			vecVelocity.z = -75;
			SetAbsVelocity( vecVelocity );

			flAltitude = GetAltitude();			

			if ( IsActivityFinished() && GetActivity() != ACT_DROPSHIP_DESCEND_IDLE )
			{
				SetActivity( (Activity)ACT_DROPSHIP_DESCEND_IDLE );
			}

			if ( flAltitude < 72 )
			{
				QAngle angles = GetLocalAngles();

				// Level out quickly.
				angles.x = UTIL_Approach( 0.0, angles.x, 0.2 );
				angles.z = UTIL_Approach( 0.0, angles.z, 0.2 );

				SetLocalAngles( angles );
			}
			else
			{
				// randomly move as if buffeted by ground effects
				// gently flatten ship from starting pitch/yaw
				m_existPitch = UTIL_Approach( 0.0, m_existPitch, 1 );
				m_existRoll = UTIL_Approach( 0.0, m_existRoll, 1 );

				QAngle angles = GetLocalAngles();
				angles.x = m_existPitch + ( sin( gpGlobals->curtime * 3.5f ) * DROPSHIP_MAX_LAND_TILT );
				angles.z = m_existRoll + ( sin( gpGlobals->curtime * 3.75f ) * DROPSHIP_MAX_LAND_TILT );
				SetLocalAngles( angles );

				// figure out where to face (nav point)
				Vector targetDir = GetDesiredPosition() - GetAbsOrigin();
//				NDebugOverlay::Cross3D( m_pGoalEnt->GetAbsOrigin(), -Vector(2,2,2), Vector(2,2,2), 255, 0, 0, false, 20 );

				QAngle targetAngles = GetAbsAngles();
				targetAngles.y += UTIL_AngleDiff(UTIL_VecToYaw( targetDir ), targetAngles.y);
				// orient ship towards path corner on the way down
				angles = GetAbsAngles();
				angles.y = UTIL_Approach(targetAngles.y, angles.y, 2 );
				SetAbsAngles( angles );
			}

			if ( flAltitude <= 0.5f )
			{
				m_iLandState = LANDING_TOUCHDOWN;

				// upon landing, make sure ship is flat
				QAngle angles = GetLocalAngles();
				angles.x = 0;
				angles.z = 0;
				SetLocalAngles( angles );

				// TODO: Release cargo anim
				SetActivity( (Activity)ACT_DROPSHIP_DESCEND_IDLE );
			}

			DoRotorWash();

			// place danger sounds 1 foot above ground to get troops to scatter if they are below dropship
			Vector vecBottom = GetAbsOrigin();
			vecBottom.z += WorldAlignMins().z;
			Vector vecSpot = vecBottom + Vector(0, 0, -1) * (GetAltitude() - 12 );
			CSoundEnt::InsertSound( SOUND_DANGER, vecSpot, 400, 0.2, this, 0 );
			CSoundEnt::InsertSound( SOUND_PHYSICS_DANGER, vecSpot, 400, 0.2, this, 1 );
//			NDebugOverlay::Cross3D( vecSpot, -Vector(4,4,4), Vector(4,4,4), 255, 0, 255, false, 10.0f );

			// now check to see if player is below us, if so, cause heat damage to them (i.e. get them to move)
			trace_t tr;
			Vector vecBBoxMin = CRATE_BBOX_MIN;		// use flat box for check
			vecBBoxMin.z = -5;
			Vector vecBBoxMax = CRATE_BBOX_MAX;
			vecBBoxMax.z = 5;
			Vector pEndPoint = vecBottom + Vector(0, 0, -1) * ( GetAltitude() - 12 );
			AI_TraceHull( vecBottom, pEndPoint, vecBBoxMin, vecBBoxMax, MASK_SOLID, this, COLLISION_GROUP_NONE, &tr );

			if ( tr.fraction < 1.0f )
			{
				if ( tr.GetEntityIndex() == 1 )			// player???
				{
					CTakeDamageInfo info( this, this, 20 * dt, DMG_BURN );
					CBasePlayer *pPlayer = UTIL_PlayerByIndex(1);
					pPlayer->TakeDamage( info );
				}
			}

		}
		break;

	case LANDING_TOUCHDOWN:
		{
			if ( IsActivityFinished() && ( GetActivity() != ACT_DROPSHIP_DESCEND_IDLE ) )
			{
				SetActivity( (Activity)ACT_DROPSHIP_DESCEND_IDLE );
			}

			m_iLandState = LANDING_UNLOADING;
			m_flTroopDeployPause = gpGlobals->curtime + DROPSHIP_PAUSE_B4_TROOP_UNLOAD;
			m_flTimeTakeOff = m_flTroopDeployPause + DROPSHIP_DEPLOY_TIME;
		}
		break;

	case LANDING_UNLOADING:
		{
			// pause before dropping troops
			if ( gpGlobals->curtime > m_flTroopDeployPause )
			{
				if ( m_hContainer )	// don't drop troops if we don't have a crate any more
				{
					SpawnTroops();
					m_flTroopDeployPause = m_flTimeTakeOff + 2;	// only drop once
				}
			}
			// manage engine wash and volume
			if ( m_flTimeTakeOff - gpGlobals->curtime < 0.5f )
			{
				m_engineThrust = UTIL_Approach( 1.0f, m_engineThrust, 0.1f );
				DoRotorWash();
			}
			else
			{
				float idleVolume = 0.2f;
				m_engineThrust = UTIL_Approach( idleVolume, m_engineThrust, 0.04f );
				if ( m_engineThrust > idleVolume ) 
				{
					DoRotorWash();				// make sure we're kicking up dust/water as long as engine thrust is up
				}
			}

			if( gpGlobals->curtime > m_flTimeTakeOff )
			{
				m_iLandState = LANDING_LIFTOFF;
				SetActivity( (Activity)ACT_DROPSHIP_LIFTOFF );
				m_engineThrust = 1.0f;			// ensure max volume once we're airborne
				if ( m_bIsFiring )
				{
					StopCannon();				// kill cannon sounds if they are on
				}

				// detach container from ship
				if ( m_hContainer && m_leaveCrate )
				{
					m_hContainer->SetParent(NULL);
					m_hContainer->SetMoveType( (MoveType_t)m_iContainerMoveType );

					// If the container has a physics object, remove it's shadow
					IPhysicsObject *pPhysicsObject = m_hContainer->VPhysicsGetObject();
					if ( pPhysicsObject )
					{
						pPhysicsObject->RemoveShadowController();
					}

					m_hContainer = NULL;
				}
			}
		}
		break;

	case LANDING_LIFTOFF:
		{
			// give us some clearance before changing back to larger hull -- keeps ship from getting stuck on
			// things like the player, etc since we "pop" the hull...
			if ( GetAltitude() > 120 )		
			{
				m_OnFinishedDropoff.FireOutput( this, this );

				m_iLandState = LANDING_NO;

				// change bounding box back to normal ship hull
				Vector vecBBMin, vecBBMax;
				ExtractBbox( SelectHeaviestSequence( ACT_DROPSHIP_DEPLOY_IDLE ), vecBBMin, vecBBMax ); 
				UTIL_SetSize( this, vecBBMin, vecBBMax );
				Relink();
			}
		}
		break;

	case LANDING_SWOOPING:
		{
			// Did we lose our pickup target?
			if ( !m_hPickupTarget )
			{
				m_iLandState = LANDING_NO;
			}
			else
			{
				// Decrease altitude and speed to hit the target point.
				Vector vecToTarget = (GetDesiredPosition() - GetAbsOrigin());
				float flDistance = vecToTarget.Length();

				// Start cheating when we get near it
				if ( flDistance < 50 )
				{
					/*
					if ( flDistance > 10 )
					{
						// Cheat and ensure we touch the target
						float flSpeed = GetAbsVelocity().Length();
						Vector vecVelocity = vecToTarget;
						VectorNormalize( vecVelocity );
						SetAbsVelocity( vecVelocity * min(flSpeed,flDistance) );
					}
					else
					*/
					{
						// Grab the target
						m_hContainer = m_hPickupTarget;
						m_hPickupTarget = NULL;
						m_iContainerMoveType = m_hContainer->GetMoveType();

						// If the container has a physics object, move it to shadow
						IPhysicsObject *pPhysicsObject = m_hContainer->VPhysicsGetObject();
						if ( pPhysicsObject )
						{
							pPhysicsObject->SetShadow( Vector(1e4,1e4,1e4), AngularImpulse(1e4,1e4,1e4), false, false );
							pPhysicsObject->UpdateShadow( GetAbsOrigin(), GetAbsAngles(), false, 0 );
						}

						int iIndex = 0;//LookupAttachment("Cargo");
						/*
						Vector vecOrigin;
						QAngle vecAngles;
						GetAttachment( iIndex, vecOrigin, vecAngles );
						m_hContainer->SetAbsOrigin( vecOrigin );
						m_hContainer->SetAbsAngles( vec3_angle );
						*/
						m_hContainer->SetAbsOrigin( GetAbsOrigin() );
						m_hContainer->SetParent(this, iIndex);
						m_hContainer->SetMoveType( MOVETYPE_PUSH );
						m_hContainer->RemoveFlag( FL_ONGROUND );
						m_hContainer->Relink();
						m_hContainer->SetAbsAngles( vec3_angle );

						m_OnFinishedPickup.FireOutput( this, this );
						m_iLandState = LANDING_NO;
					}
				}
			}

			DoRotorWash();
		}
		break;
	}

	DoCombatStuff();

	if ( GetActivity() != GetIdealActivity() )
	{
		//Msg( "setactivity" );
		SetActivity( GetIdealActivity() );
	}
}
 void flatten(TreeNode *root) {
     Relink(root);
 }