//------------------------------------------------------------------------------ // Pow! //------------------------------------------------------------------------------ void CQUAGrenadeHelicopter::DoExplosion( const Vector &vecOrigin, const Vector &vecVelocity ) { ExplosionCreate( GetAbsOrigin(), GetAbsAngles(), this, 75.0, 275.0, (SF_ENVEXPLOSION_NOSPARKS|SF_ENVEXPLOSION_NODLIGHTS|SF_ENVEXPLOSION_NODECAL|SF_ENVEXPLOSION_NOFIREBALL|SF_ENVEXPLOSION_NOPARTICLES), 55000.0 ); if ( GetShakeAmplitude() ) { UTIL_ScreenShake( GetAbsOrigin(), GetShakeAmplitude(), 150.0, 1.0, GetShakeRadius(), SHAKE_START ); } CEffectData data; // If we're under water do a water explosion if ( GetWaterLevel() != 0 && (GetWaterType() & CONTENTS_WATER) ) { data.m_vOrigin = WorldSpaceCenter(); data.m_flMagnitude = 128; data.m_flScale = 128; data.m_fFlags = 0; DispatchEffect( "WaterSurfaceExplosion", data ); } else { // Otherwise do a normal explosion data.m_vOrigin = GetAbsOrigin(); DispatchEffect( "HelicopterMegaBomb", data ); } UTIL_Remove( this ); }
//----------------------------------------------------------------------------- // Purpose: Makes a splash when the player transitions between water states //----------------------------------------------------------------------------- void CSDKPlayer::Splash( void ) { CEffectData data; data.m_fFlags = 0; data.m_vOrigin = GetAbsOrigin(); data.m_vNormal = Vector(0,0,1); data.m_vAngles = QAngle( 0, 0, 0 ); if ( GetWaterType() & CONTENTS_SLIME ) { data.m_fFlags |= FX_WATER_IN_SLIME; } float flSpeed = GetAbsVelocity().Length(); if ( flSpeed < 300 ) { data.m_flScale = random->RandomFloat( 10, 12 ); DispatchEffect( "waterripple", data ); } else { data.m_flScale = random->RandomFloat( 6, 8 ); DispatchEffect( "watersplash", data ); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CASW_PropJeep::CreateRipple( const Vector &vecPosition ) { // Ripple data. CEffectData data; data.m_fFlags = 0; data.m_vOrigin = vecPosition; data.m_vNormal.Init( 0.0f, 0.0f, 1.0f ); VectorAngles( data.m_vNormal, data.m_vAngles ); data.m_flScale = 10.0f + random->RandomFloat( 0, 2 ); if ( GetWaterType() & CONTENTS_SLIME ) { data.m_fFlags |= FX_WATER_IN_SLIME; } // Create the ripple. DispatchEffect( "waterripple", data ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CBasePlayer::UpdateUnderwaterState( void ) { if ( GetWaterLevel() == WL_Eyes ) { if ( IsPlayerUnderwater() == false ) { SetPlayerUnderwater( true ); } return; } if ( IsPlayerUnderwater() ) { SetPlayerUnderwater( false ); } if ( GetWaterLevel() == 0 ) { if ( GetFlags() & FL_INWATER ) { #ifndef CLIENT_DLL if ( m_iHealth > 0 && IsAlive() ) { EmitSound( "Player.Wade" ); } #endif RemoveFlag( FL_INWATER ); } } else if ( !(GetFlags() & FL_INWATER) ) { #ifndef CLIENT_DLL // player enter water sound if (GetWaterType() == CONTENTS_WATER) { EmitSound( "Player.Wade" ); } #endif AddFlag( FL_INWATER ); } }
/* =========== WaterMove ============ */ void CBasePlayer::WaterMove() { if( GetMoveType() == MOVETYPE_NOCLIP ) return; if( GetHealth() < 0 ) return; if( GetWaterLevel() != WATERLEVEL_HEAD ) { // not underwater // play 'up for air' sound if( pev->air_finished < gpGlobals->time ) EMIT_SOUND( this, CHAN_VOICE, "player/pl_wade1.wav", 1, ATTN_NORM ); else if( pev->air_finished < gpGlobals->time + 9 ) EMIT_SOUND( this, CHAN_VOICE, "player/pl_wade2.wav", 1, ATTN_NORM ); pev->air_finished = gpGlobals->time + PLAYER_SWIM_AIRTIME; SetDamage( 2 ); // if we took drowning damage, give it back slowly if( m_idrowndmg > m_idrownrestored ) { // set drowning damage bit. hack - dmg_drownrecover actually // makes the time based damage code 'give back' health over time. // make sure counter is cleared so we start count correctly. // NOTE: this actually causes the count to continue restarting // until all drowning damage is healed. m_bitsDamageType |= DMG_DROWNRECOVER; m_bitsDamageType &= ~DMG_DROWN; m_rgbTimeBasedDamage[ itbd_DrownRecover ] = 0; } } else { // fully under water // stop restoring damage while underwater m_bitsDamageType &= ~DMG_DROWNRECOVER; m_rgbTimeBasedDamage[ itbd_DrownRecover ] = 0; if( pev->air_finished < gpGlobals->time ) // drown! { if( pev->pain_finished < gpGlobals->time ) { // take drowning damage SetDamage( GetDamage() + 1 ); if( GetDamage() > 5 ) SetDamage( 5 ); TakeDamage( CWorld::GetInstance(), CWorld::GetInstance(), GetDamage(), DMG_DROWN ); pev->pain_finished = gpGlobals->time + 1; // track drowning damage, give it back when // player finally takes a breath m_idrowndmg += GetDamage(); } } else { m_bitsDamageType &= ~DMG_DROWN; } } if( !GetWaterLevel() ) { if( GetFlags().Any( FL_INWATER ) ) { GetFlags().ClearFlags( FL_INWATER ); } return; } // make bubbles const int air = ( int ) ( pev->air_finished - gpGlobals->time ); if( !RANDOM_LONG( 0, 0x1f ) && RANDOM_LONG( 0, PLAYER_SWIM_AIRTIME - 1 ) >= air ) { switch( RANDOM_LONG( 0, 3 ) ) { case 0: EMIT_SOUND( this, CHAN_BODY, "player/pl_swim1.wav", 0.8, ATTN_NORM ); break; case 1: EMIT_SOUND( this, CHAN_BODY, "player/pl_swim2.wav", 0.8, ATTN_NORM ); break; case 2: EMIT_SOUND( this, CHAN_BODY, "player/pl_swim3.wav", 0.8, ATTN_NORM ); break; case 3: EMIT_SOUND( this, CHAN_BODY, "player/pl_swim4.wav", 0.8, ATTN_NORM ); break; } } if( GetWaterType() == CONTENTS_LAVA ) // do damage { if( GetDamageTime() < gpGlobals->time ) TakeDamage( CWorld::GetInstance(), CWorld::GetInstance(), 10 * GetWaterLevel(), DMG_BURN ); } else if( GetWaterType() == CONTENTS_SLIME ) // do damage { SetDamageTime( gpGlobals->time + 1 ); TakeDamage( CWorld::GetInstance(), CWorld::GetInstance(), 4 * GetWaterLevel(), DMG_ACID ); } if( !GetFlags().Any( FL_INWATER ) ) { GetFlags() |= FL_INWATER; SetDamageTime( 0 ); } }
void CBasePlayer::PostThink() { if( g_fGameOver ) goto pt_end; // intermission or finale if( !IsAlive() ) goto pt_end; // Handle Tank controlling if( m_pTank != NULL ) { // if they've moved too far from the gun, or selected a weapon, unuse the gun if( m_pTank->OnControls( this ) && !HasWeaponModelName() ) { m_pTank->Use( this, this, USE_SET, 2 ); // try fire the gun } else { // they've moved off the platform m_pTank->Use( this, this, USE_OFF, 0 ); m_pTank = NULL; } } // do weapon stuff ItemPostFrame(); // check to see if player landed hard enough to make a sound // falling farther than half of the maximum safe distance, but not as far a max safe distance will // play a bootscrape sound, and no damage will be inflicted. Fallling a distance shorter than half // of maximum safe distance will make no sound. Falling farther than max safe distance will play a // fallpain sound, and damage will be inflicted based on how far the player fell if( GetFlags().Any( FL_ONGROUND ) && ( GetHealth() > 0 ) && m_flFallVelocity >= PLAYER_FALL_PUNCH_THRESHHOLD ) { // ALERT ( at_console, "%f\n", m_flFallVelocity ); if( GetWaterType() == CONTENTS_WATER ) { // Did he hit the world or a non-moving entity? // BUG - this happens all the time in water, especially when // BUG - water has current force //CBaseEntity* pEntity = GetGroundEntity(); //if ( !pEntity || pEntity->GetAbsVelocity().z == 0 ) // EMIT_SOUND( this, CHAN_BODY, "player/pl_wade1.wav", 1, ATTN_NORM); } else if( m_flFallVelocity > PLAYER_MAX_SAFE_FALL_SPEED ) { // after this point, we start doing damage float flFallDamage = g_pGameRules->FlPlayerFallDamage( this ); if( flFallDamage > GetHealth() ) {//splat // note: play on item channel because we play footstep landing on body channel EMIT_SOUND( this, CHAN_ITEM, "common/bodysplat.wav", 1, ATTN_NORM ); } if( flFallDamage > 0 ) { TakeDamage( CWorld::GetInstance(), CWorld::GetInstance(), flFallDamage, DMG_FALL ); Vector vecPunchAngle = GetPunchAngle(); vecPunchAngle.x = 0; SetPunchAngle( vecPunchAngle ); } } if( IsAlive() ) { SetAnimation( PLAYER_WALK ); } } if( GetFlags().Any( FL_ONGROUND ) ) { if( m_flFallVelocity > 64 && !g_pGameRules->IsMultiplayer() ) { CSoundEnt::InsertSound( bits_SOUND_PLAYER, GetAbsOrigin(), m_flFallVelocity, 0.2 ); // ALERT( at_console, "fall %f\n", m_flFallVelocity ); } m_flFallVelocity = 0; } // select the proper animation for the player character if( IsAlive() ) { if( !GetAbsVelocity().x && !GetAbsVelocity().y ) SetAnimation( PLAYER_IDLE ); else if( ( GetAbsVelocity().x || GetAbsVelocity().y ) && ( GetFlags().Any( FL_ONGROUND ) ) ) SetAnimation( PLAYER_WALK ); else if( GetWaterLevel() > WATERLEVEL_FEET ) SetAnimation( PLAYER_WALK ); } StudioFrameAdvance(); CheckPowerups( this ); UpdatePlayerSound(); pt_end: #if defined( CLIENT_WEAPONS ) // Decay timers on weapons // go through all of the weapons and make a list of the ones to pack for( int i = 0; i < MAX_WEAPON_SLOTS; i++ ) { if( m_rgpPlayerItems[ i ] ) { CBasePlayerWeapon *pPlayerItem = m_rgpPlayerItems[ i ]; while( pPlayerItem ) { if( pPlayerItem->IsPredicted() ) { pPlayerItem->m_flNextPrimaryAttack = max( pPlayerItem->m_flNextPrimaryAttack - gpGlobals->frametime, -1.0f ); pPlayerItem->m_flNextSecondaryAttack = max( pPlayerItem->m_flNextSecondaryAttack - gpGlobals->frametime, -0.001f ); if( pPlayerItem->m_flTimeWeaponIdle != 1000 ) { pPlayerItem->m_flTimeWeaponIdle = max( pPlayerItem->m_flTimeWeaponIdle - gpGlobals->frametime, -0.001f ); } if( pPlayerItem->pev->fuser1 != 1000 ) { pPlayerItem->pev->fuser1 = max( pPlayerItem->pev->fuser1 - gpGlobals->frametime, -0.001f ); } pPlayerItem->DecrementTimers( gpGlobals->frametime ); // Only decrement if not flagged as NO_DECREMENT // if ( gun->m_flPumpTime != 1000 ) // { // gun->m_flPumpTime = max( gun->m_flPumpTime - gpGlobals->frametime, -0.001 ); // } } pPlayerItem = pPlayerItem->m_pNext; } } } m_flNextAttack -= gpGlobals->frametime; if( m_flNextAttack < -0.001 ) m_flNextAttack = -0.001; if( m_flNextAmmoBurn != 1000 ) { m_flNextAmmoBurn -= gpGlobals->frametime; if( m_flNextAmmoBurn < -0.001 ) m_flNextAmmoBurn = -0.001; } if( m_flAmmoStartCharge != 1000 ) { m_flAmmoStartCharge -= gpGlobals->frametime; if( m_flAmmoStartCharge < -0.001 ) m_flAmmoStartCharge = -0.001; } #endif // Track button info so we can detect 'pressed' and 'released' buttons next frame m_afButtonLast = GetButtons().Get(); }