void CTriggerCamera::Move( void ) { // Not moving on a path, return if (!m_pGoalEnt) return; // Subtract movement from the previous frame pev->frags -= pev->speed * gpGlobals->frametime; // Have we moved enough to reach the target? if ( pev->frags <= 0 ) { // Fire the passtarget if there is one if ( m_pGoalEnt->pev->message ) { UTIL_FireTargets( m_pGoalEnt->pev->message, this, this, USE_TOGGLE, 0 ); if ( FBitSet( m_pGoalEnt->pev->spawnflags, SF_CORNER_FIREONCE ) ) m_pGoalEnt->pev->message = 0; } if ( FBitSet( m_pGoalEnt->pev->spawnflags, SF_CORNER_TELEPORT ) ) { m_pGoalEnt = m_pGoalEnt->GetNext(); if ( m_pGoalEnt ) UTIL_AssignOrigin( this, m_pGoalEnt->pev->origin ); } if ( FBitSet( m_pGoalEnt->pev->spawnflags, SF_CORNER_WAITFORTRIG ) ) { //strange feature... } // Time to go to the next target m_pGoalEnt = m_pGoalEnt->GetNext(); // Set up next corner if ( !m_pGoalEnt ) UTIL_SetVelocity( this, g_vecZero ); else { pev->message = m_pGoalEnt->pev->targetname; //save last corner pev->armorvalue = m_pGoalEnt->pev->speed; Vector delta = m_pGoalEnt->pev->origin - pev->origin; pev->frags = delta.Length(); pev->movedir = delta.Normalize(); m_flDelay = gpGlobals->time + m_pGoalEnt->GetDelay(); } } if ( m_flDelay > gpGlobals->time ) pev->speed = UTIL_Approach( 0, pev->speed, 500 * gpGlobals->frametime ); else pev->speed = UTIL_Approach( pev->armorvalue, pev->speed, 500 * gpGlobals->frametime ); if( !pTarget ) UTIL_WatchTarget( this, m_pGoalEnt ); // watch for track float fraction = 2 * gpGlobals->frametime; UTIL_SetVelocity( this, ((pev->movedir * pev->speed) * fraction) + (pev->velocity * ( 1 - fraction ))); }
void CWateryDeathLeech::LeechThink( void ) { if ( IsMarkedForDeletion() ) return; StudioFrameAdvance(); SetNextThink( gpGlobals->curtime + 0.1 ); if ( m_iFadeState != 0 ) { float dt = gpGlobals->frametime; if ( dt > 0.1f ) { dt = 0.1f; } m_nRenderMode = kRenderTransTexture; int speed = max(1,256*dt); // fade out over 1 second if ( m_iFadeState == -1 ) SetRenderColorA( UTIL_Approach( 0, m_clrRender->a, speed ) ); else SetRenderColorA( UTIL_Approach( 255, m_clrRender->a, speed ) ); if ( m_clrRender->a == 0 ) { UTIL_Remove(this); } else if ( m_clrRender->a == 255 ) { m_iFadeState = 0; } else { SetNextThink( gpGlobals->curtime ); } } if ( GetOwnerEntity() ) { if ( GetOwnerEntity()->GetWaterLevel() < 3 ) { AddEffects( EF_NODRAW ); } else { RemoveEffects( EF_NODRAW ); } SetAbsOrigin( GetOwnerEntity()->GetAbsOrigin() + GetOwnerEntity()->GetViewOffset() ); } }
void CNPC_HL1Barney::SUB_LVFadeOut( void ) { if( VPhysicsGetObject() ) { if( VPhysicsGetObject()->GetGameFlags() & FVPHYSICS_PLAYER_HELD || GetEFlags() & EFL_IS_BEING_LIFTED_BY_BARNACLE ) { // Try again in a few seconds. SetNextThink( gpGlobals->curtime + 5 ); SetRenderColorA( 255 ); return; } } float dt = gpGlobals->frametime; if ( dt > 0.1f ) { dt = 0.1f; } m_nRenderMode = kRenderTransTexture; int speed = max(3,256*dt); // fade out over 3 seconds SetRenderColorA( UTIL_Approach( 0, m_clrRender->a, speed ) ); NetworkStateChanged(); if ( m_clrRender->a == 0 ) { UTIL_Remove(this); } else { SetNextThink( gpGlobals->curtime ); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWeaponGaussGun::ItemPostFrame() { //Get the view kick CBasePlayer *pPlayer = ToBasePlayer( GetOwner() ); if ( !pPlayer ) return; if ( pPlayer->m_afButtonReleased & IN_ATTACK2 ) { if ( m_bCharging ) ChargedFire(); } #ifndef CLIENT_DLL m_flCoilVelocity = UTIL_Approach( m_flCoilMaxVelocity, m_flCoilVelocity, 10.0f ); m_flCoilAngle = UTIL_AngleMod( m_flCoilAngle + ( m_flCoilVelocity * gpGlobals->frametime ) ); static float fanAngle = 0.0f; fanAngle = UTIL_AngleMod( fanAngle + 2 ); //Update spinning bits SetBoneController( 0, fanAngle ); SetBoneController( 1, m_flCoilAngle ); #endif BaseClass::ItemPostFrame(); }
void CGargantua::EyeUpdate( void ) { if ( m_pEyeGlow ) { m_pEyeGlow->pev->renderamt = UTIL_Approach( m_eyeBrightness, m_pEyeGlow->pev->renderamt, 26 ); if ( m_pEyeGlow->pev->renderamt == 0 ) m_pEyeGlow->pev->effects |= EF_NODRAW; else m_pEyeGlow->pev->effects &= ~EF_NODRAW; UTIL_SetOrigin( m_pEyeGlow, GetAbsOrigin() ); } }
void CGargantua::EyeUpdate( void ) { if ( m_pEyeGlow ) { m_pEyeGlow->SetRenderAmount( UTIL_Approach( m_eyeBrightness, m_pEyeGlow->GetRenderAmount(), 26 ) ); if ( m_pEyeGlow->GetRenderAmount() == 0 ) m_pEyeGlow->GetEffects() |= EF_NODRAW; else m_pEyeGlow->GetEffects().ClearFlags( EF_NODRAW ); m_pEyeGlow->SetAbsOrigin( GetAbsOrigin() ); } }
void CPropVehicleManhack::UpdateHead( void ) { float yaw = GetPoseParameter( "head_yaw" ); float pitch = GetPoseParameter( "head_pitch" ); // If we should be watching our enemy, turn our head CNPC_Manhack *pManhack=GetManhack(); if (pManhack != NULL) { Vector vehicleEyeOrigin; QAngle vehicleEyeAngles; GetAttachment( "vehicle_driver_eyes", vehicleEyeOrigin, vehicleEyeAngles ); // FIXME: cache this Vector vBodyDir; AngleVectors( vehicleEyeAngles, &vBodyDir ); Vector manhackDir = pManhack->GetAbsOrigin() - vehicleEyeOrigin; VectorNormalize( manhackDir ); float angle = UTIL_VecToYaw( vBodyDir ); float angleDiff = UTIL_VecToYaw( manhackDir ); angleDiff = UTIL_AngleDiff( angleDiff, angle + yaw ); SetPoseParameter( "head_yaw", UTIL_Approach( yaw + angleDiff, yaw, 1 ) ); angle = UTIL_VecToPitch( vBodyDir ); angleDiff = UTIL_VecToPitch( manhackDir ); angleDiff = UTIL_AngleDiff( angleDiff, angle + pitch ); SetPoseParameter( "head_pitch", UTIL_Approach( pitch + angleDiff, pitch, 1 ) ); } else { // Otherwise turn the head back to its normal position SetPoseParameter( "head_yaw", UTIL_Approach( 0, yaw, 10 ) ); SetPoseParameter( "head_pitch", UTIL_Approach( 0, pitch, 10 ) ); } }
void CFlyingMonster::MoveExecute( CBaseEntity *pTargetEnt, const Vector &vecDir, float flInterval ) { if ( pev->movetype == MOVETYPE_FLY ) { if ( gpGlobals->time - m_stopTime > 1.0 ) { if ( m_IdealActivity != m_movementActivity ) { m_IdealActivity = m_movementActivity; m_flGroundSpeed = m_flightSpeed = 200; } } Vector vecMove = pev->origin + (( vecDir + (m_vecTravel * m_momentum) ).Normalize() * (m_flGroundSpeed * flInterval)); if ( m_IdealActivity != m_movementActivity ) { m_flightSpeed = UTIL_Approach( 100, m_flightSpeed, 75 * gpGlobals->frametime ); if ( m_flightSpeed < 100 ) m_stopTime = gpGlobals->time; } else m_flightSpeed = UTIL_Approach( 20, m_flightSpeed, 300 * gpGlobals->frametime ); if ( CheckLocalMove ( pev->origin, vecMove, pTargetEnt, NULL ) ) { m_vecTravel = (vecMove - pev->origin); m_vecTravel = m_vecTravel.Normalize(); UTIL_MoveToOrigin(ENT(pev), vecMove, (m_flGroundSpeed * flInterval), MOVE_STRAFE); } else { m_IdealActivity = GetStoppedActivity(); m_stopTime = gpGlobals->time; m_vecTravel = g_vecZero; } } else CBaseMonster::MoveExecute( pTargetEnt, vecDir, flInterval ); }
void CPhysMotor::Think( void ) { // angular acceleration is always positive - it should be treated as a magnitude - the controller // will apply it in the proper direction Assert(m_angularAcceleration>=0); m_motor.m_speed = UTIL_Approach( m_targetSpeed, m_motor.m_speed, m_angularAcceleration*(gpGlobals->curtime-m_lastTime) ); m_lastTime = gpGlobals->curtime; if ( m_motor.m_speed != m_targetSpeed ) { SetNextThink( gpGlobals->curtime ); } }
void CNPC_Gargantua::EyeUpdate( void ) { if ( m_pEyeGlow ) { m_pEyeGlow->SetBrightness( UTIL_Approach( m_eyeBrightness, m_pEyeGlow->GetBrightness(), 26 ), 0.5f ); if ( m_pEyeGlow->GetBrightness() == 0 ) { m_pEyeGlow->AddEffects( EF_NODRAW ); } else { m_pEyeGlow->RemoveEffects( EF_NODRAW ); } } }
void CNPC_Gargantua::EyeUpdate( void ) { if ( m_pEyeGlow ) { m_pEyeGlow->SetBrightness( UTIL_Approach( m_eyeBrightness, m_pEyeGlow->GetBrightness(), 26 ), 0.5f ); if ( m_pEyeGlow->GetBrightness() == 0 ) { m_pEyeGlow->m_fEffects |= EF_NODRAW; } else { m_pEyeGlow->m_fEffects &= ~EF_NODRAW; } } }
float CIchthyosaur :: ChangePitch( int speed ) { if ( pev->movetype == MOVETYPE_FLY ) { float diff = FlPitchDiff(); float target = 0; if ( m_IdealActivity != GetStoppedActivity() ) { if (diff < -20) target = 45; else if (diff > 20) target = -45; } pev->angles.x = UTIL_Approach(target, pev->angles.x, 220.0 * 0.1 ); } return 0; }
float CFlyingMonster :: ChangeYaw( int speed ) { if ( pev->movetype == MOVETYPE_FLY ) { float diff = FlYawDiff(); float target = 0; if ( m_IdealActivity != GetStoppedActivity() ) { if ( diff < -20 ) target = 90; else if ( diff > 20 ) target = -90; } pev->angles.z = UTIL_Approach( target, pev->angles.z, 220.0 * gpGlobals->frametime ); } return CBaseMonster::ChangeYaw( speed ); }
float CIchthyosaur::ChangeYaw( int speed ) { if ( pev->movetype == MOVETYPE_FLY ) { float diff = FlYawDiff(); float target = 0; if ( m_IdealActivity != GetStoppedActivity() ) { if ( diff < -20 ) target = 20; else if ( diff > 20 ) target = -20; } pev->angles.z = UTIL_Approach( target, pev->angles.z, 220.0 * 0.1 ); } return CFlyingMonster::ChangeYaw( speed ); }
//----------------------------------------------------------------------------- // Purpose: Aim Gun at a target //----------------------------------------------------------------------------- void CASW_PropJeep::AimGunAt( Vector *endPos, float flInterval ) { Vector aimPos = *endPos; // See if the gun should be allowed to aim if ( IsOverturned() || m_bEngineLocked || m_bHasGun == false ) { SetPoseParameter( JEEP_GUN_YAW, 0 ); SetPoseParameter( JEEP_GUN_PITCH, 0 ); SetPoseParameter( JEEP_GUN_SPIN, 0 ); return; // Make the gun go limp and look "down" Vector v_forward, v_up; AngleVectors( GetLocalAngles(), NULL, &v_forward, &v_up ); aimPos = WorldSpaceCenter() + ( v_forward * -32.0f ) - Vector( 0, 0, 128.0f ); } matrix3x4_t gunMatrix; GetAttachment( LookupAttachment("gun_ref"), gunMatrix ); // transform the enemy into gun space Vector localEnemyPosition; VectorITransform( aimPos, gunMatrix, localEnemyPosition ); // do a look at in gun space (essentially a delta-lookat) QAngle localEnemyAngles; VectorAngles( localEnemyPosition, localEnemyAngles ); // convert to +/- 180 degrees localEnemyAngles.x = UTIL_AngleDiff( localEnemyAngles.x, 0 ); localEnemyAngles.y = UTIL_AngleDiff( localEnemyAngles.y, 0 ); float targetYaw = m_aimYaw + localEnemyAngles.y; float targetPitch = m_aimPitch + localEnemyAngles.x; // Constrain our angles float newTargetYaw = clamp( targetYaw, -CANNON_MAX_LEFT_YAW, CANNON_MAX_RIGHT_YAW ); float newTargetPitch = clamp( targetPitch, -CANNON_MAX_DOWN_PITCH, CANNON_MAX_UP_PITCH ); // If the angles have been clamped, we're looking outside of our valid range if ( fabs(newTargetYaw-targetYaw) > 1e-4 || fabs(newTargetPitch-targetPitch) > 1e-4 ) { m_bUnableToFire = true; } targetYaw = newTargetYaw; targetPitch = newTargetPitch; // Exponentially approach the target float yawSpeed = 8; float pitchSpeed = 8; m_aimYaw = UTIL_Approach( targetYaw, m_aimYaw, yawSpeed ); m_aimPitch = UTIL_Approach( targetPitch, m_aimPitch, pitchSpeed ); SetPoseParameter( JEEP_GUN_YAW, -m_aimYaw); SetPoseParameter( JEEP_GUN_PITCH, -m_aimPitch ); InvalidateBoneCache(); // read back to avoid drift when hitting limits // as long as the velocity is less than the delta between the limit and 180, this is fine. m_aimPitch = -GetPoseParameter( JEEP_GUN_PITCH ); m_aimYaw = -GetPoseParameter( JEEP_GUN_YAW ); // Now draw crosshair for actual aiming point Vector vecMuzzle, vecMuzzleDir; QAngle vecMuzzleAng; GetAttachment( "Muzzle", vecMuzzle, vecMuzzleAng ); AngleVectors( vecMuzzleAng, &vecMuzzleDir ); trace_t tr; UTIL_TraceLine( vecMuzzle, vecMuzzle + (vecMuzzleDir * MAX_TRACE_LENGTH), MASK_SHOT, this, COLLISION_GROUP_NONE, &tr ); // see if we hit something, if so, adjust endPos to hit location if ( tr.fraction < 1.0 ) { m_vecGunCrosshair = vecMuzzle + ( vecMuzzleDir * MAX_TRACE_LENGTH * tr.fraction ); } }
//------------------------------------------------------------------------------ // 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 : // 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() ); } }
//----------------------------------------------------------------------------- // Purpose: Crane rotates around with +left and +right, and extends/retracts // the cable with +forward and +back. //----------------------------------------------------------------------------- void CPropCrane::DriveCrane( int iDriverButtons, int iButtonsPressed, float flNPCSteering ) { bool bWasExtending = m_bExtending; // Handle rotation of the crane if ( iDriverButtons & IN_MOVELEFT ) { // NPCs may cheat and set the steering if ( flNPCSteering ) { m_flTurn = flNPCSteering; } else { // Try adding some randomness to make it feel shaky? float flTurnAdd = m_flTurnAccel; // If we're turning back on ourselves, use decel speed if ( m_flTurn < 0 ) { flTurnAdd = MAX( flTurnAdd, m_flTurnDecel ); } m_flTurn = UTIL_Approach( m_flMaxTurnSpeed, m_flTurn, flTurnAdd * gpGlobals->frametime ); } m_iTurning = TURNING_LEFT; } else if ( iDriverButtons & IN_MOVERIGHT ) { // NPCs may cheat and set the steering if ( flNPCSteering ) { m_flTurn = flNPCSteering; } else { // Try adding some randomness to make it feel shaky? float flTurnAdd = m_flTurnAccel; // If we're turning back on ourselves, increase the rate if ( m_flTurn > 0 ) { flTurnAdd = MAX( flTurnAdd, m_flTurnDecel ); } m_flTurn = UTIL_Approach( -m_flMaxTurnSpeed, m_flTurn, flTurnAdd * gpGlobals->frametime ); } m_iTurning = TURNING_RIGHT; } else { m_flTurn = UTIL_Approach( 0, m_flTurn, m_flTurnDecel * gpGlobals->frametime ); m_iTurning = TURNING_NOT; } if ( m_hPlayer ) { float maxTurn = GetMaxTurnRate(); static float maxRumble = 0.35f; static float minRumble = 0.1f; float rumbleRange = maxRumble - minRumble; float rumble; float factor = fabs(m_flTurn) / maxTurn; factor = MIN( factor, 1.0f ); rumble = minRumble + (rumbleRange * factor); m_hPlayer->RumbleEffect( RUMBLE_FLAT_BOTH, (int)(rumble * 100), RUMBLE_FLAG_UPDATE_SCALE ); } SetLocalAngularVelocity( QAngle(0,m_flTurn * 10,0) ); // Handle extension / retraction of the arm if ( iDriverButtons & IN_FORWARD ) { m_flExtensionRate = UTIL_Approach( m_flMaxExtensionSpeed, m_flExtensionRate, m_flExtensionAccel * gpGlobals->frametime ); m_bExtending = true; } else if ( iDriverButtons & IN_BACK ) { m_flExtensionRate = UTIL_Approach( -m_flMaxExtensionSpeed, m_flExtensionRate, m_flExtensionAccel * gpGlobals->frametime ); m_bExtending = true; } else { m_flExtensionRate = UTIL_Approach( 0, m_flExtensionRate, m_flExtensionDecel * gpGlobals->frametime ); m_bExtending = false; } //Msg("Turn: %f\nExtensionRate: %f\n", m_flTurn, m_flExtensionRate ); //If we're holding down an attack button, update our state if ( iButtonsPressed & (IN_ATTACK | IN_ATTACK2) ) { // If we have something on the magnet, turn the magnet off if ( m_hCraneMagnet->GetTotalMassAttachedObjects() ) { TurnMagnetOff(); } else if ( !m_bDropping && m_flNextDropAllowedTime < gpGlobals->curtime ) { TurnMagnetOn(); // Drop the magnet till it hits something m_bDropping = true; m_hCraneMagnet->ResetHasHitSomething(); m_hCraneTip->m_pSpring->SetSpringConstant( CRANE_SPRING_CONSTANT_LOWERING ); m_ServerVehicle.PlaySound( VS_MISC1 ); } } float flSpeedPercentage = clamp( fabs(m_flTurn) / m_flMaxTurnSpeed, 0, 1 ); vbs_sound_update_t params; params.Defaults(); params.bThrottleDown = (m_iTurning != TURNING_NOT); params.flCurrentSpeedFraction = flSpeedPercentage; params.flWorldSpaceSpeed = 0; m_ServerVehicle.SoundUpdate( params ); // Play sounds for arm extension / retraction if ( m_bExtending && !bWasExtending ) { m_ServerVehicle.StopSound( VS_ENGINE2_STOP ); m_ServerVehicle.PlaySound( VS_ENGINE2_START ); } else if ( !m_bExtending && bWasExtending ) { m_ServerVehicle.StopSound( VS_ENGINE2_START ); m_ServerVehicle.PlaySound( VS_ENGINE2_STOP ); } }
//----------------------------------------------------------------------------- // Purpose: Crane rotates around with +left and +right, and extends/retracts // the cable with +forward and +back. //----------------------------------------------------------------------------- void CPropCannon::DriveCannon( int iDriverButtons, int iButtonsPressed ) { bool bWasExtending = m_bExtending; // Handle rotation of the crane if ( iDriverButtons & IN_MOVELEFT ) { // Try adding some randomness to make it feel shaky? float flTurnAdd = m_flTurnAccel; // If we're turning back on ourselves, use decel speed if ( m_flTurn < 0 ) { flTurnAdd = MAX( flTurnAdd, m_flTurnDecel ); } m_flTurn = UTIL_Approach( m_flMaxTurnSpeed, m_flTurn, flTurnAdd * gpGlobals->frametime ); m_iTurning = CANNON_TURNING_LEFT; } else if ( iDriverButtons & IN_MOVERIGHT ) { // Try adding some randomness to make it feel shaky? float flTurnAdd = m_flTurnAccel; // If we're turning back on ourselves, increase the rate if ( m_flTurn > 0 ) { flTurnAdd = MAX( flTurnAdd, m_flTurnDecel ); } m_flTurn = UTIL_Approach( -m_flMaxTurnSpeed, m_flTurn, flTurnAdd * gpGlobals->frametime ); m_iTurning = CANNON_TURNING_RIGHT; } else { m_flTurn = UTIL_Approach( 0, m_flTurn, m_flTurnDecel * gpGlobals->frametime ); m_iTurning = CANNON_TURNING_NOT; } SetLocalAngularVelocity( QAngle(0,m_flTurn * 10,0) ); // Handle extension / retraction of the arm if ( iDriverButtons & IN_FORWARD ) { m_flExtensionRate = UTIL_Approach( m_flMaxExtensionSpeed, m_flExtensionRate, m_flExtensionAccel * gpGlobals->frametime ); m_bExtending = true; } else if ( iDriverButtons & IN_BACK ) { m_flExtensionRate = UTIL_Approach( -m_flMaxExtensionSpeed, m_flExtensionRate, m_flExtensionAccel * gpGlobals->frametime ); m_bExtending = true; } else { m_flExtensionRate = UTIL_Approach( 0, m_flExtensionRate, m_flExtensionDecel * gpGlobals->frametime ); m_bExtending = false; } //Msg("Turn: %f\nExtensionRate: %f\n", m_flTurn, m_flExtensionRate ); //If we're holding down an attack button, update our state if ( iButtonsPressed & (IN_ATTACK | IN_ATTACK2) ) { if ( m_flNextAttackTime <= gpGlobals->curtime ) { LaunchProjectile(); } } float flSpeedPercentage = clamp( fabs(m_flTurn) / m_flMaxTurnSpeed, 0, 1 ); vbs_sound_update_t params; params.Defaults(); params.bThrottleDown = (m_iTurning != CANNON_TURNING_NOT); params.flCurrentSpeedFraction = flSpeedPercentage; params.flWorldSpaceSpeed = 0; m_ServerVehicle.SoundUpdate( params ); // Play sounds for arm extension / retraction if ( m_bExtending && !bWasExtending ) { m_ServerVehicle.StopSound( VS_ENGINE2_STOP ); m_ServerVehicle.PlaySound( VS_ENGINE2_START ); } else if ( !m_bExtending && bWasExtending ) { m_ServerVehicle.StopSound( VS_ENGINE2_START ); m_ServerVehicle.PlaySound( VS_ENGINE2_STOP ); } }
void CLeech::UpdateMotion( void ) { float flapspeed = (pev->speed - m_flAccelerate) / LEECH_ACCELERATE; m_flAccelerate = m_flAccelerate * 0.8 + pev->speed * 0.2; if (flapspeed < 0) flapspeed = -flapspeed; flapspeed += 1.0; if (flapspeed < 0.5) flapspeed = 0.5; if (flapspeed > 1.9) flapspeed = 1.9; pev->framerate = flapspeed; if ( !m_fPathBlocked ) pev->avelocity.y = pev->ideal_yaw; else pev->avelocity.y = pev->ideal_yaw * m_obstacle; if ( pev->avelocity.y > 150 ) m_IdealActivity = ACT_TURN_LEFT; else if ( pev->avelocity.y < -150 ) m_IdealActivity = ACT_TURN_RIGHT; else m_IdealActivity = ACT_SWIM; // lean float targetPitch, delta; delta = m_height - pev->origin.z; if ( delta < -10 ) targetPitch = -30; else if ( delta > 10 ) targetPitch = 30; else targetPitch = 0; pev->angles.x = UTIL_Approach( targetPitch, pev->angles.x, 60 * LEECH_FRAMETIME ); // bank pev->avelocity.z = - (pev->angles.z + (pev->avelocity.y * 0.25)); if ( m_MonsterState == MONSTERSTATE_COMBAT && HasConditions( bits_COND_CAN_MELEE_ATTACK1 ) ) m_IdealActivity = ACT_MELEE_ATTACK1; // Out of water check if ( !pev->waterlevel ) { pev->movetype = MOVETYPE_TOSS; m_IdealActivity = ACT_TWITCH; pev->velocity = g_vecZero; // Animation will intersect the floor if either of these is non-zero pev->angles.z = 0; pev->angles.x = 0; if ( pev->framerate < 1.0 ) pev->framerate = 1.0; } else if ( pev->movetype == MOVETYPE_TOSS ) { pev->movetype = MOVETYPE_FLY; pev->flags &= ~FL_ONGROUND; RecalculateWaterlevel(); m_waterTime = gpGlobals->time + 2; // Recalc again soon, water may be rising } if ( m_Activity != m_IdealActivity ) { SetActivity ( m_IdealActivity ); } float flInterval = StudioFrameAdvance(); DispatchAnimEvents ( flInterval ); #if DEBUG_BEAMS if ( !m_pb ) m_pb = CBeam::BeamCreate( "sprites/laserbeam.spr", 5 ); if ( !m_pt ) m_pt = CBeam::BeamCreate( "sprites/laserbeam.spr", 5 ); m_pb->PointsInit( pev->origin, pev->origin + gpGlobals->v_forward * LEECH_CHECK_DIST ); m_pt->PointsInit( pev->origin, pev->origin - gpGlobals->v_right * (pev->avelocity.y*0.25) ); if ( m_fPathBlocked ) { float color = m_obstacle * 30; if ( m_obstacle == 1.0 ) color = 0; if ( color > 255 ) color = 255; m_pb->SetColor( 255, (int)color, (int)color ); } else m_pb->SetColor( 255, 255, 0 ); m_pt->SetColor( 0, 0, 255 ); #endif }
void CWeaponGravityGun::EffectUpdate( void ) { Vector start, angles, forward, right; trace_t tr; CBasePlayer *pOwner = ToBasePlayer( GetOwner() ); if ( !pOwner ) return; m_viewModelIndex = pOwner->entindex(); // Make sure I've got a view model CBaseViewModel *vm = pOwner->GetViewModel(); if ( vm ) { m_viewModelIndex = vm->entindex(); } pOwner->EyeVectors( &forward, &right, NULL ); start = pOwner->Weapon_ShootPosition(); Vector end = start + forward * 4096; UTIL_TraceLine( start, end, MASK_SHOT, pOwner, COLLISION_GROUP_NONE, &tr ); end = tr.endpos; float distance = tr.fraction * 4096; if ( tr.fraction != 1 ) { // too close to the player, drop the object if ( distance < 36 ) { DetachObject(); return; } } if ( m_hObject == NULL && tr.DidHitNonWorldEntity() ) { CBaseEntity *pEntity = tr.m_pEnt; // inform the object what was hit ClearMultiDamage(); pEntity->DispatchTraceAttack( CTakeDamageInfo( pOwner, pOwner, 0, DMG_PHYSGUN ), forward, &tr ); ApplyMultiDamage(); AttachObject( pEntity, start, tr.endpos, distance ); m_lastYaw = pOwner->EyeAngles().y; } // Add the incremental player yaw to the target transform matrix3x4_t curMatrix, incMatrix, nextMatrix; QAngle ang(0.0f, pOwner->EyeAngles().y - m_lastYaw, 0.0f); AngleMatrix( m_gravCallback.m_targetRotation, curMatrix ); AngleMatrix( ang, incMatrix ); ConcatTransforms( incMatrix, curMatrix, nextMatrix ); MatrixAngles( nextMatrix, m_gravCallback.m_targetRotation ); m_lastYaw = pOwner->EyeAngles().y; CBaseEntity *pObject = m_hObject; if ( pObject ) { if ( m_useDown ) { if ( pOwner->m_afButtonPressed & IN_USE ) { m_useDown = false; } } else { if ( pOwner->m_afButtonPressed & IN_USE ) { m_useDown = true; } } if ( m_useDown ) { pOwner->SetPhysicsFlag( PFLAG_DIROVERRIDE, true ); if ( pOwner->m_nButtons & IN_FORWARD ) { m_distance = UTIL_Approach( 1024, m_distance, gpGlobals->frametime * 100 ); } if ( pOwner->m_nButtons & IN_BACK ) { m_distance = UTIL_Approach( 40, m_distance, gpGlobals->frametime * 100 ); } } if ( pOwner->m_nButtons & IN_WEAPON1 ) { m_distance = UTIL_Approach( 1024, m_distance, m_distance * 0.1 ); } if ( pOwner->m_nButtons & IN_WEAPON2 ) { m_distance = UTIL_Approach( 40, m_distance, m_distance * 0.1 ); } // Send the object a physics damage message (0 damage). Some objects interpret this // as something else being in control of their physics temporarily. pObject->TakeDamage( CTakeDamageInfo( this, pOwner, 0, DMG_PHYSGUN ) ); Vector newPosition = start + forward * m_distance; // 24 is a little larger than 16 * sqrt(2) (extent of player bbox) // HACKHACK: We do this so we can "ignore" the player and the object we're manipulating // If we had a filter for tracelines, we could simply filter both ents and start from "start" Vector awayfromPlayer = start + forward * 24; UTIL_TraceLine( start, awayfromPlayer, MASK_SOLID, pOwner, COLLISION_GROUP_NONE, &tr ); if ( tr.fraction == 1 ) { UTIL_TraceLine( awayfromPlayer, newPosition, MASK_SOLID, pObject, COLLISION_GROUP_NONE, &tr ); Vector dir = tr.endpos - newPosition; float distance = VectorNormalize(dir); float maxDist = m_gravCallback.m_maxVel * gpGlobals->frametime; if ( distance > maxDist ) { newPosition += dir * maxDist; } else { newPosition = tr.endpos; } } else { newPosition = tr.endpos; } CreatePelletAttraction( phys_gunglueradius.GetFloat(), pObject ); // If I'm looking more than 20 degrees away from the glue point, then give up // This lets the player "gesture" for the glue to let go. Vector pelletDir = m_gravCallback.m_worldPosition - start; VectorNormalize(pelletDir); if ( DotProduct( pelletDir, forward ) < 0.939 ) // 0.939 ~= cos(20deg) { // lose attach for 2 seconds if you're too far away m_glueTime = gpGlobals->curtime + 1; } if ( m_pelletHeld >= 0 && gpGlobals->curtime > m_glueTime ) { CGravityPellet *pPelletAttract = m_activePellets[m_pelletAttract].pellet; g_pEffects->Sparks( pPelletAttract->GetAbsOrigin() ); } m_gravCallback.SetTargetPosition( newPosition ); Vector dir = (newPosition - pObject->GetLocalOrigin()); m_movementLength = dir.Length(); } else { m_gravCallback.SetTargetPosition( end ); } if ( m_pelletHeld >= 0 && gpGlobals->curtime > m_glueTime ) { Vector worldNormal, worldPos; GetPelletWorldCoords( m_pelletAttract, &worldPos, &worldNormal ); m_gravCallback.SetAutoAlign( m_activePellets[m_pelletHeld].localNormal, m_activePellets[m_pelletHeld].pellet->GetLocalOrigin(), worldNormal, worldPos ); } else { m_gravCallback.ClearAutoAlign(); } }
void CIchthyosaur::Swim( ) { int retValue = 0; Vector start = pev->origin; Vector Angles; Vector Forward, Right, Up; if (FBitSet( pev->flags, FL_ONGROUND)) { pev->angles.x = 0; pev->angles.y += RANDOM_FLOAT( -45, 45 ); ClearBits( pev->flags, FL_ONGROUND ); Angles = Vector( -pev->angles.x, pev->angles.y, pev->angles.z ); UTIL_MakeVectorsPrivate(Angles, Forward, Right, Up); pev->velocity = Forward * 200 + Up * 200; return; } if (m_bOnAttack && m_flightSpeed < m_flMaxSpeed) { m_flightSpeed += 40; } if (m_flightSpeed < 180) { if (m_IdealActivity == ACT_RUN) SetActivity( ACT_WALK ); if (m_IdealActivity == ACT_WALK) pev->framerate = m_flightSpeed / 150.0; // ALERT( at_console, "walk %.2f\n", pev->framerate ); } else { if (m_IdealActivity == ACT_WALK) SetActivity( ACT_RUN ); if (m_IdealActivity == ACT_RUN) pev->framerate = m_flightSpeed / 150.0; // ALERT( at_console, "run %.2f\n", pev->framerate ); } /* if (!m_pBeam) { m_pBeam = CBeam::BeamCreate( "sprites/laserbeam.spr", 80 ); m_pBeam->PointEntInit( pev->origin + m_SaveVelocity, entindex( ) ); m_pBeam->SetEndAttachment( 1 ); m_pBeam->SetColor( 255, 180, 96 ); m_pBeam->SetBrightness( 192 ); } */ #define PROBE_LENGTH 150 Angles = UTIL_VecToAngles( m_SaveVelocity ); Angles.x = -Angles.x; UTIL_MakeVectorsPrivate(Angles, Forward, Right, Up); Vector f, u, l, r, d; f = DoProbe(start + PROBE_LENGTH * Forward); r = DoProbe(start + PROBE_LENGTH/3 * Forward+Right); l = DoProbe(start + PROBE_LENGTH/3 * Forward-Right); u = DoProbe(start + PROBE_LENGTH/3 * Forward+Up); d = DoProbe(start + PROBE_LENGTH/3 * Forward-Up); Vector SteeringVector = f+r+l+u+d; m_SaveVelocity = (m_SaveVelocity + SteeringVector/2).Normalize(); Angles = Vector( -pev->angles.x, pev->angles.y, pev->angles.z ); UTIL_MakeVectorsPrivate(Angles, Forward, Right, Up); // ALERT( at_console, "%f : %f\n", Angles.x, Forward.z ); float flDot = DotProduct( Forward, m_SaveVelocity ); if (flDot > 0.5) pev->velocity = m_SaveVelocity = m_SaveVelocity * m_flightSpeed; else if (flDot > 0) pev->velocity = m_SaveVelocity = m_SaveVelocity * m_flightSpeed * (flDot + 0.5); else pev->velocity = m_SaveVelocity = m_SaveVelocity * 80; // ALERT( at_console, "%.0f %.0f\n", m_flightSpeed, pev->velocity.Length() ); // ALERT( at_console, "Steer %f %f %f\n", SteeringVector.x, SteeringVector.y, SteeringVector.z ); /* m_pBeam->SetStartPos( pev->origin + pev->velocity ); m_pBeam->RelinkBeam( ); */ // ALERT( at_console, "speed %f\n", m_flightSpeed ); Angles = UTIL_VecToAngles( m_SaveVelocity ); // Smooth Pitch // if (Angles.x > 180) Angles.x = Angles.x - 360; pev->angles.x = UTIL_Approach(Angles.x, pev->angles.x, 50 * 0.1 ); if (pev->angles.x < -80) pev->angles.x = -80; if (pev->angles.x > 80) pev->angles.x = 80; // Smooth Yaw and generate Roll // float turn = 360; // ALERT( at_console, "Y %.0f %.0f\n", Angles.y, pev->angles.y ); if (fabs(Angles.y - pev->angles.y) < fabs(turn)) { turn = Angles.y - pev->angles.y; } if (fabs(Angles.y - pev->angles.y + 360) < fabs(turn)) { turn = Angles.y - pev->angles.y + 360; } if (fabs(Angles.y - pev->angles.y - 360) < fabs(turn)) { turn = Angles.y - pev->angles.y - 360; } float speed = m_flightSpeed * 0.1; // ALERT( at_console, "speed %.0f %f\n", turn, speed ); if (fabs(turn) > speed) { if (turn < 0.0) { turn = -speed; } else { turn = speed; } } pev->angles.y += turn; pev->angles.z -= turn; pev->angles.y = fmod((pev->angles.y + 360.0), 360.0); static float yaw_adj; yaw_adj = yaw_adj * 0.8 + turn; // ALERT( at_console, "yaw %f : %f\n", turn, yaw_adj ); SetBoneController( 0, -yaw_adj / 4.0 ); // Roll Smoothing // turn = 360; if (fabs(Angles.z - pev->angles.z) < fabs(turn)) { turn = Angles.z - pev->angles.z; } if (fabs(Angles.z - pev->angles.z + 360) < fabs(turn)) { turn = Angles.z - pev->angles.z + 360; } if (fabs(Angles.z - pev->angles.z - 360) < fabs(turn)) { turn = Angles.z - pev->angles.z - 360; } speed = m_flightSpeed/2 * 0.1; if (fabs(turn) < speed) { pev->angles.z += turn; } else { if (turn < 0.0) { pev->angles.z -= speed; } else { pev->angles.z += speed; } } if (pev->angles.z < -20) pev->angles.z = -20; if (pev->angles.z > 20) pev->angles.z = 20; UTIL_MakeVectorsPrivate( Vector( -Angles.x, Angles.y, Angles.z ), Forward, Right, Up); // UTIL_MoveToOrigin ( ENT(pev), pev->origin + Forward * speed, speed, MOVE_STRAFE ); }
void CASW_Broadcast_Camera::Move() { /* if ( HasSpawnFlags( SF_CAMERA_PLAYER_INTERRUPT ) ) { if ( m_hPlayer ) { CBasePlayer *pPlayer = ToBasePlayer( m_hPlayer ); if ( pPlayer ) { int buttonsChanged = m_nPlayerButtons ^ pPlayer->m_nButtons; if ( buttonsChanged && pPlayer->m_nButtons ) { Disable(); return; } m_nPlayerButtons = pPlayer->m_nButtons; } } } */ // Not moving on a path, return if (!m_pPath) return; // Subtract movement from the previous frame //m_moveDistance -= m_flSpeed * gpGlobals->frametime; m_moveDistance -= VectorNormalize(GetAbsOrigin() - m_vecLastPos); // Have we moved enough to reach the target? if ( m_moveDistance <= 0 ) { variant_t emptyVariant; m_pPath->AcceptInput( "InPass", this, this, emptyVariant, 0 ); // Time to go to the next target m_pPath = m_pPath->GetNextTarget(); // Set up next corner if ( !m_pPath ) { SetAbsVelocity( vec3_origin ); } else { if ( m_pPath->m_flSpeed != 0 ) m_targetSpeed = m_pPath->m_flSpeed; m_vecMoveDir = m_pPath->GetLocalOrigin() - GetLocalOrigin(); m_moveDistance = VectorNormalize( m_vecMoveDir ); m_flStopTime = gpGlobals->curtime + m_pPath->GetDelay(); } } if ( m_flStopTime > gpGlobals->curtime ) m_flSpeed = UTIL_Approach( 0, m_flSpeed, m_deceleration * gpGlobals->frametime ); else m_flSpeed = UTIL_Approach( m_targetSpeed, m_flSpeed, m_acceleration * gpGlobals->frametime ); float fraction = 2 * gpGlobals->frametime; SetAbsVelocity( ((m_vecMoveDir * m_flSpeed) * fraction) + (GetAbsVelocity() * (1-fraction)) ); m_vecLastPos = GetAbsOrigin(); }
void CLeech::SwimThink( void ) { TraceResult tr; float flLeftSide; float flRightSide; float targetSpeed; float targetYaw = 0; CBaseEntity *pTarget; if ( FNullEnt( FIND_CLIENT_IN_PVS( edict() ) ) ) { pev->nextthink = gpGlobals->time + RANDOM_FLOAT(1,1.5); pev->velocity = g_vecZero; return; } else pev->nextthink = gpGlobals->time + 0.1; targetSpeed = LEECH_SWIM_SPEED; if ( m_waterTime < gpGlobals->time ) RecalculateWaterlevel(); if ( m_stateTime < gpGlobals->time ) SwitchLeechState(); ClearConditions( bits_COND_CAN_MELEE_ATTACK1 ); switch( m_MonsterState ) { case MONSTERSTATE_COMBAT: pTarget = m_hEnemy; if ( !pTarget ) SwitchLeechState(); else { // Chase the enemy's eyes m_height = pTarget->pev->origin.z + pTarget->pev->view_ofs.z - 5; // Clip to viable water area if ( m_height < m_bottom ) m_height = m_bottom; else if ( m_height > m_top ) m_height = m_top; Vector location = pTarget->pev->origin - pev->origin; location.z += (pTarget->pev->view_ofs.z); if ( location.Length() < 40 ) SetConditions( bits_COND_CAN_MELEE_ATTACK1 ); // Turn towards target ent targetYaw = UTIL_VecToYaw( location ); targetYaw = UTIL_AngleDiff( targetYaw, UTIL_AngleMod( pev->angles.y ) ); if ( targetYaw < (-LEECH_TURN_RATE*0.75) ) targetYaw = (-LEECH_TURN_RATE*0.75); else if ( targetYaw > (LEECH_TURN_RATE*0.75) ) targetYaw = (LEECH_TURN_RATE*0.75); else targetSpeed *= 2; } break; default: if ( m_zTime < gpGlobals->time ) { float newHeight = RANDOM_FLOAT( m_bottom, m_top ); m_height = 0.5 * m_height + 0.5 * newHeight; m_zTime = gpGlobals->time + RANDOM_FLOAT( 1, 4 ); } if ( RANDOM_LONG( 0, 100 ) < 10 ) targetYaw = RANDOM_LONG( -30, 30 ); pTarget = NULL; // oldorigin test if ( (pev->origin - pev->oldorigin).Length() < 1 ) { // If leech didn't move, there must be something blocking it, so try to turn m_sideTime = 0; } break; } m_obstacle = ObstacleDistance( pTarget ); pev->oldorigin = pev->origin; if ( m_obstacle < 0.1 ) m_obstacle = 0.1; // is the way ahead clear? if ( m_obstacle == 1.0 ) { // if the leech is turning, stop the trend. if ( m_flTurning != 0 ) { m_flTurning = 0; } m_fPathBlocked = FALSE; pev->speed = UTIL_Approach( targetSpeed, pev->speed, LEECH_SWIM_ACCEL * LEECH_FRAMETIME ); pev->velocity = gpGlobals->v_forward * pev->speed; } else { m_obstacle = 1.0 / m_obstacle; // IF we get this far in the function, the leader's path is blocked! m_fPathBlocked = TRUE; if ( m_flTurning == 0 )// something in the way and leech is not already turning to avoid { Vector vecTest; // measure clearance on left and right to pick the best dir to turn vecTest = pev->origin + (gpGlobals->v_right * LEECH_SIZEX) + (gpGlobals->v_forward * LEECH_CHECK_DIST); UTIL_TraceLine(pev->origin, vecTest, missile, edict(), &tr); flRightSide = tr.flFraction; vecTest = pev->origin + (gpGlobals->v_right * -LEECH_SIZEX) + (gpGlobals->v_forward * LEECH_CHECK_DIST); UTIL_TraceLine(pev->origin, vecTest, missile, edict(), &tr); flLeftSide = tr.flFraction; // turn left, right or random depending on clearance ratio float delta = (flRightSide - flLeftSide); if ( delta > 0.1 || (delta > -0.1 && RANDOM_LONG(0,100)<50) ) m_flTurning = -LEECH_TURN_RATE; else m_flTurning = LEECH_TURN_RATE; } pev->speed = UTIL_Approach( -(LEECH_SWIM_SPEED*0.5), pev->speed, LEECH_SWIM_DECEL * LEECH_FRAMETIME * m_obstacle ); pev->velocity = gpGlobals->v_forward * pev->speed; } pev->ideal_yaw = m_flTurning + targetYaw; UpdateMotion(); }