Esempio n. 1
0
void C_Func_Dust::AttemptSpawnNewParticle()
{
	// Find a random spot inside our bmodel.
	static int nTests=10;

	for( int iTest=0; iTest < nTests; iTest++ )
	{
		Vector vPercent = RandomVector( 0, 1 );
		Vector vTest = WorldAlignMins() + (WorldAlignMaxs() - WorldAlignMins()) * vPercent;

		int contents = enginetrace->GetPointContents_Collideable( GetCollideable(), vTest );
		if( contents & CONTENTS_SOLID )
		{
			CFuncDustParticle *pParticle = (CFuncDustParticle*)m_Effect.AddParticle( 10, m_hMaterial, vTest );
			if( pParticle )
			{
				pParticle->m_vVelocity = RandomVector( -m_SpeedMax, m_SpeedMax );
				pParticle->m_vVelocity.z -= m_FallSpeed;

				pParticle->m_flLifetime = 0;
				pParticle->m_flDieTime = RemapVal( rand(), 0, RAND_MAX, m_LifetimeMin, m_LifetimeMax );

				if( m_DustFlags & DUSTFLAGS_SCALEMOTES )
					pParticle->m_flSize = RemapVal( rand(), 0, RAND_MAX, m_flSizeMin/10000.0f, m_flSizeMax/10000.0f );
				else
					pParticle->m_flSize = RemapVal( rand(), 0, RAND_MAX, m_flSizeMin, m_flSizeMax );
			
				pParticle->m_Color = m_Color;
			}

			break;
		}
	}
}
void CNPC_Ichthyosaur::DragVictim( float moveDist )
{
	Vector	mins, maxs;
	float	width;
	
	mins	= WorldAlignMins();
	maxs	= WorldAlignMaxs();
	width	= ( maxs.y - mins.y ) * 0.5f;

	Vector	forward, up;
	GetVectors( &forward, NULL, &up );

	Vector	newPos = GetAbsOrigin() + ( (forward+(up*0.25f)) * ( moveDist + width + DRAG_OFFSET ) );

	trace_t	tr;
	AI_TraceEntity( this, m_pVictim->GetAbsOrigin(), newPos, MASK_NPCSOLID, &tr );

	if ( ( tr.fraction == 1.0f ) && ( tr.m_pEnt != this ) )
	{
		UTIL_SetOrigin( m_pVictim, tr.endpos );
	}
	else
	{
		ReleaseVictim();
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CNPC_Bug_Builder::Spawn( void )
{
	Precache();

	SetModel( BUG_BUILDER_MODEL );

	SetHullType(HULL_TINY);
	SetHullSizeNormal();
	SetDefaultEyeOffset();
	SetViewOffset( (WorldAlignMins() + WorldAlignMaxs()) * 0.5 );	// See from my center
	SetDistLook( 1024.0 );
	m_flNextDawdle = 0;
	
	SetNavType(NAV_GROUND);
	m_NPCState		= NPC_STATE_NONE;
	SetBloodColor( BLOOD_COLOR_YELLOW );
	m_iHealth		= npc_bug_builder_health.GetFloat();

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

	CapabilitiesAdd( bits_CAP_MOVE_GROUND );

	NPCInit();

	BaseClass::Spawn();
}
Esempio n. 4
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;
}
	inline Vector GetSmokeParticlePos(int x, int y, int z )	
	{
		return WorldAlignMins() + 
			Vector( x * m_SpacingRadius * 2 + m_SpacingRadius,
				    y * m_SpacingRadius * 2 + m_SpacingRadius,
				    z * m_SpacingRadius * 2 + m_SpacingRadius );
	}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
void CNPC_Bug_Warrior::Spawn( void )
{
	Precache();

	SetModel( BUG_WARRIOR_MODEL );

	SetHullType(HULL_WIDE_HUMAN);//HULL_WIDE_SHORT;
	SetHullSizeNormal();
	SetDefaultEyeOffset();
	SetViewOffset( (WorldAlignMins() + WorldAlignMaxs()) * 0.5 );	// See from my center
	SetDistLook( 1024.0 );
	
	SetNavType(NAV_GROUND);
	m_NPCState		= NPC_STATE_NONE;
	SetBloodColor( BLOOD_COLOR_YELLOW );
	m_iHealth		= npc_bug_warrior_health.GetFloat();

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

	m_iszPatrolPathName = NULL_STRING;

	// Only do this if a squadname appears in the entity
	if ( m_SquadName != NULL_STRING )
	{
		CapabilitiesAdd( bits_CAP_SQUAD );
	}

	CapabilitiesAdd( bits_CAP_MOVE_GROUND | bits_CAP_INNATE_MELEE_ATTACK1 );

	NPCInit();

	BaseClass::Spawn();
}
Esempio n. 7
0
//-----------------------------------------------------------------------------
// Default to a simple single trace, but allow overriding.
// This is used for the strider, so it can determine the height based on the legs.
//-----------------------------------------------------------------------------
void UnitBaseAirLocomotion::UpdateCurrentHeight()
{
	trace_t pm;
	UTIL_TraceHull( mv->origin, mv->origin-Vector(0, 0, MAX_TRACE_LENGTH), WorldAlignMins(), WorldAlignMaxs(),
		MASK_NPCWORLDSTATIC, m_pOuter, GetOuter()->CalculateIgnoreOwnerCollisionGroup(), &pm );
	m_fCurrentHeight = fabs( pm.endpos.z-mv->origin.z );
}
Esempio n. 8
0
//=========================================================
// SetEyePosition
//
// queries the units's model for $eyeposition and copies
// that vector to the npc's m_vDefaultEyeOffset and m_vecViewOffset
//
//=========================================================
void CUnitBase::SetDefaultEyeOffset( Vector *pCustomOfset )
{
	if( pCustomOfset )
	{
		m_vDefaultEyeOffset = *pCustomOfset;
	}
	else if  ( GetModelPtr() )
	{
		GetEyePosition( GetModelPtr(), m_vDefaultEyeOffset );

		if ( m_vDefaultEyeOffset == vec3_origin )
		{
			//if ( Classify() != CLASS_NONE )
			{
				DevMsg( "WARNING: %s(%s) has no eye offset in .qc!\n", GetClassname(), STRING(GetModelName()) );
			}
			VectorAdd( WorldAlignMins(), WorldAlignMaxs(), m_vDefaultEyeOffset );
			m_vDefaultEyeOffset *= 0.75;
		}
	}
	else
		m_vDefaultEyeOffset = vec3_origin;

	// Clamp to values in dt
	m_vDefaultEyeOffset.x = Max<float>( Min<float>( m_vDefaultEyeOffset.x, 256.0f ), -256.0 );
	m_vDefaultEyeOffset.y = Max<float>( Min<float>( m_vDefaultEyeOffset.y, 256.0f ), -256.0 );
	m_vDefaultEyeOffset.z = Max<float>( Min<float>( m_vDefaultEyeOffset.z, 1024.0f ), -1.0f );

#ifndef CLIENT_DLL
	SetViewOffset( m_vDefaultEyeOffset );
#endif // CLIENT_DLL
}
Esempio n. 9
0
//-----------------------------------------------------------------------------
// Purpose: Do not test against hit boxes, but against the bounding box.
//			Much cheaper and we don't really need hitboxes for hl2wars.
//-----------------------------------------------------------------------------
bool CUnitBase::TestHitboxes( const Ray_t &ray, unsigned int fContentsMask, trace_t& tr )
{
#if 1
	if( unit_cheaphitboxtest.GetBool() == false )
		return BaseClass::TestHitboxes( ray, fContentsMask, tr );

	CStudioHdr *pStudioHdr = GetModelPtr( );
	if (!pStudioHdr)
		return false;

	Ray_t ray2 = ray;
	Vector start = GetAbsOrigin() - ray.m_Start;
	ray2.Init(start, start+ray.m_Delta);
	IntersectRayWithBox(ray2, WorldAlignMins(), WorldAlignMaxs(), 0.0f, &tr);

	if ( tr.DidHit() )
	{
		tr.surface.name = "**studio**";
		tr.surface.flags = SURF_HITBOX;
		tr.surface.surfaceProps = VPhysicsGetObject() ? VPhysicsGetObject()->GetMaterialIndex() : 0;
		//NDebugOverlay::SweptBox(ray.m_Start, tr.endpos, -Vector(32, 32, 32), Vector(32, 32, 32), GetAbsAngles(), 255, 0, 0, 255, 1.0f);
		return true;
	}
	return false;
#else
	return BaseClass::TestHitboxes( ray, fContentsMask, tr );
#endif // 0
}
Esempio n. 10
0
void CRopeKeyframe::UpdateBBox( bool bForceRelink )
{
	Vector v1, v2;
	Vector vMin, vMax;
	if ( GetEndPointPos( 0, v1 ) )
	{
		if ( GetEndPointPos( 1, v2 ) )
		{
			VectorMin( v1, v2, vMin );
			VectorMax( v1, v2, vMax );

			// Set our bounds to enclose both endpoints and relink.
			vMin -= GetAbsOrigin();
			vMax -= GetAbsOrigin();
		}
		else
		{
			vMin = vMax = v1 - GetAbsOrigin();
		}
	}
	else
	{
		vMin = vMax = Vector( 0, 0, 0 );
	}

	if ( WorldAlignMins() != vMin || WorldAlignMaxs() != vMax )
	{
		UTIL_SetSize( this, vMin, vMax );
	}
}
void C_FuncSmokeVolume::OnDataChanged( DataUpdateType_t updateType )
{		
	m_MinColor[0] = ( 1.0f / 255.0f ) * m_Color1.r;
	m_MinColor[1] = ( 1.0f / 255.0f ) * m_Color1.g;
	m_MinColor[2] = ( 1.0f / 255.0f ) * m_Color1.b;

	m_MaxColor[0] = ( 1.0f / 255.0f ) * m_Color2.r;
	m_MaxColor[1] = ( 1.0f / 255.0f ) * m_Color2.g;
	m_MaxColor[2] = ( 1.0f / 255.0f ) * m_Color2.b;

	m_ParticleRadius = m_ParticleDrawWidth * 0.5f;
	m_SpacingRadius = m_ParticleSpacingDistance * 0.5f;
//	Warning( "m_Density: %f\n", m_Density );
//	Warning( "m_MovementSpeed: %f\n", m_MovementSpeed );

	if(updateType == DATA_UPDATE_CREATED)
	{
		Vector size = WorldAlignMaxs() - WorldAlignMins();
		m_xCount = 0.5f + ( size.x / ( m_SpacingRadius * 2.0f ) );
		m_yCount = 0.5f + ( size.y / ( m_SpacingRadius * 2.0f ) );
		m_zCount = 0.5f + ( size.z / ( m_SpacingRadius * 2.0f ) );
		m_CurrentDensity = m_Density;

		delete [] m_pSmokeParticleInfos;
		m_pSmokeParticleInfos = new SmokeParticleInfo[m_xCount * m_yCount * m_zCount];
		Start( &g_ParticleMgr, NULL );
	}
	BaseClass::OnDataChanged( updateType );
}
//-----------------------------------------------------------------------------
// Purpose: custom code to fix collision errors
//-----------------------------------------------------------------------------
bool CBaseHelicopter::TestCollision( const Ray_t &ray, unsigned int mask, trace_t& trace )
{
	// Let normal hitbox code handle rays
	if ( mask & CONTENTS_HITBOX )
		return BaseClass::TestCollision( ray, mask, trace );

	return TestCollisionBox( ray, mask, trace, WorldAlignMins() + GetAbsOrigin(), WorldAlignMaxs() + GetAbsOrigin() );
}
Esempio n. 13
0
//=========================================================
// Retire - stop being active
//=========================================================
void CNPC_BaseTurret::Retire(void)
{
	// make the turret level
	m_vecGoalAngles.x = 0;
	m_vecGoalAngles.y = m_flStartYaw;

	SetNextThink( gpGlobals->curtime + 0.1 );

	StudioFrameAdvance( );

	EyeOff( );

	if (!MoveTurret())
	{
		if (m_iSpin)
		{
			SpinDownCall();
		}
		else if (GetSequence() != TURRET_ANIM_RETIRE)
		{
			SetTurretAnim(TURRET_ANIM_RETIRE);
			CPASAttenuationFilter filter( this );
			EmitSound( filter, entindex(), "Turret.Undeploy" );
			m_OnDeactivate.FireOutput(this, this);
		}
		//else if (IsSequenceFinished()) 
		else if( GetSequence() == TURRET_ANIM_RETIRE && GetCycle() <= 0.0 )
		{	
			m_iOn = 0;
			m_flLastSight = 0;
			//SetTurretAnim(TURRET_ANIM_NONE);

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

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

			SetCollisionBounds( curmins, curmaxs );
			if (m_iAutoStart)
			{
				SetThink(&CNPC_BaseTurret::AutoSearchThink);	
				SetNextThink( gpGlobals->curtime + 0.1 );
			}
			else
			{
				SetThink( &CBaseEntity::SUB_DoNothing );
			}
		}
	}
	else
	{
		SetTurretAnim(TURRET_ANIM_SPIN);
	}
}
Esempio n. 14
0
	virtual void SetObjectCollisionBox( void )
	{
		SetAbsMins( GetAbsOrigin() + WorldAlignMins() );
		SetAbsMaxs( GetAbsOrigin() + WorldAlignMaxs() );

		// Extend our bounding box downwards the length of the tongue
		Vector vecAbsMins = GetAbsMins();
		vecAbsMins.z -= m_flAltitude;
		SetAbsMins( vecAbsMins );
	}
//-----------------------------------------------------------------------------
// Purpose: Checks collisions against other entities
//-----------------------------------------------------------------------------
void CTFFlameEntity::CheckCollision( CBaseEntity *pOther, bool *pbHitWorld )
{
	*pbHitWorld = false;

	// if we've already burnt this entity, don't do more damage, so skip even checking for collision with the entity
	int iIndex = m_hEntitiesBurnt.Find( pOther );
	if ( iIndex != m_hEntitiesBurnt.InvalidIndex() )
		return;

	// Do a bounding box check against the entity
	Vector vecMins, vecMaxs;
	pOther->GetCollideable()->WorldSpaceSurroundingBounds( &vecMins, &vecMaxs );
	CBaseTrace trace;
	Ray_t ray;
	float flFractionLeftSolid;				
	ray.Init( m_vecPrevPos, GetAbsOrigin(), WorldAlignMins(), WorldAlignMaxs() );
	if ( IntersectRayWithBox( ray, vecMins, vecMaxs, 0.0, &trace, &flFractionLeftSolid ) )
	{
		// if bounding box check passes, check player hitboxes
		trace_t trHitbox;
		trace_t trWorld;
		bool bTested = pOther->GetCollideable()->TestHitboxes( ray, MASK_SOLID | CONTENTS_HITBOX, trHitbox );
		if ( !bTested || !trHitbox.DidHit() )
			return;

		// now, let's see if the flame visual could have actually hit this player.  Trace backward from the
		// point of impact to where the flame was fired, see if we hit anything.  Since the point of impact was
		// determined using the flame's bounding box and we're just doing a ray test here, we extend the
		// start point out by the radius of the box.
		Vector vDir = ray.m_Delta;
		vDir.NormalizeInPlace();
		UTIL_TraceLine( GetAbsOrigin() + vDir * WorldAlignMaxs().x, m_vecInitialPos, MASK_SOLID, this, COLLISION_GROUP_DEBRIS, &trWorld );			

		if ( tf_debug_flamethrower.GetInt() )
		{
			NDebugOverlay::Line( trWorld.startpos, trWorld.endpos, 0, 255, 0, true, 3.0f );
		}
		
		if ( trWorld.fraction == 1.0 )
		{						
			// if there is nothing solid in the way, damage the entity
			OnCollide( pOther );
		}					
		else
		{
			// we hit the world, remove ourselves
			*pbHitWorld = true;
			UTIL_Remove( this );
		}
	}

}
Esempio n. 16
0
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);
		}
	}
}
Esempio n. 17
0
//-----------------------------------------------------------------------------
// Purpose: Does not change the entities velocity at all
// Input  : push - 
// Output : trace_t
//-----------------------------------------------------------------------------
void C_BaseEntity::PhysicsCheckSweep( const Vector& vecAbsStart, const Vector &vecAbsDelta, trace_t *pTrace )
{
	unsigned int mask = PhysicsSolidMaskForEntity();

	Vector vecAbsEnd;
	VectorAdd( vecAbsStart, vecAbsDelta, vecAbsEnd );

	// Set collision type
	if ( !IsSolid() || IsSolidFlagSet( FSOLID_VOLUME_CONTENTS ) )
	{
		// don't collide with monsters
		mask &= ~CONTENTS_MONSTER;
	}

	Physics_TraceHull( this, vecAbsStart, vecAbsEnd, WorldAlignMins(), WorldAlignMaxs(), mask, pTrace );
}
Esempio n. 18
0
//=========================================================
// Deploy - go active
//=========================================================
void CNPC_BaseTurret::Deploy(void)
{
	SetNextThink( gpGlobals->curtime + 0.1 );
	StudioFrameAdvance( );

	if (GetSequence() != TURRET_ANIM_DEPLOY)
	{
		m_iOn = 1;
		SetTurretAnim(TURRET_ANIM_DEPLOY);
		CPASAttenuationFilter filter( this );
		EmitSound( filter, entindex(), "Turret.Deploy" );
		m_OnActivate.FireOutput(this, this);
	}

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

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

		SetCollisionBounds( curmins, curmaxs );

		m_vecCurAngles.x = 0;

		QAngle angles = GetAbsAngles();

		if (m_iOrientation == TURRET_ORIENTATION_CEILING)
		{
			m_vecCurAngles.y = UTIL_AngleMod( angles.y + 180 );
		}
		else
		{
			m_vecCurAngles.y = UTIL_AngleMod( angles.y );
		}

		SetTurretAnim(TURRET_ANIM_SPIN);
		m_flPlaybackRate = 0;
		SetThink(&CNPC_BaseTurret::SearchThink);
	}

	m_flLastSight = gpGlobals->curtime + m_flMaxWait;
}
Esempio n. 19
0
void C_WeaponSpawner::ClientThink()
{
	m_qAngle.y += 90 * gpGlobals->frametime;
	if ( m_qAngle.y >= 360 )
		m_qAngle.y -= 360;

	SetAbsAngles( m_qAngle );

	C_BasePlayer *pPlayer = C_BasePlayer::GetLocalPlayer();

	bool bShouldGlow = false;
	bool bTouchingPlayer = false;

	if ( pPlayer )
	{
		Vector vecPlayerOrigin = pPlayer->GetAbsOrigin();
		Vector vecPlayerMins = vecPlayerOrigin + pPlayer->GetPlayerMins();
		Vector vecPlayerMaxs = vecPlayerOrigin + pPlayer->GetPlayerMaxs();

		bTouchingPlayer = IsBoxIntersectingBox( GetAbsOrigin() + WorldAlignMins(), GetAbsOrigin() + WorldAlignMaxs(), vecPlayerMins, vecPlayerMaxs );

		// Disable the outline if the weapon has been picked up.
		if ( !m_bRespawning && !m_bDisabled )
		{
			// Temp crutch for Occluded\Unoccluded glow parameters not working.
			trace_t tr;
			UTIL_TraceLine( GetAbsOrigin(), pPlayer->EyePosition(), MASK_OPAQUE, this, COLLISION_GROUP_NONE, &tr );
			if ( tr.fraction == 1.0f )
			{
				bShouldGlow = true;
			}
		}
	}

	if ( m_bShouldGlow != bShouldGlow || m_bTouchingPlayer != bTouchingPlayer )
	{
		m_bShouldGlow = bShouldGlow;
		m_bTouchingPlayer = bTouchingPlayer;
		UpdateGlowEffect();
	}

	SetNextClientThink( CLIENT_THINK_ALWAYS );
}
// This creates a vphysics object with a shadow controller that follows the AI
IPhysicsObject *C_RagdollShadow::VPhysicsInitShadow( bool allowPhysicsMovement, bool allowPhysicsRotation )
{
	studiohdr_t *hdr = GetModelPtr();
	if ( !hdr )
	{
		return NULL;
	}

	// If this entity already has a physics object, then it should have been deleted prior to making this call.
	Assert(!m_pPhysicsObject);

	// make sure m_vecOrigin / m_vecAngles are correct
	const Vector &origin = GetAbsOrigin();
	QAngle angles = GetAbsAngles();
	IPhysicsObject *pPhysicsObject = NULL;

	if ( GetSolid() == SOLID_BBOX )
	{
		const char *pSurfaceProps = "flesh";
		if ( GetModelIndex() && modelinfo->GetModelType( GetModel() ) == mod_studio )
		{
			pSurfaceProps = Studio_GetDefaultSurfaceProps( hdr );
		}
		angles = vec3_angle;
		CPhysCollide *pCollide = PhysCreateBbox( WorldAlignMins(), WorldAlignMaxs() );
		if ( !pCollide )
			return NULL;
		pPhysicsObject = PhysModelCreateCustom( this, pCollide, origin, angles, pSurfaceProps );
	}
	else
	{
		pPhysicsObject = PhysModelCreateRagdoll( this, GetModelIndex(), origin, angles );
	}
	VPhysicsSetObject( pPhysicsObject );
	pPhysicsObject->SetShadow( Vector(1e4,1e4,1e4), AngularImpulse(1e4,1e4,1e4), allowPhysicsMovement, allowPhysicsRotation );
	pPhysicsObject->UpdateShadow( GetAbsOrigin(), GetAbsAngles(), false, 0 );
//	PhysAddShadow( this );
	return pPhysicsObject;
}	
Esempio n. 21
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();
}
//------------------------------------------------------------------------------
// 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() );
	}
}
Esempio n. 23
0
//-----------------------------------------------------------------------------
// Purpose: Override to check throw
// Input  :
// Output :
//-----------------------------------------------------------------------------
int CWeaponMolotov::WeaponRangeAttack1Condition( float flDot, float flDist )
{
	// If things haven't changed too much since last time
	// just return that previously calculated value
	if (gpGlobals->curtime < m_fNextThrowCheck )
	{
		return m_iThrowBits;
	}
	
	if ( flDist < m_fMinRange1) {
		m_iThrowBits = COND_TOO_CLOSE_TO_ATTACK;
	}
	else if (flDist > m_fMaxRange1) {
		m_iThrowBits = COND_TOO_FAR_TO_ATTACK;
	}
	else if (flDot < 0.5) {
		m_iThrowBits = COND_NOT_FACING_ATTACK;
	}

	// If moving, can't throw.
	else if ( m_flGroundSpeed != 0 )
	{
		m_iThrowBits = COND_NONE;
	}
	else {
		// Ok we should check again as some time has passed
		// This function is only used by NPC's so we can cast to a Base Monster
		CAI_BaseNPC *pNPC	= GetOwner()->MyNPCPointer();
		CBaseEntity *pEnemy = pNPC->GetEnemy();

		if (!pEnemy)
		{
			m_iThrowBits = COND_NONE;
		}
		// Get Enemy Position 
		Vector vecTarget;
		pEnemy->CollisionProp()->NormalizedToWorldSpace( Vector( 0.5f, 0.5f, 0.0f ), &vecTarget );

		// Get Toss Vector
		Vector			throwStart  = pNPC->Weapon_ShootPosition();
		Vector			vecToss;
		CBaseEntity*	pBlocker	= NULL;
		float			throwDist	= (throwStart - vecTarget).Length();
		float			fGravity	= sv_gravity.GetFloat();
		float			throwLimit	= pNPC->ThrowLimit(throwStart, vecTarget, fGravity, 35, WorldAlignMins(), WorldAlignMaxs(), pEnemy, &vecToss, &pBlocker);

		// If I can make the throw (or most of the throw)
		if (!throwLimit || (throwLimit != throwDist && throwLimit > 0.8*throwDist))
		{
			m_vecTossVelocity = vecToss;
			m_iThrowBits = COND_CAN_RANGE_ATTACK1;

		}
		else
		{
			m_iThrowBits = COND_NONE;
		}

	}
	// don't check again for a while.
	m_fNextThrowCheck = gpGlobals->curtime + 0.33; // 1/3 second.

	return m_iThrowBits;
}
Esempio n. 24
0
void CNPC_Dog::SetPlayerAvoidState( void )
{
	bool bIntersectingBoneFollowers = false;
	bool bIntersectingNPCBox = false;

	Vector vNothing;

	GetSequenceLinearMotion( GetSequence(), &vNothing );
	bool bIsMoving = ( IsMoving() || ( vNothing != vec3_origin ) );

	//If we are coming out of a script, check if we are stuck inside the player.
	if ( m_bPerformAvoidance || ( ShouldPlayerAvoid() && bIsMoving ) )
	{
		trace_t trace;
		Vector vMins, vMaxs;
		Vector vWorldMins, vWorldMaxs;
		Vector vPlayerMins, vPlayerMaxs;
		physfollower_t *pBone;
		int i;
		
		#ifdef SecobMod__Enable_Fixed_Multiplayer_AI
			CBasePlayer *pLocalPlayer = UTIL_GetNearestPlayer(GetAbsOrigin()); 
		#else
			CBasePlayer *pLocalPlayer = AI_GetSinglePlayer();
		#endif //SecobMod__Enable_Fixed_Multiplayer_AI

		if ( pLocalPlayer )
		{
			vWorldMins = WorldAlignMins();
			vWorldMaxs = WorldAlignMaxs();

			vPlayerMins = pLocalPlayer->GetAbsOrigin() + pLocalPlayer->WorldAlignMins();
			vPlayerMaxs = pLocalPlayer->GetAbsOrigin() + pLocalPlayer->WorldAlignMaxs();

			// check if the player intersects the bounds of any of the bone followers
			for ( i = 0; i < m_BoneFollowerManager.GetNumBoneFollowers(); i++ )
			{
				pBone = m_BoneFollowerManager.GetBoneFollower( i );
				if ( pBone && pBone->hFollower )
				{
					pBone->hFollower->CollisionProp()->WorldSpaceSurroundingBounds( &vMins, &vMaxs );
					if ( IsBoxIntersectingBox( vMins, vMaxs, vPlayerMins, vPlayerMaxs ) )
					{
						bIntersectingBoneFollowers = true;
						break;
					}
				}
			}

			bIntersectingNPCBox = IsBoxIntersectingBox( GetAbsOrigin() + vWorldMins, GetAbsOrigin() + vWorldMaxs, vPlayerMins, vPlayerMaxs );

			if ( ai_debug_avoidancebounds.GetBool() )
			{
				int iRed = ( bIntersectingNPCBox == true ) ? 255 : 0;

				NDebugOverlay::Box( GetAbsOrigin(), vWorldMins, vWorldMaxs, iRed, 0, 255, 64, 0.1 );

				// draw the bounds of the bone followers
				for ( i = 0; i < m_BoneFollowerManager.GetNumBoneFollowers(); i++ )
				{
					pBone = m_BoneFollowerManager.GetBoneFollower( i );
					if ( pBone && pBone->hFollower )
					{
						pBone->hFollower->CollisionProp()->WorldSpaceSurroundingBounds( &vMins, &vMaxs );
						iRed = ( IsBoxIntersectingBox( vMins, vMaxs, vPlayerMins, vPlayerMaxs ) ) ? 255 : 0;

						NDebugOverlay::Box( vec3_origin, vMins, vMaxs, iRed, 0, 255, 64, 0.1 );
					}
				}
			}
		}
	}

	m_bPlayerAvoidState = ShouldPlayerAvoid();
	m_bPerformAvoidance = bIntersectingNPCBox || bIntersectingBoneFollowers;

	if ( GetCollisionGroup() == COLLISION_GROUP_NPC || GetCollisionGroup() == COLLISION_GROUP_NPC_ACTOR )
	{
		if ( bIntersectingNPCBox == true )
		{
			SetCollisionGroup( COLLISION_GROUP_NPC_ACTOR );
		}
		else
		{
			SetCollisionGroup( COLLISION_GROUP_NPC );
		}

		if ( bIntersectingBoneFollowers == true )
		{
			MantainBoneFollowerCollisionGroups( COLLISION_GROUP_NPC_ACTOR );
		}
		else
		{
			MantainBoneFollowerCollisionGroups( COLLISION_GROUP_NPC );
		}
	}
}
//-----------------------------------------------------------------------------
// Purpose: 
//-----------------------------------------------------------------------------
bool CObjectResupply::CalculatePlacement( CBaseTFPlayer *pPlayer )
{
	trace_t tr;
	Vector vecAiming;
	// Get an aim vector. Don't use GetAimVector() because we don't want autoaiming.
	Vector vecSrc = pPlayer->Weapon_ShootPosition( );
	pPlayer->EyeVectors( &vecAiming );
	Vector vecTarget;
	VectorMA( vecSrc, 90, vecAiming, vecTarget );
	m_vecBuildOrigin = vecTarget;

	// Angle it towards me
	Vector vecForward = pPlayer->WorldSpaceCenter() - m_vecBuildOrigin;
	SetLocalAngles( QAngle( 0, UTIL_VecToYaw( vecForward ), 0 ) );

	// Is there something to attach to? 
	// Use my bounding box, not the build box, so I fit to the wall
	UTIL_TraceLine( vecSrc, vecTarget, MASK_SOLID, pPlayer, COLLISION_GROUP_PLAYER_MOVEMENT, &tr);
	//UTIL_TraceHull( vecSrc, vecTarget, WorldAlignMins(), WorldAlignMaxs(), MASK_SOLID, pPlayer, TFCOLLISION_GROUP_OBJECT, &tr );
	m_vecBuildOrigin = tr.endpos;
	bool bTryToPlaceGroundVersion = false;
	if ( tr.allsolid || (tr.fraction == 1.0) )
	{
		bTryToPlaceGroundVersion = true;
	}
	else 
	{
		// Make sure we're planting on the world
		CBaseEntity *pEntity = tr.m_pEnt;
		if ( pEntity != GetWorldEntity() )
		{
			bTryToPlaceGroundVersion = true;
		}
	}

	// Make sure the wall we've touched is vertical
	if ( !bTryToPlaceGroundVersion && fabs(tr.plane.normal.z) > 0.3 )
	{
		bTryToPlaceGroundVersion = true;
	}

	// Aborting?
	if ( bTryToPlaceGroundVersion )
	{
		// We couldn't find a wall, so try and place a ground version instead
		if ( GetTeamNumber() == TEAM_HUMANS )
		{
			SetModel( RESUPPLY_GROUND_MODEL_HUMAN );
		}
		else
		{
			SetModel( RESUPPLY_GROUND_MODEL );
		}
		UTIL_SetSize(this, RESUPPLY_GROUND_MINS, RESUPPLY_GROUND_MAXS);
		m_vecBuildMins = WorldAlignMins() - Vector( 4,4,0 );
		m_vecBuildMaxs = WorldAlignMaxs() + Vector( 4,4,0 );
		return BaseClass::CalculatePlacement( pPlayer );
	}

	SetupAttachedVersion();
	m_vecBuildMins = WorldAlignMins() - Vector( 4,4,0 );
	m_vecBuildMaxs = WorldAlignMaxs() + Vector( 4,4,0 );

	// Set the angles
	vecForward = tr.plane.normal;
	SetLocalAngles( QAngle( 0, UTIL_VecToYaw( vecForward ), 0 ) );

	// Trace back from the corners
	Vector vecMins, vecMaxs, vecModelMins, vecModelMaxs;
	const model_t *pModel = GetModel();
	modelinfo->GetModelBounds( pModel, vecModelMins, vecModelMaxs );

	// Check the four build points
	Vector vecPointCheck = (vecForward * 32);
	Vector vecUp = Vector(0,0,1);
	Vector vecRight;
	CrossProduct( vecUp, vecForward, vecRight );
	float flWidth = fabs(vecModelMaxs.y - vecModelMins.y) * 0.5;
	float flHeight = fabs(vecModelMaxs.z - vecModelMins.z) * 0.5;

	bool bResult = true;
	if ( bResult )
	{
		bResult = CheckBuildPoint( m_vecBuildOrigin + (vecRight * flWidth) + (vecUp * flHeight), vecPointCheck );
	}
	if ( bResult )
	{
		bResult = CheckBuildPoint( m_vecBuildOrigin + (vecRight * flWidth) - (vecUp * flHeight), vecPointCheck );
	}
	if ( bResult )
	{
		bResult = CheckBuildPoint( m_vecBuildOrigin - (vecRight * flWidth) + (vecUp * flHeight), vecPointCheck );
	}
	if ( bResult )
	{
		bResult = CheckBuildPoint( m_vecBuildOrigin - (vecRight * flWidth) - (vecUp * flHeight), vecPointCheck );
	}

	AttemptToFindPower();

	return bResult;
}