//------------------------------------------------------------------------------ // 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 ); }
//----------------------------------------------------------------------------- // 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: 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 ); } }
//------------------------------------------------------------------------------ // Purpose : // Input : // Output : //------------------------------------------------------------------------------ void CBaseHelicopter::DyingThink( void ) { StudioFrameAdvance( ); SetNextThink( gpGlobals->curtime + 0.1f ); SetLocalAngularVelocity( GetLocalAngularVelocity() * 1.02 ); }
void CBaseGrenadeContact::Spawn( void ) { // point sized, solid, bouncing SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE ); SetSolid( SOLID_BBOX ); SetCollisionGroup( COLLISION_GROUP_PROJECTILE ); SetModel( "models/weapons/w_grenade.mdl" ); // BUG: wrong model UTIL_SetSize(this, vec3_origin, vec3_origin); // contact grenades arc lower SetGravity( UTIL_ScaleForGravity( 400 ) ); // use a lower gravity for grenades to make them easier to see QAngle angles; VectorAngles(GetAbsVelocity(), angles); SetLocalAngles( angles ); // make NPCs afaid of it while in the air SetThink( &CBaseGrenadeContact::DangerSoundThink ); SetNextThink( gpGlobals->curtime ); // Tumble in air QAngle vecAngVelocity( random->RandomFloat ( -100, -500 ), 0, 0 ); SetLocalAngularVelocity( vecAngVelocity ); // Explode on contact SetTouch( &CBaseGrenadeContact::ExplodeTouch ); m_flDamage = 100; // BOXBOX was sk_plr_dmg_grenade.GetFloat(); // Allow player to blow this puppy up in the air m_takedamage = DAMAGE_YES; m_iszBounceSound = NULL_STRING; }
//------------------------------------------------------------------------------ // Purpose : The main think function for the helicopters // Input : // Output : //------------------------------------------------------------------------------ void CBaseHelicopter::HelicopterThink( void ) { SetNextThink( gpGlobals->curtime + HELICOPTER_THINK_INTERVAL ); // Don't keep this around for more than one frame. ClearCondition( COND_ENEMY_DEAD ); // Animate and dispatch animation events. StudioFrameAdvance( ); DispatchAnimEvents( this ); PrescheduleThink(); ShowDamage( ); // ----------------------------------------------- // If AI is disabled, kill any motion and return // ----------------------------------------------- if (CAI_BaseNPC::m_nDebugBits & bits_debugDisableAI) { SetAbsVelocity( vec3_origin ); SetLocalAngularVelocity( vec3_angle ); SetNextThink( gpGlobals->curtime + HELICOPTER_THINK_INTERVAL ); return; } Hunt(); HelicopterPostThink(); }
// // Sticky gib puts blood on the wall and stays put. // void CGib::StickyGibTouch ( CBaseEntity *pOther ) { Vector vecSpot; trace_t tr; SetThink ( &CGib::SUB_Remove ); SetNextThink( gpGlobals->curtime + 10 ); if ( !FClassnameIs( pOther, "worldspawn" ) ) { SetNextThink( gpGlobals->curtime ); return; } UTIL_TraceLine ( GetAbsOrigin(), GetAbsOrigin() + GetAbsVelocity() * 32, MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr); UTIL_BloodDecalTrace( &tr, m_bloodColor ); Vector vecForward = tr.plane.normal * -1; QAngle angles; VectorAngles( vecForward, angles ); SetLocalAngles( angles ); SetAbsVelocity( vec3_origin ); SetLocalAngularVelocity( vec3_angle ); SetMoveType( MOVETYPE_NONE ); }
//----------------------------------------------------------------------------- // 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: //----------------------------------------------------------------------------- void CASW_Broadcast_Camera::Disable( void ) { RestoreAllPlayerViews(); //if ( m_hPlayer && m_hPlayer->IsAlive() ) //{ //if ( HasSpawnFlags( SF_CAMERA_PLAYER_NOT_SOLID ) ) //{ //m_hPlayer->RemoveSolidFlags( FSOLID_NOT_SOLID ); //} //((CBasePlayer*)m_hPlayer.Get())->SetViewEntity( m_hPlayer ); //((CBasePlayer*)m_hPlayer.Get())->EnableControl(TRUE); // Restore the player's viewmodel //if ( ((CBasePlayer*)m_hPlayer.Get())->GetActiveWeapon() ) //{ //((CBasePlayer*)m_hPlayer.Get())->GetActiveWeapon()->RemoveEffects( EF_NODRAW ); //} //} m_state = USE_OFF; m_flReturnTime = gpGlobals->curtime; SetThink( NULL ); m_OnEndFollow.FireOutput(this, this); // dvsents2: what is the best name for this output? SetLocalAngularVelocity( vec3_angle ); DispatchUpdateTransmitState(); }
//----------------------------------------------------------------------------- // Purpose: // Input : *pOther - //----------------------------------------------------------------------------- void CRocket_Turret_Projectile::MissileTouch( CBaseEntity *pOther ) { Assert( pOther ); Vector vVel = GetAbsVelocity(); // Touched a launcher, and is heading towards that launcher if ( FClassnameIs( pOther, "npc_rocket_turret" ) ) { Dissolve( NULL, gpGlobals->curtime + 0.1f, false, ENTITY_DISSOLVE_NORMAL ); Vector vBounceVel = Vector( -vVel.x, -vVel.y, 200 ); SetAbsVelocity ( vBounceVel * 0.1f ); QAngle vBounceAngles; VectorAngles( vBounceVel, vBounceAngles ); SetAbsAngles ( vBounceAngles ); SetLocalAngularVelocity ( QAngle ( 180, 90, 45 ) ); UTIL_Remove ( m_hRocketTrail ); SetSolid ( SOLID_NONE ); if( m_hRocketTrail ) { m_hRocketTrail->SetLifetime(0.1f); m_hRocketTrail = NULL; } return; } // Don't touch triggers (but DO hit weapons) if ( pOther->IsSolidFlagSet(FSOLID_TRIGGER|FSOLID_VOLUME_CONTENTS) && pOther->GetCollisionGroup() != COLLISION_GROUP_WEAPON ) return; Explode(); }
//------------------------------------------------------------------------------ // 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 ); }
//========================================================= // WaitTillLand - in order to emit their meaty scent from // the proper location, gibs should wait until they stop // bouncing to emit their scent. That's what this function // does. //========================================================= void CGib::WaitTillLand ( void ) { if (!IsInWorld()) { UTIL_Remove( this ); return; } if ( GetAbsVelocity() == vec3_origin ) { SetRenderAlpha( 255 ); m_nRenderMode = kRenderTransTexture; if ( GetMoveType() != MOVETYPE_VPHYSICS ) { AddSolidFlags( FSOLID_NOT_SOLID ); } SetLocalAngularVelocity( vec3_angle ); SetNextThink( gpGlobals->curtime + m_lifeTime ); SetThink ( &CGib::SUB_FadeOut ); if ( GetSprite() ) { CSprite *pSprite = dynamic_cast<CSprite*>( GetSprite() ); if ( pSprite ) { //Adrian - Why am I doing this? Check InitPointGib for the answer! if ( m_lifeTime == 0 ) m_lifeTime = random->RandomFloat( 1, 3 ); pSprite->FadeAndDie( m_lifeTime ); } } if ( GetFlame() ) { CEntityFlame *pFlame = dynamic_cast< CEntityFlame*>( GetFlame() ); if ( pFlame ) { pFlame->SetLifetime( 1.0f ); } } // If you bleed, you stink! if ( m_bloodColor != DONT_BLEED ) { // ok, start stinkin! // FIXME: It's too easy to fill up the sound queue with all these meat sounds // CSoundEnt::InsertSound ( SOUND_MEAT, GetAbsOrigin(), 384, 25 ); } } else { // wait and check again in another half second. SetNextThink( gpGlobals->curtime + 0.5f ); } }
//------------------------------------------------------------------------------ // Purpose : Initialize a gibs position and velocity // Input : // Output : //------------------------------------------------------------------------------ void CGib::InitGib( CBaseEntity *pVictim, float fMinVelocity, float fMaxVelocity ) { // ------------------------------------------------------------------------ // If have a pVictim spawn the gib somewhere in the pVictim's bounding volume // ------------------------------------------------------------------------ if ( pVictim ) { // Find a random position within the bounding box (add 1 to Z to get it out of the ground) Vector vecOrigin; pVictim->CollisionProp()->RandomPointInBounds( vec3_origin, Vector( 1, 1, 1 ), &vecOrigin ); vecOrigin.z += 1.0f; SetAbsOrigin( vecOrigin ); // make the gib fly away from the attack vector Vector vecNewVelocity = g_vecAttackDir * -1; // mix in some noise vecNewVelocity.x += random->RandomFloat ( -0.25, 0.25 ); vecNewVelocity.y += random->RandomFloat ( -0.25, 0.25 ); vecNewVelocity.z += random->RandomFloat ( -0.25, 0.25 ); vecNewVelocity *= random->RandomFloat ( fMaxVelocity, fMinVelocity ); QAngle vecNewAngularVelocity = GetLocalAngularVelocity(); vecNewAngularVelocity.x = random->RandomFloat ( 100, 200 ); vecNewAngularVelocity.y = random->RandomFloat ( 100, 300 ); SetLocalAngularVelocity( vecNewAngularVelocity ); // copy owner's blood color SetBloodColor( pVictim->BloodColor() ); AdjustVelocityBasedOnHealth( pVictim->m_iHealth, vecNewVelocity ); // Attempt to be physical if we can if ( VPhysicsInitNormal( SOLID_BBOX, 0, false ) ) { IPhysicsObject *pObj = VPhysicsGetObject(); if ( pObj != NULL ) { AngularImpulse angImpulse = RandomAngularImpulse( -500, 500 ); pObj->AddVelocity( &vecNewVelocity, &angImpulse ); } } else { SetSolid( SOLID_BBOX ); SetCollisionBounds( vec3_origin, vec3_origin ); SetAbsVelocity( vecNewVelocity ); } SetCollisionGroup( COLLISION_GROUP_DEBRIS ); } LimitVelocity(); }
void CSatchelCharge::SatchelThink( void ) { // If attached resize so player can pick up off wall if (m_bIsAttached) { UTIL_SetSize(this, Vector( -2, -2, -6), Vector(2, 2, 6)); } // See if I can lose my owner (has dropper moved out of way?) // Want do this so owner can shoot the satchel charge if (GetOwnerEntity()) { trace_t tr; Vector vUpABit = GetAbsOrigin(); vUpABit.z += 5.0; CBaseEntity* saveOwner = GetOwnerEntity(); SetOwnerEntity( NULL ); UTIL_TraceEntity( this, GetAbsOrigin(), vUpABit, MASK_SOLID, &tr ); if ( tr.startsolid || tr.fraction != 1.0 ) { SetOwnerEntity( saveOwner ); } } // Bounce movement code gets this think stuck occasionally so check if I've // succeeded in moving, otherwise kill my motions. else if ((GetAbsOrigin() - m_vLastPosition).LengthSqr()<1) { SetAbsVelocity( vec3_origin ); QAngle angVel = GetLocalAngularVelocity(); angVel.y = 0; SetLocalAngularVelocity( angVel ); // Clear think function SetThink(NULL); return; } m_vLastPosition= GetAbsOrigin(); StudioFrameAdvance( ); SetNextThink( gpGlobals->curtime + 0.1f ); if (!IsInWorld()) { UTIL_Remove( this ); return; } // Is it attached to a wall? if (m_bIsAttached) { return; } }
void CASW_Simple_Alien::CorpseFade() { StopAnimation(); SetAbsVelocity( vec3_origin ); SetMoveType( MOVETYPE_NONE ); SetLocalAngularVelocity( vec3_angle ); m_flAnimTime = gpGlobals->curtime; AddEffects( EF_NOINTERP ); SUB_StartFadeOut(); }
void CASW_Boomer_Blob::Spawn( void ) { //d:\dev\main\game\infested\models\swarm\mortarbugprojectile\mortarbugprojectile.mdl Precache(); SetModel( ASW_BOOMER_BLOB_MODEL ); SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE ); m_flDamage = 80; m_DmgRadius = 165.0f; // NOTE: this gets overriden m_takedamage = DAMAGE_NO; m_iHealth = 1; m_bModelOpening = false; SetSize( -Vector(4,4,4), Vector(4,4,4) ); SetSolid( SOLID_BBOX ); SetGravity( asw_boomer_blob_gravity.GetFloat() ); SetFriction( asw_boomer_blob_friction.GetFloat() ); SetElasticity( asw_vindicator_grenade_elasticity.GetFloat() ); SetCollisionGroup( ASW_COLLISION_GROUP_PASSABLE ); SetTouch( &CASW_Boomer_Blob::Touch ); //CreateEffects(); m_hFirer = NULL; // Tumble in air QAngle vecAngVelocity( random->RandomFloat ( -100, -500 ), 0, 0 ); SetLocalAngularVelocity( vecAngVelocity ); m_fEarliestAOEDetonationTime = GetEarliestAOEDetonationTime(); m_fEarliestTouchDetonationTime = GetEarliestTouchDetonationTime(); m_iClusters = 0; m_bMaster = true; ResetSequence( LookupSequence( "MortarBugProjectile_Closed" ) ); //EmitSound( "ASWGrenade.Alarm" ); SetFuseLength( asw_boomer_blob_fuse.GetFloat() + RandomFloat( -0.25, 0.66f ) ); if ( m_fDetonateTime <= gpGlobals->curtime + asw_boomer_blob_radius_check_interval.GetFloat() ) { SetThink( &CASW_Boomer_Blob::Detonate ); SetNextThink( m_fDetonateTime ); } else { SetThink( &CASW_Boomer_Blob::CheckNearbyTargets ); SetNextThink( gpGlobals->curtime + asw_boomer_blob_radius_check_interval.GetFloat() ); } }
//----------------------------------------------------------------------------- // 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 ); }
//----------------------------------------------------------------------------- // Purpose: // GetLocalTime() is the objects local current time // Input : destTime - new time that is being moved to // moveTime - amount of time to be advanced this frame // Output : float - the actual amount of time to move (usually moveTime) //----------------------------------------------------------------------------- float CBaseMoveBehavior::SetObjectPhysicsVelocity( float moveTime ) { // make sure we have a valid set up if ( !m_pCurrentKeyFrame || !m_pTargetKeyFrame ) return moveTime; // if we're not moving, we're not moving if ( !IsMoving() ) return moveTime; float destTime = moveTime + GetLocalTime(); // work out where we want to be, using destTime m_flTimeIntoFrame = destTime - m_flAnimStartTime; float newTime = (destTime - m_flAnimStartTime) / (m_flAnimEndTime - m_flAnimStartTime); Vector newPos; QAngle newAngles; IPositionInterpolator *pInterp = GetPositionInterpolator( m_iPositionInterpolator ); if( pInterp ) { // setup key frames pInterp->SetKeyPosition( -1, m_pPreKeyFrame->m_Origin ); Motion_SetKeyAngles( -1, m_pPreKeyFrame->m_qAngle ); pInterp->SetKeyPosition( 0, m_pCurrentKeyFrame->m_Origin ); Motion_SetKeyAngles( 0, m_pCurrentKeyFrame->m_qAngle ); pInterp->SetKeyPosition( 1, m_pTargetKeyFrame->m_Origin ); Motion_SetKeyAngles( 1, m_pTargetKeyFrame->m_qAngle ); pInterp->SetKeyPosition( 2, m_pPostKeyFrame->m_Origin ); Motion_SetKeyAngles( 2, m_pPostKeyFrame->m_qAngle ); // find new interpolated position & rotation pInterp->InterpolatePosition( newTime, newPos ); } else { newPos.Init(); } Quaternion qRot; Motion_InterpolateRotation( newTime, m_iRotationInterpolator, qRot ); QuaternionAngles( qRot, newAngles ); // find our velocity vector (newPos - currentPos) and scale velocity vector according to the movetime float oneOnMoveTime = 1 / moveTime; SetAbsVelocity( (newPos - GetLocalOrigin()) * oneOnMoveTime ); SetLocalAngularVelocity( (newAngles - GetLocalAngles()) * oneOnMoveTime ); return moveTime; }
//------------------------------------------------------------------------------ // Purpose : // Input : // Output : //------------------------------------------------------------------------------ void CNPC_CombineDropship::LandCommon( void ) { // If we don't have a crate, we're not able to land if ( !m_hContainer ) return; //Msg( "Landing\n" ); m_iLandState = LANDING_LEVEL_OUT; UTIL_SetSize( this, CRATE_BBOX_MIN, CRATE_BBOX_MAX ); SetLocalAngularVelocity( vec3_angle ); }
void CNPC_HL1Barney::SUB_StartLVFadeOut( float delay, bool notSolid ) { SetThink( &CNPC_HL1Barney::SUB_LVFadeOut ); SetNextThink( gpGlobals->curtime + delay ); SetRenderColorA( 255 ); m_nRenderMode = kRenderNormal; if ( notSolid ) { AddSolidFlags( FSOLID_NOT_SOLID ); SetLocalAngularVelocity( vec3_angle ); } }
void CFuncTank::Think( void ) { // refresh the matrix UpdateMatrix(); SetLocalAngularVelocity( vec3_angle ); TrackTarget(); if ( fabs(GetLocalAngularVelocity().x) > 1 || fabs(GetLocalAngularVelocity().y) > 1 ) StartRotSound(); else StopRotSound(); }
//----------------------------------------------------------------------------- // Purpose: 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 ); }
// // Gib bounces on the ground or wall, sponges some blood down, too! // void CGib::BounceGibTouch ( CBaseEntity *pOther ) { Vector vecSpot; trace_t tr; IPhysicsObject *pPhysics = VPhysicsGetObject(); if ( pPhysics ) return; //if ( random->RandomInt(0,1) ) // return;// don't bleed everytime if (GetFlags() & FL_ONGROUND) { SetAbsVelocity( GetAbsVelocity() * 0.9 ); QAngle angles = GetLocalAngles(); angles.x = 0; angles.z = 0; SetLocalAngles( angles ); QAngle angVel = GetLocalAngularVelocity(); angVel.x = 0; angVel.z = 0; SetLocalAngularVelocity( vec3_angle ); } else { //City17: Germany Violence Fix. if ( /*g_Language.GetInt() != LANGUAGE_GERMAN &&*/ m_cBloodDecals > 0 && m_bloodColor != DONT_BLEED ) { vecSpot = GetAbsOrigin() + Vector ( 0 , 0 , 8 );//move up a bit, and trace down. UTIL_TraceLine ( vecSpot, vecSpot + Vector ( 0, 0, -24 ), MASK_SOLID_BRUSHONLY, this, COLLISION_GROUP_NONE, &tr); UTIL_BloodDecalTrace( &tr, m_bloodColor ); m_cBloodDecals--; } if ( m_material != matNone && random->RandomInt(0,2) == 0 ) { float volume; float zvel = fabs(GetAbsVelocity().z); volume = 0.8f * min(1.0, ((float)zvel) / 450.0f); CBreakable::MaterialSoundRandom( entindex(), (Materials)m_material, volume ); } } }
//------------------------------------------------------------------------------ // Spawn //------------------------------------------------------------------------------ void CQUAGrenadeHelicopter::Spawn( void ) { Precache(); // point sized, solid, bouncing SetCollisionGroup( COLLISION_GROUP_PROJECTILE ); SetModel( "models/combine_helicopter/helicopter_bomb01.mdl" ); SetSolid( SOLID_BBOX ); SetCollisionBounds( Vector( -12.5, -12.5, -12.5 ), Vector( 12.5, 12.5, 12.5 ) ); VPhysicsInitShadow( false, false ); SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_CUSTOM ); SetElasticity( 0.5f ); AddEffects( EF_NOSHADOW ); // We're always being dropped beneath the helicopter; need to not // be affected by the rotor wash AddEFlags( EFL_NO_ROTORWASH_PUSH ); // contact grenades arc lower SetGravity( UTIL_ScaleForGravity( 400 ) ); // use a lower gravity for grenades to make them easier to see QAngle angles; VectorAngles(GetAbsVelocity(), angles ); SetLocalAngles( angles ); SetThink( NULL ); // Tumble in air QAngle vecAngVel( random->RandomFloat ( -100, -500 ), 0, 0 ); SetLocalAngularVelocity( vecAngVel ); // Explode on contact SetTouch( &CQUAGrenadeHelicopter::ExplodeConcussion ); m_bActivated = false; m_pWarnSound = NULL; m_flDamage = 75.0; // Allow player to blow this puppy up in the air m_takedamage = DAMAGE_YES; g_pNotify->AddEntity( this, this ); }
void CASW_Bait::Spawn( void ) { Precache( ); SetModel( BAIT_MODEL ); UTIL_SetSize( this, Vector( -2, -2, -2 ), Vector( 2, 2, 2 ) ); SetSolid( SOLID_BBOX ); AddSolidFlags( FSOLID_NOT_SOLID ); SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE ); m_takedamage = DAMAGE_NO; SetFriction( 0.6f ); m_flTimeBurnOut = gpGlobals->curtime + 30; AddEffects( EF_NOSHADOW|EF_NORECEIVESHADOW ); AddFlag( FL_OBJECT ); SetCollisionGroup( ASW_COLLISION_GROUP_IGNORE_NPCS ); //CreateVPhysics(); // Tumble in air QAngle vecAngVelocity( 0, random->RandomFloat ( -100, -500 ), 0 ); SetLocalAngularVelocity( vecAngVelocity ); SetTouch( &CASW_Bait::BaitTouch ); SetThink( &CASW_Bait::BaitThink ); // join the flares team so that aliens will hate us ChangeFaction( FACTION_BAIT ); if ( ASW_BAIT_LIFETIME > 0 ) { m_flTimeBurnOut = gpGlobals->curtime + ASW_BAIT_LIFETIME; } else { m_flTimeBurnOut = -1.0f; } SetNextThink( gpGlobals->curtime + 0.1f ); g_AI_SensedObjectsManager.AddEntity( this ); }
//----------------------------------------------------------------------------- // Purpose: Setup basic values for Thrown grens //----------------------------------------------------------------------------- void CThrownGrenade::Spawn( void ) { // point sized, solid, bouncing SetMoveType( MOVETYPE_FLYGRAVITY, MOVECOLLIDE_FLY_BOUNCE ); SetSolid( SOLID_BBOX ); UTIL_SetSize(this, vec3_origin, vec3_origin); // Movement SetGravity( UTIL_ScaleForGravity( 648 ) ); SetFriction(0.6); QAngle angles; VectorAngles( GetAbsVelocity(), angles ); SetLocalAngles( angles ); QAngle vecAngVel( random->RandomFloat ( -100, -500 ), 0, 0 ); SetLocalAngularVelocity( vecAngVel ); SetTouch( &CThrownGrenade::BounceTouch ); }
//----------------------------------------------------------------------------- // 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 : The main think function for the helicopters // Input : // Output : //------------------------------------------------------------------------------ void CBaseHelicopter::HelicopterThink( void ) { CheckPVSCondition(); SetNextThink( gpGlobals->curtime + HELICOPTER_THINK_INTERVAL ); // Don't keep this around for more than one frame. ClearCondition( COND_ENEMY_DEAD ); // Animate and dispatch animation events. StudioFrameAdvance( ); DispatchAnimEvents( this ); PrescheduleThink(); if ( IsMarkedForDeletion() ) return; ShowDamage( ); // ----------------------------------------------- // If AI is disabled, kill any motion and return // ----------------------------------------------- if (CAI_BaseNPC::m_nDebugBits & bits_debugDisableAI) { SetAbsVelocity( vec3_origin ); SetLocalAngularVelocity( vec3_angle ); SetNextThink( gpGlobals->curtime + HELICOPTER_THINK_INTERVAL ); return; } Hunt(); // Finally, forget dead enemies, or ones we've been told to ignore. if( GetEnemy() != NULL && (!GetEnemy()->IsAlive() || GetEnemy()->GetFlags() & FL_NOTARGET || IRelationType( GetEnemy() ) == D_NU ) ) { SetEnemy( NULL ); } HelicopterPostThink(); }
void CASW_Laser_Mine::StartSpawnFlipping( Vector vecStart, Vector vecEnd, QAngle angEnd, float flDuration ) { m_vecSpawnFlipStartPos = vecStart; m_vecSpawnFlipEndPos = vecEnd; m_angSpawnFlipEndAngle = angEnd; StopFollowingEntity( ); SetMoveType( MOVETYPE_NOCLIP ); SetGroundEntity( NULL ); SetTouch(NULL); SetSolidFlags( 0 ); m_flSpawnFlipStartTime = gpGlobals->curtime; m_flSpawnFlipEndTime = gpGlobals->curtime + flDuration; SetContextThink( &CASW_Laser_Mine::SpawnFlipThink, gpGlobals->curtime, s_pLaserMineSpawnFlipThink ); SetAbsAngles( m_angSpawnFlipEndAngle ); QAngle angVel( 0, random->RandomFloat ( 200, 400 ), 0 ); SetLocalAngularVelocity( angVel ); m_bIsSpawnFlipping = true; }
// this is the think that flips the weapon into the world when it is spawned void CASW_Laser_Mine::SpawnFlipThink() { // we are still flagged as spawn flipping in the air if ( m_bIsSpawnFlipping == false ) { // we get here if we spawned, but haven't started spawn flipping yet, please try again! SetContextThink( &CASW_Laser_Mine::SpawnFlipThink, gpGlobals->curtime, s_pLaserMineSpawnFlipThink ); return; } // when we should hit the ground float flEndTime = m_flSpawnFlipEndTime; // the total time it takes for us to flip float flFlipTime = flEndTime - m_flSpawnFlipStartTime; float flFlipProgress = ( gpGlobals->curtime - m_flSpawnFlipStartTime ) / flFlipTime; flFlipProgress = clamp( flFlipProgress, 0.0f, 2.5f ); if ( !m_bIsSpawnLanded ) { // high gravity, it looks more satisfying float flGravity = 2200; float flInitialZVelocity = (m_vecSpawnFlipEndPos.z - m_vecSpawnFlipStartPos.z)/flFlipTime + (flGravity/2) * flFlipTime; float flZVelocity = flInitialZVelocity - flGravity * (gpGlobals->curtime - m_flSpawnFlipStartTime); float flXDiff = (m_vecSpawnFlipEndPos.x - m_vecSpawnFlipStartPos.x) / flFlipTime; float flYDiff = (m_vecSpawnFlipEndPos.y - m_vecSpawnFlipStartPos.y) / flFlipTime; Vector vecVelocity( flXDiff, flYDiff, flZVelocity ); SetAbsVelocity( vecVelocity ); // angular velocity QAngle angCurAngVel = GetLocalAngularVelocity(); float flXAngDiff = 360 / flFlipTime; // keep the Y angular velocity that was given to it at the start (it's random) SetLocalAngularVelocity( QAngle( flXAngDiff, angCurAngVel.y, 0 ) ); } if ( flFlipProgress >= 1.0f ) { if ( !m_bIsSpawnLanded ) { Vector vecVelStop( 0,0,0 ); SetAbsVelocity( vecVelStop ); SetAbsOrigin( m_vecSpawnFlipEndPos ); QAngle angVel( 0, 0, 0 ); SetLocalAngularVelocity( angVel ); /* // get the current angles of the item so we can use them to determine the final angles QAngle angPrevAngles = GetAbsAngles(); float flYAngles = angPrevAngles.y; QAngle angFlat( 0, flYAngles, 0 ); */ SetAbsAngles( m_angSpawnFlipEndAngle ); EmitSound("ASW_Laser_Mine.Lay"); m_bIsSpawnLanded = true; } if ( flFlipProgress >= 2.5f ) { SetContextThink( NULL, 0, s_pLaserMineSpawnFlipThink ); EmitSound("ASW_Mine.Lay"); m_bMineActive = true; return; } } SetContextThink( &CASW_Laser_Mine::SpawnFlipThink, gpGlobals->curtime, s_pLaserMineSpawnFlipThink ); }