//----------------------------------------------------------------------------- // 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 ); } }
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: 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 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() ); }
void CMomentaryDoor::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { if ( useType != USE_SET ) // Momentary buttons will pass down a float in here return; if ( value > 1.0 ) value = 1.0; if ( value < 0.0 ) value = 0.0; Vector move = m_vecPosition1 + (value * (m_vecPosition2 - m_vecPosition1)); Vector delta = move - pev->origin; //float speed = delta.Length() * 10; float speed = delta.Length() / 0.1; // move there in 0.1 sec if ( speed == 0 ) return; // This entity only thinks when it moves, so if it's thinking, it's in the process of moving // play the sound when it starts moving (not yet thinking) if ( pev->nextthink < pev->ltime || pev->nextthink == 0 ) EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving), 1, ATTN_NORM); // If we already moving to designated point, return else if (move == m_vecFinalDest) return; SetMoveDone( &CMomentaryDoor::DoorMoveDone ); LinearMove( move, speed ); }
//----------------------------------------------------------------------------- // Purpose: Starts the door going to its "down" position (simply ToggleData->vecPosition1). //----------------------------------------------------------------------------- void CBaseDoor::DoorGoDown( void ) { if ( !HasSpawnFlags( SF_DOOR_SILENT ) ) { // If we're not moving already, start the moving noise if ( m_toggle_state != TS_GOING_UP && m_toggle_state != TS_GOING_DOWN ) { StartMovingSound(); } } #ifdef DOOR_ASSERT ASSERT(m_toggle_state == TS_AT_TOP); #endif // DOOR_ASSERT m_toggle_state = TS_GOING_DOWN; SetMoveDone( &CBaseDoor::DoorHitBottom ); if ( IsRotatingDoor() )//rotating door AngularMove( m_vecAngle1, m_flSpeed); else LinearMove( m_vecPosition1, m_flSpeed); //Fire our closed output m_OnClose.FireOutput( this, this ); }
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: 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() ); }
// // 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() ); }
void CBaseButton :: ButtonActivate( void ) { EMIT_SOUND( edict(), CHAN_VOICE, STRING( pev->noise ), 1, ATTN_NORM ); if( IsLockedByMaster( )) { // button is locked, play locked sound PlayLockSounds( pev, &m_ls, TRUE, TRUE ); return; } else { // button is unlocked, play unlocked sound PlayLockSounds( pev, &m_ls, FALSE, TRUE ); } ASSERT( m_iState == STATE_OFF ); m_iState = STATE_TURN_ON; if( pev->spawnflags & SF_BUTTON_DONTMOVE ) { TriggerAndWait(); } else { SetMoveDone( &CBaseButton::TriggerAndWait ); if( !m_fRotating ) LinearMove( m_vecPosition2, pev->speed ); else AngularMove( m_vecAngle2, pev->speed ); } }
// // Starts the door going to its "up" position (simply ToggleData->vecPosition2). // void CBaseTrainDoor::DoorGoUp( void ) { // It could be going-down, if blocked. ASSERT( door_state == TD_CLOSED ); door_state = TD_SHIFT_UP; UTIL_MakeVectors( m_vecOldAngles ); STOP_SOUND( edict(), CHAN_STATIC, STRING( pev->noise1 )); EMIT_SOUND( edict(), CHAN_STATIC, STRING( pev->noise2 ), 1, ATTN_NORM ); // Subtract 2 from size because the engine expands bboxes by 1 in all directions making the size too big Vector vecSize = pev->size - Vector( 2, 2, 2 ); float depth = (fabs( gpGlobals->v_right.x * vecSize.x ) + fabs( gpGlobals->v_right.y * vecSize.y ) + fabs( gpGlobals->v_right.z * vecSize.z ) - m_flLip); if( pev->spawnflags & SF_TRAINDOOR_INVERSE ) depth = -depth; VectorMatrix( pev->movedir, gpGlobals->v_right, gpGlobals->v_up ); m_vecPosition3 = m_vecPosition1 + gpGlobals->v_right * -depth; SetMoveDone( &CBaseTrainDoor:: DoorSlideWait ); LinearMove( m_vecPosition3, pev->speed ); }
// // Starts the button moving "in/up". // void CBaseButton::ButtonActivate() { EMIT_SOUND(ENT(pev), CHAN_VOICE, (char *)STRING(pev->noise), 1, ATTN_NORM); if(!UTIL_IsMasterTriggered(m_sMaster, m_hActivator)) { // button is locked, play locked sound PlayLockSounds(pev, &m_ls, TRUE, TRUE); return; } else { // button is unlocked, play unlocked sound PlayLockSounds(pev, &m_ls, FALSE, TRUE); } ASSERT(m_toggle_state == TS_AT_BOTTOM); m_toggle_state = TS_GOING_UP; SetMoveDone(&CBaseButton::TriggerAndWait); if(!m_fRotating) LinearMove(m_vecPosition2, pev->speed); else AngularMove(m_vecAngle2, pev->speed); }
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 ); } }
/* <697ad> ../cstrike/dlls/doors.cpp:762 */ void CBaseDoor::DoorGoDown(void) { bool isReversing = (m_toggle_state == TS_GOING_UP); if (!isReversing) { if (!(pev->spawnflags & SF_DOOR_SILENT)) { if (m_toggle_state != TS_GOING_UP && m_toggle_state != TS_GOING_DOWN) { EMIT_SOUND(ENT(pev), CHAN_STATIC, (char *)STRING(pev->noiseMoving), VOL_NORM, ATTN_NORM); } TheBots->OnEvent(EVENT_DOOR, m_hActivator); } } #ifdef DOOR_ASSERT assert(m_toggle_state == TS_AT_TOP); #endif // DOOR_ASSERT m_toggle_state = TS_GOING_DOWN; SetMoveDone(&CBaseDoor::DoorHitBottom); //rotating door if (FClassnameIs(pev, "func_door_rotating")) { AngularMove(m_vecAngle1, pev->speed); } else LinearMove(m_vecPosition1, pev->speed); }
//----------------------------------------------------------------------------- // 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 ); } }
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 ); }
// // Train next - path corner needs to change to next target // void CFuncTrain::Next( void ) { CBaseEntity *pTarg; // now find our next target //TODO: this entity is supposed to work with path_corner only. Other entities will work, but will probably misbehave. - Solokiller //Check for classname and ignore others? pTarg = GetNextTarget(); if( !pTarg ) { if( pev->noiseMovement ) STOP_SOUND( this, CHAN_STATIC, ( char* ) STRING( pev->noiseMovement ) ); // Play stop sound if( pev->noiseStopMoving ) EMIT_SOUND( this, CHAN_VOICE, ( char* ) STRING( pev->noiseStopMoving ), m_volume, ATTN_NORM ); return; } // Save last target in case we need to find it again pev->message = pev->target; pev->target = pTarg->pev->target; m_flWait = pTarg->GetDelay(); if( m_pevCurrentTarget && m_pevCurrentTarget->speed != 0 ) {// don't copy speed from target if it is 0 (uninitialized) pev->speed = m_pevCurrentTarget->speed; ALERT( at_aiconsole, "Train %s speed to %4.2f\n", GetTargetname(), pev->speed ); } m_pevCurrentTarget = pTarg->pev;// keep track of this since path corners change our target for us. pev->enemy = pTarg->edict();//hack if( FBitSet( m_pevCurrentTarget->spawnflags, SF_CORNER_TELEPORT ) ) { // Path corner has indicated a teleport to the next corner. SetBits( pev->effects, EF_NOINTERP ); SetAbsOrigin( pTarg->GetAbsOrigin() - ( pev->mins + pev->maxs )* 0.5 ); Wait(); // Get on with doing the next path corner. } else { // Normal linear move. // CHANGED this from CHAN_VOICE to CHAN_STATIC around OEM beta time because trains should // use CHAN_STATIC for their movement sounds to prevent sound field problems. // this is not a hack or temporary fix, this is how things should be. (sjb). if( pev->noiseMovement ) { STOP_SOUND( this, CHAN_STATIC, ( char* ) STRING( pev->noiseMovement ) ); EMIT_SOUND( this, CHAN_STATIC, ( char* ) STRING( pev->noiseMovement ), m_volume, ATTN_NORM ); } ClearBits( pev->effects, EF_NOINTERP ); SetMoveDone( &CFuncTrain::Wait ); LinearMove( pTarg->GetAbsOrigin() - ( pev->mins + pev->maxs )* 0.5, pev->speed ); } }
// // Starts the door going to its "down" position (simply ToggleData->vecPosition1). // void CBaseTrainDoor :: DoorGoDown( void ) { ASSERT( door_state == TD_SLIDING_DOWN ); door_state = TD_SHIFT_DOWN; SetMoveDone( &CBaseTrainDoor:: DoorHitBottom ); LinearMove( m_vecPosition1, pev->speed ); }
//----------------------------------------------------------------------------- // 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 ); }
// // Starts the door going to its "up" position (simply ToggleData->vecPosition2). // void CBaseDoor::DoorGoUp( void ) { entvars_t *pevActivator; // It could be going-down, if blocked. ASSERT(m_toggle_state == TS_AT_BOTTOM || m_toggle_state == TS_GOING_DOWN); // emit door moving and stop sounds on CHAN_STATIC so that the multicast doesn't // filter them out and leave a client stuck with looping door sounds! if ( !FBitSet( pev->spawnflags, SF_DOOR_SILENT ) ) EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving), 1, ATTN_NORM); // ALERT(at_debug, "%s go up (was %d)\n", STRING(pev->targetname), m_toggle_state); m_toggle_state = TS_GOING_UP; SetMoveDone(&CBaseDoor:: DoorHitTop ); // LRC- if synched, we fire as soon as we start to go up if (m_iImmediateMode) { if (m_iOnOffMode) SUB_UseTargets( m_hActivator, USE_ON, 0 ); else SUB_UseTargets( m_hActivator, USE_TOGGLE, 0 ); } if ( FClassnameIs(pev, "func_door_rotating")) // !!! BUGBUG Triggered doors don't work with this yet { float sign = 1.0; if ( m_hActivator != NULL ) { pevActivator = m_hActivator->pev; if ( !FBitSet( pev->spawnflags, SF_DOOR_ONEWAY ) && pev->movedir.y ) // Y axis rotation, move away from the player { Vector vec = pevActivator->origin - pev->origin; Vector angles = pevActivator->angles; angles.x = 0; angles.z = 0; UTIL_MakeVectors (angles); // Vector vnext = (pevToucher->origin + (pevToucher->velocity * 10)) - pev->origin; UTIL_MakeVectors ( pevActivator->angles ); Vector vnext = (pevActivator->origin + (gpGlobals->v_forward * 10)) - pev->origin; if ( (vec.x*vnext.y - vec.y*vnext.x) < 0 ) sign = -1.0; } } AngularMove(m_vecAngle2*sign, pev->speed); } else if(m_iSpeedMode==1){ //AJH modifed to allow two types of accelerating doors LinearMove(m_vecPosition2, pev->speed); }else{ LinearMove(m_vecPosition2, pev->speed, m_fAcceleration, m_fDeceleration); } }
void CBaseTrainDoor :: DoorSlideDown( void ) { EMIT_SOUND( edict(), CHAN_STATIC, STRING( pev->noise1 ), 1, ATTN_NORM ); ASSERT( door_state == TD_OPENED ); door_state = TD_SLIDING_DOWN; SetMoveDone( &CBaseTrainDoor:: DoorSlideWait ); LinearMove( m_vecPosition3, pev->speed ); }
// // Platform is at top, now starts moving down. // void CFuncPlat::GoDown( void ) { if( pev->noiseMovement ) EMIT_SOUND( ENT( pev ), CHAN_STATIC, ( char* ) STRING( pev->noiseMovement ), m_volume, ATTN_NORM ); ASSERT( m_toggle_state == TS_AT_TOP || m_toggle_state == TS_GOING_UP ); m_toggle_state = TS_GOING_DOWN; SetMoveDone( &CFuncPlat::CallHitBottom ); LinearMove( m_vecPosition2, pev->speed ); }
// // Platform is at bottom, now starts moving up // void CFuncPlat::GoUp( void ) { if( pev->noiseMovement ) EMIT_SOUND( ENT( pev ), CHAN_STATIC, ( char* ) STRING( pev->noiseMovement ), m_volume, ATTN_NORM ); ASSERT( m_toggle_state == TS_AT_BOTTOM || m_toggle_state == TS_GOING_DOWN ); m_toggle_state = TS_GOING_UP; SetMoveDone( &CFuncPlat::CallHitTop ); LinearMove( m_vecPosition1, pev->speed ); }
void CBaseDoor::DoorGoUp( void ) { entvars_t *pevActivator; // It could be going-down, if blocked. ASSERT( m_iState == STATE_OFF || m_iState == STATE_TURN_OFF ); // emit door moving and stop sounds on CHAN_STATIC so that the multicast doesn't // filter them out and leave a client stuck with looping door sounds! if( !FBitSet( pev->spawnflags, SF_DOOR_SILENT )) EMIT_SOUND( edict(), CHAN_STATIC, STRING( pev->noise1 ), 1, ATTN_NORM ); m_iState = STATE_TURN_ON; SetMoveDone( DoorHitTop ); if( IsRotatingDoor( )) { float sign = 1.0; // !!! BUGBUG Triggered doors don't work with this yet if( m_hActivator != NULL && m_bDoorTouched ) { pevActivator = m_hActivator->pev; // Y axis rotation, move away from the player if( !FBitSet( pev->spawnflags, SF_DOOR_ONEWAY ) && pev->movedir.y ) { // Positive is CCW, negative is CW, so make 'sign' 1 or -1 based on which way we want to open. // Important note: All doors face East at all times, and twist their local angle to open. // So you can't look at the door's facing to determine which way to open. Vector nearestPoint; CalcNearestPoint( m_hActivator->GetAbsOrigin(), &nearestPoint ); Vector activatorToNearestPoint = nearestPoint - m_hActivator->GetAbsOrigin(); activatorToNearestPoint.z = 0; Vector activatorToOrigin = GetAbsOrigin() - m_hActivator->GetAbsOrigin(); activatorToOrigin.z = 0; // Point right hand at door hinge, curl hand towards closest spot on door, if thumb // is up, open door CW. -- Department of Basic Cross Product Understanding for Noobs // g-cont. MWA-HA-HA! Vector cross = activatorToOrigin.Cross( activatorToNearestPoint ); if( cross.z > 0.0f ) sign = -1.0f; } } AngularMove( m_vecAngle2 * sign, pev->speed ); } else { LinearMove( m_vecPosition2, pev->speed ); } }
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 ); }
//----------------------------------------------------------------------------- // 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 CMomentaryDoor::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { if ( useType != USE_SET ) // Momentary buttons will pass down a float in here return; if ( value > 1.0 ) value = 1.0; if (IsLockedByMaster()) return; Vector move = m_vecPosition1 + (value * (m_vecPosition2 - m_vecPosition1)); float speed = 0; Vector delta; /* if ((value == 1) || (value == 0)) { STOP_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving));//G-Cont. fix sound bug (original HL). return; } */ if (pev->speed) { //LRC- move at the given speed, if any. speed = pev->speed; } else { // default: get there in 0.1 secs delta = move - pev->origin; speed = delta.Length() * 10; } //FIXME: allow for it being told to move at the same speed in the _opposite_ direction! if ( speed != 0 ) { // This entity only thinks when it moves //LRC- nope, in a MoveWith world you can't rely on that. Check the state instead. if ( m_iState == STATE_OFF ) { //ALERT(at_console,"USE: start moving to %f %f %f.\n", move.x, move.y, move.z); m_iState = STATE_ON; EMIT_SOUND(ENT(pev), CHAN_STATIC, (char*)STRING(pev->noiseMoving), 1, ATTN_NORM); } m_fLastPos = value; LinearMove( move, speed ); //LinearMove( m_vecPosition1, pev->speed, m_fAcceleration, m_fDeceleration); SetMoveDone(&CMomentaryDoor:: MomentaryMoveDone ); } }
// // Starts the button moving "out/down". // void CBaseButton::ButtonReturn(void) { ASSERT(m_toggle_state == TS_AT_TOP); m_toggle_state = TS_GOING_DOWN; SetMoveDone(&CBaseButton::ButtonBackHome); if(!m_fRotating) LinearMove(m_vecPosition1, pev->speed); else AngularMove(m_vecAngle1, pev->speed); pev->frame = 0; // use normal textures }
void CBaseDoor::DoorGoDown( void ) { if( !FBitSet( pev->spawnflags, SF_DOOR_SILENT )) EMIT_SOUND( edict(), CHAN_STATIC, STRING( pev->noise1 ), 1, ATTN_NORM ); ASSERT( m_iState == STATE_ON || m_iState == STATE_TURN_ON ); m_iState = STATE_TURN_OFF; SetMoveDone( DoorHitBottom ); if( IsRotatingDoor( )) AngularMove( m_vecAngle1, pev->speed ); else LinearMove( m_vecPosition1, pev->speed ); }
//========================================================= // Rotating Use - when a rotating brush is triggered //========================================================= void CFuncRotating :: Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { if( IsLockedByMaster( pActivator )) return; m_bStopAtStartPos = false; if( useType == USE_SET ) { if( value != 0 ) { // never toggle direction from momentary entities if( pCaller && !FClassnameIs( pCaller, "momentary_rot_button" ) && !FClassnameIs( pCaller, "momentary_rot_door" )) pev->impulse = (value < 0) ? true : false; value = fabs( value ); SetTargetSpeed( bound( 0, value, 1 ) * m_flMaxSpeed ); } else { SetTargetSpeed( 0 ); } return; } // a liitle easter egg if( useType == USE_RESET ) { if( value == 0.0f ) { if( m_iState == STATE_OFF ) pev->impulse = !pev->impulse; return; } if( m_iState == STATE_OFF ) { // apply angular impulse (XashXT feature) SetLocalAvelocity( pev->movedir * (bound( -1, value, 1 ) * m_flMaxSpeed )); SetMoveDone( RotateFriction ); pev->friction = 1.0f; RotateFriction(); } return; } if( pev->speed != 0 ) SetTargetSpeed( 0 ); else SetTargetSpeed( m_flMaxSpeed ); }