void CNPC_Portal_FloorTurret::UpdateOnRemove( void )
{
	if ( IsDissolving() )
		EmitSound( GetTurretTalkName( PORTAL_TURRET_DISSOLVED ) );

	LaserOff();
	RopesOff();
	BaseClass::UpdateOnRemove();
}
//-----------------------------------------------------------------------------
// Purpose: The turret has been tipped over and will thrash for awhile
//-----------------------------------------------------------------------------
void CNPC_Portal_FloorTurret::HeldThink( void )
{
	PreThink( (turretState_e)PORTAL_TURRET_PICKUP );

	SetNextThink( gpGlobals->curtime + 0.05f );
	SetEnemy( NULL );

	StudioFrameAdvance();

	IPhysicsObject *pTurretPhys = VPhysicsGetObject();

	// If we're not held anymore, stop thrashing
	if ( !(pTurretPhys->GetGameFlags() & FVPHYSICS_PLAYER_HELD) )
	{
		m_fNextTalk = gpGlobals->curtime + 1.25f;

		if ( m_lifeState == LIFE_ALIVE )
			SetThink( &CNPC_FloorTurret::ActiveThink );
		else
			SetThink( &CNPC_FloorTurret::InactiveThink );
	}

	LaserOn();
	RopesOn();

	//See if we should continue to thrash
	if ( !IsDissolving() )
	{
		if ( m_flShotTime < gpGlobals->curtime )
		{
			SetActivity( (Activity) ACT_FLOOR_TURRET_OPEN_IDLE );

			DryFire();

			m_flShotTime = gpGlobals->curtime + RandomFloat( 0.25f, 0.75f );

			m_vecGoalAngles.x = GetAbsAngles().x + RandomFloat( -15, 15 );
			m_vecGoalAngles.y = GetAbsAngles().y + RandomFloat( -40, 40 );
		}

		UpdateFacing();
	}
}
void CGEPropDynamic::Event_Killed(const CTakeDamageInfo &info)
{
	// More or less just the kill event copied straight from prop_physics_respawnable, though it does not teleport as it cannot move on its own.

	IPhysicsObject *pPhysics = VPhysicsGetObject();
	if (pPhysics && !pPhysics->IsMoveable())
	{
		pPhysics->EnableMotion(true);
		VPhysicsTakeDamage(info);
	}

	Break(info.GetInflictor(), info);

	PhysCleanupFrictionSounds(this);

	VPhysicsDestroyObject();

	CBaseEntity::PhysicsRemoveTouchedList(this);
	CBaseEntity::PhysicsRemoveGroundList(this);
	DestroyAllDataObjects();

	AddEffects(EF_NODRAW);

	if (IsOnFire() || IsDissolving())
	{
		UTIL_Remove(GetEffectEntity());
	}

	SetContextThink(NULL, 0, "PROP_CLEARFLAGS");

	if (m_flRespawnTime > 0)
	{
		SetThink(&CGEPropDynamic::Materialize);
		SetNextThink(gpGlobals->curtime + m_flRespawnTime);
	}
}
//-----------------------------------------------------------------------------
// Purpose: Allows a generic think function before the others are called
// Input  : state - which state the turret is currently in
//-----------------------------------------------------------------------------
bool CNPC_Portal_FloorTurret::PreThink( turretState_e state )
{
	// Working 2 enums into one integer
	int iNewState = state;

	// If the turret is dissolving go to a special state
	if ( IsDissolving() )
		iNewState = PORTAL_TURRET_DISSOLVED;

	// Need to play these sounds immediately
	if ( m_iLastState != iNewState && ( ( iNewState == TURRET_TIPPED && !m_bDelayTippedTalk ) || 
										iNewState == TURRET_RETIRING || 
										iNewState == PORTAL_TURRET_DISSOLVED || 
										iNewState == PORTAL_TURRET_PICKUP ) )
	{
		m_fNextTalk = gpGlobals->curtime -1.0f;
	}

	// If we've changed states or are in a state with a repeating message
	if ( gpGlobals->curtime > m_fNextTalk && m_iLastState != iNewState )
	{
		m_iLastState = (turretState_e)iNewState;

		const char *pchScriptName = GetTurretTalkName( m_iLastState );

		switch ( iNewState )
		{
			case TURRET_SEARCHING:
				EmitSound( pchScriptName );
				m_fNextTalk = gpGlobals->curtime + 1.75f;
				break;

			case TURRET_AUTO_SEARCHING:
				EmitSound( pchScriptName );
				m_fNextTalk = gpGlobals->curtime + 1.75f;
				break;

			/*case TURRET_ACTIVE:
				EmitSound( pchScriptName );
				m_fNextTalk = gpGlobals->curtime + 2.5f;
				break;*/

			// Suppress is too fleeting for a message
			/*case TURRET_SUPPRESSING:
				EmitSound( pchScriptName );
				m_fNextTalk = gpGlobals->curtime + 1.5f;
				break;*/

			case TURRET_DEPLOYING:
				EmitSound( pchScriptName );
				m_fNextTalk = gpGlobals->curtime + 1.75f;
				break;

			case TURRET_RETIRING:
				EmitSound( pchScriptName );
				m_fNextTalk = gpGlobals->curtime + 3.5f;
				break;

			case TURRET_TIPPED:
				EmitSound( pchScriptName );
				m_fNextTalk = gpGlobals->curtime + 1.15f;
				break;

			case PORTAL_TURRET_PICKUP:
				EmitSound( GetTurretTalkName( PORTAL_TURRET_PICKUP ) );
				m_fNextTalk = gpGlobals->curtime + 2.25f;
				break;

			case PORTAL_TURRET_DISSOLVED:
				EmitSound( pchScriptName );
				m_fNextTalk = gpGlobals->curtime + 10.0f;	// Never going to talk again
				break;
		}
	}

	// New states are not supported by old turret code
	if ( iNewState != TURRET_TIPPED && iNewState < TURRET_STATE_TOTAL )
		return BaseClass::PreThink( (turretState_e)iNewState );

	return true;
}
//-----------------------------------------------------------------------------
// Purpose: The turret has been tipped over and will thrash for awhile
//-----------------------------------------------------------------------------
void CNPC_Portal_FloorTurret::TippedThink( void )
{
	PreThink( TURRET_TIPPED );

	SetNextThink( gpGlobals->curtime + 0.05f );
	SetEnemy( NULL );

	StudioFrameAdvance();
	// If we're not on side anymore, stop thrashing
	if ( !OnSide() && VPhysicsGetObject()->GetContactPoint( NULL, NULL ) )
	{
		ReturnToLife();
		return;
	}

	LaserOn();
	RopesOn();

	//See if we should continue to thrash
	if ( gpGlobals->curtime < m_flThrashTime && !IsDissolving() )
	{
		if ( m_flShotTime < gpGlobals->curtime )
		{
			if( m_bOutOfAmmo )
			{
				SetActivity( (Activity) ACT_FLOOR_TURRET_OPEN_IDLE );
				DryFire();
			}
			else
			{
				Vector vecMuzzle, vecMuzzleDir;
				GetAttachment( m_iMuzzleAttachment, vecMuzzle, &vecMuzzleDir );

				SetActivity( (Activity) ACT_FLOOR_TURRET_OPEN_IDLE );
				SetActivity( (Activity)( ( m_bShootWithBottomBarrels ) ? ( ACT_FLOOR_TURRET_FIRE2 ) : ( ACT_FLOOR_TURRET_FIRE ) ) );

#if !DISABLE_SHOT
				Shoot( vecMuzzle, vecMuzzleDir );
#endif
			}

			m_flShotTime = gpGlobals->curtime + 0.05f;
		}

		m_vecGoalAngles.x = GetAbsAngles().x + random->RandomFloat( -60, 60 );
		m_vecGoalAngles.y = GetAbsAngles().y + random->RandomFloat( -60, 60 );

		UpdateFacing();
	}
	else
	{
		//Face forward
		m_vecGoalAngles = GetAbsAngles();

		//Set ourselves to close
		if ( GetActivity() != ACT_FLOOR_TURRET_CLOSE )
		{
			SetActivity( (Activity) ACT_FLOOR_TURRET_OPEN_IDLE );

			//If we're done moving to our desired facing, close up
			if ( UpdateFacing() == false )
			{
				//Make any last death noises and anims
				EmitSound( "NPC_FloorTurret.Die" );
				EmitSound( GetTurretTalkName( PORTAL_TURRET_DISABLED ) );
				SpinDown();

				SetActivity( (Activity) ACT_FLOOR_TURRET_CLOSE );
				EmitSound( "NPC_FloorTurret.Retract" );

				CTakeDamageInfo	info;
				info.SetDamage( 1 );
				info.SetDamageType( DMG_CRUSH );
				Event_Killed( info );
			}
		}
		else if ( IsActivityFinished() )
		{	
			m_bActive		= false;
			m_flLastSight	= 0;

			SetActivity( (Activity) ACT_FLOOR_TURRET_CLOSED_IDLE );

			// Don't need to store last NPC anymore, because I've been knocked over
			if ( m_hLastNPCToKickMe )
			{
				m_hLastNPCToKickMe = NULL;
				m_flKnockOverFailedTime = 0;
			}

			//Try to look straight
			if ( UpdateFacing() == false )
			{
				m_OnTipped.FireOutput( this, this );
				SetEyeState( TURRET_EYE_DEAD );
				//SetCollisionGroup( COLLISION_GROUP_DEBRIS_TRIGGER );

				// Start thinking slowly to see if we're ever set upright somehow
				SetThink( &CNPC_FloorTurret::InactiveThink );
				SetNextThink( gpGlobals->curtime + 1.0f );
				RopesOff();
			}
		}
	}
}