예제 #1
0
//---------------------------------------------------------
//---------------------------------------------------------
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 );
}
예제 #2
0
파일: Bullet.c 프로젝트: yoyz/genesis
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 );
}
예제 #4
0
//-----------------------------------------------------------------------------
// 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 );
}
예제 #5
0
//-----------------------------------------------------------------------------
// 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 );
}
예제 #7
0
//-----------------------------------------------------------------------------
// 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);
}
예제 #8
0
파일: Bullet.c 프로젝트: yoyz/genesis
void BulletCollide(ObjectStruct* bulletObject, ObjectStruct* collidedObject)
{
    bulletObject->objectState = OBJECTSTATE_INACTIVE;

    if (collidedObject->objectType == TYPE_BREAKABLE)
    {
        ExplosionCreate(bulletObject->x, bulletObject->y);
    }
}
예제 #9
0
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 );
}
예제 #10
0
//-----------------------------------------------------------------------------
// 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 );
}
예제 #12
0
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 );
}
예제 #13
0
파일: EnemyPlane.c 프로젝트: yoyz/genesis
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);
        }
    }
예제 #14
0
//-----------------------------------------------------------------------------
// 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 );
}
예제 #15
0
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 );
	}
}
예제 #16
0
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 );
}
예제 #17
0
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);
}
예제 #18
0
//-----------------------------------------------------------------------------
// 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 );
}
예제 #19
0
//-----------------------------------------------------------------------------
// 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;
}
예제 #20
0
파일: EnemyBullet.c 프로젝트: yoyz/genesis
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;
    }
}
예제 #21
0
void ExplosionCreate( const Vector &center, 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 );
}
예제 #24
0
//---------------------------------------------------------
//---------------------------------------------------------
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 );
}
예제 #25
0
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);
}
예제 #26
0
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 );
	}
}
예제 #27
0
파일: simcb.c 프로젝트: hsanjuan/sar2
/*
 *	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);
    }
예제 #28
0
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();
		}
	}
}
예제 #29
0
//-----------------------------------------------------------------------------
// 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 );
	}
}
예제 #30
0
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);
	}
}