void CFuncTank::Think( void ) { // refresh the matrix UpdateMatrix(); SetLocalAngularVelocity( vec3_angle ); TrackTarget(); if ( fabs(GetLocalAngularVelocity().x) > 1 || fabs(GetLocalAngularVelocity().y) > 1 ) StartRotSound(); else StopRotSound(); }
//----------------------------------------------------------------------------- // Purpose: Draw any debug text overlays // Output : Current text offset from the top //----------------------------------------------------------------------------- int CMomentaryRotButton::DrawDebugTextOverlays(void) { int text_offset = BaseClass::DrawDebugTextOverlays(); if (m_debugOverlays & OVERLAY_TEXT_BIT) { char tempstr[255]; Q_snprintf(tempstr,sizeof(tempstr),"QAngle: %.2f %.2f %.2f", GetLocalAngles()[0], GetLocalAngles()[1], GetLocalAngles()[2]); EntityText(text_offset,tempstr,0); text_offset++; Q_snprintf(tempstr,sizeof(tempstr),"AVelocity: %.2f %.2f %.2f", GetLocalAngularVelocity()[0], GetLocalAngularVelocity()[1], GetLocalAngularVelocity()[2]); EntityText(text_offset,tempstr,0); text_offset++; Q_snprintf(tempstr,sizeof(tempstr),"Target Pos: %3.3f",m_IdealYaw); EntityText(text_offset,tempstr,0); text_offset++; float flCurPos = GetPos(GetLocalAngles()); Q_snprintf(tempstr,sizeof(tempstr),"Current Pos: %3.3f",flCurPos); EntityText(text_offset,tempstr,0); text_offset++; Q_snprintf(tempstr,sizeof(tempstr),"Direction: %s",(m_direction == 1) ? "Forward" : "Backward"); EntityText(text_offset,tempstr,0); text_offset++; } return text_offset; }
//------------------------------------------------------------------------------ // Purpose : // Input : // Output : //------------------------------------------------------------------------------ void CBaseHelicopter::DyingThink( void ) { StudioFrameAdvance( ); SetNextThink( gpGlobals->curtime + 0.1f ); SetLocalAngularVelocity( GetLocalAngularVelocity() * 1.02 ); }
//----------------------------------------------------------------------------- // Purpose: Think function. Called while rotating at a constant angular velocity. //----------------------------------------------------------------------------- void CFuncRotating::RotateMove( void ) { SetMoveDoneTime( 10 ); if ( m_bStopAtStartPos ) { SetMoveDoneTime( GetNextMoveInterval() ); int checkAxis = 2; // See if we got close to the starting orientation if ( m_vecMoveAng[0] != 0 ) { checkAxis = 0; } else if ( m_vecMoveAng[1] != 0 ) { checkAxis = 1; } float angDelta = anglemod( GetLocalAngles()[ checkAxis ] - m_angStart[ checkAxis ] ); if ( angDelta > 180.0f ) angDelta -= 360.0f; QAngle avel = GetLocalAngularVelocity(); // Delta per tick QAngle avelpertick = avel * TICK_INTERVAL; if ( fabs( angDelta ) < fabs( avelpertick[ checkAxis ] ) ) { SetTargetSpeed( 0 ); SetLocalAngles( m_angStart ); m_bStopAtStartPos = false; } } }
//------------------------------------------------------------------------------ // Purpose : Initialize a gibs position and velocity // Input : // Output : //------------------------------------------------------------------------------ void CGib::InitGib( CBaseEntity *pVictim, float fMinVelocity, float fMaxVelocity ) { // ------------------------------------------------------------------------ // If have a pVictim spawn the gib somewhere in the pVictim's bounding volume // ------------------------------------------------------------------------ if ( pVictim ) { // Find a random position within the bounding box (add 1 to Z to get it out of the ground) Vector vecOrigin; pVictim->CollisionProp()->RandomPointInBounds( vec3_origin, Vector( 1, 1, 1 ), &vecOrigin ); vecOrigin.z += 1.0f; SetAbsOrigin( vecOrigin ); // make the gib fly away from the attack vector Vector vecNewVelocity = g_vecAttackDir * -1; // mix in some noise vecNewVelocity.x += random->RandomFloat ( -0.25, 0.25 ); vecNewVelocity.y += random->RandomFloat ( -0.25, 0.25 ); vecNewVelocity.z += random->RandomFloat ( -0.25, 0.25 ); vecNewVelocity *= random->RandomFloat ( fMaxVelocity, fMinVelocity ); QAngle vecNewAngularVelocity = GetLocalAngularVelocity(); vecNewAngularVelocity.x = random->RandomFloat ( 100, 200 ); vecNewAngularVelocity.y = random->RandomFloat ( 100, 300 ); SetLocalAngularVelocity( vecNewAngularVelocity ); // copy owner's blood color SetBloodColor( pVictim->BloodColor() ); AdjustVelocityBasedOnHealth( pVictim->m_iHealth, vecNewVelocity ); // Attempt to be physical if we can if ( VPhysicsInitNormal( SOLID_BBOX, 0, false ) ) { IPhysicsObject *pObj = VPhysicsGetObject(); if ( pObj != NULL ) { AngularImpulse angImpulse = RandomAngularImpulse( -500, 500 ); pObj->AddVelocity( &vecNewVelocity, &angImpulse ); } } else { SetSolid( SOLID_BBOX ); SetCollisionBounds( vec3_origin, vec3_origin ); SetAbsVelocity( vecNewVelocity ); } SetCollisionGroup( COLLISION_GROUP_DEBRIS ); } LimitVelocity(); }
void CSatchelCharge::SatchelThink( void ) { // If attached resize so player can pick up off wall if (m_bIsAttached) { UTIL_SetSize(this, Vector( -2, -2, -6), Vector(2, 2, 6)); } // See if I can lose my owner (has dropper moved out of way?) // Want do this so owner can shoot the satchel charge if (GetOwnerEntity()) { trace_t tr; Vector vUpABit = GetAbsOrigin(); vUpABit.z += 5.0; CBaseEntity* saveOwner = GetOwnerEntity(); SetOwnerEntity( NULL ); UTIL_TraceEntity( this, GetAbsOrigin(), vUpABit, MASK_SOLID, &tr ); if ( tr.startsolid || tr.fraction != 1.0 ) { SetOwnerEntity( saveOwner ); } } // Bounce movement code gets this think stuck occasionally so check if I've // succeeded in moving, otherwise kill my motions. else if ((GetAbsOrigin() - m_vLastPosition).LengthSqr()<1) { SetAbsVelocity( vec3_origin ); QAngle angVel = GetLocalAngularVelocity(); angVel.y = 0; SetLocalAngularVelocity( angVel ); // Clear think function SetThink(NULL); return; } m_vLastPosition= GetAbsOrigin(); StudioFrameAdvance( ); SetNextThink( gpGlobals->curtime + 0.1f ); if (!IsInWorld()) { UTIL_Remove( this ); return; } // Is it attached to a wall? if (m_bIsAttached) { return; } }
//------------------------------------------------------------------------------ // Purpose : Override to return correct velocity // Input : // Output : //------------------------------------------------------------------------------ void CAI_BasePhysicsFlyingBot::GetVelocity(Vector *vVelocity, QAngle *vAngVelocity) { if (vVelocity != NULL) { VectorCopy(m_vCurrentVelocity,*vVelocity); } if (vAngVelocity != NULL) { *vAngVelocity = GetLocalAngularVelocity(); } }
//------------------------------------------------------------------------------ // Purpose : Override to return correct velocity // Input : // Output : //------------------------------------------------------------------------------ void CAI_BaseFlyingBot::GetVelocity(Vector *vVelocity, AngularImpulse *vAngVelocity) { if (vVelocity != NULL) { VectorCopy(m_vCurrentVelocity,*vVelocity); } if (vAngVelocity != NULL) { QAngle tmp = GetLocalAngularVelocity(); QAngleToAngularImpulse( tmp, *vAngVelocity ); } }
// // Gib bounces on the ground or wall, sponges some blood down, too! // void CGib::BounceGibTouch ( CBaseEntity *pOther ) { Vector vecSpot; trace_t tr; IPhysicsObject *pPhysics = VPhysicsGetObject(); if ( pPhysics ) return; //if ( random->RandomInt(0,1) ) // return;// don't bleed everytime if (GetFlags() & FL_ONGROUND) { SetAbsVelocity( GetAbsVelocity() * 0.9 ); QAngle angles = GetLocalAngles(); angles.x = 0; angles.z = 0; SetLocalAngles( angles ); QAngle angVel = GetLocalAngularVelocity(); angVel.x = 0; angVel.z = 0; SetLocalAngularVelocity( vec3_angle ); } else { //City17: Germany Violence Fix. if ( /*g_Language.GetInt() != LANGUAGE_GERMAN &&*/ m_cBloodDecals > 0 && m_bloodColor != DONT_BLEED ) { vecSpot = GetAbsOrigin() + Vector ( 0 , 0 , 8 );//move up a bit, and trace down. UTIL_TraceLine ( vecSpot, vecSpot + Vector ( 0, 0, -24 ), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr); UTIL_BloodDecalTrace( &tr, m_bloodColor ); m_cBloodDecals--; } if ( m_material != matNone && random->RandomInt(0,2) == 0 ) { float volume; float zvel = fabs(GetAbsVelocity().z); volume = 0.8f * min(1.0, ((float)zvel) / 450.0f); CBreakable::MaterialSoundRandom( entindex(), (Materials)m_material, volume ); } } }
void CWorld::Think( void ) { // Uncomment this is you want to see the world bbox displayed on the client // // NDebugOverlay::Box(GetOrigin(), m_WorldMins, m_WorldMaxs, 0, 255, 0, 0, 0.1); Assert( GetAbsVelocity() == vec3_origin ); Assert( GetLocalAngularVelocity() == vec3_angle ); if (game_speeds.GetInt()) { DrawMeasuredSections(); } SetNextThink( gpGlobals->curtime + 0.05 ); }
//----------------------------------------------------------------------------- // Purpose: Will hurt others based on how fast the brush is spinning. // Input : pOther - //----------------------------------------------------------------------------- void CFuncRotating::HurtTouch ( CBaseEntity *pOther ) { // we can't hurt this thing, so we're not concerned with it if ( !pOther->m_takedamage ) return; // calculate damage based on rotation speed m_flBlockDamage = GetLocalAngularVelocity().Length() / 10; pOther->TakeDamage( CTakeDamageInfo( this, this, m_flBlockDamage, DMG_CRUSH ) ); Vector vecNewVelocity = pOther->GetAbsOrigin() - WorldSpaceCenter(); VectorNormalize(vecNewVelocity); vecNewVelocity *= m_flBlockDamage; pOther->SetAbsVelocity( vecNewVelocity ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- bool CItem_DynamicResupply::SpawnItemFromRatio( int nCount, DynamicResupplyItems_t *pItems, int iDebug, SpawnInfo_t *pSpawnInfo, Vector *pVecSpawnOrigin ) { // Now find the one we're farthest from float flFarthest = 0; int iSelectedIndex = -1; for ( int i = 0; i < nCount; ++i ) { if ( pSpawnInfo[i].m_flDelta > flFarthest ) { flFarthest = pSpawnInfo[i].m_flDelta; iSelectedIndex = i; } } if ( iSelectedIndex < 0 ) return false; if ( iDebug ) { Msg("Chosen item: %s (had farthest delta, %.2f)\n", pItems[iSelectedIndex].sEntityName, pSpawnInfo[iSelectedIndex].m_flDelta ); } CBaseEntity *pEnt = CBaseEntity::Create( pItems[iSelectedIndex].sEntityName, *pVecSpawnOrigin, GetAbsAngles(), this ); pEnt->SetAbsVelocity( GetAbsVelocity() ); pEnt->SetLocalAngularVelocity( GetLocalAngularVelocity() ); // Move the entity up so that it doesn't go below the spawn origin Vector vecWorldMins, vecWorldMaxs; pEnt->CollisionProp()->WorldSpaceAABB( &vecWorldMins, &vecWorldMaxs ); if ( vecWorldMins.z < pVecSpawnOrigin->z ) { float dz = pVecSpawnOrigin->z - vecWorldMins.z; pVecSpawnOrigin->z += dz; vecWorldMaxs.z += dz; pEnt->SetAbsOrigin( *pVecSpawnOrigin ); } // Update the spawn position to spawn them on top of each other pVecSpawnOrigin->z = vecWorldMaxs.z + 6.0f; pVecSpawnOrigin->x += random->RandomFloat( -6, 6 ); pVecSpawnOrigin->y += random->RandomFloat( -6, 6 ); return true; }
void C_PhysPropClientside::Break() { m_takedamage = DAMAGE_NO; IPhysicsObject *pPhysics = VPhysicsGetObject(); Vector velocity; AngularImpulse angVelocity; Vector origin; QAngle angles; AddSolidFlags( FSOLID_NOT_SOLID ); if ( pPhysics ) { pPhysics->GetVelocity( &velocity, &angVelocity ); pPhysics->GetPosition( &origin, &angles ); pPhysics->RecheckCollisionFilter(); } else { velocity = GetAbsVelocity(); QAngleToAngularImpulse( GetLocalAngularVelocity(), angVelocity ); origin = GetAbsOrigin(); angles = GetAbsAngles(); } breakablepropparams_t params( origin, angles, velocity, angVelocity ); params.impactEnergyScale = m_impactEnergyScale; params.defCollisionGroup = GetCollisionGroup(); if ( params.defCollisionGroup == COLLISION_GROUP_NONE ) { // don't automatically make anything COLLISION_GROUP_NONE or it will // collide with debris being ejected by breaking params.defCollisionGroup = COLLISION_GROUP_INTERACTIVE; } // no damage/damage force? set a burst of 100 for some movement params.defBurstScale = 100; // spwan break chunks PropBreakableCreateAll( GetModelIndex(), pPhysics, params, this, -1, false ); Release(); // destroy object }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CFuncRotating::Precache( void ) { // // Set up rotation sound. // char *szSoundFile = ( char * )STRING( m_NoiseRunning ); if ( !m_NoiseRunning || strlen( szSoundFile ) == 0 ) { // No sound set up, use the null sound. m_NoiseRunning = AllocPooledString("DoorSound.Null"); } PrecacheScriptSound( STRING( m_NoiseRunning ) ); if (GetLocalAngularVelocity() != vec3_angle ) { // // If fan was spinning, and we went through transition or save/restore, // make sure we restart the sound. 1.5 sec delay is a magic number. // SetMoveDone( &CFuncRotating::SpinUpMove ); SetMoveDoneTime( 1.5 ); } }
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------ void CBaseHelicopter::Flight( void ) { if( GetFlags() & FL_ONGROUND ) { //This would be really bad. SetGroundEntity( NULL ); } // Generic speed up if (m_flGoalSpeed < GetMaxSpeed()) { m_flGoalSpeed += GetAcceleration(); } //NDebugOverlay::Line(GetAbsOrigin(), m_vecDesiredPosition, 0,0,255, true, 0.1); // tilt model 5 degrees (why?! sjb) QAngle vecAdj = QAngle( 5.0, 0, 0 ); // estimate where I'll be facing in one seconds Vector forward, right, up; AngleVectors( GetLocalAngles() + GetLocalAngularVelocity() * 2 + vecAdj, &forward, &right, &up ); // Vector vecEst1 = GetLocalOrigin() + GetAbsVelocity() + up * m_flForce - Vector( 0, 0, 384 ); // float flSide = DotProduct( m_vecDesiredPosition - vecEst1, right ); QAngle angVel = GetLocalAngularVelocity(); float flSide = DotProduct( m_vecDesiredFaceDir, right ); if (flSide < 0) { if (angVel.y < 60) { angVel.y += 8; } } else { if (angVel.y > -60) { angVel.y -= 8; } } angVel.y *= ( 0.98 ); // why?! (sjb) // estimate where I'll be in two seconds AngleVectors( GetLocalAngles() + angVel * 1 + vecAdj, NULL, NULL, &up ); Vector vecEst = GetAbsOrigin() + GetAbsVelocity() * 2.0 + up * m_flForce * 20 - Vector( 0, 0, 384 * 2 ); // add immediate force AngleVectors( GetLocalAngles() + vecAdj, &forward, &right, &up ); Vector vecImpulse( 0, 0, 0 ); vecImpulse.x += up.x * m_flForce; vecImpulse.y += up.y * m_flForce; vecImpulse.z += up.z * m_flForce; // add gravity vecImpulse.z -= 38.4; // 32ft/sec ApplyAbsVelocityImpulse( vecImpulse ); float flSpeed = GetAbsVelocity().Length(); float flDir = DotProduct( Vector( forward.x, forward.y, 0 ), Vector( GetAbsVelocity().x, GetAbsVelocity().y, 0 ) ); if (flDir < 0) { flSpeed = -flSpeed; } float flDist = DotProduct( GetDesiredPosition() - vecEst, forward ); // float flSlip = DotProduct( GetAbsVelocity(), right ); float flSlip = -DotProduct( GetDesiredPosition() - vecEst, right ); // fly sideways if (flSlip > 0) { if (GetLocalAngles().z > -30 && angVel.z > -15) angVel.z -= 4; else angVel.z += 2; } else { if (GetLocalAngles().z < 30 && angVel.z < 15) angVel.z += 4; else angVel.z -= 2; } // These functions contain code Ken wrote that used to be right here as part of the flight model, // but we want different helicopter vehicles to have different drag characteristics, so I made // them virtual functions (sjb) ApplySidewaysDrag( right ); ApplyGeneralDrag(); // apply power to stay correct height // FIXME: these need to be per class variables #define MAX_FORCE 80 #define FORCE_POSDELTA 12 #define FORCE_NEGDELTA 8 if (m_flForce < MAX_FORCE && vecEst.z < GetDesiredPosition().z) { m_flForce += FORCE_POSDELTA; } else if (m_flForce > 30) { if (vecEst.z > GetDesiredPosition().z) m_flForce -= FORCE_NEGDELTA; } // pitch forward or back to get to target //----------------------------------------- // Pitch is reversed since Half-Life! (sjb) //----------------------------------------- if (flDist > 0 && flSpeed < m_flGoalSpeed /* && flSpeed < flDist */ && GetLocalAngles().x + angVel.x < 40) { // ALERT( at_console, "F " ); // lean forward angVel.x += 12.0; } else if (flDist < 0 && flSpeed > -50 && GetLocalAngles().x + angVel.x > -20) { // ALERT( at_console, "B " ); // lean backward angVel.x -= 12.0; } else if (GetLocalAngles().x + angVel.x < 0) { // ALERT( at_console, "f " ); angVel.x += 4.0; } else if (GetLocalAngles().x + angVel.x > 0) { // ALERT( at_console, "b " ); angVel.x -= 4.0; } SetLocalAngularVelocity( angVel ); // ALERT( at_console, "%.0f %.0f : %.0f %.0f : %.0f %.0f : %.0f\n", GetAbsOrigin().x, GetAbsVelocity().x, flDist, flSpeed, GetLocalAngles().x, m_vecAngVelocity.x, m_flForce ); // ALERT( at_console, "%.0f %.0f : %.0f %0.f : %.0f\n", GetAbsOrigin().z, GetAbsVelocity().z, vecEst.z, m_vecDesiredPosition.z, m_flForce ); }
// this is the think that flips the weapon into the world when it is spawned void CASW_Laser_Mine::SpawnFlipThink() { // we are still flagged as spawn flipping in the air if ( m_bIsSpawnFlipping == false ) { // we get here if we spawned, but haven't started spawn flipping yet, please try again! SetContextThink( &CASW_Laser_Mine::SpawnFlipThink, gpGlobals->curtime, s_pLaserMineSpawnFlipThink ); return; } // when we should hit the ground float flEndTime = m_flSpawnFlipEndTime; // the total time it takes for us to flip float flFlipTime = flEndTime - m_flSpawnFlipStartTime; float flFlipProgress = ( gpGlobals->curtime - m_flSpawnFlipStartTime ) / flFlipTime; flFlipProgress = clamp( flFlipProgress, 0.0f, 2.5f ); if ( !m_bIsSpawnLanded ) { // high gravity, it looks more satisfying float flGravity = 2200; float flInitialZVelocity = (m_vecSpawnFlipEndPos.z - m_vecSpawnFlipStartPos.z)/flFlipTime + (flGravity/2) * flFlipTime; float flZVelocity = flInitialZVelocity - flGravity * (gpGlobals->curtime - m_flSpawnFlipStartTime); float flXDiff = (m_vecSpawnFlipEndPos.x - m_vecSpawnFlipStartPos.x) / flFlipTime; float flYDiff = (m_vecSpawnFlipEndPos.y - m_vecSpawnFlipStartPos.y) / flFlipTime; Vector vecVelocity( flXDiff, flYDiff, flZVelocity ); SetAbsVelocity( vecVelocity ); // angular velocity QAngle angCurAngVel = GetLocalAngularVelocity(); float flXAngDiff = 360 / flFlipTime; // keep the Y angular velocity that was given to it at the start (it's random) SetLocalAngularVelocity( QAngle( flXAngDiff, angCurAngVel.y, 0 ) ); } if ( flFlipProgress >= 1.0f ) { if ( !m_bIsSpawnLanded ) { Vector vecVelStop( 0,0,0 ); SetAbsVelocity( vecVelStop ); SetAbsOrigin( m_vecSpawnFlipEndPos ); QAngle angVel( 0, 0, 0 ); SetLocalAngularVelocity( angVel ); /* // get the current angles of the item so we can use them to determine the final angles QAngle angPrevAngles = GetAbsAngles(); float flYAngles = angPrevAngles.y; QAngle angFlat( 0, flYAngles, 0 ); */ SetAbsAngles( m_angSpawnFlipEndAngle ); EmitSound("ASW_Laser_Mine.Lay"); m_bIsSpawnLanded = true; } if ( flFlipProgress >= 2.5f ) { SetContextThink( NULL, 0, s_pLaserMineSpawnFlipThink ); EmitSound("ASW_Mine.Lay"); m_bMineActive = true; return; } } SetContextThink( &CASW_Laser_Mine::SpawnFlipThink, gpGlobals->curtime, s_pLaserMineSpawnFlipThink ); }
void CSnark::HuntThink( void ) { if (!IsInWorld()) { SetTouch( NULL ); UTIL_Remove( this ); return; } StudioFrameAdvance( ); SetNextThink( gpGlobals->curtime + 0.1f ); // explode when ready if ( gpGlobals->curtime >= m_flDie ) { g_vecAttackDir = GetAbsVelocity(); VectorNormalize( g_vecAttackDir ); m_iHealth = -1; CTakeDamageInfo info( this, this, 1, DMG_GENERIC ); Event_Killed( info ); return; } // float if ( GetWaterLevel() != 0) { if ( GetMoveType() == MOVETYPE_FLYGRAVITY ) { SetMoveType( MOVETYPE_FLY, MOVECOLLIDE_FLY_BOUNCE ); } Vector vecVel = GetAbsVelocity(); vecVel *= 0.9; vecVel.z += 8.0; SetAbsVelocity( vecVel ); } else if ( GetMoveType() == MOVETYPE_FLY ) { SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE ); } // return if not time to hunt if ( m_flNextHunt > gpGlobals->curtime ) return; m_flNextHunt = gpGlobals->curtime + 2.0; Vector vecFlat = GetAbsVelocity(); vecFlat.z = 0; VectorNormalize( vecFlat ); if ( GetEnemy() == NULL || !GetEnemy()->IsAlive() ) { // find target, bounce a bit towards it. GetSenses()->Look( 512 ); SetEnemy( BestEnemy() ); } // squeek if it's about time blow up if ( (m_flDie - gpGlobals->curtime <= 0.5) && (m_flDie - gpGlobals->curtime >= 0.3) ) { CPASAttenuationFilter filter( this ); enginesound->EmitSound( filter, entindex(), CHAN_VOICE, "squeek/sqk_die1.wav", 1, ATTN_NORM, 0, 100 + random->RandomInt( 0, 0x3F ) ); CSoundEnt::InsertSound( SOUND_COMBAT, GetAbsOrigin(), 256, 0.25 ); } // higher pitch as squeeker gets closer to detonation time float flpitch = 155.0 - 60.0 * ( (m_flDie - gpGlobals->curtime) / SQUEEK_DETONATE_DELAY ); if ( flpitch < 80 ) flpitch = 80; if ( GetEnemy() != NULL ) { if ( FVisible( GetEnemy() ) ) { m_vecTarget = GetEnemy()->EyePosition() - GetAbsOrigin(); VectorNormalize( m_vecTarget ); } float flVel = GetAbsVelocity().Length(); float flAdj = 50.0 / ( flVel + 10.0 ); if ( flAdj > 1.2 ) flAdj = 1.2; // ALERT( at_console, "think : enemy\n"); // ALERT( at_console, "%.0f %.2f %.2f %.2f\n", flVel, m_vecTarget.x, m_vecTarget.y, m_vecTarget.z ); SetAbsVelocity( GetAbsVelocity() * flAdj + (m_vecTarget * 300) ); } if ( GetFlags() & FL_ONGROUND ) { SetLocalAngularVelocity( QAngle( 0, 0, 0 ) ); } else { QAngle angVel = GetLocalAngularVelocity(); if ( angVel == QAngle( 0, 0, 0 ) ) { angVel.x = random->RandomFloat( -100, 100 ); angVel.z = random->RandomFloat( -100, 100 ); SetLocalAngularVelocity( angVel ); } } if ( ( GetAbsOrigin() - m_posPrev ).Length() < 1.0 ) { Vector vecVel = GetAbsVelocity(); vecVel.x = random->RandomFloat( -100, 100 ); vecVel.y = random->RandomFloat( -100, 100 ); SetAbsVelocity( vecVel ); } m_posPrev = GetAbsOrigin(); QAngle angles; VectorAngles( GetAbsVelocity(), angles ); angles.z = 0; angles.x = 0; SetAbsAngles( angles ); }
//----------------------------------------------------------------------------- // Purpose: // Input : *pPlayer - // *pMoveData - //----------------------------------------------------------------------------- void CPropCrane::RunCraneMovement( float flTime ) { if ( m_flExtensionRate ) { // Extend / Retract the crane m_flExtension = clamp( m_flExtension + (m_flExtensionRate * 10 * flTime), 0, 2 ); SetPoseParameter( "armextensionpose", m_flExtension ); StudioFrameAdvance(); } // Drop the magnet until it hits the ground if ( m_bDropping ) { // Drop until the magnet hits something if ( m_hCraneMagnet->HasHitSomething() ) { // We hit the ground, stop dropping m_hCraneTip->m_pSpring->SetSpringConstant( CRANE_SPRING_CONSTANT_INITIAL_RAISING ); m_bDropping = false; m_flNextDropAllowedTime = gpGlobals->curtime + 3.0; m_flSlowRaiseTime = gpGlobals->curtime; m_ServerVehicle.PlaySound( VS_MISC2 ); } } else if ( (m_flSlowRaiseTime + CRANE_SLOWRAISE_TIME) > gpGlobals->curtime ) { float flDelta = (gpGlobals->curtime - m_flSlowRaiseTime); flDelta = clamp( flDelta, 0, CRANE_SLOWRAISE_TIME ); float flCurrentSpringConstant = RemapVal( flDelta, 0, CRANE_SLOWRAISE_TIME, CRANE_SPRING_CONSTANT_INITIAL_RAISING, CRANE_SPRING_CONSTANT_HANGING ); m_hCraneTip->m_pSpring->SetSpringConstant( flCurrentSpringConstant ); } // If we've moved in any way, update the tip if ( m_bDropping || m_flExtensionRate || GetLocalAngularVelocity() != vec3_angle ) { RecalculateCraneTip(); } // Make danger sounds underneath the magnet if we have something attached to it /* if ( (m_flNextDangerSoundTime < gpGlobals->curtime) && (m_hCraneMagnet->GetTotalMassAttachedObjects() > 0) ) { // Trace down from the magnet and make a danger sound on the ground trace_t tr; Vector vecSource = m_hCraneMagnet->GetAbsOrigin(); UTIL_TraceLine( vecSource, vecSource - Vector(0,0,2048), MASK_SOLID_BRUSHONLY, m_hCraneMagnet, 0, &tr ); if ( tr.fraction < 1.0 ) { // Make the volume proportional to the amount of mass on the magnet float flVolume = clamp( (m_hCraneMagnet->GetTotalMassAttachedObjects() * 0.5), 100.f, 600.f ); CSoundEnt::InsertSound( SOUND_DANGER, tr.endpos, flVolume, 0.2, this ); //Msg("Total: %.2f Volume: %.2f\n", m_hCraneMagnet->GetTotalMassAttachedObjects(), flVolume ); //Vector vecVolume = Vector(flVolume,flVolume,flVolume) * 0.5; //NDebugOverlay::Box( tr.endpos, -vecVolume, vecVolume, 255,0,0, false, 0.3 ); //NDebugOverlay::Cross3D( tr.endpos, -Vector(10,10,10), Vector(10,10,10), 255,0,0, false, 0.3 ); } m_flNextDangerSoundTime = gpGlobals->curtime + 0.3; } */ // Play creak sounds on the magnet if there's heavy weight on it if ( (m_flNextCreakSound < gpGlobals->curtime) && (m_hCraneMagnet->GetTotalMassAttachedObjects() > 100) ) { // Randomly play creaks from the magnet, and increase the chance based on the turning speed float flSpeedPercentage = clamp( fabs(m_flTurn) / m_flMaxTurnSpeed, 0, 1 ); if ( RandomFloat(0,1) > (0.95 - (0.1 * flSpeedPercentage)) ) { if ( m_ServerVehicle.m_vehicleSounds.iszSound[VS_MISC4] != NULL_STRING ) { CPASAttenuationFilter filter( m_hCraneMagnet ); EmitSound_t ep; ep.m_nChannel = CHAN_VOICE; ep.m_pSoundName = STRING(m_ServerVehicle.m_vehicleSounds.iszSound[VS_MISC4]); ep.m_flVolume = 1.0f; ep.m_SoundLevel = SNDLVL_NORM; CBaseEntity::EmitSound( filter, m_hCraneMagnet->entindex(), ep ); } m_flNextCreakSound = gpGlobals->curtime + 5.0; } } }
//----------------------------------------------------------------------------- // Purpose: Return true of the player's allowed to enter / exit the vehicle //----------------------------------------------------------------------------- bool CPropCrane::CanExitVehicle( CBaseEntity *pEntity ) { // Prevent exiting if the vehicle's locked, or rotating // Adrian: Check also if I'm currently jumping in or out. return ( !m_bLocked && (GetLocalAngularVelocity() == vec3_angle) && m_bExitAnimOn == false && m_bEnterAnimOn == false ); }
void CFuncTank::TrackTarget( void ) { trace_t tr; bool updateTime = FALSE, lineOfSight; QAngle angles; Vector barrelEnd; CBaseEntity *pTarget = NULL; barrelEnd.Init(); // Get a position to aim for if (m_pController) { // Tanks attempt to mirror the player's angles angles = m_pController->EyeAngles(); SetNextThink( gpGlobals->curtime + 0.05 ); } else { if ( IsActive() ) { SetNextThink( gpGlobals->curtime + 0.1f ); } else { return; } // ----------------------------------- // Get world target position // ----------------------------------- barrelEnd = WorldBarrelPosition(); Vector worldTargetPosition; if (m_spawnflags & SF_TANK_AIM_AT_POS) { worldTargetPosition = m_vTargetPosition; } else { CBaseEntity *pEntity = (CBaseEntity *)m_hTarget; if ( !pEntity || ( pEntity->GetFlags() & FL_NOTARGET ) ) { if ( m_targetEntityName != NULL_STRING ) // New HL2 behavior { m_hTarget = FindTarget( m_targetEntityName, NULL ); } else // HL1 style { m_hTarget = ToBasePlayer( GetContainingEntity( UTIL_FindClientInPVS( edict() ) ) ); } if ( m_hTarget != NULL ) { SetNextThink( gpGlobals->curtime ); // Think again immediately } else { if ( IsActive() ) { SetNextThink( gpGlobals->curtime + 2 ); // Wait 2 secs } if ( m_fireLast !=0 ) { m_OnLoseTarget.FireOutput(this, this); m_fireLast = 0; } } return; } pTarget = pEntity; // Calculate angle needed to aim at target worldTargetPosition = pEntity->EyePosition(); } float range = (worldTargetPosition - barrelEnd).Length(); if ( !InRange( range ) ) { m_fireLast = 0; return; } UTIL_TraceLine( barrelEnd, worldTargetPosition, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); if (m_spawnflags & SF_TANK_AIM_AT_POS) { updateTime = TRUE; m_sightOrigin = m_vTargetPosition; } else { lineOfSight = FALSE; // No line of sight, don't track if ( tr.fraction == 1.0 || tr.m_pEnt == pTarget ) { lineOfSight = TRUE; CBaseEntity *pInstance = pTarget; if ( InRange( range ) && pInstance && pInstance->IsAlive() ) { updateTime = TRUE; // Sight position is BodyTarget with no noise (so gun doesn't bob up and down) m_sightOrigin = pInstance->BodyTarget( GetLocalOrigin(), false ); } } } // Convert targetPosition to parent angles = AimBarrelAt( m_parentMatrix.WorldToLocal( m_sightOrigin ) ); } // Force the angles to be relative to the center position float offsetY = UTIL_AngleDistance( angles.y, m_yawCenter ); float offsetX = UTIL_AngleDistance( angles.x, m_pitchCenter ); angles.y = m_yawCenter + offsetY; angles.x = m_pitchCenter + offsetX; // Limit against range in y // MDB - don't check pitch! If two func_tanks are meant to align, // and one can pitch and the other cannot, this can lead to them getting // different values for angles.y. Nothing is lost by not updating yaw // because the target is not in pitch range. bool bOutsideYawRange = ( fabs( offsetY ) > m_yawRange + m_yawTolerance ); bool bOutsidePitchRange = ( fabs( offsetX ) > m_pitchRange + m_pitchTolerance ); Vector vecToTarget = m_sightOrigin - GetLocalOrigin(); // if target is outside yaw range if ( bOutsideYawRange ) { if ( angles.y > m_yawCenter + m_yawRange ) { angles.y = m_yawCenter + m_yawRange; } else if ( angles.y < (m_yawCenter - m_yawRange) ) { angles.y = (m_yawCenter - m_yawRange); } } if ( bOutsidePitchRange || bOutsideYawRange || ( vecToTarget.Length() < ( barrelEnd - GetAbsOrigin() ).Length() ) ) { // Don't update if you saw the player, but out of range updateTime = false; } if ( updateTime ) { m_lastSightTime = gpGlobals->curtime; m_persist2burst = 0; } // Move toward target at rate or less float distY = UTIL_AngleDistance( angles.y, GetLocalAngles().y ); QAngle vecAngVel = GetLocalAngularVelocity(); vecAngVel.y = distY * 10; vecAngVel.y = clamp( vecAngVel.y, -m_yawRate, m_yawRate ); // Limit against range in x angles.x = clamp( angles.x, m_pitchCenter - m_pitchRange, m_pitchCenter + m_pitchRange ); // Move toward target at rate or less float distX = UTIL_AngleDistance( angles.x, GetLocalAngles().x ); vecAngVel.x = distX * 10; vecAngVel.x = clamp( vecAngVel.x, -m_pitchRate, m_pitchRate ); SetLocalAngularVelocity( vecAngVel ); SetMoveDoneTime( 0.1 ); if ( m_pController ) return; if ( CanFire() && ( (fabs(distX) < m_pitchTolerance && fabs(distY) < m_yawTolerance) || (m_spawnflags & SF_TANK_LINEOFSIGHT) ) ) { bool fire = FALSE; Vector forward; AngleVectors( GetLocalAngles(), &forward ); forward = m_parentMatrix.ApplyRotation( forward ); if ( m_spawnflags & SF_TANK_LINEOFSIGHT ) { float length = (m_maxRange > 0) ? m_maxRange : MAX_TRACE_LENGTH; UTIL_TraceLine( barrelEnd, barrelEnd + forward * length, MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); if ( tr.m_pEnt == pTarget ) fire = TRUE; } else fire = TRUE; if ( fire ) { if (m_fireLast == 0) { m_OnAquireTarget.FireOutput(this, this); } FiringSequence( barrelEnd, forward, this ); } else { if (m_fireLast !=0) { m_OnLoseTarget.FireOutput(this, this); } m_fireLast = 0; } } else { if (m_fireLast !=0) { m_OnLoseTarget.FireOutput(this, this); } m_fireLast = 0; } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CASW_Broadcast_Camera::FollowTarget( ) { //if (m_hPlayer == NULL) //return; if ( m_hTarget == NULL ) { Disable(); return; } if ( !HasSpawnFlags(SF_CAMERA_PLAYER_INFINITE_WAIT) && (!m_hTarget || m_flReturnTime < gpGlobals->curtime) ) { Disable(); return; } UpdateAllPlayers(); QAngle vecGoal; if ( m_iAttachmentIndex ) { Vector vecOrigin; m_hTarget->GetBaseAnimating()->GetAttachment( m_iAttachmentIndex, vecOrigin ); VectorAngles( vecOrigin - GetAbsOrigin(), vecGoal ); } else { if ( m_hTarget ) { VectorAngles( m_hTarget->GetAbsOrigin() - GetAbsOrigin(), vecGoal ); } else { // Use the viewcontroller's angles vecGoal = GetAbsAngles(); } } // Should we just snap to the goal angles? if ( m_bSnapToGoal ) { SetAbsAngles( vecGoal ); m_bSnapToGoal = false; } else { // UNDONE: Can't we just use UTIL_AngleDiff here? QAngle angles = GetLocalAngles(); if (angles.y > 360) angles.y -= 360; if (angles.y < 0) angles.y += 360; SetLocalAngles( angles ); float dx = vecGoal.x - GetLocalAngles().x; float dy = vecGoal.y - GetLocalAngles().y; if (dx < -180) dx += 360; if (dx > 180) dx = dx - 360; if (dy < -180) dy += 360; if (dy > 180) dy = dy - 360; QAngle vecAngVel; vecAngVel.Init( dx * 40 * gpGlobals->frametime, dy * 40 * gpGlobals->frametime, GetLocalAngularVelocity().z ); SetLocalAngularVelocity(vecAngVel); } if (!HasSpawnFlags(SF_CAMERA_PLAYER_TAKECONTROL)) { SetAbsVelocity( GetAbsVelocity() * 0.8 ); if (GetAbsVelocity().Length( ) < 10.0) { SetAbsVelocity( vec3_origin ); } } SetNextThink( gpGlobals->curtime ); Move(); }
//------------------------------------------------------------------------------ // Purpose : // Input : // Output : //------------------------------------------------------------------------------ void CNPC_CombineDropship::Flight( void ) { // Only run pose params in some flight states bool bRunPoseParams = ( m_iLandState == LANDING_NO || m_iLandState == LANDING_LEVEL_OUT || m_iLandState == LANDING_LIFTOFF || m_iLandState == LANDING_SWOOPING ); if ( bRunPoseParams ) { if( GetFlags() & FL_ONGROUND ) { //This would be really bad. RemoveFlag( FL_ONGROUND ); } // NDebugOverlay::Line(GetLocalOrigin(), GetDesiredPosition(), 0,0,255, true, 0.1); Vector deltaPos = GetDesiredPosition() - GetLocalOrigin(); // calc desired acceleration float dt = 1.0f; Vector accel; float accelRate = DROPSHIP_ACCEL_RATE; float maxSpeed = m_flMaxSpeed; if ( m_lifeState == LIFE_DYING ) { accelRate *= 5.0; maxSpeed *= 5.0; } float flDist = min( GetAbsVelocity().Length() + accelRate, maxSpeed ); // Only decelerate to our goal if we're going to hit it if ( deltaPos.Length() > flDist * dt ) { float scale = flDist * dt / deltaPos.Length(); deltaPos = deltaPos * scale; } // If we're swooping, floor it if ( m_iLandState == LANDING_SWOOPING ) { VectorNormalize( deltaPos ); deltaPos *= maxSpeed; } // calc goal linear accel to hit deltaPos in dt time. accel.x = 2.0 * (deltaPos.x - GetAbsVelocity().x * dt) / (dt * dt); accel.y = 2.0 * (deltaPos.y - GetAbsVelocity().y * dt) / (dt * dt); accel.z = 2.0 * (deltaPos.z - GetAbsVelocity().z * dt + 0.5 * 384 * dt * dt) / (dt * dt); //NDebugOverlay::Line(GetLocalOrigin(), GetLocalOrigin() + deltaPos, 255,0,0, true, 0.1); //NDebugOverlay::Line(GetLocalOrigin(), GetLocalOrigin() + accel, 0,255,0, true, 0.1); // don't fall faster than 0.2G or climb faster than 2G if ( m_iLandState != LANDING_SWOOPING ) { accel.z = clamp( accel.z, 384 * 0.2, 384 * 2.0 ); } Vector forward, right, up; GetVectors( &forward, &right, &up ); Vector goalUp = accel; VectorNormalize( goalUp ); // calc goal orientation to hit linear accel forces float goalPitch = RAD2DEG( asin( DotProduct( forward, goalUp ) ) ); float goalYaw = UTIL_VecToYaw( m_vecDesiredFaceDir ); float goalRoll = RAD2DEG( asin( DotProduct( right, goalUp ) ) ); // clamp goal orientations goalPitch = clamp( goalPitch, -45, 60 ); goalRoll = clamp( goalRoll, -45, 45 ); // calc angular accel needed to hit goal pitch in dt time. dt = 0.6; QAngle goalAngAccel; goalAngAccel.x = 2.0 * (AngleDiff( goalPitch, AngleNormalize( GetLocalAngles().x ) ) - GetLocalAngularVelocity().x * dt) / (dt * dt); goalAngAccel.y = 2.0 * (AngleDiff( goalYaw, AngleNormalize( GetLocalAngles().y ) ) - GetLocalAngularVelocity().y * dt) / (dt * dt); goalAngAccel.z = 2.0 * (AngleDiff( goalRoll, AngleNormalize( GetLocalAngles().z ) ) - GetLocalAngularVelocity().z * dt) / (dt * dt); goalAngAccel.x = clamp( goalAngAccel.x, -300, 300 ); //goalAngAccel.y = clamp( goalAngAccel.y, -60, 60 ); goalAngAccel.y = clamp( goalAngAccel.y, -120, 120 ); goalAngAccel.z = clamp( goalAngAccel.z, -300, 300 ); // limit angular accel changes to simulate mechanical response times dt = 0.1; QAngle angAccelAccel; angAccelAccel.x = (goalAngAccel.x - m_vecAngAcceleration.x) / dt; angAccelAccel.y = (goalAngAccel.y - m_vecAngAcceleration.y) / dt; angAccelAccel.z = (goalAngAccel.z - m_vecAngAcceleration.z) / dt; angAccelAccel.x = clamp( angAccelAccel.x, -1000, 1000 ); angAccelAccel.y = clamp( angAccelAccel.y, -1000, 1000 ); angAccelAccel.z = clamp( angAccelAccel.z, -1000, 1000 ); m_vecAngAcceleration += angAccelAccel * 0.1; // Msg( "pitch %6.1f (%6.1f:%6.1f) ", goalPitch, GetLocalAngles().x, m_vecAngVelocity.x ); // Msg( "roll %6.1f (%6.1f:%6.1f) : ", goalRoll, GetLocalAngles().z, m_vecAngVelocity.z ); // Msg( "%6.1f %6.1f %6.1f : ", goalAngAccel.x, goalAngAccel.y, goalAngAccel.z ); // Msg( "%6.0f %6.0f %6.0f\n", angAccelAccel.x, angAccelAccel.y, angAccelAccel.z ); ApplySidewaysDrag( right ); ApplyGeneralDrag(); QAngle angVel = GetLocalAngularVelocity(); angVel += m_vecAngAcceleration * 0.1; //angVel.y = clamp( angVel.y, -60, 60 ); //angVel.y = clamp( angVel.y, -120, 120 ); angVel.y = clamp( angVel.y, -120, 120 ); SetLocalAngularVelocity( angVel ); m_flForce = m_flForce * 0.8 + (accel.z + fabs( accel.x ) * 0.1 + fabs( accel.y ) * 0.1) * 0.1 * 0.2; Vector vecImpulse = m_flForce * up; if ( m_lifeState == LIFE_DYING ) { vecImpulse.z = -38.4; // 64ft/sec } else { vecImpulse.z -= 38.4; // 32ft/sec } // Find our acceleration direction Vector vecAccelDir = vecImpulse; VectorNormalize( vecAccelDir ); // Find our current velocity Vector vecVelDir = GetAbsVelocity(); VectorNormalize( vecVelDir ); // Level out our plane of movement vecAccelDir.z = 0.0f; vecVelDir.z = 0.0f; forward.z = 0.0f; right.z = 0.0f; // Find out how "fast" we're moving in relation to facing and acceleration float speed = m_flForce * DotProduct( vecVelDir, vecAccelDir );// * DotProduct( forward, vecVelDir ); // Use the correct pose params char *sBodyAccel; char *sBodySway; if ( m_hContainer || m_iLandState == LANDING_SWOOPING ) { sBodyAccel = "cargo_body_accel"; sBodySway = "cargo_body_sway"; SetPoseParameter( "body_accel", 0 ); SetPoseParameter( "body_sway", 0 ); } else { sBodyAccel = "body_accel"; sBodySway = "body_sway"; SetPoseParameter( "cargo_body_accel", 0 ); SetPoseParameter( "cargo_body_sway", 0 ); } // Apply the acceleration blend to the fins float finAccelBlend = SimpleSplineRemapVal( speed, -60, 60, -1, 1 ); float curFinAccel = GetPoseParameter( sBodyAccel ); curFinAccel = UTIL_Approach( finAccelBlend, curFinAccel, 0.5f ); SetPoseParameter( sBodyAccel, curFinAccel ); speed = m_flForce * DotProduct( vecVelDir, right ); // Apply the spin sway to the fins float finSwayBlend = SimpleSplineRemapVal( speed, -60, 60, -1, 1 ); float curFinSway = GetPoseParameter( sBodySway ); curFinSway = UTIL_Approach( finSwayBlend, curFinSway, 0.5f ); SetPoseParameter( sBodySway, curFinSway ); // Add in our velocity pulse for this frame ApplyAbsVelocityImpulse( vecImpulse ); //Msg("FinAccel: %f, Finsway: %f\n", curFinAccel, curFinSway ); } else { SetPoseParameter( "body_accel", 0 ); SetPoseParameter( "body_sway", 0 ); SetPoseParameter( "cargo_body_accel", 0 ); SetPoseParameter( "cargo_body_sway", 0 ); } }
//----------------------------------------------------------------------------- // Purpose: Return true of the player is allowed to exit the vehicle. //----------------------------------------------------------------------------- bool CPropVehiclePrisonerPod::CanExitVehicle( CBaseEntity *pEntity ) { // Prevent exiting if the vehicle's locked, rotating, or playing an entry/exit anim. return ( !m_bLocked && (GetLocalAngularVelocity() == vec3_angle) && !m_bEnterAnimOn && !m_bExitAnimOn ); }
//----------------------------------------------------------------------------- // Purpose: Called every frame when the door is blocked while opening or closing. // Input : pOther - The blocking entity. //----------------------------------------------------------------------------- void CBaseDoor::Blocked( CBaseEntity *pOther ) { // Hurt the blocker a little. if ( m_flBlockDamage ) { // if the door is marked "force closed" or it has a negative wait, then there's nothing to do but // push/damage the object. // If block damage is set, but this object is a physics prop that can't be damaged, just // give up and disable collisions if ( (m_bForceClosed || m_flWait < 0) && pOther->GetMoveType() == MOVETYPE_VPHYSICS && (pOther->m_takedamage == DAMAGE_NO || pOther->m_takedamage == DAMAGE_EVENTS_ONLY) ) { EntityPhysics_CreateSolver( this, pOther, true, 4.0f ); } else { pOther->TakeDamage( CTakeDamageInfo( this, this, m_flBlockDamage, DMG_CRUSH ) ); } } // If we're set to force ourselves closed, keep going if ( m_bForceClosed ) return; // if a door has a negative wait, it would never come back if blocked, // so let it just squash the object to death real fast if (m_flWait >= 0) { if (m_toggle_state == TS_GOING_DOWN) { DoorGoUp(); } else { DoorGoDown(); } } // Block all door pieces with the same targetname here. if ( GetEntityName() != NULL_STRING ) { CBaseDoor *pDoorList[64]; int doorCount = GetDoorMovementGroup( pDoorList, ARRAYSIZE(pDoorList) ); for ( int i = 0; i < doorCount; i++ ) { CBaseDoor *pDoor = pDoorList[i]; if ( pDoor->m_flWait >= 0) { if (m_bDoorGroup && pDoor->m_vecMoveDir == m_vecMoveDir && pDoor->GetAbsVelocity() == GetAbsVelocity() && pDoor->GetLocalAngularVelocity() == GetLocalAngularVelocity()) { pDoor->m_nSimulationTick = m_nSimulationTick; // don't run simulation this frame if you haven't run yet // this is the most hacked, evil, bastardized thing I've ever seen. kjb if ( !pDoor->IsRotatingDoor() ) {// set origin to realign normal doors pDoor->SetLocalOrigin( GetLocalOrigin() ); pDoor->SetAbsVelocity( vec3_origin );// stop! } else {// set angles to realign rotating doors pDoor->SetLocalAngles( GetLocalAngles() ); pDoor->SetLocalAngularVelocity( vec3_angle ); } } if ( pDoor->m_toggle_state == TS_GOING_DOWN) pDoor->DoorGoUp(); else pDoor->DoorGoDown(); } } } }
void CAPCController::TrackTarget( void ) { trace_t tr; bool updateTime = FALSE, lineOfSight; QAngle angles; Vector barrelEnd; CBaseEntity *pTarget = NULL; barrelEnd.Init(); if ( IsActive() ) { SetNextThink( gpGlobals->curtime + 0.1f ); } else { return; } // ----------------------------------- // Get world target position // ----------------------------------- barrelEnd = WorldBarrelPosition(); Vector worldTargetPosition; CBaseEntity *pEntity = (CBaseEntity *)m_hTarget; if ( !pEntity || ( pEntity->GetFlags() & FL_NOTARGET ) ) { m_hTarget = FindTarget( m_targetEntityName, NULL ); if ( IsActive() ) { SetNextThink( gpGlobals->curtime + 2 ); // Wait 2 sec s } return; } pTarget = pEntity; // Calculate angle needed to aim at target worldTargetPosition = pEntity->EyePosition(); float range = (worldTargetPosition - barrelEnd).Length(); if ( !InRange( range ) ) { m_bFireDelayed = false; return; } UTIL_TraceLine( barrelEnd, worldTargetPosition, MASK_BLOCKLOS, this, COLLISION_GROUP_NONE, &tr ); lineOfSight = FALSE; // No line of sight, don't track if ( tr.fraction == 1.0 || tr.m_pEnt == pTarget ) { lineOfSight = TRUE; CBaseEntity *pInstance = pTarget; if ( InRange( range ) && pInstance && pInstance->IsAlive() ) { updateTime = TRUE; // Sight position is BodyTarget with no noise (so gun doesn't bob up and down) m_sightOrigin = pInstance->BodyTarget( GetLocalOrigin(), false ); } } // Convert targetPosition to parent angles = AimBarrelAt( m_parentMatrix.WorldToLocal( m_sightOrigin ) ); // Force the angles to be relative to the center position float offsetY = UTIL_AngleDistance( angles.y, m_yawCenter ); float offsetX = UTIL_AngleDistance( angles.x, m_pitchCenter ); angles.y = m_yawCenter + offsetY; angles.x = m_pitchCenter + offsetX; // Move toward target at rate or less float distY = UTIL_AngleDistance( angles.y, GetLocalAngles().y ); QAngle vecAngVel = GetLocalAngularVelocity(); vecAngVel.y = distY * 10; vecAngVel.y = clamp( vecAngVel.y, -m_yawRate, m_yawRate ); // Move toward target at rate or less float distX = UTIL_AngleDistance( angles.x, GetLocalAngles().x ); vecAngVel.x = distX * 10; vecAngVel.x = clamp( vecAngVel.x, -m_pitchRate, m_pitchRate ); SetLocalAngularVelocity( vecAngVel ); SetMoveDoneTime( 0.1 ); Vector forward; AngleVectors( GetLocalAngles(), &forward ); forward = m_parentMatrix.ApplyRotation( forward ); AngleVectors(angles, &forward); if ( lineOfSight == TRUE ) { // FIXME: This will ultimately have to deal with NPCs being in the vehicle as well // See if the target is in a vehicle. If so, check its relationship CBasePlayer *pPlayer = ToBasePlayer( pTarget ); if ( pPlayer && pPlayer->IsInAVehicle() ) { IServerVehicle *pVehicle = pPlayer->GetVehicle(); if ( pVehicle->ClassifyPassenger( pPlayer, CLASS_PLAYER ) == CLASS_PLAYER) { if ( !m_bFireDelayed ) { m_bFireDelayed = true; m_flFiringDelay = gpGlobals->curtime + 1.5; // setup delay time before we start firing return; } if ( gpGlobals->curtime > m_flFiringDelay ) { m_OnFireAtTarget.Set(forward, this, this); // tell apc to fire rockets, and what direction } } } } else { m_bFireDelayed = false; // reset flag since we can no longer see target } }
//----------------------------------------------------------------------------- // Purpose: // Input : // Output : //----------------------------------------------------------------------------- void CSatchelCharge::SatchelTouch( CBaseEntity *pOther ) { Assert( pOther ); if ( !pOther->IsSolid() ) return; // If successfully thrown and touching the // NPC that released this grenade, pick it up if ( pOther == GetThrower() && GetOwnerEntity() == NULL ) { CBasePlayer *pPlayer = ToBasePlayer( m_pMyWeaponSLAM->GetOwner() ); if (pPlayer) { // Give the player ammo pPlayer->GiveAmmo(1, m_pMyWeaponSLAM->m_iSecondaryAmmoType); CPASAttenuationFilter filter( pPlayer, "SatchelCharge.Pickup" ); EmitSound( filter, pPlayer->entindex(), "SatchelCharge.Pickup" ); m_bIsLive = false; // Take weapon out of detonate mode if necessary if (!m_pMyWeaponSLAM->AnyUndetonatedCharges()) { m_pMyWeaponSLAM->m_bDetonatorArmed = false; m_pMyWeaponSLAM->m_bNeedDetonatorHolster = true; // Put detonator away right away m_pMyWeaponSLAM->SetWeaponIdleTime( gpGlobals->curtime ); } // Kill any sliding sound KillSlideSound(); // Remove satchel charge from world UTIL_Remove( this ); return; } } StudioFrameAdvance( ); // Is it attached to a wall? if (m_bIsAttached) { return; } SetGravity( 1 );// normal gravity now // HACKHACK - On ground isn't always set, so look for ground underneath trace_t tr; UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() - Vector(0,0,10), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr ); if ( tr.fraction < 1.0 ) { // add a bit of static friction SetAbsVelocity( GetAbsVelocity() * 0.85 ); SetLocalAngularVelocity( GetLocalAngularVelocity() * 0.8 ); } UpdateSlideSound(); if (m_bInAir) { BounceSound(); m_bInAir = false; } }
void CDHLProjectile::PhysicsSimulate( void ) { //------------------------------------------------------------------------------- //Our own movement/physics simulation! //------------------------------------------------------------------------------- #ifdef CLIENT_DLL if ( m_bCollided ) return; if ( !m_pShooter && m_hShooter ) m_pShooter = m_hShooter.Get(); #else if ( m_flRemoveAt > 0.0f ) { if ( m_flRemoveAt < gpGlobals->curtime ) { m_flRemoveAt = 0.0f; SUB_Remove(); } return; } if ( IsMarkedForDeletion() ) return; #endif float flFrametime = gpGlobals->frametime; //Scale for slow motion if ( DHLRules() ) { if ( (m_iType == DHL_PROJECTILE_TYPE_BULLET || m_iType == DHL_PROJECTILE_TYPE_PELLET) ) flFrametime *= (dhl_bulletspeed.GetFloat() * DHLRules()->GetTimescale()); else if ( m_iType == DHL_PROJECTILE_TYPE_COMBATKNIFE ) flFrametime *= (dhl_knifespeed.GetFloat() * DHLRules()->GetTimescale()); else flFrametime *= DHLRules()->GetTimescale(); } Vector vecDir = vec3_origin; #ifndef CLIENT_DLL Vector vecStartPos = m_vecCurPosition; //This is where we are Vector vecEndPos = m_vecCurPosition; //This is where we're going Vector vecVelocity = m_vecCurVelocity; //Velocity #else Vector vecStartPos = GetLocalOrigin(); //This is where we are Vector vecEndPos = GetLocalOrigin(); //This is where we're going Vector vecVelocity = GetLocalVelocity(); //Velocity #endif //Find out where we should move to if ( vecVelocity != vec3_origin ) { static ConVarRef gravVar( "sv_gravity" ); //Gravity float newZVelocity = vecVelocity.z - ( flFrametime * gravVar.GetFloat() * GetGravity() ); vecVelocity.z = ( (vecVelocity.z + newZVelocity) / 2 ); vecDir = vecVelocity; VectorNormalize( vecDir ); //Gravity needs to be cumulative #ifndef CLIENT_DLL m_vecCurVelocity = vecVelocity; #else SetLocalVelocity( vecVelocity ); #endif vecVelocity *= flFrametime; vecEndPos = vecStartPos + vecVelocity; if ( vecEndPos.IsValid() ) { CTraceFilterSkipTwoEntities movetrfilter( this, m_pShooter, COLLISION_GROUP_NONE ); trace_t movetr; UTIL_TraceLine( vecStartPos, vecEndPos, MASK_SHOT, &movetrfilter, &movetr ); #ifndef CLIENT_DLL //Trace to triggers so we can hit surf glass and such CTakeDamageInfo triggerInfo( this, GetOwnerEntity(), m_iDamage, DMG_BULLET ); if ( m_iType == DHL_PROJECTILE_TYPE_COMBATKNIFE ) { //CalculateMeleeDamageForce( &triggerInfo, vecDir, movetr.endpos, 0.7f ); Vector vecForce = vecDir; VectorNormalize( vecForce ); //vecForce *= 10.0f; triggerInfo.SetDamageForce( vecForce ); } else CalculateBulletDamageForce( &triggerInfo, m_iAmmoType, vecDir, movetr.endpos, 1.0f ); triggerInfo.SetDamagePosition( movetr.endpos ); TraceAttackToTriggers( triggerInfo, movetr.startpos, movetr.endpos, vecDir ); #else //Hit ragdolls on the client CBaseEntity* pEnt = DHL_FX_AffectRagdolls( movetr.endpos, movetr.startpos, DMG_BULLET, &m_RagdollHitList ); //Keep track of ones we've hit if ( pEnt ) m_RagdollHitList.AddToTail( pEnt ); #endif if ( movetr.DidHit() ) if ( OnTouch( movetr, false, &movetrfilter ) ) return; MoveProjectileToPosition( vecEndPos ); m_flDistanceTravelled += vecEndPos.DistTo( vecStartPos ); #ifndef CLIENT_DLL //On rare occasions the projectile likes to fly right through the world and keep going forever, causing a memory leak if ( m_flDistanceTravelled > MAX_TRACE_LENGTH ) { SUB_Remove(); //SetThink( &CDHLProjectile::SUB_Remove ); //SetNextThink( gpGlobals->curtime + 0.1 ); } #endif } //Simulate Angles //QAngle angles; #ifdef CLIENT_DLL QAngle angles = GetLocalAngles(); //VectorAngles( vecDir, angles ); //angles.z = GetLocalAngles().z; //Vector conversion loses z QAngle angVel = GetLocalAngularVelocity(); angles += angVel * flFrametime; SetLocalAngles( angles ); SetNetworkAngles( angles ); #endif } }
//----------------------------------------------------------------------------- // Purpose: Return true of the player is allowed to exit the vehicle. //----------------------------------------------------------------------------- bool CPropVehicleChoreoGeneric::CanExitVehicle( CBaseEntity *pEntity ) { m_playerUse.FireOutput( this, this, 0 ); // Prevent exiting if the vehicle's locked, rotating, or playing an entry/exit anim. return ( !m_bLocked && (GetLocalAngularVelocity() == vec3_angle) && !m_bEnterAnimOn && !m_bExitAnimOn ); }