//========================================================= // AttackSound //========================================================= void CNPC_Bullsquid::AttackSound( void ) { CPASAttenuationFilter filter( this ); EmitSound( filter, entindex(), "Bullsquid.Attack" ); }
//----------------------------------------------------------------------------- // Purpose: Play a random attack miss sound //----------------------------------------------------------------------------- void CNPC_Zombine::AttackMissSound( void ) { // Play a random attack miss sound EmitSound( "Zombie.AttackMiss" ); }
void C_WeaponCombat_ChargeablePlasma::StartCharging() { CLocalPlayerFilter filter; EmitSound( filter, SOUND_FROM_LOCAL_PLAYER, "WeaponCombat_ChargeablePlasma.Charging" ); m_flChargeStartTime = gpGlobals->curtime; }
//----------------------------------------------------------------------------- // Purpose: Intercept damage and decide whether or not we want to trigger // Input : &info - //----------------------------------------------------------------------------- int CWeaponStriderBuster::OnTakeDamage( const CTakeDamageInfo &info ) { // If we're attached, any damage from the player makes us trigger CBaseEntity *pInflictor = info.GetInflictor(); CBaseEntity *pAttacker = info.GetAttacker(); bool bInflictorIsPlayer = ( pInflictor != NULL && pInflictor->IsPlayer() ); bool bAttackerIsPlayer = ( pAttacker != NULL && pAttacker->IsPlayer() ); if ( GetParent() && GetParent()->ClassMatches( g_iszVehicle ) ) { return 0; } // Only take damage from a player, for the moment if ( striderbuster_allow_all_damage.GetBool() || ( IsAttachedToStrider() && ( bAttackerIsPlayer || bInflictorIsPlayer ) ) ) { Detonate(); return 0; } if ( pAttacker && ( pAttacker->Classify() == CLASS_COMBINE || pAttacker->Classify() == CLASS_COMBINE_HUNTER ) ) { if ( VPhysicsGetObject() && !VPhysicsGetObject()->IsMoveable() ) { return 0; } } // Hunters are able to destroy strider busters if ( hunter_hate_held_striderbusters.GetBool() || hunter_hate_thrown_striderbusters.GetBool() || hunter_hate_attached_striderbusters.GetBool() ) { if ( ( GetHealth() > 0 ) && ( pInflictor != NULL ) && FClassnameIs( pInflictor, "hunter_flechette" ) ) { // // Flechette impacts don't hurt the striderbuster unless it's attached to a strider, // but the explosions always do. This is so that held or thrown striderbusters fly // awry because of the flechette, but attached striderbusters break instantly to make // the hunters more effective at defending the strider. // if ( IsAttachedToStrider() || !( info.GetDamageType() & DMG_NEVERGIB ) ) { if( striderbuster_die_detach.GetBool() && IsAttachedToStrider() ) { // Make the buster fall off and break. m_takedamage = DAMAGE_NO; CNPC_Strider *pStrider = dynamic_cast<CNPC_Strider *>(GetOwnerEntity()); Assert( pStrider != NULL ); pStrider->StriderBusterDetached( this ); DestroyConstraint(); // Amplify some lateral force. Vector vecForce = info.GetDamageForce(); vecForce.z = 0.0f; VPhysicsGetObject()->ApplyForceCenter( vecForce * 5.0f ); SetContextThink( NULL, gpGlobals->curtime, s_pBusterPingThinkContext ); SetThink( &CWeaponStriderBuster::BusterDetachThink ); SetNextThink( gpGlobals->curtime ); m_iBusterFlags |= STRIDERBUSTER_FLAG_KNOCKED_OFF_STRIDER; return 0; } else { // Destroy the buster in place // Make sure they know it blew up prematurely. EmitSound( "Weapon_StriderBuster.Dud_Detonate" ); DispatchParticleEffect( "striderbuster_break_flechette", GetAbsOrigin(), GetAbsAngles() ); SetHealth( 0 ); Shatter( info.GetAttacker() ); return 0; } } if ( info.GetDamage() < 5 ) { bool bFirst = ( m_CarryAngles.x == 45 && m_CarryAngles.y == 0 && m_CarryAngles.z == 0); float sinTime = sin( gpGlobals->curtime ); bool bSubtractX = ( bFirst ) ? ( sinTime < 0 ) : ( m_CarryAngles.x < 45 ); m_CarryAngles.x += ( 10.0 + 10.0 * fabsf( sinTime ) + random->RandomFloat( -2.5, 2.5 ) + random->RandomFloat( -2.5, 2.5 ) ) * ( ( bSubtractX ) ? -1.0 : 1.0 ); m_CarryAngles.y = 15 * ( sin( gpGlobals->curtime ) + cos( gpGlobals->curtime * 0.5 ) ) * .5 + random->RandomFloat( -15, 15 ); m_CarryAngles.z = 7.5 * ( sin( gpGlobals->curtime ) + sin( gpGlobals->curtime * 2.0 ) ) * .5 + random->RandomFloat( -7.5, 7.5 ); } return 1; } } // Allow crushing damage if ( info.GetDamageType() & DMG_CRUSH ) return BaseClass::OnTakeDamage( info ); return 0; }
void CNPC_Zombine::HandleAnimEvent( animevent_t *pEvent ) { if ( pEvent->event == AE_ZOMBINE_PULLPIN ) { Vector vecStart; QAngle angles; GetAttachment( "grenade_attachment", vecStart, angles ); CBaseGrenade *pGrenade = Fraggrenade_Create( vecStart, vec3_angle, vec3_origin, AngularImpulse( 0, 0, 0 ), this, 3.5f, true ); if ( pGrenade ) { // Move physobject to shadow IPhysicsObject *pPhysicsObject = pGrenade->VPhysicsGetObject(); if ( pPhysicsObject ) { pGrenade->VPhysicsDestroyObject(); int iAttachment = LookupAttachment( "grenade_attachment"); pGrenade->SetMoveType( MOVETYPE_NONE ); pGrenade->SetSolid( SOLID_NONE ); pGrenade->SetCollisionGroup( COLLISION_GROUP_DEBRIS ); pGrenade->SetAbsOrigin( vecStart ); pGrenade->SetAbsAngles( angles ); pGrenade->SetParent( this, iAttachment ); pGrenade->SetDamage( 200.0f ); m_hGrenade = pGrenade; EmitSound( "Zombine.ReadyGrenade" ); // Tell player allies nearby to regard me! CAI_BaseNPC **ppAIs = g_AI_Manager.AccessAIs(); CAI_BaseNPC *pNPC; for ( int i = 0; i < g_AI_Manager.NumAIs(); i++ ) { pNPC = ppAIs[i]; if( pNPC->Classify() == CLASS_PLAYER_ALLY || ( pNPC->Classify() == CLASS_PLAYER_ALLY_VITAL && pNPC->FVisible(this) ) ) { int priority; Disposition_t disposition; priority = pNPC->IRelationPriority(this); disposition = pNPC->IRelationType(this); pNPC->AddEntityRelationship( this, disposition, priority + 1 ); } } } m_iGrenadeCount--; } return; } if ( pEvent->event == AE_NPC_ATTACK_BROADCAST ) { if ( HasGrenade() ) return; } BaseClass::HandleAnimEvent( pEvent ); }
//--------------------------------------------------------- //--------------------------------------------------------- void CNPC_Roller::RunTask( const Task_t *pTask ) { switch( pTask->iTask ) { case TASK_ROLLER_UNSTICK: { float yaw = UTIL_VecToYaw( m_vecUnstickDirection ); Vector vecRight; AngleVectors( QAngle( 0, yaw, 0 ), NULL, &vecRight, NULL ); m_RollerController.m_vecAngular = WorldToLocalRotation( SetupMatrixAngles(GetLocalAngles()), vecRight, m_flForwardSpeed ); } if( gpGlobals->curtime > m_flWaitFinished ) { TaskComplete(); } break; case TASK_ROLLER_WAIT_FOR_PHYSICS: { Vector vecVelocity; VPhysicsGetObject()->GetVelocity( &vecVelocity, NULL ); if( VPhysicsGetObject()->IsAsleep() ) { TaskComplete(); } } break; case TASK_RUN_PATH: case TASK_WALK_PATH: // Start turning early if( (GetLocalOrigin() - GetNavigator()->GetCurWaypointPos() ).Length() <= 64 ) { if( GetNavigator()->CurWaypointIsGoal() ) { // Hit the brakes a bit. float yaw = UTIL_VecToYaw( GetNavigator()->GetCurWaypointPos() - GetLocalOrigin() ); Vector vecRight; AngleVectors( QAngle( 0, yaw, 0 ), NULL, &vecRight, NULL ); m_RollerController.m_vecAngular += WorldToLocalRotation( SetupMatrixAngles(GetLocalAngles()), vecRight, -m_flForwardSpeed * 5 ); TaskComplete(); return; } GetNavigator()->AdvancePath(); } { float yaw = UTIL_VecToYaw( GetNavigator()->GetCurWaypointPos() - GetLocalOrigin() ); Vector vecRight; Vector vecToPath; // points at the path AngleVectors( QAngle( 0, yaw, 0 ), &vecToPath, &vecRight, NULL ); // figure out if the roller is turning. If so, cut the throttle a little. float flDot; Vector vecVelocity; VPhysicsGetObject()->GetVelocity( &vecVelocity, NULL ); VectorNormalize( vecVelocity ); vecVelocity.z = 0; flDot = DotProduct( vecVelocity, vecToPath ); m_RollerController.m_vecAngular = vec3_origin; if( flDot > 0.25 && flDot < 0.7 ) { // Feed a little torque backwards into the axis perpendicular to the velocity. // This will help get rid of momentum that would otherwise make us overshoot our goal. Vector vecCompensate; vecCompensate.x = vecVelocity.y; vecCompensate.y = -vecVelocity.x; vecCompensate.z = 0; m_RollerController.m_vecAngular = WorldToLocalRotation( SetupMatrixAngles(GetLocalAngles()), vecCompensate, m_flForwardSpeed * -0.75 ); } m_RollerController.m_vecAngular += WorldToLocalRotation( SetupMatrixAngles(GetLocalAngles()), vecRight, m_flForwardSpeed ); } break; case TASK_ROLLER_ISSUE_CODE: if( gpGlobals->curtime >= m_flWaitFinished ) { if( m_iCodeProgress == ROLLER_CODE_DIGITS ) { TaskComplete(); } else { m_flWaitFinished = gpGlobals->curtime + ROLLER_TONE_TIME; CPASAttenuationFilter filter( this ); EmitSound( filter, entindex(), CHAN_BODY, pCodeSounds[ m_iAccessCode[ m_iCodeProgress ] ], 1.0, ATTN_NORM ); m_iCodeProgress++; } } break; default: BaseClass::RunTask( pTask ); break; } }
//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CWeaponStriderBuster::BusterPingThink() { EmitSound( "Weapon_StriderBuster.Ping" ); SetContextThink( &CWeaponStriderBuster::BusterPingThink, gpGlobals->curtime + BUSTER_PING_SOUND_FREQ, s_pBusterPingThinkContext ); }
void CC4::PrimaryAttack() { bool PlaceBomb = false; CCSPlayer *pPlayer = GetPlayerOwner(); if ( !pPlayer ) return; int onGround = FBitSet( pPlayer->GetFlags(), FL_ONGROUND ); CBaseEntity *groundEntity = (onGround) ? pPlayer->GetGroundEntity() : NULL; if ( groundEntity ) { // Don't let us stand on players, breakables, or pushaway physics objects to plant if ( groundEntity->IsPlayer() || IsPushableEntity( groundEntity ) || #ifndef CLIENT_DLL IsBreakableEntity( groundEntity ) || #endif // !CLIENT_DLL IsPushAwayEntity( groundEntity ) ) { onGround = false; } } if( m_bStartedArming == false && m_bBombPlanted == false ) { if( pPlayer->m_bInBombZone && onGround ) { m_bStartedArming = true; m_fArmedTime = gpGlobals->curtime + WEAPON_C4_ARM_TIME; m_bBombPlacedAnimation = false; #if !defined( CLIENT_DLL ) // init the beep flags int i; for( i=0;i<NUM_BEEPS;i++ ) m_bPlayedArmingBeeps[i] = false; // freeze the player in place while planting pPlayer->SetMaxSpeed( 1 ); // player "arming bomb" animation pPlayer->SetAnimation( PLAYER_ATTACK1 ); pPlayer->SetNextAttack( gpGlobals->curtime ); IGameEvent * event = gameeventmanager->CreateEvent( "bomb_beginplant" ); if( event ) { event->SetInt("userid", pPlayer->GetUserID() ); event->SetInt("site", pPlayer->m_iBombSiteIndex ); event->SetInt( "priority", 8 ); gameeventmanager->FireEvent( event ); } #endif SendWeaponAnim( ACT_VM_PRIMARYATTACK ); FX_PlantBomb( pPlayer->entindex(), pPlayer->Weapon_ShootPosition() ); } else { if ( !pPlayer->m_bInBombZone ) { ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Plant_At_Bomb_Spot"); } else { ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Plant_Must_Be_On_Ground"); } m_flNextPrimaryAttack = gpGlobals->curtime + 1.0; return; } } else { if ( !onGround || !pPlayer->m_bInBombZone ) { if( !pPlayer->m_bInBombZone ) { ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Arming_Cancelled" ); } else { ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Plant_Must_Be_On_Ground" ); } m_flNextPrimaryAttack = gpGlobals->curtime + 1.5; m_bStartedArming = false; #if !defined( CLIENT_DLL ) // release the player from being frozen, we've somehow left the bomb zone pPlayer->ResetMaxSpeed(); pPlayer->SetProgressBarTime( 0 ); //pPlayer->SetAnimation( PLAYER_HOLDBOMB ); IGameEvent * event = gameeventmanager->CreateEvent( "bomb_abortplant" ); if( event ) { event->SetInt("userid", pPlayer->GetUserID() ); event->SetInt("site", pPlayer->m_iBombSiteIndex ); event->SetInt( "priority", 8 ); gameeventmanager->FireEvent( event ); } #endif if(m_bBombPlacedAnimation == true) //this means the placement animation is canceled { SendWeaponAnim( ACT_VM_DRAW ); } else { SendWeaponAnim( ACT_VM_IDLE ); } return; } else { #ifndef CLIENT_DLL PlayArmingBeeps(); #endif if( gpGlobals->curtime >= m_fArmedTime ) //the c4 is ready to be armed { //check to make sure the player is still in the bomb target area PlaceBomb = true; } else if( ( gpGlobals->curtime >= (m_fArmedTime - 0.75) ) && ( !m_bBombPlacedAnimation ) ) { //call the c4 Placement animation m_bBombPlacedAnimation = true; SendWeaponAnim( ACT_VM_SECONDARYATTACK ); #if !defined( CLIENT_DLL ) // player "place" animation //pPlayer->SetAnimation( PLAYER_HOLDBOMB ); #endif } } } if ( PlaceBomb && m_bStartedArming ) { m_bStartedArming = false; m_fArmedTime = 0; if( pPlayer->m_bInBombZone ) { #if !defined( CLIENT_DLL ) CPlantedC4 *pC4 = CPlantedC4::ShootSatchelCharge( pPlayer, pPlayer->GetAbsOrigin(), pPlayer->GetAbsAngles() ); if ( pC4 ) { pC4->SetBombSiteIndex( pPlayer->m_iBombSiteIndex ); trace_t tr; UTIL_TraceEntity( pC4, GetAbsOrigin(), GetAbsOrigin() + Vector(0,0,-200), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr ); pC4->SetAbsOrigin( tr.endpos ); CBombTarget *pBombTarget = (CBombTarget*)UTIL_EntityByIndex( pPlayer->m_iBombSiteIndex ); if ( pBombTarget ) { CBaseEntity *pAttachPoint = gEntList.FindEntityByName( NULL, pBombTarget->GetBombMountTarget() ); if ( pAttachPoint ) { pC4->SetAbsOrigin( pAttachPoint->GetAbsOrigin() ); pC4->SetAbsAngles( pAttachPoint->GetAbsAngles() ); pC4->SetParent( pAttachPoint ); } variant_t emptyVariant; pBombTarget->AcceptInput( "BombPlanted", pC4, pC4, emptyVariant, 0 ); } } IGameEvent * event = gameeventmanager->CreateEvent( "bomb_planted" ); if( event ) { event->SetInt("userid", pPlayer->GetUserID() ); event->SetInt("site", pPlayer->m_iBombSiteIndex ); event->SetInt("posx", pPlayer->GetAbsOrigin().x ); event->SetInt("posy", pPlayer->GetAbsOrigin().y ); event->SetInt( "priority", 8 ); gameeventmanager->FireEvent( event ); } // Fire a beep event also so the bots have a chance to hear the bomb event = gameeventmanager->CreateEvent( "bomb_beep" ); if ( event ) { event->SetInt( "entindex", entindex() ); gameeventmanager->FireEvent( event ); } pPlayer->SetProgressBarTime( 0 ); CSGameRules()->m_bBombDropped = false; CSGameRules()->m_bBombPlanted = true; // Play the plant sound. Vector plantPosition = pPlayer->GetAbsOrigin() + Vector( 0, 0, 5 ); CPASAttenuationFilter filter( plantPosition ); EmitSound( filter, entindex(), "c4.plant" ); // release the player from being frozen pPlayer->ResetMaxSpeed(); // No more c4! pPlayer->Weapon_Drop( this, NULL, NULL ); UTIL_Remove( this ); #endif //don't allow the planting to start over again next frame. m_bBombPlanted = true; return; } else { ClientPrint( pPlayer, HUD_PRINTCENTER, "#C4_Activated_At_Bomb_Spot" ); #if !defined( CLIENT_DLL ) //pPlayer->SetAnimation( PLAYER_HOLDBOMB ); // release the player from being frozen pPlayer->ResetMaxSpeed(); IGameEvent * event = gameeventmanager->CreateEvent( "bomb_abortplant" ); if( event ) { event->SetInt("userid", pPlayer->GetUserID() ); event->SetInt("site", pPlayer->m_iBombSiteIndex ); event->SetInt( "priority", 8 ); gameeventmanager->FireEvent( event ); } #endif m_flNextPrimaryAttack = gpGlobals->curtime + 1.0; return; } } m_flNextPrimaryAttack = gpGlobals->curtime + 0.3; SetWeaponIdleTime( gpGlobals->curtime + SharedRandomFloat("C4IdleTime", 10, 15 ) ); }
//----------------------------------------------------------------------------- // Purpose: Input handler for making the explosion explode. //----------------------------------------------------------------------------- void CASWEnvExplosion::InputExplode( inputdata_t &inputdata ) { trace_t tr; SetModelName( NULL_STRING );//invisible SetSolid( SOLID_NONE );// intangible Vector vecSpot = GetAbsOrigin() + Vector( 0 , 0 , 8 ); UTIL_TraceLine( vecSpot, vecSpot + Vector( 0, 0, -40 ), (MASK_SOLID_BRUSHONLY | MASK_WATER), this, COLLISION_GROUP_NONE, &tr ); // Pull out of the wall a bit. We used to move the explosion origin itself, but that seems unnecessary, not to mention a // little weird when you consider that it might be in hierarchy. Instead we just calculate a new virtual position at // which to place the explosion. We don't use that new position to calculate radius damage because according to Steve's // comment, that adversely affects the force vector imparted on explosion victims when they ragdoll. Vector vecExplodeOrigin = GetAbsOrigin(); if ( tr.fraction != 1.0 ) { vecExplodeOrigin = tr.endpos + (tr.plane.normal * 24 ); } // draw decal if (! ( m_spawnflags & SF_ENVEXPLOSION_NODECAL )) { if ( ! ( m_spawnflags & SF_ENVEXPLOSION_ICE )) UTIL_DecalTrace( &tr, "Scorch" ); else UTIL_DecalTrace( &tr, "Ice_Explosion_Decal" ); } //Get the damage override if specified float flRadius = ( m_iRadiusOverride > 0 ) ? ((float)m_iRadiusOverride/100.0f) : ( (float)m_iDamage / 100.0f ); // do damage if ( !( m_spawnflags & SF_ENVEXPLOSION_NODAMAGE ) ) { CBaseEntity *pAttacker = GetOwnerEntity() ? GetOwnerEntity() : this; // Only calculate damage type if we didn't get a custom one passed in int iDamageType = m_iCustomDamageType; if ( iDamageType == -1 ) { iDamageType = HasSpawnFlags( SF_ENVEXPLOSION_GENERIC_DAMAGE ) ? DMG_GENERIC : DMG_BLAST; } CTakeDamageInfo info( m_hInflictor ? m_hInflictor : this, pAttacker, m_iDamage, iDamageType ); if( HasSpawnFlags( SF_ENVEXPLOSION_SURFACEONLY ) ) { info.AddDamageType( DMG_BLAST_SURFACE ); } if ( m_flDamageForce ) { // Not the right direction, but it'll be fixed up by RadiusDamage. info.SetDamagePosition( GetAbsOrigin() ); info.SetDamageForce( Vector( m_flDamageForce, 0, 0 ) ); } ASWGameRules()->RadiusDamage( info, GetAbsOrigin(), flRadius, m_iClassIgnore, m_hEntityIgnore.Get() ); } // emit the sound if( !(m_spawnflags & SF_ENVEXPLOSION_NOSOUND) ) { EmitSound( STRING(m_iszExplosionSound) ); } // do the particle effect if( !(m_spawnflags & SF_ENVEXPLOSION_NOFIREBALL) ) { bool bOnGround = false; if ( tr.fraction != 1.0 ) bOnGround = true; UTIL_ASW_EnvExplosionFX( vecExplodeOrigin, flRadius, bOnGround ); } /* // do a dlight if ( !( m_spawnflags & SF_ENVEXPLOSION_NODLIGHTS ) ) { // Make an elight dlight_t *el = effects->CL_AllocDlight( LIGHT_INDEX_TE_DYNAMIC + entindex() ); el->origin = vecExplodeOrigin; el->radius = random->RandomFloat( flRadius + 54.0f, flRadius + 74.0f ); el->decay = el->radius / 0.05f; el->die = gpGlobals->curtime + 0.05f; Color c = Color( 255, 192, 64, 6 ); el->color.r = c.r(); el->color.g = c.g(); el->color.b = c.b(); el->color.exponent = c.a(); } */ if ( !(m_spawnflags & SF_ENVEXPLOSION_REPEATABLE) ) { SetThink( &CASWEnvExplosion::SUB_Remove ); SetNextThink( gpGlobals->curtime + 1.0f ); } }
// Regular explosions void CPlantedC4::Explode( trace_t *pTrace, int bitsDamageType ) { // Check to see if the round is over after the bomb went off... CSGameRules()->m_bTargetBombed = true; m_bBombTicking = false; CSGameRules()->CheckWinConditions(); // Do the Damage float flBombRadius = 500; if ( g_pMapInfo ) flBombRadius = g_pMapInfo->m_flBombRadius; // Output to the bomb target ent CBaseEntity *pTarget = NULL; variant_t emptyVariant; while ((pTarget = gEntList.FindEntityByClassname( pTarget, "func_bomb_target" )) != NULL) { //Adrian - But only to the one we want! if ( pTarget->entindex() != m_iBombSiteIndex ) continue; pTarget->AcceptInput( "BombExplode", this, this, emptyVariant, 0 ); break; } // Pull out of the wall a bit if ( pTrace->fraction != 1.0 ) { SetAbsOrigin( pTrace->endpos + (pTrace->plane.normal * 0.6) ); } { Vector pos = GetAbsOrigin() + Vector( 0,0,8 ); // add an explosion TE so it affects clientside physics CPASFilter filter( pos ); te->Explosion( filter, 0.0, &pos, g_sModelIndexFireball, 50.0, 25, TE_EXPLFLAG_NONE, flBombRadius * 3.5, 200 ); } // Fireball sprite and sound!! { Vector fireballPos = GetAbsOrigin(); CPVSFilter filter( fireballPos ); te->Sprite( filter, 0, &fireballPos, g_sModelIndexFireball, 100, 150 ); } { Vector fireballPos = GetAbsOrigin() + Vector( random->RandomFloat( -512, 512 ), random->RandomFloat( -512, 512 ), random->RandomFloat( -10, 10 ) ); CPVSFilter filter( fireballPos ); te->Sprite( filter, 0, &fireballPos, g_sModelIndexFireball, 100, 150 ); } { Vector fireballPos = GetAbsOrigin() + Vector( random->RandomFloat( -512, 512 ), random->RandomFloat( -512, 512 ), random->RandomFloat( -10, 10 ) ); CPVSFilter filter( fireballPos ); te->Sprite( filter, 0, &fireballPos, g_sModelIndexFireball, 100, 150 ); } // Sound! for everyone CBroadcastRecipientFilter filter; EmitSound( filter, entindex(), "c4.explode" ); // Decal! UTIL_DecalTrace( pTrace, "Scorch" ); // Shake! UTIL_ScreenShake( pTrace->endpos, 25.0, 150.0, 1.0, 3000, SHAKE_START ); SetOwnerEntity( NULL ); // can't traceline attack owner if this is set CSGameRules()->RadiusDamage( CTakeDamageInfo( this, GetOwnerEntity(), flBombRadius, bitsDamageType ), GetAbsOrigin(), flBombRadius * 3.5, //Matt - don't ask me, this is how CS does it. CLASS_NONE, true ); // IGNORE THE WORLD!! // send director message, that something important happed here /* MESSAGE_BEGIN( MSG_SPEC, SVC_DIRECTOR ); WRITE_BYTE ( 9 ); // command length in bytes WRITE_BYTE ( DRC_CMD_EVENT ); // bomb explode WRITE_SHORT( ENTINDEX(this->edict()) ); // index number of primary entity WRITE_SHORT( 0 ); // index number of secondary entity WRITE_LONG( 15 | DRC_FLAG_FINAL ); // eventflags (priority and flags) MESSAGE_END(); */ UTIL_Remove( this ); }
// For CTs to defuse the c4 void CPlantedC4::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { //Can't defuse if its already defused or if it has blown up if( !m_bBombTicking ) { SetUse( NULL ); return; } CCSPlayer *player = dynamic_cast< CCSPlayer* >( pActivator ); if ( !player || player->GetTeamNumber() != TEAM_CT ) return; if ( m_bStartDefuse ) { if ( player != m_pBombDefuser ) { if ( player->m_iNextTimeCheck < gpGlobals->curtime ) { ClientPrint( player, HUD_PRINTCENTER, "#Bomb_Already_Being_Defused" ); player->m_iNextTimeCheck = gpGlobals->curtime + 1; } return; } m_flNextDefuse = gpGlobals->curtime + 0.5; } else { // freeze the player in place while defusing player->SetMaxSpeed( 1 ); IGameEvent * event = gameeventmanager->CreateEvent("bomb_begindefuse" ); if( event ) { event->SetInt( "userid", player->GetUserID() ); if ( player->HasDefuser() ) { event->SetInt( "haskit", 1 ); // TODO show messages on clients on event ClientPrint( player, HUD_PRINTCENTER, "#Defusing_Bomb_With_Defuse_Kit" ); } else { event->SetInt( "haskit", 0 ); // TODO show messages on clients on event ClientPrint( player, HUD_PRINTCENTER, "#Defusing_Bomb_Without_Defuse_Kit" ); } event->SetInt( "priority", 8 ); gameeventmanager->FireEvent( event ); } Vector soundPosition = player->GetAbsOrigin() + Vector( 0, 0, 5 ); CPASAttenuationFilter filter( soundPosition ); EmitSound( filter, entindex(), "c4.disarmstart" ); m_flDefuseLength = player->HasDefuser() ? 5 : 10; m_flNextDefuse = gpGlobals->curtime + 0.5; m_pBombDefuser = player; m_bStartDefuse = TRUE; player->m_bIsDefusing = true; m_flDefuseCountDown = gpGlobals->curtime + m_flDefuseLength; //start the progress bar player->SetProgressBarTime( m_flDefuseLength ); } }
void CPlantedC4::C4Think() { if (!IsInWorld()) { UTIL_Remove( this ); return; } //Bomb is dead, don't think anymore if( !m_bBombTicking ) { SetThink( NULL ); return; } SetNextThink( gpGlobals->curtime + 0.12 ); #ifndef CLIENT_DLL // let the bots hear the bomb beeping // BOTPORT: Emit beep events at same time as client effects IGameEvent * event = gameeventmanager->CreateEvent( "bomb_beep" ); if( event ) { event->SetInt( "entindex", entindex() ); gameeventmanager->FireEvent( event ); } #endif // IF the timer has expired ! blow this bomb up! if (m_flC4Blow <= gpGlobals->curtime) { // give the defuser credit for defusing the bomb CBasePlayer *pBombOwner = dynamic_cast< CBasePlayer* >( GetOwnerEntity() ); if ( pBombOwner ) { pBombOwner->IncrementFragCount( 3 ); } CSGameRules()->m_bBombDropped = false; trace_t tr; Vector vecSpot = GetAbsOrigin(); vecSpot[2] += 8; UTIL_TraceLine( vecSpot, vecSpot + Vector ( 0, 0, -40 ), MASK_SOLID, this, COLLISION_GROUP_NONE, &tr ); Explode( &tr, DMG_BLAST ); CSGameRules()->m_bBombPlanted = false; IGameEvent * event = gameeventmanager->CreateEvent( "bomb_exploded" ); if( event ) { event->SetInt( "userid", pBombOwner?pBombOwner->GetUserID():-1 ); event->SetInt( "site", m_iBombSiteIndex ); event->SetInt( "priority", 9 ); gameeventmanager->FireEvent( event ); } } //if the defusing process has started if ((m_bStartDefuse == true) && (m_pBombDefuser != NULL)) { //if the defusing process has not ended yet if ( m_flDefuseCountDown > gpGlobals->curtime) { int iOnGround = FBitSet( m_pBombDefuser->GetFlags(), FL_ONGROUND ); //if the bomb defuser has stopped defusing the bomb if( m_flNextDefuse < gpGlobals->curtime || !iOnGround ) { if ( !iOnGround && m_pBombDefuser->IsAlive() ) ClientPrint( m_pBombDefuser, HUD_PRINTCENTER, "#C4_Defuse_Must_Be_On_Ground"); // release the player from being frozen m_pBombDefuser->ResetMaxSpeed(); m_pBombDefuser->m_bIsDefusing = false; #ifndef CLIENT_DLL // tell the bots someone has aborted defusing IGameEvent * event = gameeventmanager->CreateEvent( "bomb_abortdefuse" ); if( event ) { event->SetInt("userid", m_pBombDefuser->GetUserID() ); event->SetInt( "priority", 6 ); gameeventmanager->FireEvent( event ); } #endif //cancel the progress bar m_pBombDefuser->SetProgressBarTime( 0 ); m_pBombDefuser = NULL; m_bStartDefuse = false; m_flDefuseCountDown = 0; m_flDefuseLength = 0; //force it to show completely defused } return; } //if the defuse process has ended, kill the c4 else if ( !m_pBombDefuser->IsDead() ) { IGameEvent * event = gameeventmanager->CreateEvent( "bomb_defused" ); if( event ) { event->SetInt("userid", m_pBombDefuser->GetUserID() ); event->SetInt("site", m_iBombSiteIndex ); event->SetInt( "priority", 9 ); gameeventmanager->FireEvent( event ); } Vector soundPosition = m_pBombDefuser->GetAbsOrigin() + Vector( 0, 0, 5 ); CPASAttenuationFilter filter( soundPosition ); EmitSound( filter, entindex(), "c4.disarmfinish" ); // The bomb has just been disarmed.. Check to see if the round should end now m_bBombTicking = false; // release the player from being frozen m_pBombDefuser->ResetMaxSpeed(); m_pBombDefuser->m_bIsDefusing = false; CSGameRules()->m_bBombDefused = true; CSGameRules()->CheckWinConditions(); // give the defuser credit for defusing the bomb m_pBombDefuser->IncrementFragCount( 3 ); CSGameRules()->m_bBombDropped = false; CSGameRules()->m_bBombPlanted = false; // Clear their progress bar. m_pBombDefuser->SetProgressBarTime( 0 ); m_pBombDefuser = NULL; m_bStartDefuse = false; m_flDefuseLength = 10; return; } #ifndef CLIENT_DLL // tell the bots someone has aborted defusing IGameEvent * event = gameeventmanager->CreateEvent( "bomb_abortdefuse" ); if( event ) { event->SetInt("userid", m_pBombDefuser->GetUserID() ); event->SetInt( "priority", 6 ); gameeventmanager->FireEvent( event ); } #endif //if it gets here then the previouse defuser has taken off or been killed // release the player from being frozen m_pBombDefuser->ResetMaxSpeed(); m_pBombDefuser->m_bIsDefusing = false; m_bStartDefuse = false; m_pBombDefuser = NULL; } }
// Reappear void CRotatingPickup::Materialize() { EmitSound("AlyxEmp.Charge"); m_bRespawning = false; SetTouch(&CItem::ItemTouch); }
//========================================================= // HandleAnimEvent - catches the monster-specific messages // that occur when tagged animation frames are played. //========================================================= void CNPC_Bullsquid::HandleAnimEvent( animevent_t *pEvent ) { switch( pEvent->event ) { case BSQUID_AE_SPIT: { if ( GetEnemy() ) { Vector vecSpitOffset; Vector vecSpitDir; Vector vRight, vUp, vForward; AngleVectors ( GetAbsAngles(), &vForward, &vRight, &vUp ); // !!!HACKHACK - the spot at which the spit originates (in front of the mouth) was measured in 3ds and hardcoded here. // we should be able to read the position of bones at runtime for this info. vecSpitOffset = ( vRight * 8 + vForward * 60 + vUp * 50 ); vecSpitOffset = ( GetAbsOrigin() + vecSpitOffset ); vecSpitDir = ( ( GetEnemy()->BodyTarget( GetAbsOrigin() ) ) - vecSpitOffset ); VectorNormalize( vecSpitDir ); vecSpitDir.x += random->RandomFloat( -0.05, 0.05 ); vecSpitDir.y += random->RandomFloat( -0.05, 0.05 ); vecSpitDir.z += random->RandomFloat( -0.05, 0 ); AttackSound(); CSquidSpit::Shoot( this, vecSpitOffset, vecSpitDir * 900 ); } } break; case BSQUID_AE_BITE: { // SOUND HERE! CBaseEntity *pHurt = CheckTraceHullAttack( 70, Vector(-16,-16,-16), Vector(16,16,16), sk_bullsquid_dmg_bite.GetFloat(), DMG_SLASH ); if ( pHurt ) { Vector forward, up; AngleVectors( GetAbsAngles(), &forward, NULL, &up ); pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() - (forward * 100) ); pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() + (up * 100) ); pHurt->SetGroundEntity( NULL ); } } break; case BSQUID_AE_TAILWHIP: { CBaseEntity *pHurt = CheckTraceHullAttack( 70, Vector(-16,-16,-16), Vector(16,16,16), sk_bullsquid_dmg_whip.GetFloat(), DMG_SLASH | DMG_ALWAYSGIB ); if ( pHurt ) { Vector right, up; AngleVectors( GetAbsAngles(), NULL, &right, &up ); if ( pHurt->GetFlags() & ( FL_NPC | FL_CLIENT ) ) pHurt->ViewPunch( QAngle( 20, 0, -20 ) ); pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() + (right * 200) ); pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() + (up * 100) ); } } break; case BSQUID_AE_BLINK: { // close eye. m_nSkin = 1; } break; case BSQUID_AE_HOP: { float flGravity = sv_gravity.GetFloat(); // throw the squid up into the air on this frame. if ( GetFlags() & FL_ONGROUND ) { SetGroundEntity( NULL ); } // jump into air for 0.8 (24/30) seconds Vector vecVel = GetAbsVelocity(); vecVel.z += ( 0.625 * flGravity ) * 0.5; SetAbsVelocity( vecVel ); } break; case BSQUID_AE_THROW: { // squid throws its prey IF the prey is a client. CBaseEntity *pHurt = CheckTraceHullAttack( 70, Vector(-16,-16,-16), Vector(16,16,16), 0, 0 ); if ( pHurt ) { // croonchy bite sound CPASAttenuationFilter filter( this ); EmitSound( filter, entindex(), "Bullsquid.Bite" ); // screeshake transforms the viewmodel as well as the viewangle. No problems with seeing the ends of the viewmodels. UTIL_ScreenShake( pHurt->GetAbsOrigin(), 25.0, 1.5, 0.7, 2, SHAKE_START ); if ( pHurt->IsPlayer() ) { Vector forward, up; AngleVectors( GetAbsAngles(), &forward, NULL, &up ); pHurt->SetAbsVelocity( pHurt->GetAbsVelocity() + forward * 300 + up * 300 ); } } } break; default: BaseClass::HandleAnimEvent( pEvent ); } }
//----------------------------------------------------------------------------- // Purpose: // // // Output : //----------------------------------------------------------------------------- void CNPC_Roller::PowerOnSound( void ) { EmitSound( "NPC_Roller.PowerOn" ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPropCannon::Think( void ) { SetNextThink( gpGlobals->curtime + 0.1 ); if ( GetDriver() ) { BaseClass::Think(); } if ( GetDriver() ) { BaseClass::Think(); // play enter animation StudioFrameAdvance(); // If the enter or exit animation has finished, tell the server vehicle if ( IsSequenceFinished() && (m_bExitAnimOn || m_bEnterAnimOn) ) { if ( m_bEnterAnimOn ) { // Finished entering, display the hint for using the crane //UTIL_HudHintText( m_hPlayer, "#Valve_Hint_CraneKeys" ); } GetServerVehicle()->HandleEntryExitFinish( m_bExitAnimOn, true ); } } else { // Run the crane's movement // RunCraneMovement( 0.1 ); } // Update follower bones m_BoneFollowerManager.UpdateBoneFollowers(this); if ( m_flFlyTime > 0.0f ) { if ( m_flFlyTime - 1.0f <= gpGlobals->curtime && m_flFlyTime - 0.8f > gpGlobals->curtime) { CPASAttenuationFilter filter( this ); EmitSound_t ep; ep.m_nChannel = CHAN_STATIC; ep.m_pSoundName = "Weapon_Mortar.Incomming"; ep.m_flVolume = 255; ep.m_SoundLevel = SNDLVL_180dB; EmitSound( filter, entindex(), ep ); } if ( m_flFlyTime <= gpGlobals->curtime ) { if ( m_vCrashPoint != vec3_origin ) { ProjectileExplosion(); } CEffectData data; data.m_vOrigin = m_vCrashPoint; data.m_flScale = 512; DispatchEffect( "ThumperDust", data ); m_flFlyTime = 0.0f; } } }
//----------------------------------------------------------------------------- // Purpose: // // // Output : //----------------------------------------------------------------------------- void CNPC_Roller::PowerOffSound( void ) { EmitSound( "NPC_Roller.PowerOff" ); }
void CPropCannon::LaunchProjectile( void ) { //ADRIANTODO: Come back to this once we get the right model and remove all the fix ups caused by temp content. Vector vTipPos, vTipForward, vTipRight, vUp; GetAttachment( "cable_tip", vTipPos, &vTipForward, &vTipRight, &vUp ); bool bCollided = false; bool bInSky = false; float gravity = -gpGlobals->frametime * 600; Vector vOrigin = vTipPos; Vector vVelocity = vTipRight * 2500; float flDistance = 0.0f; int iFailSafe = 0; while ( bCollided == false && iFailSafe < 100000 ) { Vector vOldOrigin = vOrigin; vOrigin = vOrigin + vVelocity * gpGlobals->frametime; flDistance += (vOrigin - vOldOrigin).Length(); if ( g_cannon_debug.GetBool() == true ) { NDebugOverlay::Line( vOldOrigin, vOrigin, 0, 255, 0, true, 5 ); } trace_t pm; UTIL_TraceLine( vOldOrigin, vOrigin, MASK_SOLID, this, COLLISION_GROUP_NONE, &pm ); if ( pm.surface.flags & SURF_SKY || pm.allsolid == true ) { bInSky = true; iFailSafe++; } else { bInSky = false; } iFailSafe++; if ( pm.fraction != 1.0f && bInSky == false ) { bCollided = true; vOrigin = pm.endpos; if ( g_cannon_debug.GetBool() == true ) { NDebugOverlay::Box( vOrigin, Vector( 256, 256, 256 ), Vector( -256, -256, -256 ), 255, 0, 0, 0, 5 ); } } else { vVelocity[2] += gravity; } } float flTravelTime = flDistance / vVelocity.Length(); if ( flTravelTime > g_cannon_max_traveltime.GetFloat() ) { flTravelTime = g_cannon_max_traveltime.GetFloat(); if ( bCollided == false ) { vOrigin = vec3_origin; } } m_flFlyTime = gpGlobals->curtime + flTravelTime; m_vCrashPoint = vOrigin; m_flNextAttackTime = gpGlobals->curtime + g_cannon_reloadtime.GetFloat(); EmitSound( "HeadcrabCanister.LaunchSound" ); UTIL_ScreenShake( GetDriver()->GetAbsOrigin(), 50.0, 150.0, 1.0, 750, SHAKE_START, true ); }
//----------------------------------------------------------------------------- // Purpose: // Input : *pActivator - // *pCaller - // useType - // value - //----------------------------------------------------------------------------- void CNewWallHealth::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { // Make sure that we have a caller if (!pActivator) return; // if it's not a player, ignore if ( !pActivator->IsPlayer() ) return; CBasePlayer *pPlayer = dynamic_cast<CBasePlayer *>(pActivator); // Reset to a state of continuous use. m_iCaps = FCAP_CONTINUOUS_USE; if ( m_iOn ) { float flCharges = CHARGES_PER_SECOND; float flCalls = CALLS_PER_SECOND; m_flJuice -= flCharges / flCalls; StudioFrameAdvance(); } // if there is no juice left, turn it off if (m_iJuice <= 0) { ResetSequence( LookupSequence( "emptyclick" ) ); m_nState = 1; Off(); } // if the player doesn't have the suit, or there is no juice left, make the deny noise. // disabled HEV suit dependency for now. //if ((m_iJuice <= 0) || (!(pActivator->m_bWearingSuit))) if (m_iJuice <= 0) { if (m_flSoundTime <= gpGlobals->curtime) { m_flSoundTime = gpGlobals->curtime + 0.62; EmitSound( "WallHealth.Deny" ); } return; } if( pActivator->GetHealth() >= pActivator->GetMaxHealth() ) { if( pPlayer ) { pPlayer->m_afButtonPressed &= ~IN_USE; } // Make the user re-use me to get started drawing health. m_iCaps = FCAP_IMPULSE_USE; EmitSound( "WallHealth.Deny" ); return; } SetNextThink( gpGlobals->curtime + CHARGE_RATE ); SetThink( &CNewWallHealth::Off ); // Time to recharge yet? if (m_flNextCharge >= gpGlobals->curtime) return; // Play the on sound or the looping charging sound if (!m_iOn) { m_iOn++; EmitSound( "WallHealth.Start" ); m_flSoundTime = 0.56 + gpGlobals->curtime; m_OnPlayerUse.FireOutput( pActivator, this ); } if ((m_iOn == 1) && (m_flSoundTime <= gpGlobals->curtime)) { m_iOn++; CPASAttenuationFilter filter( this, "WallHealth.LoopingContinueCharge" ); filter.MakeReliable(); EmitSound( filter, entindex(), "WallHealth.LoopingContinueCharge" ); } // charge the player if ( pActivator->TakeHealth( 1, DMG_GENERIC ) ) { m_iJuice--; } // Send the output. float flRemaining = m_iJuice / sk_healthcharger.GetFloat(); m_OutRemainingHealth.Set(flRemaining, pActivator, this); // govern the rate of charge m_flNextCharge = gpGlobals->curtime + 0.1; }
void CBreakable::DamageSound( void ) { int pitch; float fvol; char *soundname = NULL; int material = m_Material; if (random->RandomInt(0,2)) { pitch = PITCH_NORM; } else { pitch = 95 + random->RandomInt(0,34); } fvol = random->RandomFloat(0.75, 1.0); if (material == matComputer && random->RandomInt(0,1)) { material = matMetal; } switch (material) { case matGlass: case matUnbreakableGlass: soundname = "Breakable.MatGlass"; break; case matWood: soundname = "Breakable.MatWood"; break; case matMetal: soundname = "Breakable.MatMetal"; break; case matRocks: case matCinderBlock: soundname = "Breakable.MatConcrete"; break; case matComputer: soundname = "Breakable.Computer"; break; default: break; } if ( soundname ) { CSoundParameters params; if ( GetParametersForSound( soundname, params, NULL ) ) { CPASAttenuationFilter filter( this ); EmitSound_t ep; ep.m_nChannel = params.channel; ep.m_pSoundName = params.soundname; ep.m_flVolume = fvol; ep.m_SoundLevel = params.soundlevel; ep.m_nPitch = pitch; EmitSound( filter, entindex(), ep ); } } }
//----------------------------------------------------------------------------- // Purpose: Stick to an entity (using hierarchy if we can) // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CWeaponStriderBuster::StickToEntity( CBaseEntity *pOther ) { // Make sure the object is travelling fast enough to stick if ( m_flCollisionSpeedSqr > 50 && !m_bNoseDiving ) { // See if this is a valid strider bit if ( ShouldStickToEntity( pOther ) ) { // Attempt to constraint to it if ( CreateConstraintToObject( pOther ) ) { // Only works for striders, at the moment CBaseEntity *pFollowParent = pOther->GetOwnerEntity(); if ( pFollowParent == NULL ) return false; // Allows us to identify our constrained object later SetOwnerEntity( pFollowParent ); // Make a sound EmitSound( "Weapon_StriderBuster.StickToEntity" ); DispatchParticleEffect( "striderbuster_attach", GetAbsOrigin(), GetAbsAngles(), NULL ); if( striderbuster_use_particle_flare.GetBool() ) { // We don't have to save any pointers or handles to this because it's parented to the buster. // So it will die when the buster dies. Yay. CParticleSystem *pFlare = (CParticleSystem *) CreateEntityByName( "info_particle_system" ); if ( pFlare != NULL ) { pFlare->KeyValue( "start_active", "1" ); pFlare->KeyValue( "effect_name", "striderbuster_attached_pulse" ); pFlare->SetParent( this ); pFlare->SetLocalOrigin( vec3_origin ); DispatchSpawn( pFlare ); pFlare->Activate(); } } else { // Create a glow sprite m_hGlowSprite = CSprite::SpriteCreate( "sprites/orangeflare1.vmt", GetLocalOrigin(), false ); Assert( m_hGlowSprite ); if ( m_hGlowSprite != NULL ) { m_hGlowSprite->TurnOn(); m_hGlowSprite->SetTransparency( kRenderWorldGlow, 255, 255, 255, 255, kRenderFxNoDissipation ); m_hGlowSprite->SetAbsOrigin( GetAbsOrigin() ); m_hGlowSprite->SetScale( 5.0f ); m_hGlowSprite->m_nRenderFX = kRenderFxStrobeFaster; m_hGlowSprite->SetGlowProxySize( 16.0f ); m_hGlowSprite->SetParent( this ); } } // Stop touching things SetTouch( NULL ); // Must be a strider CNPC_Strider *pStrider = dynamic_cast<CNPC_Strider *>(pFollowParent); if ( pStrider == NULL ) return false; // Notify the strider we're attaching to him pStrider->StriderBusterAttached( this ); m_OnAttachToStrider.FireOutput( this, this ); // Start the ping sound. SetContextThink( &CWeaponStriderBuster::BusterPingThink, gpGlobals->curtime + BUSTER_PING_SOUND_FREQ, s_pBusterPingThinkContext ); // Don't autodelete this one! WeaponManager_RemoveManaged( this ); return true; } return false; } } return false; }
//----------------------------------------------------------------------------- // Purpose: Breaks the breakable. m_hBreaker is the entity that caused us to break. //----------------------------------------------------------------------------- void CBreakable::Die( void ) { Vector vecVelocity;// shard velocity char cFlag = 0; int pitch; float fvol; pitch = 95 + random->RandomInt(0,29); if (pitch > 97 && pitch < 103) { pitch = 100; } // The more negative m_iHealth, the louder // the sound should be. fvol = random->RandomFloat(0.85, 1.0) + (abs(m_iHealth) / 100.0); if (fvol > 1.0) { fvol = 1.0; } const char *soundname = NULL; switch (m_Material) { default: break; case matGlass: soundname = "Breakable.Glass"; cFlag = BREAK_GLASS; break; case matWood: soundname = "Breakable.Crate"; cFlag = BREAK_WOOD; break; case matComputer: soundname = "Breakable.Computer"; cFlag = BREAK_METAL; break; case matMetal: soundname = "Breakable.Metal"; cFlag = BREAK_METAL; break; case matFlesh: case matWeb: soundname = "Breakable.Flesh"; cFlag = BREAK_FLESH; break; case matRocks: case matCinderBlock: soundname = "Breakable.Concrete"; cFlag = BREAK_CONCRETE; break; case matCeilingTile: soundname = "Breakable.Ceiling"; break; } if ( soundname ) { if ( m_hBreaker && m_hBreaker->IsPlayer() ) { IGameEvent * event = gameeventmanager->CreateEvent( "break_breakable" ); if ( event ) { event->SetInt( "userid", ToBasePlayer( m_hBreaker )->GetUserID() ); event->SetInt( "entindex", entindex() ); event->SetInt( "material", cFlag ); gameeventmanager->FireEvent( event ); } } CSoundParameters params; if ( GetParametersForSound( soundname, params, NULL ) ) { CPASAttenuationFilter filter( this ); EmitSound_t ep; ep.m_nChannel = params.channel; ep.m_pSoundName = params.soundname; ep.m_flVolume = fvol; ep.m_SoundLevel = params.soundlevel; ep.m_nPitch = pitch; EmitSound( filter, entindex(), ep ); } } switch( m_Explosion ) { case expDirected: vecVelocity = g_vecAttackDir * -200; break; case expUsePrecise: { AngleVectors( m_GibDir, &vecVelocity, NULL, NULL ); vecVelocity *= 200; } break; case expRandom: vecVelocity.x = 0; vecVelocity.y = 0; vecVelocity.z = 0; break; default: DevMsg("**ERROR - Unspecified gib dir method in func_breakable!\n"); break; } Vector vecSpot = WorldSpaceCenter(); CPVSFilter filter2( vecSpot ); int iModelIndex = 0; CCollisionProperty *pCollisionProp = CollisionProp(); Vector vSize = pCollisionProp->OBBSize(); int iCount = static_cast<int>(( vSize[0] * vSize[1] + vSize[1] * vSize[2] + vSize[2] * vSize[0] ) / ( 3 * 12 * 12 )); if ( iCount > func_break_max_pieces.GetInt() ) { iCount = func_break_max_pieces.GetInt(); } for ( int i = 0; i < iCount; i++ ) { #ifdef HL1_DLL // Use the passed model instead of the propdata type const char *modelName = STRING( m_iszModelName ); // if the map specifies a model by name if( strstr( modelName, ".mdl" ) != NULL ) { iModelIndex = modelinfo->GetModelIndex( modelName ); } else // do the hl2 / normal way #endif iModelIndex = modelinfo->GetModelIndex( g_PropDataSystem.GetRandomChunkModel( STRING( m_iszModelName ) ) ); // All objects except the first one in this run are marked as slaves... int slaveFlag = 0; if ( i != 0 ) { slaveFlag = BREAK_SLAVE; } te->BreakModel( filter2, 0.0, vecSpot, pCollisionProp->GetCollisionAngles(), vSize, vecVelocity, iModelIndex, 100, 1, 2.5, cFlag | slaveFlag ); } ResetOnGroundFlags(); // Don't fire something that could fire myself SetName( NULL_STRING ); AddSolidFlags( FSOLID_NOT_SOLID ); // Fire targets on break m_OnBreak.FireOutput( m_hBreaker, this ); VPhysicsDestroyObject(); SetThink( &CBreakable::SUB_Remove ); SetNextThink( gpGlobals->curtime + 0.1f ); if ( m_iszSpawnObject != NULL_STRING ) { CBaseEntity::Create( STRING(m_iszSpawnObject), vecSpot, pCollisionProp->GetCollisionAngles(), this ); } if ( Explodable() ) { ExplosionCreate( vecSpot, pCollisionProp->GetCollisionAngles(), this, static_cast<int>(GetExplosiveDamage()), static_cast<int>(GetExplosiveRadius()), true ); } }
void CRecharge::Use( CBaseEntity *pActivator, CBaseEntity *pCaller, USE_TYPE useType, float value ) { // Make sure that we have a caller if (!pActivator) return; // if it's not a player, ignore if ( !pActivator->IsPlayer() ) return; CBasePlayer *pPlayer = dynamic_cast<CBasePlayer *>( pActivator ); if ( pPlayer == NULL ) return; // Reset to a state of continuous use. m_iCaps = FCAP_CONTINUOUS_USE; // if there is no juice left, turn it off if (m_iJuice <= 0) { SetTextureFrameIndex( 1 ); Off(); } // if the player doesn't have the suit, or there is no juice left, make the deny noise if ( m_iJuice <= 0 ) { if (m_flSoundTime <= gpGlobals->curtime) { m_flSoundTime = gpGlobals->curtime + 0.62; EmitSound( "SuitRecharge.Deny" ); } return; } // If we're over our limit, debounce our keys if ( pPlayer->ArmorValue() >= HL1_MAX_ARMOR) { // Make the user re-use me to get started drawing health. pPlayer->m_afButtonPressed &= ~IN_USE; m_iCaps = FCAP_IMPULSE_USE; EmitSound( "SuitRecharge.Deny" ); return; } SetNextThink( gpGlobals->curtime + 0.25 ); SetThink(&CRecharge::Off); // Time to recharge yet? if (m_flNextCharge >= gpGlobals->curtime) return; m_hActivator = pActivator; // Play the on sound or the looping charging sound if (!m_iOn) { m_iOn++; EmitSound( "SuitRecharge.Start" ); m_flSoundTime = 0.56 + gpGlobals->curtime; } if ((m_iOn == 1) && (m_flSoundTime <= gpGlobals->curtime)) { m_iOn++; CPASAttenuationFilter filter( this, "SuitRecharge.ChargingLoop" ); filter.MakeReliable(); EmitSound( filter, entindex(), "SuitRecharge.ChargingLoop" ); } CBasePlayer *pl = (CBasePlayer *) m_hActivator.Get(); // charge the player if (pl->ArmorValue() < HL1_MAX_ARMOR) { m_iJuice--; pl->IncrementArmorValue( 1, HL1_MAX_ARMOR ); } // Send the output. float flRemaining = m_iJuice / sk_suitcharger.GetFloat(); m_OutRemainingCharge.Set(flRemaining, pActivator, this); // govern the rate of charge m_flNextCharge = gpGlobals->curtime + 0.1; }
//----------------------------------------------------------------------------- // Purpose: Handles USE keypress //----------------------------------------------------------------------------- void CBasePlayer::PlayerUse ( void ) { #ifdef GAME_DLL // Was use pressed or released? if ( ! ((m_nButtons | m_afButtonPressed | m_afButtonReleased) & IN_USE) ) return; if ( IsObserver() ) { // do special use operation in oberserver mode if ( m_afButtonPressed & IN_USE ) ObserverUse( true ); else if ( m_afButtonReleased & IN_USE ) ObserverUse( false ); return; } #if !defined(_XBOX) // push objects in turbo physics mode if ( (m_nButtons & IN_USE) && sv_turbophysics.GetBool() ) { Vector forward, up; EyeVectors( &forward, NULL, &up ); trace_t tr; // Search for objects in a sphere (tests for entities that are not solid, yet still useable) Vector searchCenter = EyePosition(); CUsePushFilter filter; UTIL_TraceLine( searchCenter, searchCenter + forward * 96.0f, MASK_SOLID, &filter, &tr ); // try the hit entity if there is one, or the ground entity if there isn't. CBaseEntity *entity = tr.m_pEnt; if ( entity ) { IPhysicsObject *pObj = entity->VPhysicsGetObject(); if ( pObj ) { Vector vPushAway = (entity->WorldSpaceCenter() - WorldSpaceCenter()); vPushAway.z = 0; float flDist = VectorNormalize( vPushAway ); flDist = max( flDist, 1 ); float flForce = sv_pushaway_force.GetFloat() / flDist; flForce = min( flForce, sv_pushaway_max_force.GetFloat() ); pObj->ApplyForceOffset( vPushAway * flForce, WorldSpaceCenter() ); } } } #endif if ( m_afButtonPressed & IN_USE ) { // Controlling some latched entity? if ( ClearUseEntity() ) { return; } else { if ( m_afPhysicsFlags & PFLAG_DIROVERRIDE ) { m_afPhysicsFlags &= ~PFLAG_DIROVERRIDE; m_iTrain = TRAIN_NEW|TRAIN_OFF; return; } else { // Start controlling the train! CBaseEntity *pTrain = GetGroundEntity(); if ( pTrain && !(m_nButtons & IN_JUMP) && (GetFlags() & FL_ONGROUND) && (pTrain->ObjectCaps() & FCAP_DIRECTIONAL_USE) && pTrain->OnControls(this) ) { m_afPhysicsFlags |= PFLAG_DIROVERRIDE; m_iTrain = TrainSpeed(pTrain->m_flSpeed, ((CFuncTrackTrain*)pTrain)->GetMaxSpeed()); m_iTrain |= TRAIN_NEW; EmitSound( "Player.UseTrain" ); return; } } } } CBaseEntity *pUseEntity = FindUseEntity(); // Found an object if ( pUseEntity ) { //!!!UNDONE: traceline here to prevent +USEing buttons through walls int caps = pUseEntity->ObjectCaps(); variant_t emptyVariant; if ( ( (m_nButtons & IN_USE) && (caps & FCAP_CONTINUOUS_USE) ) || ( (m_afButtonPressed & IN_USE) && (caps & (FCAP_IMPULSE_USE|FCAP_ONOFF_USE)) ) ) { if ( caps & FCAP_CONTINUOUS_USE ) { m_afPhysicsFlags |= PFLAG_USING; } if ( pUseEntity->ObjectCaps() & FCAP_ONOFF_USE ) { pUseEntity->AcceptInput( "Use", this, this, emptyVariant, USE_ON ); } else { pUseEntity->AcceptInput( "Use", this, this, emptyVariant, USE_TOGGLE ); } } // UNDONE: Send different USE codes for ON/OFF. Cache last ONOFF_USE object to send 'off' if you turn away else if ( (m_afButtonReleased & IN_USE) && (pUseEntity->ObjectCaps() & FCAP_ONOFF_USE) ) // BUGBUG This is an "off" use { pUseEntity->AcceptInput( "Use", this, this, emptyVariant, USE_OFF ); } } else if ( m_afButtonPressed & IN_USE ) { //PlayUseDenySound();//Nevik removed use fail sound } #endif }
//----------------------------------------------------------------------------- // Purpose: Play a random attack hit sound //----------------------------------------------------------------------------- void CNPC_Zombine::AttackHitSound( void ) { EmitSound( "Zombie.AttackHit" ); }
//----------------------------------------------------------------------------- // Purpose: // Input : step - // fvol - // force - force sound to play //----------------------------------------------------------------------------- void CBasePlayer::PlayStepSound( Vector &vecOrigin, surfacedata_t *psurface, float fvol, bool force ) { if ( gpGlobals->maxClients > 1 && !sv_footsteps.GetFloat() ) return; #if defined( CLIENT_DLL ) // during prediction play footstep sounds only once if ( prediction->InPrediction() && !prediction->IsFirstTimePredicted() ) return; #endif if ( !psurface ) return; int nSide = m_Local.m_nStepside; unsigned short stepSoundName = nSide ? psurface->sounds.stepleft : psurface->sounds.stepright; if ( !stepSoundName ) return; m_Local.m_nStepside = !nSide; CSoundParameters params; Assert( nSide == 0 || nSide == 1 ); if ( m_StepSoundCache[ nSide ].m_usSoundNameIndex == stepSoundName ) { params = m_StepSoundCache[ nSide ].m_SoundParameters; } else { IPhysicsSurfaceProps *physprops = MoveHelper()->GetSurfaceProps(); const char *pSoundName = physprops->GetString( stepSoundName ); if ( !CBaseEntity::GetParametersForSound( pSoundName, params, NULL ) ) return; // Only cache if there's one option. Otherwise we'd never here any other sounds if ( params.count == 1 ) { m_StepSoundCache[ nSide ].m_usSoundNameIndex = stepSoundName; m_StepSoundCache[ nSide ].m_SoundParameters = params; } } CRecipientFilter filter; filter.AddRecipientsByPAS( vecOrigin ); #ifndef CLIENT_DLL // in MP, server removes all players in the vecOrigin's PVS, these players generate the footsteps client side if ( gpGlobals->maxClients > 1 ) { filter.RemoveRecipientsByPVS( vecOrigin ); } #endif EmitSound_t ep; ep.m_nChannel = CHAN_BODY; ep.m_pSoundName = params.soundname; ep.m_flVolume = fvol; ep.m_SoundLevel = params.soundlevel; ep.m_nFlags = 0; ep.m_nPitch = params.pitch; ep.m_pOrigin = &vecOrigin; EmitSound( filter, entindex(), ep ); }
//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CNPC_Zombine::DeathSound( const CTakeDamageInfo &info ) { EmitSound( "Zombine.Die" ); }
//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- void CCrossbowBolt::BoltTouch( CBaseEntity *pOther ) { if ( pOther->IsSolidFlagSet(FSOLID_VOLUME_CONTENTS | FSOLID_TRIGGER) ) { // Some NPCs are triggers that can take damage (like antlion grubs). We should hit them. if ( ( pOther->m_takedamage == DAMAGE_NO ) || ( pOther->m_takedamage == DAMAGE_EVENTS_ONLY ) ) return; } if ( pOther->m_takedamage != DAMAGE_NO ) { trace_t tr, tr2; tr = BaseClass::GetTouchTrace(); Vector vecNormalizedVel = GetAbsVelocity(); ClearMultiDamage(); VectorNormalize( vecNormalizedVel ); #if defined(HL2_EPISODIC) //!!!HACKHACK - specific hack for ep2_outland_10 to allow crossbow bolts to pass through her bounding box when she's crouched in front of the player // (the player thinks they have clear line of sight because Alyx is crouching, but her BBOx is still full-height and blocks crossbow bolts. if( GetOwnerEntity() && GetOwnerEntity()->IsPlayer() && pOther->Classify() == CLASS_PLAYER_ALLY_VITAL && FStrEq(STRING(gpGlobals->mapname), "ep2_outland_10") ) { // Change the owner to stop further collisions with Alyx. We do this by making her the owner. // The player won't get credit for this kill but at least the bolt won't magically disappear! SetOwnerEntity( pOther ); return; } #endif//HL2_EPISODIC if( GetOwnerEntity() && GetOwnerEntity()->IsPlayer() && pOther->IsNPC() ) { CTakeDamageInfo dmgInfo( this, GetOwnerEntity(), sk_plr_dmg_crossbow.GetFloat(), DMG_NEVERGIB ); dmgInfo.AdjustPlayerDamageInflictedForSkillLevel(); CalculateMeleeDamageForce( &dmgInfo, vecNormalizedVel, tr.endpos, 0.7f ); dmgInfo.SetDamagePosition( tr.endpos ); pOther->DispatchTraceAttack( dmgInfo, vecNormalizedVel, &tr ); CBasePlayer *pPlayer = ToBasePlayer( GetOwnerEntity() ); if ( pPlayer ) { gamestats->Event_WeaponHit( pPlayer, true, "weapon_crossbow", dmgInfo ); } } else { CTakeDamageInfo dmgInfo( this, GetOwnerEntity(), sk_plr_dmg_crossbow.GetFloat(), DMG_BULLET | DMG_NEVERGIB ); CalculateMeleeDamageForce( &dmgInfo, vecNormalizedVel, tr.endpos, 0.7f ); dmgInfo.SetDamagePosition( tr.endpos ); pOther->DispatchTraceAttack( dmgInfo, vecNormalizedVel, &tr ); } ApplyMultiDamage(); //Adrian: keep going through the glass. if ( pOther->GetCollisionGroup() == COLLISION_GROUP_BREAKABLE_GLASS ) return; /*if ( !pOther->IsAlive() ) { // We killed it! const surfacedata_t *pdata = physprops->GetSurfaceData( tr.surface.surfaceProps ); if ( pdata->game.material == CHAR_TEX_GLASS ) { return; } }*/ SetAbsVelocity( Vector( 0, 0, 0 ) ); // play body "thwack" sound EmitSound( "Weapon_Crossbow.BoltHitBody" ); Vector vForward; AngleVectors( GetAbsAngles(), &vForward ); VectorNormalize ( vForward ); UTIL_TraceLine( GetAbsOrigin(), GetAbsOrigin() + vForward * 128, MASK_BLOCKLOS, pOther, COLLISION_GROUP_NONE, &tr2 ); if ( tr2.fraction != 1.0f ) { // NDebugOverlay::Box( tr2.endpos, Vector( -16, -16, -16 ), Vector( 16, 16, 16 ), 0, 255, 0, 0, 10 ); // NDebugOverlay::Box( GetAbsOrigin(), Vector( -16, -16, -16 ), Vector( 16, 16, 16 ), 0, 0, 255, 0, 10 ); if ( tr2.m_pEnt == NULL || ( tr2.m_pEnt && tr2.m_pEnt->GetMoveType() == MOVETYPE_NONE ) ) { CEffectData data; data.m_vOrigin = tr2.endpos; data.m_vNormal = vForward; data.m_nEntIndex = tr2.fraction != 1.0f; DispatchEffect( "BoltImpact", data ); } } SetTouch( NULL ); SetThink( NULL ); if ( !g_pGameRules->IsMultiplayer() ) { UTIL_Remove( this ); } } else { trace_t tr; tr = BaseClass::GetTouchTrace(); // See if we struck the world if ( pOther->GetMoveType() == MOVETYPE_NONE && !( tr.surface.flags & SURF_SKY ) ) { EmitSound( "Weapon_Crossbow.BoltHitWorld" ); // if what we hit is static architecture, can stay around for a while. Vector vecDir = GetAbsVelocity(); float speed = VectorNormalize( vecDir ); // See if we should reflect off this surface float hitDot = DotProduct( tr.plane.normal, -vecDir ); if ( ( hitDot < 0.5f ) && ( speed > 100 ) ) { Vector vReflection = 2.0f * tr.plane.normal * hitDot + vecDir; QAngle reflectAngles; VectorAngles( vReflection, reflectAngles ); SetLocalAngles( reflectAngles ); SetAbsVelocity( vReflection * speed * 0.75f ); // Start to sink faster SetGravity( 1.0f ); } else { SetThink( &CCrossbowBolt::SUB_Remove ); SetNextThink( gpGlobals->curtime + 2.0f ); //FIXME: We actually want to stick (with hierarchy) to what we've hit SetMoveType( MOVETYPE_NONE ); Vector vForward; AngleVectors( GetAbsAngles(), &vForward ); VectorNormalize ( vForward ); CEffectData data; data.m_vOrigin = tr.endpos; data.m_vNormal = vForward; data.m_nEntIndex = 0; DispatchEffect( "BoltImpact", data ); UTIL_ImpactTrace( &tr, DMG_BULLET ); AddEffects( EF_NODRAW ); SetTouch( NULL ); SetThink( &CCrossbowBolt::SUB_Remove ); SetNextThink( gpGlobals->curtime + 2.0f ); if ( m_pGlowSprite != NULL ) { m_pGlowSprite->TurnOn(); m_pGlowSprite->FadeAndDie( 3.0f ); } } // Shoot some sparks if ( UTIL_PointContents( GetAbsOrigin() ) != CONTENTS_WATER) { g_pEffects->Sparks( GetAbsOrigin() ); } } else { // Put a mark unless we've hit the sky if ( ( tr.surface.flags & SURF_SKY ) == false ) { UTIL_ImpactTrace( &tr, DMG_BULLET ); } UTIL_Remove( this ); } } if ( g_pGameRules->IsMultiplayer() ) { // SetThink( &CCrossbowBolt::ExplodeThink ); // SetNextThink( gpGlobals->curtime + 0.1f ); } }
void CWeaponGravityGun::SoundUpdate( void ) { int newState; if ( m_hObject ) newState = SS_LOCKEDON; else newState = SS_SCANNING; if ( newState != m_soundState ) { SoundStop(); m_soundState = newState; SoundStart(); } switch( m_soundState ) { case SS_SCANNING: break; case SS_LOCKEDON: { CPASAttenuationFilter filter( GetOwner() ); filter.MakeReliable(); float height = m_hObject->GetAbsOrigin().z - m_originalObjectPosition.z; // go from pitch 90 to 150 over a height of 500 int pitch = 90 + (int)UTIL_LineFraction( height, 0, 500, 60 ); CSoundParameters params; if ( GetParametersForSound( "Weapon_Physgun.LockedOn", params, NULL ) ) { EmitSound_t ep( params ); ep.m_nFlags = SND_CHANGE_VOL | SND_CHANGE_PITCH; ep.m_nPitch = pitch; EmitSound( filter, GetOwner()->entindex(), ep ); } // attenutate the movement sounds over 200 units of movement float distance = UTIL_LineFraction( m_movementLength, 0, 200, 1.0 ); // blend the "mass" sounds between 50 and 500 kg IPhysicsObject *pPhys = m_hObject->VPhysicsGetObject(); float fade = UTIL_LineFraction( pPhys->GetMass(), 50, 500, 1.0 ); if ( GetParametersForSound( "Weapon_Physgun.LightObject", params, NULL ) ) { EmitSound_t ep( params ); ep.m_nFlags = SND_CHANGE_VOL; ep.m_flVolume = fade * distance; EmitSound( filter, GetOwner()->entindex(), ep ); } if ( GetParametersForSound( "Weapon_Physgun.HeavyObject", params, NULL ) ) { EmitSound_t ep( params ); ep.m_nFlags = SND_CHANGE_VOL; ep.m_flVolume = (1.0 - fade) * distance; EmitSound( filter, GetOwner()->entindex(), ep ); } } break; } }
//========================================================= // DeathSound //========================================================= void CNPC_Bullsquid::DeathSound( const CTakeDamageInfo &info ) { CPASAttenuationFilter filter( this ); EmitSound( filter, entindex(), "Bullsquid.Die" ); }