//--------------------------------------------------------- //--------------------------------------------------------- void CBounceBomb::ExplodeThink() { SetSolid( SOLID_NONE ); // Don't catch self in own explosion! m_takedamage = DAMAGE_NO; if( m_hSprite ) { UpdateLight( false, 0, 0, 0, 0 ); } if( m_pWarnSound ) { CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController(); controller.SoundDestroy( m_pWarnSound ); } CBaseEntity *pThrower = HasPhysicsAttacker( 0.5 ); if (m_iModification == MINE_MODIFICATION_CAVERN) { ExplosionCreate( GetAbsOrigin(), GetAbsAngles(), (pThrower) ? pThrower : this, BOUNCEBOMB_EXPLODE_DAMAGE, BOUNCEBOMB_EXPLODE_RADIUS, true, NULL, CLASS_PLAYER_ALLY ); } else { ExplosionCreate( GetAbsOrigin(), GetAbsAngles(), (pThrower) ? pThrower : this, BOUNCEBOMB_EXPLODE_DAMAGE, BOUNCEBOMB_EXPLODE_RADIUS, true); } UTIL_Remove( this ); }
void BulletUpdate(ObjectStruct* bulletObject) { //KDebug_Alert("Bullet Update"); bulletObject->x += bulletObject->speedx; bulletObject->y += bulletObject->speedy; bulletObject->sprite.posx = VIRTUAL_TO_PIXEL(bulletObject->x) + scrollData.scrollx_vdp - 4; bulletObject->sprite.posy = VIRTUAL_TO_PIXEL(bulletObject->y) - scrollData.scrolly_vdp - 4; if (bulletObject->visible) { if (collidesWithTile(bulletObject->x, bulletObject->y)) { bulletObject->objectState = OBJECTSTATE_INACTIVE; #ifdef DEBUG_OBJECTS KDebug_Alert("Bullet Hit Background. Creating explosion"); #endif ExplosionCreate(bulletObject->x, bulletObject->y); #ifdef DEBUG_OBJECTS KDebug_Alert("Finished creating explosion"); #endif } } else { bulletObject->objectState = OBJECTSTATE_INACTIVE; } }
//------------------------------------------------------------------------------ // 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: // Input : // Output : //----------------------------------------------------------------------------- void CSatchelCharge::InputExplode( inputdata_t &inputdata ) { ExplosionCreate( GetAbsOrigin() + Vector( 0, 0, 16 ), GetAbsAngles(), GetThrower(), GetDamage(), 200, SF_ENVEXPLOSION_NOSPARKS | SF_ENVEXPLOSION_NODLIGHTS | SF_ENVEXPLOSION_NOSMOKE, 0.0f, this); UTIL_Remove( this ); }
//----------------------------------------------------------------------------- // Creates the explosion effect //----------------------------------------------------------------------------- void CEnvHeadcrabCanister::Detonate( ) { // Send the impact output m_OnImpacted.FireOutput( this, this, 0 ); if ( !HasSpawnFlags( SF_NO_IMPACT_SOUND ) ) { StopSound( "HeadcrabCanister.IncomingSound" ); EmitSound( "HeadcrabCanister.Explosion" ); } // If we're supposed to be removed, do that now if ( HasSpawnFlags( SF_REMOVE_ON_IMPACT ) ) { SetAbsOrigin( m_vecImpactPosition ); SetModel( ENV_HEADCRABCANISTER_BROKEN_MODEL ); SetMoveType( MOVETYPE_NONE ); IncrementInterpolationFrame(); m_bLanded = true; // Become invisible so our trail can finish up AddEffects( EF_NODRAW ); SetSolidFlags( FSOLID_NOT_SOLID ); SetThink( &CEnvHeadcrabCanister::SUB_Remove ); SetNextThink( gpGlobals->curtime + ENV_HEADCRABCANISTER_TRAIL_TIME ); return; } // Test for damaging things TestForCollisionsAgainstWorld( m_vecImpactPosition ); // Shake the screen unless flagged otherwise if ( !HasSpawnFlags( SF_NO_SHAKE ) ) { CBasePlayer *pPlayer = UTIL_GetNearestPlayer(GetAbsOrigin()); // If the player is on foot, then do a more limited shake float shakeRadius = ( pPlayer && pPlayer->IsInAVehicle() ) ? sk_env_headcrabcanister_shake_radius_vehicle.GetFloat() : sk_env_headcrabcanister_shake_radius.GetFloat(); UTIL_ScreenShake( m_vecImpactPosition, sk_env_headcrabcanister_shake_amplitude.GetFloat(), 150.0, 1.0, shakeRadius, SHAKE_START ); } // Do explosion effects if ( !HasSpawnFlags( SF_NO_IMPACT_EFFECTS ) ) { // Normal explosion ExplosionCreate( m_vecImpactPosition, GetAbsAngles(), this, 50.0f, 500.0f, SF_ENVEXPLOSION_NODLIGHTS | SF_ENVEXPLOSION_NOSPARKS | SF_ENVEXPLOSION_NODAMAGE | SF_ENVEXPLOSION_NOSOUND, 1300.0f ); // Dust explosion AR2Explosion *pExplosion = AR2Explosion::CreateAR2Explosion( m_vecImpactPosition ); if( pExplosion ) { pExplosion->SetLifetime(10); } } }
void CStickyBomb::Detonate() { SetBombOrigin(); ExplosionCreate( GetAbsOrigin(), GetAbsAngles(), m_hOperator, 100, 250, true ); UTIL_ScreenShake( GetAbsOrigin(), 25.0, 150.0, 1.0, 250, SHAKE_START ); UTIL_Remove( this ); }
//----------------------------------------------------------------------------- // The actual explosion //----------------------------------------------------------------------------- void CRocketMissile::DoExplosion( void ) { unsigned int spawnflags = SF_ENVEXPLOSION_NOSPARKS | SF_ENVEXPLOSION_NODLIGHTS | SF_ENVEXPLOSION_NOSMOKE; float explodeforce = BALANCE_VALUE( Float, lfm_rocket_launcher_explodeforce ); // Create the actual explosion ExplosionCreate( GetAbsOrigin(), GetAbsAngles(), GetOwnerEntity(), GetDamage(), GetDamage() * 2, spawnflags, explodeforce, this); }
void BulletCollide(ObjectStruct* bulletObject, ObjectStruct* collidedObject) { bulletObject->objectState = OBJECTSTATE_INACTIVE; if (collidedObject->objectType == TYPE_BREAKABLE) { ExplosionCreate(bulletObject->x, bulletObject->y); } }
void CPropCannon::ProjectileExplosion( void ) { ExplosionCreate( m_vCrashPoint, vec3_angle, NULL, 512, 512, false ); // do damage CTakeDamageInfo info( this, this, g_cannon_damageandradius.GetInt(), DMG_BLAST ); info.SetDamagePosition( m_vCrashPoint ); RadiusDamage( info, m_vCrashPoint, g_cannon_damageandradius.GetInt(), CLASS_NONE, NULL ); }
//----------------------------------------------------------------------------- // Add a smoke trail since we've taken more damage //----------------------------------------------------------------------------- void CPropAPC::AddSmokeTrail( const Vector &vecPos ) { // Start this trail out with a bang! ExplosionCreate( vecPos, vec3_angle, this, 1000, 500, SF_ENVEXPLOSION_NODAMAGE | SF_ENVEXPLOSION_NOSPARKS | SF_ENVEXPLOSION_NODLIGHTS | SF_ENVEXPLOSION_NOSMOKE | SF_ENVEXPLOSION_NOFIREBALLSMOKE, 0 ); UTIL_ScreenShake( vecPos, 25.0, 150.0, 1.0, 750.0f, SHAKE_START ); if ( m_nSmokeTrailCount == MAX_SMOKE_TRAILS ) return; SmokeTrail *pSmokeTrail = SmokeTrail::CreateSmokeTrail(); if( !pSmokeTrail ) return; // See if there's an attachment for this smoke trail char buf[32]; Q_snprintf( buf, 32, "damage%d", m_nSmokeTrailCount ); int nAttachment = LookupAttachment( buf ); ++m_nSmokeTrailCount; pSmokeTrail->m_SpawnRate = 4; pSmokeTrail->m_ParticleLifetime = 5.0f; pSmokeTrail->m_StartColor.Init( 0.7f, 0.7f, 0.7f ); pSmokeTrail->m_EndColor.Init( 0.6, 0.6, 0.6 ); pSmokeTrail->m_StartSize = 32; pSmokeTrail->m_EndSize = 64; pSmokeTrail->m_SpawnRadius = 4; pSmokeTrail->m_Opacity = 0.5f; pSmokeTrail->m_MinSpeed = 16; pSmokeTrail->m_MaxSpeed = 16; pSmokeTrail->m_MinDirectedSpeed = 16.0f; pSmokeTrail->m_MaxDirectedSpeed = 16.0f; pSmokeTrail->SetLifetime( 5 ); pSmokeTrail->SetParent( this, nAttachment ); Vector vecForward( 0, 0, 1 ); QAngle angles; VectorAngles( vecForward, angles ); if ( nAttachment == 0 ) { pSmokeTrail->SetAbsOrigin( vecPos ); pSmokeTrail->SetAbsAngles( angles ); } else { pSmokeTrail->SetLocalOrigin( vec3_origin ); pSmokeTrail->SetLocalAngles( angles ); } pSmokeTrail->SetMoveType( MOVETYPE_NONE ); }
//------------------------------------------------------------------------------ // Pow! //------------------------------------------------------------------------------ void CPropAPC2::ExplodeAndThrowChunk( const Vector &vecExplosionPos ) { ExplosionCreate( vecExplosionPos, vec3_angle, this, 1000, 500.0f, SF_ENVEXPLOSION_NODAMAGE | SF_ENVEXPLOSION_NOSPARKS | SF_ENVEXPLOSION_NODLIGHTS | SF_ENVEXPLOSION_NOSMOKE | SF_ENVEXPLOSION_NOFIREBALLSMOKE, 0 ); UTIL_ScreenShake( vecExplosionPos, 25.0, 150.0, 1.0, 750.0f, SHAKE_START ); // Drop a flaming, smoking chunk. CGib *pChunk = CREATE_ENTITY( CGib, "gib" ); pChunk->Spawn( "models/gibs/hgibs.mdl" ); pChunk->SetBloodColor( DONT_BLEED ); QAngle vecSpawnAngles; vecSpawnAngles.Random( -90, 90 ); pChunk->SetAbsOrigin( vecExplosionPos ); pChunk->SetAbsAngles( vecSpawnAngles ); int nGib = random->RandomInt( 0, APC_MAX_CHUNKS - 1 ); pChunk->Spawn( s_pChunkModelName[nGib] ); pChunk->SetOwnerEntity( this ); pChunk->m_lifeTime = random->RandomFloat( 6.0f, 8.0f ); pChunk->SetCollisionGroup( COLLISION_GROUP_DEBRIS ); IPhysicsObject *pPhysicsObject = pChunk->VPhysicsInitNormal( SOLID_VPHYSICS, pChunk->GetSolidFlags(), false ); // Set the velocity if ( pPhysicsObject ) { pPhysicsObject->EnableMotion( true ); Vector vecVelocity; QAngle angles; angles.x = random->RandomFloat( -40, 0 ); angles.y = random->RandomFloat( 0, 360 ); angles.z = 0.0f; AngleVectors( angles, &vecVelocity ); vecVelocity *= random->RandomFloat( 300, 900 ); vecVelocity += GetAbsVelocity(); AngularImpulse angImpulse; angImpulse = RandomAngularImpulse( -180, 180 ); pChunk->SetAbsVelocity( vecVelocity ); pPhysicsObject->SetVelocity(&vecVelocity, &angImpulse ); } CEntityFlame *pFlame = CEntityFlame::Create( pChunk, false ); if ( pFlame != NULL ) { pFlame->SetLifetime( pChunk->m_lifeTime ); } pChunk->Dissolve( NULL, gpGlobals->curtime, false, ENTITY_DISSOLVE_NORMAL ); }
void CTripmineGrenade::DelayDeathThink( void ) { KillBeam(); trace_t tr; UTIL_TraceLine ( GetAbsOrigin() + m_vecDir * 8, GetAbsOrigin() - m_vecDir * 64, MASK_SOLID, this, COLLISION_GROUP_NONE, & tr); UTIL_ScreenShake( GetAbsOrigin(), 25.0, 150.0, 1.0, 750, SHAKE_START ); ExplosionCreate( GetAbsOrigin() + m_vecDir * 8, GetAbsAngles(), m_hOwner, GetDamage(), 200, SF_ENVEXPLOSION_NOSPARKS | SF_ENVEXPLOSION_NODLIGHTS | SF_ENVEXPLOSION_NOSMOKE, 0.0f, this); UTIL_Remove( this ); }
void EnemyPlaneUpdate(ObjectStruct* enemyPlaneObject) { //KDebug_Alert("EnemyPlane Update"); enemyPlaneObject->sprite.posx = VIRTUAL_TO_PIXEL(enemyPlaneObject->x) + scrollData.scrollx_vdp - 12; enemyPlaneObject->sprite.posy = VIRTUAL_TO_PIXEL(enemyPlaneObject->y) - scrollData.scrolly_vdp - 12; RotatePlane(enemyPlaneObject); /* if (enemyPlaneObject->aiState == ENEMYPLANE_AI_STATE_FLYING) { enemyPlaneObject->x += enemyPlaneObject->speedx; enemyPlaneObject->y += enemyPlaneObject->speedy; if (ObjectIsOnScreen(enemyPlaneObject->x, enemyPlaneObject->y)) { if ((enemyPlaneObject->lifetime % 64) == 0) { EnemyBulletCreate(enemyPlaneObject->x, enemyPlaneObject->y, goplanes_costable32[enemyPlaneObject->spriteIndex], goplanes_sintable32[enemyPlaneObject->spriteIndex]); } } } else*/ if (enemyPlaneObject->aiState == ENEMYPLANE_AI_STATE_DEAD) { enemyPlaneObject->x += enemyPlaneObject->speedx; enemyPlaneObject->y += enemyPlaneObject->speedy >> 2; enemyPlaneObject->speedy++; if (enemyPlaneObject->visible) { if ((enemyPlaneObject->lifetime % 20) == 0) { ExplosionCreate(enemyPlaneObject->x, enemyPlaneObject->y); } } else { enemyPlaneObject->objectState = OBJECTSTATE_INACTIVE; } if (collidesWithTile(enemyPlaneObject->x, enemyPlaneObject->y)) { enemyPlaneObject->objectState = OBJECTSTATE_INACTIVE; LargeExplosionCreate(enemyPlaneObject->x, enemyPlaneObject->y); } }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CPhysicsCannister::Explode( CBaseEntity *pAttacker ) { // don't recurse m_takedamage = 0; Deactivate(); Vector velocity; AngularImpulse angVelocity; IPhysicsObject *pPhysics = VPhysicsGetObject(); pPhysics->GetVelocity( &velocity, &angVelocity ); PropBreakableCreateAll( GetModelIndex(), pPhysics, GetAbsOrigin(), GetAbsAngles(), velocity, angVelocity, 1.0, 20, COLLISION_GROUP_DEBRIS ); ExplosionCreate( GetAbsOrigin(), GetAbsAngles(), pAttacker, m_damage, 0, true ); UTIL_Remove( this ); }
void CMineAC :: MineThink ( void ) { pev->nextthink = gpGlobals->time + 0.1; TraceResult tr; UTIL_TraceHull ( pev->origin, pev->origin + Vector (0,0,20), dont_ignore_monsters, head_hull, edict(), &tr ); if ( tr.pHit == NULL ) return; if ( (tr.pHit->v.flags & FL_MONSTER) || (tr.pHit->v.flags & FL_CLIENT) ) { ExplosionCreate ( pev->origin + Vector ( 0,0,30 ), Vector(0,0,0), edict(), 200, TRUE ); SetThink ( SUB_Remove ); } }
void CFuncTankMortar::Fire( int bulletCount, const Vector &barrelEnd, const Vector &vecForward, CBaseEntity *pAttacker ) { if ( m_fireEndSound != NULL_STRING ) { CPASAttenuationFilter filter( this ); EmitSound( filter, entindex(), CHAN_WEAPON, STRING(m_fireEndSound), 1.0, ATTN_NORM ); } trace_t tr; TankTrace( barrelEnd, vecForward, gTankSpread[m_spread], tr ); ExplosionCreate( tr.endpos, GetAbsAngles(), this, m_Magnitude, 0, true ); BaseClass::Fire( bulletCount, barrelEnd, vecForward, this ); }
void CFuncTankMortar::Fire(const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker) { if (m_fireLast != 0) { int bulletCount = (int)((gpGlobals->time - m_fireLast) * m_fireRate); if (bulletCount > 0) { UTIL_MakeAimVectors(pev->angles); TraceResult tr; TankTrace(barrelEnd, forward, gTankSpread[m_spread], tr); ExplosionCreate(tr.vecEndPos, pev->angles, edict(), pev->impulse, TRUE); CFuncTank::Fire(barrelEnd, forward, pev); } } else CFuncTank::Fire(barrelEnd, forward, pev); }
//----------------------------------------------------------------------------- // The actual explosion //----------------------------------------------------------------------------- void CDODBaseRocket::DoExplosion( void ) { // Explode ExplosionCreate( GetAbsOrigin(), //DMG_ROCKET GetAbsAngles(), GetOwnerEntity(), GetDamage(), //magnitude mp_rocketradius.GetFloat(), //radius SF_ENVEXPLOSION_NOSPARKS | SF_ENVEXPLOSION_NODLIGHTS | SF_ENVEXPLOSION_NOSMOKE, 0.0f, //explosion force this); //inflictor // stun players in a radius const float flStunDamage = 75; const float flRadius = 150; CTakeDamageInfo info( this, GetOwnerEntity(), vec3_origin, GetAbsOrigin(), flStunDamage, DMG_STUN ); DODGameRules()->RadiusStun( info, GetAbsOrigin(), flRadius ); }
//----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- int CNPC_CeilingTurret::OnTakeDamage( const CTakeDamageInfo &inputInfo ) { if ( !m_takedamage ) return 0; CTakeDamageInfo info = inputInfo; if ( m_bActive == false ) info.ScaleDamage( 0.1f ); // If attacker can't do at least the min required damage to us, don't take any damage from them if ( info.GetDamage() < m_iMinHealthDmg ) return 0; m_iHealth -= info.GetDamage(); if ( m_iHealth <= 0 ) { m_iHealth = 0; m_takedamage = DAMAGE_NO; RemoveFlag( FL_NPC ); // why are they set in the first place??? //FIXME: This needs to throw a ragdoll gib or something other than animating the retraction -- jdw ExplosionCreate( GetAbsOrigin(), GetLocalAngles(), this, 100, 100, false ); SetThink( &CNPC_CeilingTurret::DeathThink ); StopSound( "NPC_CeilingTurret.Alert" ); m_OnDamaged.FireOutput( info.GetInflictor(), this ); SetNextThink( gpGlobals->curtime + 0.1f ); return 0; } return 1; }
void EnemyBulletUpdate(ObjectStruct* enemyBulletObject) { //KDebug_Alert("EnemyBullet Update"); enemyBulletObject->x += enemyBulletObject->speedx; enemyBulletObject->y += enemyBulletObject->speedy; enemyBulletObject->sprite.posx = VIRTUAL_TO_PIXEL(enemyBulletObject->x) + scrollData.scrollx_vdp - 4; enemyBulletObject->sprite.posy = VIRTUAL_TO_PIXEL(enemyBulletObject->y) - scrollData.scrolly_vdp - 4; if (enemyBulletObject->visible) { if (collidesWithTile(enemyBulletObject->x, enemyBulletObject->y)) { enemyBulletObject->objectState = OBJECTSTATE_INACTIVE; ExplosionCreate(enemyBulletObject->x, enemyBulletObject->y); } } else { enemyBulletObject->objectState = OBJECTSTATE_INACTIVE; } }
void ExplosionCreate( const Vector ¢er, const QAngle &angles, CBaseEntity *pOwner, int magnitude, int radius, bool doDamage, float flExplosionForce, bool bSurfaceOnly, bool bSilent, int iCustomDamageType ) { // For E3, no sparks int nFlags = SF_ENVEXPLOSION_NOSPARKS | SF_ENVEXPLOSION_NODLIGHTS | SF_ENVEXPLOSION_NOSMOKE; if ( !doDamage ) { nFlags |= SF_ENVEXPLOSION_NODAMAGE; } if( bSurfaceOnly ) { nFlags |= SF_ENVEXPLOSION_SURFACEONLY; } if( bSilent ) { nFlags |= SF_ENVEXPLOSION_NOSOUND; } ExplosionCreate( center, angles, pOwner, magnitude, radius, nFlags, flExplosionForce, NULL, iCustomDamageType ); }
void CRocket_Turret_Projectile::DoExplosion( void ) { NotifyLauncherOnDeath(); StopLoopingSounds(); // Explode ExplosionCreate( GetAbsOrigin(), GetAbsAngles(), GetOwnerEntity(), 200, 25, SF_ENVEXPLOSION_NOSPARKS | SF_ENVEXPLOSION_NODLIGHTS | SF_ENVEXPLOSION_NOSMOKE, 100.0f, this); // Hackish: Knock turrets in the area CBaseEntity* pTurretIter = NULL; while ( (pTurretIter = gEntList.FindEntityByClassnameWithin( pTurretIter, "npc_portal_turret_floor", GetAbsOrigin(), 128 )) != NULL ) { CTakeDamageInfo info( this, this, 200, DMG_BLAST ); info.SetDamagePosition( GetAbsOrigin() ); CalculateExplosiveDamageForce( &info, (pTurretIter->GetAbsOrigin() - GetAbsOrigin()), GetAbsOrigin() ); pTurretIter->VPhysicsTakeDamage( info ); } }
void CFuncTankMortar::Fire( int bulletCount, const Vector &barrelEnd, const Vector &vecForward, CBaseEntity *pAttacker ) { if ( m_fireEndSound != NULL_STRING ) { CPASAttenuationFilter filter( this ); EmitSound_t ep; ep.m_nChannel = CHAN_WEAPON; ep.m_pSoundName = STRING(m_fireEndSound); ep.m_flVolume = 1.0f; ep.m_SoundLevel = SNDLVL_NORM; EmitSound( filter, entindex(), ep ); } trace_t tr; TankTrace( barrelEnd, vecForward, gTankSpread[m_spread], tr ); const CBaseEntity * ent = NULL; if ( g_pGameRules->IsMultiplayer() ) { // temp remove suppress host ent = te->GetSuppressHost(); te->SetSuppressHost( NULL ); } ExplosionCreate( tr.endpos, GetAbsAngles(), this, m_Magnitude, 0, true ); if ( g_pGameRules->IsMultiplayer() ) { te->SetSuppressHost( (CBaseEntity *) ent ); } BaseClass::Fire( bulletCount, barrelEnd, vecForward, this ); }
//--------------------------------------------------------- //--------------------------------------------------------- void CBounceBomb::ExplodeThink() { SetSolid( SOLID_NONE ); // Don't catch self in own explosion! m_takedamage = DAMAGE_NO; if( m_hSprite ) { UpdateLight( false, 0, 0, 0, 0 ); } if( m_pWarnSound ) { CSoundEnvelopeController &controller = CSoundEnvelopeController::GetController(); controller.SoundDestroy( m_pWarnSound ); } CBaseEntity *pThrower = HasPhysicsAttacker( 0.5 ); ExplosionCreate( GetAbsOrigin(), GetAbsAngles(), (pThrower) ? pThrower : this, static_cast<int>(BOUNCEBOMB_EXPLODE_DAMAGE), static_cast<int>(BOUNCEBOMB_EXPLODE_RADIUS), true ); UTIL_Remove( this ); }
void CFuncTankMortar::__MAKE_VHOOK(Fire)(const Vector &barrelEnd, const Vector &forward, entvars_t *pevAttacker) { if (m_fireLast != 0.0f) { int bulletCount = int((gpGlobals->time - m_fireLast) * m_fireRate); // Only create 1 explosion if (bulletCount > 0) { TraceResult tr; // TankTrace needs gpGlobals->v_up, etc. UTIL_MakeAimVectors(pev->angles); TankTrace(barrelEnd, forward, gTankSpread[m_spread], tr); ExplosionCreate(tr.vecEndPos, pev->angles, edict(), pev->impulse, TRUE); CFuncTank::Fire(barrelEnd, forward, pev); } } else CFuncTank::Fire(barrelEnd, forward, pev); }
void CBreakable::Die( void ) { Vector vecSpot;// shard origin Vector vecVelocity;// shard velocity CBaseEntity *pEntity = NULL; char cFlag = 0; int pitch; float fvol; pitch = 95 + RANDOM_LONG(0,29); if (pitch > 97 && pitch < 103) pitch = 100; // The more negative pev->health, the louder // the sound should be. fvol = RANDOM_FLOAT(0.85, 1.0) + (abs(pev->health) / 100.0); if (fvol > 1.0) fvol = 1.0; switch (m_Material) { case matGlass: switch ( RANDOM_LONG(0,1) ) { case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustglass1.wav", fvol, ATTN_NORM, 0, pitch); break; case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustglass2.wav", fvol, ATTN_NORM, 0, pitch); break; } cFlag = BREAK_GLASS; break; case matWood: switch ( RANDOM_LONG(0,1) ) { case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustcrate1.wav", fvol, ATTN_NORM, 0, pitch); break; case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustcrate2.wav", fvol, ATTN_NORM, 0, pitch); break; } cFlag = BREAK_WOOD; break; case matComputer: case matMetal: switch ( RANDOM_LONG(0,1) ) { case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustmetal1.wav", fvol, ATTN_NORM, 0, pitch); break; case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustmetal2.wav", fvol, ATTN_NORM, 0, pitch); break; } cFlag = BREAK_METAL; break; case matFlesh: switch ( RANDOM_LONG(0,1) ) { case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustflesh1.wav", fvol, ATTN_NORM, 0, pitch); break; case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustflesh2.wav", fvol, ATTN_NORM, 0, pitch); break; } cFlag = BREAK_FLESH; break; case matRocks: case matCinderBlock: switch ( RANDOM_LONG(0,1) ) { case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustconcrete1.wav", fvol, ATTN_NORM, 0, pitch); break; case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustconcrete2.wav", fvol, ATTN_NORM, 0, pitch); break; } cFlag = BREAK_CONCRETE; break; case matCeilingTile: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustceiling.wav", fvol, ATTN_NORM, 0, pitch); break; } if (m_Explosion == expDirected) vecVelocity = g_vecAttackDir * 200; else { vecVelocity.x = 0; vecVelocity.y = 0; vecVelocity.z = 0; } vecSpot = pev->origin + (pev->mins + pev->maxs) * 0.5; MESSAGE_BEGIN( MSG_PVS, SVC_TEMPENTITY, vecSpot ); WRITE_BYTE( TE_BREAKMODEL); // position WRITE_COORD( vecSpot.x ); WRITE_COORD( vecSpot.y ); WRITE_COORD( vecSpot.z ); // size WRITE_COORD( pev->size.x); WRITE_COORD( pev->size.y); WRITE_COORD( pev->size.z); // velocity WRITE_COORD( vecVelocity.x ); WRITE_COORD( vecVelocity.y ); WRITE_COORD( vecVelocity.z ); // randomization WRITE_BYTE( 10 ); // Model WRITE_SHORT( m_idShard ); //model id# // # of shards WRITE_BYTE( 0 ); // let client decide // duration WRITE_BYTE( 25 );// 2.5 seconds // flags WRITE_BYTE( cFlag ); MESSAGE_END(); float size = pev->size.x; if ( size < pev->size.y ) size = pev->size.y; if ( size < pev->size.z ) size = pev->size.z; // !!! HACK This should work! // Build a box above the entity that looks like an 8 pixel high sheet Vector mins = pev->absmin; Vector maxs = pev->absmax; mins.z = pev->absmax.z; maxs.z += 8; // BUGBUG -- can only find 256 entities on a breakable -- should be enough CBaseEntity *pList[256]; int count = UTIL_EntitiesInBox( pList, 256, mins, maxs, FL_ONGROUND ); if ( count ) { for ( int i = 0; i < count; i++ ) { ClearBits( pList[i]->pev->flags, FL_ONGROUND ); pList[i]->pev->groundentity = NULL; } } // Don't fire something that could fire myself pev->targetname = 0; pev->solid = SOLID_NOT; // Fire targets on break SUB_UseTargets( NULL, USE_TOGGLE, 0 ); SetThink( &CBreakable::SUB_Remove ); pev->nextthink = pev->ltime + 0.1; if ( m_iszSpawnObject ) CBaseEntity::Create( (char *)STRING(m_iszSpawnObject), VecBModelOrigin(pev), pev->angles, edict() ); if ( Explodable() ) { ExplosionCreate( Center(), pev->angles, edict(), ExplosionMagnitude(), TRUE ); } }
/* * FDM Touchdown callback. * * Called whenever the FDM just lands (on any surface). */ void SARSimTouchDownCB( void *realm_ptr, SFMModelStruct *model, void *client_data, double impact_coeff ) { int obj_num, *gcc_list, gcc_list_total, crash_cause = 0; Boolean over_water = False, have_floats = False, camera_in_cockpit = False; float distance_to_camera, contact_radius = 0.0f; sar_obj_flags_t crash_flags = 0; sar_air_worthy_state air_worthy_state = SAR_AIR_WORTHY_FLYABLE; sar_position_struct *pos, *ear_pos, *vel = NULL; sar_direction_struct *dir; sar_contact_bounds_struct *cb; sar_object_struct *obj_ptr; sar_object_aircraft_struct *obj_aircraft_ptr = NULL; sar_scene_struct *scene; SFMRealmStruct *realm = SFM_REALM(realm_ptr); sar_core_struct *core_ptr = SAR_CORE(client_data); const sar_option_struct *opt; if((realm == NULL) || (model == NULL) || (core_ptr == NULL)) return; opt = &core_ptr->option; scene = core_ptr->scene; if(scene == NULL) return; /* Creates sparks and plays the landed on belly sound */ #define DO_EFFECTS_LAND_BELLY \ { if((obj_aircraft_ptr != NULL) && (cb != NULL)) { \ const time_t life_span = 5000l; \ sar_position_struct pos_offset; \ pos_offset.x = 0.0f; \ pos_offset.y = 0.0f; \ pos_offset.z = -obj_aircraft_ptr->belly_height; \ /* Create sparks */ \ SmokeCreateSparks( \ scene, &core_ptr->object, &core_ptr->total_objects, \ &obj_ptr->pos, &pos_offset, \ cb->contact_radius * 2.0f, \ obj_num, \ cur_millitime + life_span \ ); \ } \ /* Play sound */ \ if(opt->event_sounds) \ SARSoundSourcePlayFromList( \ core_ptr->recorder, \ obj_ptr->sndsrc, obj_ptr->total_sndsrcs, \ camera_in_cockpit ? "land_belly_inside" : "land_belly", \ pos, dir, ear_pos \ ); \ } /* Plays landed on skis with minimal scraping sound */ #define DO_EFFECTS_LAND_SKIS \ { if(opt->event_sounds) \ SARSoundSourcePlayFromList( \ core_ptr->recorder, \ obj_ptr->sndsrc, obj_ptr->total_sndsrcs, \ camera_in_cockpit ? "land_ski_inside" : "land_ski", \ pos, dir, ear_pos \ ); \ } /* Creates sparks and play landed on skis with hard scraping sound */ #define DO_EFFECTS_LAND_SKIS_SKID \ { if((obj_aircraft_ptr != NULL) && (cb != NULL)) { \ const time_t life_span = 4000l; \ sar_position_struct pos_offset; \ pos_offset.x = 0.0f; \ pos_offset.y = 0.0f; \ pos_offset.z = (float)-( \ obj_aircraft_ptr->belly_height + \ obj_aircraft_ptr->gear_height \ ); \ /* Create sparks */ \ SmokeCreateSparks( \ scene, &core_ptr->object, &core_ptr->total_objects, \ &obj_ptr->pos, &pos_offset, \ cb->contact_radius * 2.0f, \ obj_num, \ cur_millitime + life_span \ ); \ } \ /* Play Sound */ \ if(opt->event_sounds) \ SARSoundSourcePlayFromList( \ core_ptr->recorder, \ obj_ptr->sndsrc, obj_ptr->total_sndsrcs, \ camera_in_cockpit ? "land_ski_skid_inside" : "land_ski_skid", \ pos, dir, ear_pos \ ); \ } /* Creates smoke puffs at each landing gear and plays the wheel skid * sound */ #define DO_EFFECTS_LAND_WHEEL_SKID \ { if(obj_aircraft_ptr != NULL) { \ const time_t life_span = 3500l; \ int i; \ sar_obj_part_struct *part; \ for(i = 0; True; i++) { \ part = SARObjGetPartPtr( \ obj_ptr, SAR_OBJ_PART_TYPE_LANDING_GEAR, i \ ); \ if(part == NULL) \ break; \ /* Create smoke puff at this landing gear */ \ SmokeCreate( \ scene, &core_ptr->object, &core_ptr->total_objects, \ SAR_SMOKE_TYPE_SMOKE, \ &obj_ptr->pos, &part->pos_max, \ 0.25f, 1.5f,/* Radius min and max */ \ -1.0f, /* Autocalc growth */ \ 1, /* Hide at max? */ \ 1, /* Total units */ \ life_span, /* Respawn interval in ms */ \ SAR_STD_TEXNAME_SMOKE_LIGHT, \ -1, /* No reference object */ \ cur_millitime + life_span \ ); \ } \ } \ /* Play sound */ \ if(opt->event_sounds) \ SARSoundSourcePlayFromList( \ core_ptr->recorder, \ obj_ptr->sndsrc, obj_ptr->total_sndsrcs, \ camera_in_cockpit ? "land_wheel_skid_inside" : "land_wheel_skid", \ pos, dir, ear_pos \ ); \ } /* Plays the crash on ground sound */ #define DO_EFFECTS_CRASH_GROUND \ { if(opt->event_sounds) \ SARSoundSourcePlayFromList( \ core_ptr->recorder, \ scene->sndsrc, scene->total_sndsrcs, \ "crash_ground", \ pos, dir, ear_pos \ ); \ } /* Plays the splash on water sound */ #define DO_EFFECTS_SPLASH_AIRCRAFT \ { if(opt->event_sounds) \ SARSoundSourcePlayFromList( \ core_ptr->recorder, \ scene->sndsrc, scene->total_sndsrcs, \ "splash_aircraft", \ pos, dir, ear_pos \ ); \ } /* Match object from FDM */ obj_ptr = SARSimMatchObjectFromFDM( core_ptr->object, core_ptr->total_objects, model, &obj_num ); if(obj_ptr == NULL) return; /* Skip touch down check entirly if in slew mode */ if(SARSimIsSlew(obj_ptr)) return; /* Get list of objects at this object's position */ gcc_list = SARGetGCCHitList( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, obj_num, &gcc_list_total ); /* Check if this object landed over water */ SARGetGHCOverWater( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, obj_num, NULL, &over_water ); /* Get up to date object position from the FDM */ pos = &obj_ptr->pos; pos->x = (float)model->position.x; pos->y = (float)model->position.y; pos->z = (float)model->position.z; ear_pos = &scene->ear_pos; /* Get up to date object direction from the FDM */ dir = &obj_ptr->dir; dir->heading = (float)model->direction.heading; dir->pitch = (float)model->direction.pitch; dir->bank = (float)model->direction.bank; /* Get contact bounds */ cb = obj_ptr->contact_bounds; if(cb != NULL) { crash_flags = cb->crash_flags; contact_radius = SARSimGetFlatContactRadius(obj_ptr); } /* Calculate distance between the object and the camera/ear */ distance_to_camera = (float)SFMHypot3( pos->x - ear_pos->x, pos->y - ear_pos->y, pos->z - ear_pos->z ); /* Check if camera is inside the cockpit */ switch(scene->camera_ref) { case SAR_CAMERA_REF_COCKPIT: camera_in_cockpit = True; break; case SAR_CAMERA_REF_SPOT: case SAR_CAMERA_REF_TOWER: case SAR_CAMERA_REF_MAP: case SAR_CAMERA_REF_HOIST: break; } /* Get object type specific values */ switch(obj_ptr->type) { case SAR_OBJ_TYPE_GARBAGE: case SAR_OBJ_TYPE_STATIC: case SAR_OBJ_TYPE_AUTOMOBILE: case SAR_OBJ_TYPE_WATERCRAFT: break; case SAR_OBJ_TYPE_AIRCRAFT: obj_aircraft_ptr = SAR_OBJ_GET_AIRCRAFT(obj_ptr); if(obj_aircraft_ptr != NULL) { int i; const sar_obj_part_struct *gear; vel = &obj_aircraft_ptr->vel; vel->x = (float)model->velocity_vector.x; vel->y = (float)model->velocity_vector.y; vel->z = (float)model->velocity_vector.z; air_worthy_state = obj_aircraft_ptr->air_worthy_state; /* Check if this object has floats */ for(i = 0; True; i++) { gear = SARObjGetPartPtr( obj_ptr, SAR_OBJ_PART_TYPE_LANDING_GEAR, i ); if(gear == NULL) break; if(gear->flags & SAR_OBJ_PART_FLAG_LGEAR_FLOATS) have_floats = True; } } break; case SAR_OBJ_TYPE_GROUND: case SAR_OBJ_TYPE_RUNWAY: case SAR_OBJ_TYPE_HELIPAD: case SAR_OBJ_TYPE_HUMAN: case SAR_OBJ_TYPE_SMOKE: case SAR_OBJ_TYPE_FIRE: case SAR_OBJ_TYPE_EXPLOSION: case SAR_OBJ_TYPE_CHEMICAL_SPRAY: case SAR_OBJ_TYPE_FUELTANK: case SAR_OBJ_TYPE_PREMODELED: break; } /* Substructure data pointer should now be set */ /* Values for crash_cause are: * * 5 Hit ground but was not flyable * 4 Splash * 3 Hit ground but was out of control * 2 Landed at bad angle * 1 Hit ground too hard * 0 No crash */ /* If object was already in flight but was not flyable * (ie it hit a building and is falling to the ground), * then contacting the ground is a crash. */ if(air_worthy_state == SAR_AIR_WORTHY_NOT_FLYABLE) { /* Already crashed and is considered a pile of junk */ crash_cause = 5; } else if(air_worthy_state == SAR_AIR_WORTHY_OUT_OF_CONTROL) { /* Collided with building, overspeed damage, or some other * prior damage */ crash_cause = 3; } /* Impact tolorance exceeded? */ else if(impact_coeff > 1.0f) { /* Aircraft was in flyable condition but now has contacted * ground with an impact greater than it's tolorance, which * means that it has crashed */ crash_cause = 1; } /* Landed in water and does not have floats? */ else if(over_water && !have_floats) { /* Splash */ crash_cause = 4; } /* Contacted ground at bad angle? */ else { if(dir->pitch > (float)(1.0 * PI)) { if(dir->pitch < (float)(1.75 * PI)) crash_cause = 2; } else { if(dir->pitch > (float)(0.25 * PI)) crash_cause = 2; } if(dir->bank > (float)(1.0 * PI)) { if(dir->bank < (float)(1.75 * PI)) crash_cause = 2; } else { if(dir->bank > (float)(0.25 * PI)) crash_cause = 2; } } #if 0 printf( "Touch down: crash_cause=%i impact_coeff=%.4f\n", crash_cause, impact_coeff ); #endif /* Did the object contact the ground abnormally (did it * "crash")? */ if(crash_cause) { float explosion_radius; sar_position_struct explosion_pos; char text[1024]; /* Set object as crashed in accordance with its type */ /* Aircraft? */ if(obj_aircraft_ptr != NULL) { /* If the crash was a splash then mark the object that * it is on water */ if(over_water) obj_aircraft_ptr->on_water = 1; /* Set all appropriate values for the aircraft to show * that it is crashed */ SARSimSetAircraftCrashed( scene, &core_ptr->object, &core_ptr->total_objects, obj_ptr, obj_aircraft_ptr ); } else { /* Add support for other types of objects that can crash */ } /* Is the crashed object the player object? */ if(obj_ptr == scene->player_obj_ptr) { /* Mark the player object as crashed on scene */ scene->player_has_crashed = True; /* Check if object has not crashed into anything * prior, such as if the object's airworth state was * not set to SAR_AIR_WORTHY_NOT_FLYABLE or * SAR_AIR_WORTHY_OUT_OF_CONTROL */ if((crash_cause != 3) && (crash_cause != 5)) { /* Set banner message to display the cause of the * crash */ SARBannerMessageAppend(scene, NULL); SARBannerMessageAppend(scene, SAR_MESG_CRASH_BANNER); switch(crash_cause) { case 4: /* Splash */ strcpy(text, SAR_MESG_CRASH_SPLASH); SARBannerMessageAppend(scene, text); break; case 2: /* Landed at bad angle */ strcpy(text, SAR_MESG_CRASH_ROTATION_TOO_STEEP); SARBannerMessageAppend(scene, text); break; case 1: /* Hit ground too hard */ /* There should be exactly one occurance of * "%.0f%%" in * SAR_MESG_CRASH_IMPACTED_PAST_TOLORANCE for * the substitution to work */ sprintf( text, SAR_MESG_CRASH_IMPACTED_PAST_TOLORANCE, (float)(impact_coeff * 100) ); SARBannerMessageAppend(scene, text); break; } /* Set footer to indicate what player should do * now, press space to continue */ SARBannerMessageAppend(scene, SAR_MESG_POST_CRASH_BANNER); } } else { /* An object other than the player object has * crashed */ char numstr[80]; sprintf(numstr, "Object #%i", obj_num); *text = '\0'; strcat(text, "*** "); strncat(text, (obj_ptr->name != NULL) ? obj_ptr->name : numstr, 80 ); strcat(text, " has crashed! ***"); SARMessageAdd(scene, text); } /* Get position and size for the creation of the explosion */ memcpy(&explosion_pos, &obj_ptr->pos, sizeof(sar_position_struct)); explosion_radius = (float)MAX(contact_radius * 1.8, 10.0); /* Begin checking if we should create explosion or splash */ /* Check if object has not crashed into anything * prior, such as if the object's airworth state was * not set to SAR_AIR_WORTHY_NOT_FLYABLE or * SAR_AIR_WORTHY_OUT_OF_CONTROL */ if((crash_cause != 3) && (crash_cause != 5)) { /* Just crashed into ground and did not crash into * anything prior or was not out of control, so we * should create an explosion */ int i, explosion_obj_num = -1; sar_object_struct *explosion_obj_ptr = NULL; sar_external_fueltank_struct *eft_ptr; float fuel_remaining = 10.0f; /* Assume some fuel, in kg */ /* Get amount of fuel remaining on this object */ if(obj_aircraft_ptr != NULL) { fuel_remaining = MAX(obj_aircraft_ptr->fuel, 0.0f); for(i = 0; i < obj_aircraft_ptr->total_external_fueltanks; i++) { eft_ptr = obj_aircraft_ptr->external_fueltank[i]; if((eft_ptr != NULL) ? (eft_ptr->flags & SAR_EXTERNAL_FUELTANK_FLAG_ONBOARD) : False ) fuel_remaining += (eft_ptr->dry_mass + eft_ptr->fuel); } } /* Has fuel and not over water? */ if((fuel_remaining > 0.0f) && !over_water) { /* Create explosion because this object crashed with * fuel */ sar_position_struct smoke_offset; /* Delete all effects objects related to this object * but only stop smoke trails from respawning */ SARSimDeleteEffects( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, obj_num, SARSIM_DELETE_EFFECTS_SMOKE_STOP_RESPAWN ); /* Create explosion object */ explosion_obj_num = ExplosionCreate( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, &explosion_pos, /* Position of explosion */ explosion_radius, /* Radius of size in meters */ obj_num, /* Reference object number */ SAR_STD_TEXNAME_EXPLOSION, SAR_STD_TEXNAME_EXPLOSION_IR ); if(explosion_obj_num > -1) { sar_object_explosion_struct *obj_explosion_ptr; explosion_obj_ptr = core_ptr->object[explosion_obj_num]; obj_explosion_ptr = SAR_OBJ_GET_EXPLOSION(explosion_obj_ptr); if(obj_explosion_ptr != NULL) { /* Set lifespan for explosion */ explosion_obj_ptr->life_span = cur_millitime + opt->crash_explosion_life_span; /* Repeat frames until life span is reached */ obj_explosion_ptr->total_frame_repeats = -1; } } /* Create smoke trails object */ smoke_offset.x = 0.0f; smoke_offset.y = 0.0f; smoke_offset.z = explosion_radius; SmokeCreate( scene, &core_ptr->object, &core_ptr->total_objects, SAR_SMOKE_TYPE_SMOKE, &explosion_pos, &smoke_offset, explosion_radius * 1.0f, /* Radius start */ explosion_radius * 3.0f, /* Radius max */ -1.0f, /* Autocalc growth */ 1, /* Hide at max */ 10, /* Total units */ 3000l, /* Respawn interval in ms */ SAR_STD_TEXNAME_SMOKE_DARK, obj_num, cur_millitime + opt->crash_explosion_life_span ); } /* Splash? */ else if(over_water) { /* Delete all effects objects related to this object * but only stop smoke trails from respawning */ SARSimDeleteEffects( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, obj_num, SARSIM_DELETE_EFFECTS_SMOKE_STOP_RESPAWN ); /* Create splash */ explosion_obj_num = SplashCreate( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, &explosion_pos, /* Position of explosion */ explosion_radius, /* Radius of size in meters */ obj_num, /* Reference object number */ SAR_STD_TEXNAME_SPLASH, SAR_STD_TEXNAME_SPLASH ); if(explosion_obj_num > -1) { explosion_obj_ptr = core_ptr->object[explosion_obj_num]; /* No need to modify splash values */ } } /* Is this the player object? */ if(scene->player_obj_ptr == obj_ptr) { /* Set spot camera position */ scene->camera_ref = SAR_CAMERA_REF_SPOT; scene->camera_target = scene->player_obj_num; } } /* Was out of control? */ else if(crash_cause == 3) { /* Object was out of control and has now just hit the * ground so it needs to crash */ int explosion_obj_num = -1; sar_object_struct *explosion_obj_ptr = NULL; /* We still need to create a splash if landed on water */ if(over_water) { /* Delete all effects objects related to this object * but only stop smoke trails from respawning */ SARSimDeleteEffects( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, obj_num, SARSIM_DELETE_EFFECTS_SMOKE_STOP_RESPAWN ); /* Create splash (explosion) object */ explosion_obj_num = SplashCreate( core_ptr, scene, &core_ptr->object, &core_ptr->total_objects, &explosion_pos, /* Position of explosion */ explosion_radius, /* Radius of size in meters */ obj_num, /* Reference object number */ SAR_STD_TEXNAME_SPLASH, SAR_STD_TEXNAME_SPLASH ); if(explosion_obj_num > -1) { explosion_obj_ptr = core_ptr->object[explosion_obj_num]; /* No need to modify splash values */ } } /* Is this the player object? */ if(scene->player_obj_ptr == obj_ptr) { /* Set spot camera position */ scene->camera_ref = SAR_CAMERA_REF_SPOT; scene->camera_target = scene->player_obj_num; } } /* Play splash or explosion sound if the object was not crashed before (cause 5)*/ if (crash_cause != 5) { if(over_water) { DO_EFFECTS_SPLASH_AIRCRAFT } else { DO_EFFECTS_CRASH_GROUND } } /* Call mission destroy notify instead of mission land * notify, to let mission know this object has crashed */ SARMissionDestroyNotify(core_ptr, obj_ptr); }
void CTank :: Fire ( int canon ) { Vector vecGun; GetAttachment( canon, vecGun, Vector(0,0,0) ); if ( !FStrEq(STRING(gpGlobals->mapname), "l3m10") && !FStrEq(STRING(gpGlobals->mapname), "l3m12") && !FStrEq(STRING(gpGlobals->mapname), "l3m14") ) { CSprite *pSprite = CSprite::SpriteCreate( SPRITE_SMOKE, vecGun, TRUE ); pSprite->AnimateAndDie( 15 ); pSprite->SetTransparency( kRenderTransAdd, 255, 255, 255, 255, kRenderFxNoDissipation ); pSprite->SetAttachment( edict(), canon+1 ); pSprite->SetScale( SPRITE_SMOKE_SCALE ); } TraceResult tr; UTIL_MakeVectors ( TourelleAngle() ); UTIL_TraceLine( vecGun, vecGun + gpGlobals->v_forward * 8192, dont_ignore_monsters, edict(), &tr ); // pas de dommages - la fonction standart donne un rayon 2.5 fois les dommages // 250 * 2.5 = 625 - bcp trop grand ExplosionCreate( tr.vecEndPos, pev->angles, NULL/*edict()*/, 250, FALSE ); // on applique nous-même les dommages - rayon : 250 ::RadiusDamage( tr.vecEndPos, pev, pev, 300, 300, CLASS_NONE, DMG_BLAST ); //effet de fumée EnvSmokeCreate( tr.vecEndPos, 4, 10, 2, NULL ); /* // sprites de feu for ( int i=0; i<4; i++ ) { for ( int j=0; j<3; j++ ) { CSprite *pSpr = CSprite::SpriteCreate ( SPRITE_FEU, tr.vecEndPos + Vector(0,0,50), TRUE ); pSpr->SetTransparency ( kRenderTransAdd, 255, 255, 255, 180, kRenderFxNone ); pSpr->pev->scale = (float)((float)SPRITE_FEU_SCALE*2*(1/(i+1))); pSpr->pev->framerate = RANDOM_FLOAT(18,24); pSpr->pev->velocity = Vector ( RANDOM_FLOAT(-50,50)*(3-i)/3,RANDOM_FLOAT(-50,50)*(3-i)/3, 50*(i)); pSpr->pev->spawnflags |= SF_SPRITE_ONCE; pSpr->TurnOn(); } } */ /* for ( i=0; i<1; i++ ) { CSprite *pSpr = CSprite::SpriteCreate ( SPRITE_SMOKEBALL, Vector(pev->origin.x,pev->origin.y,pev->origin.z + 100), TRUE ); pSpr->SetScale ( SPRITE_SMOKEBALL_SCALE ); pSpr->AnimateAndDie ( RANDOM_FLOAT(3,4) ); pSpr->SetTransparency ( kRenderTransAlpha, 255, 255, 255, 200, kRenderFxNone ); pSpr->pev->velocity = Vector ( RANDOM_FLOAT(-50,50),RANDOM_FLOAT(-50,50),RANDOM_FLOAT(130,150) ); } */ //breakable spéciaux if ( FClassnameIs (tr.pHit, "func_breakable") && VARS(tr.pHit)->spawnflags & SF_BREAK_TANKTOUCH ) { CBreakable *pBreak = (CBreakable*) CBaseEntity::Instance(tr.pHit); if ( pBreak->CheckTankPrev() ) { pBreak->pev->health = 0; pBreak->Killed( pev, GIB_NORMAL ); pBreak->Die(); } } }
//----------------------------------------------------------------------------- // 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 = ( 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(); } ConVarRef breakable_disable_gib_limit( "breakable_disable_gib_limit" ); if ( !breakable_disable_gib_limit.GetBool() && iCount ) { if ( m_PerformanceMode == PM_NO_GIBS ) { iCount = 0; } else if ( m_PerformanceMode == PM_REDUCED_GIBS ) { int iNewCount = iCount * func_break_reduction_factor.GetFloat(); iCount = MAX( iNewCount, 1 ); } } if ( m_iszModelName != NULL_STRING ) { 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, GetExplosiveDamage(), GetExplosiveRadius(), true ); } }
void CBreakable::Die() { Vector vecSpot; // shard origin Vector vecVelocity; // shard velocity CBaseEntity *pEntity = NULL; char cFlag = 0; int pitch; float fvol; pev->takedamage = DAMAGE_NO; pev->deadflag = DEAD_DEAD; pev->effects = EF_NODRAW; pitch = 95 + RANDOM_LONG(0, 29); if (pitch > 97 && pitch < 103) pitch = 100; // The more negative pev->health, the louder // the sound should be. fvol = RANDOM_FLOAT(0.85, 1.0) + (abs((int)pev->health) / 100.0f); if (fvol > 1.0f) fvol = 1.0f; switch (m_Material) { case matGlass: switch (RANDOM_LONG(0, 1)) { case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustglass1.wav", fvol, ATTN_NORM, 0, pitch); break; case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustglass2.wav", fvol, ATTN_NORM, 0, pitch); break; } cFlag = BREAK_GLASS; if (TheBots != NULL) { TheBots->OnEvent(EVENT_BREAK_GLASS, this); } break; case matWood: switch (RANDOM_LONG(0, 1)) { case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustcrate1.wav", fvol, ATTN_NORM, 0, pitch); break; case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustcrate2.wav", fvol, ATTN_NORM, 0, pitch); break; } cFlag = BREAK_WOOD; if (TheBots != NULL) { TheBots->OnEvent(EVENT_BREAK_WOOD, this); } break; case matMetal: case matComputer: switch (RANDOM_LONG(0, 1)) { case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustmetal1.wav", fvol, ATTN_NORM, 0, pitch); break; case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustmetal2.wav", fvol, ATTN_NORM, 0, pitch); break; } cFlag = BREAK_METAL; if (TheBots != NULL) { TheBots->OnEvent(EVENT_BREAK_METAL, this); } break; case matFlesh: switch (RANDOM_LONG(0, 1)) { case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustflesh1.wav", fvol, ATTN_NORM, 0, pitch); break; case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustflesh2.wav", fvol, ATTN_NORM, 0, pitch); break; } cFlag = BREAK_FLESH; if (TheBots != NULL) { TheBots->OnEvent(EVENT_BREAK_FLESH, this); } break; case matCinderBlock: case matRocks: switch (RANDOM_LONG(0, 1)) { case 0: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustconcrete1.wav", fvol, ATTN_NORM, 0, pitch); break; case 1: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustconcrete2.wav", fvol, ATTN_NORM, 0, pitch); break; } cFlag = BREAK_CONCRETE; if (TheBots != NULL) { TheBots->OnEvent(EVENT_BREAK_CONCRETE, this); } break; case matCeilingTile: EMIT_SOUND_DYN(ENT(pev), CHAN_VOICE, "debris/bustceiling.wav", fvol, ATTN_NORM, 0, pitch); break; default: break; } if (m_Explosion == expDirected) { vecVelocity = g_vecAttackDir * 200.0f; } else { vecVelocity.x = 0; vecVelocity.y = 0; vecVelocity.z = 0; } vecSpot = pev->origin + (pev->mins + pev->maxs) * 0.5; MESSAGE_BEGIN(MSG_PVS, SVC_TEMPENTITY, vecSpot); WRITE_BYTE(TE_BREAKMODEL); WRITE_COORD(vecSpot.x); // position WRITE_COORD(vecSpot.y); WRITE_COORD(vecSpot.z); WRITE_COORD(pev->size.x); // size WRITE_COORD(pev->size.y); WRITE_COORD(pev->size.z); WRITE_COORD(vecVelocity.x); // velocity WRITE_COORD(vecVelocity.y); WRITE_COORD(vecVelocity.z); WRITE_BYTE(10); // randomization WRITE_SHORT(m_idShard); // model id# WRITE_BYTE(0); // # of shards, let client decide WRITE_BYTE(25); // duration, 2.5 seconds WRITE_BYTE(cFlag); // flags MESSAGE_END(); float size = pev->size.x; if (size < pev->size.y) size = pev->size.y; if (size < pev->size.z) size = pev->size.z; Vector mins = pev->absmin; Vector maxs = pev->absmax; mins.z = pev->absmax.z; maxs.z += 8; CBaseEntity *pList[256]; int count = UTIL_EntitiesInBox(pList, ARRAYSIZE(pList), mins, maxs, FL_ONGROUND); if (count) { for (int i = 0; i < count; ++i) { pList[i]->pev->flags &= ~FL_ONGROUND; pList[i]->pev->groundentity = NULL; } } pev->solid = SOLID_NOT; SUB_UseTargets(NULL, USE_TOGGLE, 0); SetThink(NULL); pev->nextthink = pev->ltime + 0.1f; if (m_iszSpawnObject) { CBaseEntity::Create((char *)STRING(m_iszSpawnObject), VecBModelOrigin(pev), pev->angles, edict()); } if (Explodable()) { ExplosionCreate(Center(), pev->angles, edict(), ExplosionMagnitude(), TRUE); } }