void CMomentaryRotButton :: UseMoveDone( void ) { SetLocalAvelocity( g_vecZero ); // make sure our targets stop where we stopped. float flPos = GetPos( GetLocalAngles( )); UpdateTarget( flPos ); m_lastUsed = 0; if( FBitSet( pev->spawnflags, SF_MOMENTARY_ROT_BUTTON_AUTO_RETURN ) && m_returnSpeed > 0 ) { SetMoveDone( &CMomentaryRotButton::ReturnMoveDone ); m_direction = -1; if( flPos >= 1.0f ) { // disable use until button is waiting SetUse( NULL ); // delay before autoreturn. SetMoveDoneTime( m_flDelay + 0.1f ); } else SetMoveDoneTime( 0.1f ); } else { SetThink( NULL ); SetMoveDone( NULL ); } }
//----------------------------------------------------------------------------- // Purpose: MoveDone function for rotating back to the start position. //----------------------------------------------------------------------------- void CMomentaryRotButton::ReturnMoveDone( void ) { float value = GetPos( GetLocalAngles() ); if ( value <= 0 ) { // // Got back to the start, stop spinning. // SetLocalAngularVelocity( vec3_angle ); SetLocalAngles( m_start ); UpdateTarget( 0, NULL ); SetMoveDoneTime( -1 ); SetMoveDone( NULL ); SetNextThink( TICK_NEVER_THINK ); SetThink( NULL ); } else { SetLocalAngularVelocity( -m_returnSpeed * m_vecMoveAng ); SetMoveDoneTime( 0.1f ); SetThink( &CMomentaryRotButton::UpdateThink ); SetNextThink( gpGlobals->curtime + 0.01f ); } }
//------------------------------------------------------------------------------ // Purpose: MoveDone function for the SetPosition input handler. Tracks our // progress toward a movement goal and updates our outputs. //------------------------------------------------------------------------------ void CMomentaryRotButton::SetPositionMoveDone(void) { float flCurPos = GetPos( GetLocalAngles() ); if ((( flCurPos >= m_IdealYaw ) && ( m_direction == 1 )) || (( flCurPos <= m_IdealYaw ) && ( m_direction == -1 ))) { // // We reached or surpassed our movement goal. // SetLocalAngularVelocity( vec3_angle ); // BUGBUG: Won't this get the player stuck? SetLocalAngles( m_start + m_vecMoveAng * ( m_IdealYaw * m_flMoveDistance ) ); SetNextThink( TICK_NEVER_THINK ); SetMoveDoneTime( -1 ); UpdateTarget( m_IdealYaw, this ); OutputMovementComplete(); return; } // TODO: change this to use a Think function like ReturnThink. QAngle vecNewAngles = m_start + m_vecMoveAng * ( m_IdealYaw * m_flMoveDistance ); float flAngleDelta = fabs( AxisDelta( m_spawnflags, vecNewAngles, GetLocalAngles() )); float dt = flAngleDelta / m_flSpeed; if ( dt < TICK_INTERVAL ) { dt = TICK_INTERVAL; float speed = flAngleDelta / TICK_INTERVAL; SetLocalAngularVelocity( speed * m_vecMoveAng * m_direction ); } dt = clamp( dt, TICK_INTERVAL, TICK_INTERVAL * 6); SetMoveDoneTime( dt ); }
void CMomentaryRotButton :: ReturnMoveDone( void ) { float value = GetPos( GetLocalAngles() ); SetUse( &CMomentaryRotButton::ButtonUse ); if( value <= 0 ) { // Got back to the start, stop spinning. SetLocalAvelocity( g_vecZero ); SetLocalAngles( m_start ); m_iState = STATE_OFF; UpdateTarget( 0 ); SetMoveDoneTime( -1 ); SetMoveDone( NULL ); SetNextThink( -1 ); SetThink( NULL ); } else { m_iState = STATE_TURN_OFF; SetLocalAvelocity( -m_returnSpeed * pev->movedir ); SetMoveDoneTime( 0.1f ); SetThink( &CMomentaryRotButton::UpdateThink ); SetNextThink( 0.01f ); } }
//----------------------------------------------------------------------------- // 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; } } }
void CFuncRotating :: RotateFriction( void ) { // angular impulse support if( GetLocalAvelocity() != g_vecZero ) { m_iState = STATE_ON; SetMoveDoneTime( 0.1 ); RampPitchVol(); } else { STOP_SOUND( edict(), CHAN_STATIC, STRING( pev->noise3 )); SetMoveDoneTime( -1 ); m_iState = STATE_OFF; } }
void CGunTarget::Wait( void ) { CBaseEntity *pTarget = m_hTargetEnt; if ( !pTarget ) { Stop(); return; } variant_t emptyVariant; pTarget->AcceptInput( "InPass", this, this, emptyVariant, 0 ); m_flWait = pTarget->GetDelay(); m_target = pTarget->m_target; SetMoveDone( &CGunTarget::Next ); if (m_flWait != 0) {// -1 wait will wait forever! SetMoveDoneTime( m_flWait ); } else { Next();// do it RIGHT now! } }
//----------------------------------------------------------------------------- // Purpose: Handles the end of motion caused by player use. //----------------------------------------------------------------------------- void CMomentaryRotButton::UseMoveDone( void ) { SetLocalAngularVelocity( vec3_angle ); // Make sure our targets stop where we stopped. float flPos = GetPos( GetLocalAngles() ); UpdateTarget( flPos, this ); // Alert that we've been unpressed m_OnUnpressed.FireOutput( m_hActivator, this ); m_lastUsed = 0; if ( !HasSpawnFlags( SF_BUTTON_TOGGLE ) && m_returnSpeed > 0 ) { SetMoveDone( &CMomentaryRotButton::ReturnMoveDone ); m_direction = -1; // Delay before autoreturn. SetMoveDoneTime( 0.1f ); } else { SetThink( NULL ); SetMoveDone( NULL ); } }
// // SpinUp - accelerates a non-moving func_rotating up to it's speed // void CFuncRotating :: SpinUp( void ) { // calculate our new speed. float flNewSpeed = fabs( pev->speed ) + 0.2f * m_flMaxSpeed * m_flFanFriction; bool bSpinUpDone = false; if( fabs( flNewSpeed ) >= fabs( m_flTargetSpeed )) { // Reached our target speed. flNewSpeed = m_flTargetSpeed; bSpinUpDone = !m_bStopAtStartPos; } else if( m_flTargetSpeed < 0 ) { // spinning up in reverse - negate the speed. flNewSpeed *= -1; } m_iState = STATE_TURN_ON; // Apply the new speed, adjust sound pitch and volume. UpdateSpeed( flNewSpeed ); // If we've met or exceeded target speed, stop spinning up. if( bSpinUpDone ) { SetMoveDone( Rotate ); Rotate(); } SetMoveDoneTime( GetNextMoveInterval() ); }
//----------------------------------------------------------------------------- // Purpose: Calculate m_vecVelocity and m_flNextThink to reach vecDest from // GetOrigin() traveling at flSpeed. // Input : Vector vecDest - // flSpeed - //----------------------------------------------------------------------------- void CBaseToggle::LinearMove( const Vector &vecDest, float flSpeed ) { ASSERTSZ(flSpeed != 0, "LinearMove: no speed is defined!"); m_vecFinalDest = vecDest; m_movementType = MOVE_TOGGLE_LINEAR; // Already there? if (vecDest == GetLocalOrigin()) { MoveDone(); return; } // set destdelta to the vector needed to move Vector vecDestDelta = vecDest - GetLocalOrigin(); // divide vector length by speed to get time to reach dest float flTravelTime = vecDestDelta.Length() / flSpeed; // set m_flNextThink to trigger a call to LinearMoveDone when dest is reached SetMoveDoneTime( flTravelTime ); // scale the destdelta vector by the time spent traveling to get velocity SetLocalVelocity( vecDestDelta / flTravelTime ); }
//----------------------------------------------------------------------------- // Purpose: Think function. Accelerates a func_rotating to a higher angular velocity. //----------------------------------------------------------------------------- void CFuncRotating::SpinUpMove( void ) { // // Calculate our new speed. // bool bSpinUpDone = false; float flNewSpeed = fabs( m_flSpeed ) + 0.2 * m_flMaxSpeed * m_flFanFriction; if ( fabs( flNewSpeed ) >= fabs( m_flTargetSpeed ) ) { // Reached our target speed. flNewSpeed = m_flTargetSpeed; bSpinUpDone = !m_bStopAtStartPos; } else if ( m_flTargetSpeed < 0 ) { // Spinning up in reverse - negate the speed. flNewSpeed *= -1; } // // Apply the new speed, adjust sound pitch and volume. // UpdateSpeed( flNewSpeed ); // // If we've met or exceeded target speed, stop spinning up. // if ( bSpinUpDone ) { SetMoveDone( &CFuncRotating::RotateMove ); RotateMove(); } SetMoveDoneTime( GetNextMoveInterval() ); }
//----------------------------------------------------------------------------- // Purpose: Sets a new angular velocity to achieve. // Input : flSpeed - Target angular velocity in degrees per second. //----------------------------------------------------------------------------- void CFuncRotating::SetTargetSpeed( float flSpeed ) { // // Make sure the sign is correct - positive for forward rotation, // negative for reverse rotation. // flSpeed = fabs( flSpeed ); if ( m_bReversed ) { flSpeed *= -1; } m_flTargetSpeed = flSpeed; // // If we don't accelerate, change to the new speed instantly. // if ( !HasSpawnFlags(SF_BRUSH_ACCDCC ) ) { UpdateSpeed( m_flTargetSpeed ); SetMoveDone( &CFuncRotating::RotateMove ); } // // Otherwise deal with acceleration/deceleration: // else { // // Check for reversing directions. // if ((( m_flSpeed > 0 ) && ( m_flTargetSpeed < 0 )) || (( m_flSpeed < 0 ) && ( m_flTargetSpeed > 0 ))) { SetMoveDone( &CFuncRotating::ReverseMove ); } // // If we are below the new target speed, spin up to the target speed. // else if ( fabs( m_flSpeed ) < fabs( m_flTargetSpeed ) ) { SetMoveDone( &CFuncRotating::SpinUpMove ); } // // If we are above the new target speed, spin down to the target speed. // else if ( fabs( m_flSpeed ) > fabs( m_flTargetSpeed ) ) { SetMoveDone( &CFuncRotating::SpinDownMove ); } // // We are already at the new target speed. Just keep rotating. // else { SetMoveDone( &CFuncRotating::RotateMove ); } } SetMoveDoneTime( GetNextMoveInterval() ); }
void CMomentaryRotButton :: UpdateSelf( float value, bool bPlaySound ) { // set our move clock to 0.1 seconds in the future so we stop spinning unless we are // used again before then. SetMoveDoneTime( 0.1 ); if( m_direction > 0 && value >= 1.0 ) { // if we hit the end, zero our avelocity and snap to the end angles. SetLocalAvelocity( g_vecZero ); SetLocalAngles( m_end ); m_iState = STATE_ON; return; } else if( m_direction < 0 && value <= 0 ) { // if we returned to the start, zero our avelocity and snap to the start angles. SetLocalAvelocity( g_vecZero ); SetLocalAngles( m_start ); m_iState = STATE_OFF; return; } // i'm "in use" player turn me :-) m_iState = STATE_IN_USE; if( bPlaySound ) PlaySound(); SetLocalAvelocity(( m_direction * pev->speed ) * pev->movedir ); SetMoveDone( &CMomentaryRotButton::UseMoveDone ); }
//----------------------------------------------------------------------------- // Purpose: Calculate m_vecVelocity and m_flNextThink to reach vecDest from // GetLocalOrigin() traveling at flSpeed. Just like LinearMove, but rotational. // Input : vecDestAngle - // flSpeed - //----------------------------------------------------------------------------- void CBaseToggle::AngularMove( const QAngle &vecDestAngle, float flSpeed ) { ASSERTSZ(flSpeed != 0, "AngularMove: no speed is defined!"); m_vecFinalAngle = vecDestAngle; m_movementType = MOVE_TOGGLE_ANGULAR; // Already there? if (vecDestAngle == GetLocalAngles()) { MoveDone(); return; } // set destdelta to the vector needed to move QAngle vecDestDelta = vecDestAngle - GetLocalAngles(); // divide by speed to get time to reach dest float flTravelTime = vecDestDelta.Length() / flSpeed; const float MinTravelTime = 0.01f; if ( flTravelTime < MinTravelTime ) { // If we only travel for a short time, we can fail WillSimulateGamePhysics() flTravelTime = MinTravelTime; flSpeed = vecDestDelta.Length() / flTravelTime; } // set m_flNextThink to trigger a call to AngularMoveDone when dest is reached SetMoveDoneTime( flTravelTime ); // scale the destdelta vector by the time spent traveling to get velocity SetLocalAngularVelocity( vecDestDelta * (1.0 / flTravelTime) ); }
//----------------------------------------------------------------------------- // Purpose: Unlocks the button, making it able to be pressed again. //----------------------------------------------------------------------------- void CMomentaryRotButton::Unlock() { BaseClass::Unlock(); SetMoveDone( &CMomentaryRotButton::ReturnMoveDone ); // Delay before autoreturn. SetMoveDoneTime( 0.1f ); }
//----------------------------------------------------------------------------- // Purpose: Locks the button. If locked, the button will play the locked sound // when the player tries to use it. //----------------------------------------------------------------------------- void CMomentaryRotButton::Lock() { BaseClass::Lock(); SetLocalAngularVelocity( vec3_angle ); SetMoveDoneTime( -1 ); SetMoveDone( NULL ); SetNextThink( TICK_NEVER_THINK ); SetThink( NULL ); }
void CMomentaryRotButton :: SetPosition( float value ) { pev->ideal_yaw = bound( 0.0f, value, 1 ); float flCurPos = GetPos( GetLocalAngles( )); if( flCurPos < pev->ideal_yaw ) { // moving forward (from start to end). SetLocalAvelocity( pev->speed * pev->movedir ); m_direction = 1; } else if( flCurPos > pev->ideal_yaw ) { // moving backward (from end to start). SetLocalAvelocity( -pev->speed * pev->movedir ); m_direction = -1; } else { // we're there already; nothing to do. SetLocalAvelocity( g_vecZero ); return; } // g-cont. to avoid moving by user in back direction if( FBitSet( pev->spawnflags, SF_MOMENTARY_ROT_BUTTON_AUTO_RETURN ) && m_returnSpeed > 0 ) m_lastUsed = 1; // play sound on set new pos PlaySound(); SetMoveDone( &CMomentaryRotButton::SetPositionMoveDone ); SetThink( &CMomentaryRotButton::UpdateThink ); SetNextThink( 0 ); // Think again in 0.1 seconds or the time that it will take us to reach our movement goal, // whichever is the shorter interval. This prevents us from overshooting and stuttering when we // are told to change position in very small increments. Vector vecNewAngles = m_start + pev->movedir * ( pev->ideal_yaw * m_flMoveDistance ); float flAngleDelta = fabs( AxisDelta( pev->spawnflags, vecNewAngles, GetLocalAngles( ))); float dt = flAngleDelta / pev->speed; if( dt < gpGlobals->frametime ) { dt = gpGlobals->frametime; float speed = flAngleDelta / gpGlobals->frametime; SetLocalAvelocity( speed * pev->movedir * m_direction ); } dt = bound( gpGlobals->frametime, dt, gpGlobals->frametime * 6 ); SetMoveDoneTime( dt ); }
void CFuncRotating :: Rotate( void ) { // NOTE: only full speed moving set state to "On" if( fabs( pev->speed ) == fabs( m_flMaxSpeed )) m_iState = STATE_ON; SetMoveDoneTime( 0.1f ); if( m_bStopAtStartPos ) { SetMoveDoneTime( GetNextMoveInterval() ); int checkAxis = 2; // see if we got close to the starting orientation if( pev->movedir[0] != 0 ) { checkAxis = 0; } else if( pev->movedir[1] != 0 ) { checkAxis = 1; } float angDelta = anglemod( GetLocalAngles()[checkAxis] - m_angStart[checkAxis] ); if( angDelta > 180.0f ) angDelta -= 360.0f; Vector avel = GetLocalAvelocity(); // delta per tick Vector avelpertick = avel * gpGlobals->frametime; if( fabs( angDelta ) < fabs( avelpertick[checkAxis] )) { SetTargetSpeed( 0 ); SetLocalAngles( m_angStart ); m_bStopAtStartPos = false; } } }
//----------------------------------------------------------------------------- // Purpose: Think function for reversing directions. Spins down to zero, then // starts spinning up to the target speed. //----------------------------------------------------------------------------- void CFuncRotating::ReverseMove( void ) { if ( SpinDown( 0 ) ) { // We've reached zero - spin back up to the target speed. SetTargetSpeed( m_flTargetSpeed ); } else { SetMoveDoneTime( GetNextMoveInterval() ); } }
void CBaseMoveBehavior::Activate( void ) { BaseClass::Activate(); SetMoveDoneTime( 0.5 ); // start moving in 0.2 seconds time // if we are just the basic keyframed entity, cycle our animation if ( !stricmp(GetClassname(), "move_keyframed") ) { StartMoving( 1 ); } }
void CFuncRotating::SetTargetSpeed( float flSpeed ) { if( flSpeed == 0.0f && FBitSet( pev->spawnflags, SF_ROTATING_STOP_AT_START_POS )) m_bStopAtStartPos = true; // make sure the sign is correct - positive for forward rotation, // negative for reverse rotation. flSpeed = fabs( flSpeed ); if( pev->impulse ) { flSpeed *= -1; } m_flTargetSpeed = flSpeed; pev->friction = 0.0f; // clear impulse friction // If we don't accelerate, change to the new speed instantly. if( !FBitSet( pev->spawnflags, SF_ROTATING_ACCDCC )) { UpdateSpeed( m_flTargetSpeed ); SetMoveDone( Rotate ); } else { // Otherwise deal with acceleration/deceleration: if((( pev->speed > 0 ) && ( m_flTargetSpeed < 0 )) || (( pev->speed < 0 ) && ( m_flTargetSpeed > 0 ))) { // check for reversing directions. SetMoveDone( ReverseMove ); } else if( fabs( pev->speed ) < fabs( m_flTargetSpeed )) { // If we are below the new target speed, spin up to the target speed. SetMoveDone( SpinUp ); } else if( fabs( pev->speed ) > fabs( m_flTargetSpeed )) { // If we are above the new target speed, spin down to the target speed. SetMoveDone( SpinDown ); } else { // we are already at the new target speed. Just keep rotating. SetMoveDone( Rotate ); } } SetMoveDoneTime( GetNextMoveInterval() ); }
//----------------------------------------------------------------------------- // Purpose: Think function. Decelerates a func_rotating to a lower angular velocity. //----------------------------------------------------------------------------- void CFuncRotating::SpinDownMove( void ) { // // If we've met or exceeded target speed, stop spinning down. // if ( SpinDown( m_flTargetSpeed ) ) { SetMoveDone( &CFuncRotating::RotateMove ); RotateMove(); } else { SetMoveDoneTime( GetNextMoveInterval() ); } }
// // SpinDown - decelerates a moving func_rotating to a standstill. // void CFuncRotating :: SpinDown( void ) { // If we've met or exceeded target speed, stop spinning down. if( SpinDown( m_flTargetSpeed )) { if( m_iState != STATE_OFF ) { SetMoveDone( Rotate ); Rotate(); } } else { SetMoveDoneTime( GetNextMoveInterval() ); } }
//------------------------------------------------------------------------------ // Purpose : // Input : flPosition //------------------------------------------------------------------------------ void CMomentaryRotButton::InputSetPosition( inputdata_t &inputdata ) { m_IdealYaw = clamp( inputdata.value.Float(), 0, 1 ); float flCurPos = GetPos( GetLocalAngles() ); if ( flCurPos < m_IdealYaw ) { // Moving forward (from start to end). SetLocalAngularVelocity( m_flSpeed * m_vecMoveAng ); m_direction = 1; } else if ( flCurPos > m_IdealYaw ) { // Moving backward (from end to start). SetLocalAngularVelocity( -m_flSpeed * m_vecMoveAng ); m_direction = -1; } else { // We're there already; nothing to do. SetLocalAngularVelocity( vec3_angle ); return; } SetMoveDone( &CMomentaryRotButton::SetPositionMoveDone ); SetThink( &CMomentaryRotButton::UpdateThink ); SetNextThink( gpGlobals->curtime ); // // Think again in 0.1 seconds or the time that it will take us to reach our movement goal, // whichever is the shorter interval. This prevents us from overshooting and stuttering when we // are told to change position in very small increments. // QAngle vecNewAngles = m_start + m_vecMoveAng * ( m_IdealYaw * m_flMoveDistance ); float flAngleDelta = fabs( AxisDelta( m_spawnflags, vecNewAngles, GetLocalAngles() )); float dt = flAngleDelta / m_flSpeed; if ( dt < TICK_INTERVAL ) { dt = TICK_INTERVAL; float speed = flAngleDelta / TICK_INTERVAL; SetLocalAngularVelocity( speed * m_vecMoveAng * m_direction ); } dt = clamp( dt, TICK_INTERVAL, TICK_INTERVAL * 6); SetMoveDoneTime( dt ); }
//----------------------------------------------------------------------------- // Purpose: The door has reached the "up" position. Either go back down, or // wait for another activation. //----------------------------------------------------------------------------- void CBaseDoor::DoorHitTop( void ) { if ( !HasSpawnFlags( SF_DOOR_SILENT ) ) { CPASAttenuationFilter filter( this ); filter.MakeReliable(); StopMovingSound(); EmitSound_t ep; ep.m_nChannel = CHAN_STATIC; ep.m_pSoundName = (char*)STRING(m_NoiseArrived); ep.m_flVolume = 1; ep.m_SoundLevel = SNDLVL_NORM; EmitSound( filter, entindex(), ep ); } ASSERT(m_toggle_state == TS_GOING_UP); m_toggle_state = TS_AT_TOP; // toggle-doors don't come down automatically, they wait for refire. if (HasSpawnFlags( SF_DOOR_NO_AUTO_RETURN)) { // Re-instate touch method, movement is complete SetTouch( &CBaseDoor::DoorTouch ); } else { // In flWait seconds, DoorGoDown will fire, unless wait is -1, then door stays open SetMoveDoneTime( m_flWait ); SetMoveDone( &CBaseDoor::DoorGoDown ); if ( m_flWait == -1 ) { SetNextThink( TICK_NEVER_THINK ); } } if (HasSpawnFlags(SF_DOOR_START_OPEN_OBSOLETE) ) { m_OnFullyClosed.FireOutput(this, this); } else { m_OnFullyOpen.FireOutput(this, this); } }
void CFuncRotating :: Precache( void ) { // set up fan sounds if( !FStringNull( pev->message )) { // if a path is set for a wave, use it pev->noise3 = UTIL_PrecacheSound( STRING( pev->message )); } else { int m_sound = UTIL_LoadSoundPreset( m_sounds ); // otherwise use preset sound switch( m_sound ) { case 1: pev->noise3 = UTIL_PrecacheSound( "fans/fan1.wav" ); break; case 2: pev->noise3 = UTIL_PrecacheSound( "fans/fan2.wav" ); break; case 3: pev->noise3 = UTIL_PrecacheSound( "fans/fan3.wav" ); break; case 4: pev->noise3 = UTIL_PrecacheSound( "fans/fan4.wav" ); break; case 5: pev->noise3 = UTIL_PrecacheSound( "fans/fan5.wav" ); break; case 0: pev->noise3 = UTIL_PrecacheSound( "common/null.wav" ); break; default: pev->noise3 = UTIL_PrecacheSound( m_sound ); break; } } if( GetLocalAvelocity() != g_vecZero && !pev->friction ) { // if fan was spinning, and we went through transition or save/restore, // make sure we restart the sound. 1.5 sec delay is magic number. KDB SetMoveDone( SpinUp ); SetMoveDoneTime( 0.2 ); } }
void CPendulum :: Swing( void ) { float delta, dt; delta = CBaseToggle::AxisDelta( pev->spawnflags, GetLocalAngles(), m_center ); dt = gpGlobals->time - m_time; // how much time has passed? m_time = gpGlobals->time; // remember the last time called // integrate velocity if( delta > 0 && m_accel > 0 ) pev->speed -= m_accel * dt; else pev->speed += m_accel * dt; pev->speed = bound( -m_maxSpeed, pev->speed, m_maxSpeed ); m_iState = STATE_ON; // scale the destdelta vector by the time spent traveling to get velocity SetLocalAvelocity( pev->speed * pev->movedir ); // call this again SetNextThink( 0.1f ); SetMoveDoneTime( 0.1f ); if( m_damp ) { m_dampSpeed -= m_damp * m_dampSpeed * dt; if( m_dampSpeed < 30.0 ) { SetLocalAngles( m_center ); pev->speed = 0; SetThink( NULL ); SetLocalAvelocity( g_vecZero ); m_iState = STATE_OFF; } else if( pev->speed > m_dampSpeed ) { pev->speed = m_dampSpeed; } else if( pev->speed < -m_dampSpeed ) { pev->speed = -m_dampSpeed; } } }
void CBaseDoor::DoorHitTop( void ) { if( !FBitSet( pev->spawnflags, SF_DOOR_SILENT )) { STOP_SOUND( edict(), CHAN_STATIC, STRING( pev->noise1 )); EMIT_SOUND( edict(), CHAN_STATIC, STRING( pev->noise2 ), 1, ATTN_NORM ); } ASSERT( m_iState == STATE_TURN_ON ); m_iState = STATE_ON; // toggle-doors don't come down automatically, they wait for refire. if( FBitSet( pev->spawnflags, SF_DOOR_NO_AUTO_RETURN )) { // re-instate touch method, movement is complete if( !FBitSet( pev->spawnflags, SF_DOOR_USE_ONLY )) SetTouch( DoorTouch ); } else { // in flWait seconds, DoorGoDown will fire, unless wait is -1, then door stays open SetMoveDoneTime( m_flWait ); SetMoveDone( DoorGoDown ); if( m_flWait == -1 ) { SetNextThink( -1 ); } } // fire the close target (if startopen is set, then "top" is closed) - netname is the close target if( FBitSet( pev->spawnflags, SF_DOOR_START_OPEN )) { UTIL_FireTargets( pev->netname, m_hActivator, this, USE_TOGGLE, 0 ); } else { UTIL_FireTargets( pev->message, m_hActivator, this, USE_TOGGLE, 0 ); } if( FBitSet( pev->spawnflags, SF_DOOR_ONOFF_MODE )) SUB_UseTargets( m_hActivator, USE_OFF, 0 ); else SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); // this isn't finished }
//----------------------------------------------------------------------------- // Purpose: stops the object from moving // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- void CBaseMoveBehavior::StopMoving( void ) { // remember exactly where we are in the frame m_flTimeIntoFrame = 0; if ( m_iDirection == 1 ) { // record the time if we're not at the end of the frame if ( GetLocalTime() < m_flAnimEndTime ) { m_flTimeIntoFrame = GetLocalTime() - m_flAnimStartTime; } else { // we're actually at the end if ( m_pTargetKeyFrame ) { m_pCurrentKeyFrame = m_pTargetKeyFrame; } } } else if ( m_iDirection == -1 ) { // store it only as a forward movement m_pCurrentKeyFrame = m_pTargetKeyFrame; if ( GetLocalTime() < m_flAnimEndTime ) { m_flTimeIntoFrame = m_flAnimEndTime - GetLocalTime(); } } // stop moving totally SetMoveDoneTime( -1 ); m_iDirection = 0; m_flAnimStartTime = 0; m_flAnimEndTime = 0; m_pTargetKeyFrame = NULL; SetAbsVelocity(vec3_origin); SetLocalAngularVelocity( vec3_angle ); }
//----------------------------------------------------------------------------- // Purpose: Handles changing direction at the extremes of our range of motion // and updating our avelocity while being used by the player. // Input : value - Number from 0 to 1 indicating our desired position within // our range of motion, 0 = start, 1 = end. //----------------------------------------------------------------------------- void CMomentaryRotButton::UpdateSelf( float value, bool bPlaySound ) { // // Set our move clock to 0.1 seconds in the future so we stop spinning unless we are // used again before then. // SetMoveDoneTime( 0.1 ); // // If we hit the end, zero our avelocity and snap to the end angles. // if ( m_direction > 0 && value >= 1.0 ) { SetLocalAngularVelocity( vec3_angle ); SetLocalAngles( m_end ); m_OnFullyClosed.FireOutput(this, this); return; } // // If we returned to the start, zero our avelocity and snap to the start angles. // else if ( m_direction < 0 && value <= 0 ) { SetLocalAngularVelocity( vec3_angle ); SetLocalAngles( m_start ); m_OnFullyOpen.FireOutput(this, this); return; } if ( bPlaySound ) { PlaySound(); } SetLocalAngularVelocity( ( m_direction * m_flSpeed ) * m_vecMoveAng ); SetMoveDone( &CMomentaryRotButton::UseMoveDone ); }