Exemplo n.º 1
0
bool HoldableItemExplosive::use( void )
{
	if ( _owner )
	{
		if ( !_owner->isSubclassOf( Player ) )
			return false;

		Player *player;

		player = (Player *)_owner;

		// If explosive armed

		if ( _explosiveArmed && ( _explosiveArmTime + 1.0f < level.time ) )
		{
			if ( _explosiveAlive && _explosive )
			{
				// Blow up the explosive

				ExplosionAttack( _explosive->origin, _owner, "models/weapons/explosion-holdable.tik" );

				// Must check again if _explosive exists, because ExplosionAttack might have caused the holdable item to be destroyed

				if ( _explosive )
				{
					_explosive->PostEvent( EV_Remove, 0.0f );
					_explosive = NULL;
				}

				_explosiveAlive = false;
			}

			return true;
		}
		else if ( !_explosiveArmed )
		{
			Vector newOrigin;
			Vector newAngles;

			// Explosive hasn't been armed yet

			if ( !findPlaceToSet( newOrigin, newAngles ) )
			{
				if ( _lastSoundTime + 0.5f < level.time )
				{
					Sound( "snd_noammo" );

					_lastSoundTime = level.time;
				}

				return false;
			}

			_explosiveArmTime = level.time;
			_explosiveArmed = true;

			// Spawn the item into the world

			_explosive = new Entity( EntityCreateFlagAnimate );

			_explosive->setModel( "models/item/holdable_explosive.tik" );

			_explosive->CancelEventsOfType( EV_ProcessInitCommands );
			_explosive->ProcessInitCommands( _explosive->edict->s.modelindex );

			_explosive->setSolidType( SOLID_BBOX );
			_explosive->setContents( CONTENTS_SHOOTABLE_ONLY );

			_explosive->setSize( Vector( -16, -16, 0 ), Vector( 16, 16, 32 ) );

			_explosive->setHealth( 5.0f );

			_explosive->takedamage = DamageYes;

			_explosive->setOrigin( newOrigin );
			_explosive->setAngles( newAngles );
			_explosive->animate->RandomAnimate( "idle_placed" );
		}
	}

	return false;
}
Exemplo n.º 2
0
void GooProjectile::Explode( Event *ev )
{
	int i;
	Entity *owner;
	Entity *ignoreEnt=NULL;
	
	if ( ev->NumArgs() == 1 )
		ignoreEnt = ev->GetEntity( 1 );
	
	// Get the owner of this projectile
	owner = G_GetEntity( this->owner );
	
	// If the owner's not here, make the world the owner
	if ( !owner )
		owner = world;
	
	takedamage = DamageNo;
	
	// Spawn an explosion model
	if ( explosionmodel.length() )
	{
		// Move the projectile back off the surface a bit so we can see
		// explosion effects.
		Vector dir, v;
		v = velocity;
		v.normalize();
		dir = v;
		v = origin - v * 36.0f;
		setOrigin( v );
		
		ExplosionAttack( v, owner, explosionmodel, dir, ignoreEnt );
	}
	
	CancelEventsOfType( EV_Projectile_UpdateBeam );
	
	// Kill the beam
	if ( m_beam )
	   {
		m_beam->ProcessEvent( EV_Remove );
		m_beam = NULL;
	   }
	
	// When the goo hits something, spawn debris
	for ( i=0; i<m_debriscount; i++ )
	{
		GooDebris  *proj;
		Vector      dir;
		
		dir = Vector( level.impact_trace.plane.normal );
		dir += Vector( crandom() * 0.5, crandom() * 0.5f, 0.0f );
		
		proj = ( GooDebris * )ProjectileAttack( this->origin, dir, this, m_debrismodel, 1.0f );
		
		if ( !proj )
		{
			warning( "GooProjectile::Explode", "Could not create debris projectile" );
			return;
		}
		
		proj->owner = ENTITYNUM_WORLD;
		proj->setSolidType( SOLID_TRIGGER );
		proj->avelocity = Vector( G_CRandom( 360.0f ), G_CRandom( 360.0f ), G_CRandom( 360.0f ) );
		proj->setSize( Vector( -16.0f, -16.0f, 0.0f ) * proj->edict->s.scale, Vector( 16.0f ,16.0f ,32.0f ) * proj->edict->s.scale );
		proj->setMoveType( MOVETYPE_TOSS );
		proj->PostEvent( EV_GooDebris_Prethink, level.frametime );
	}
	
	// Change to the splat
	if ( level.impact_trace.ent && ( level.impact_trace.ent->solid == SOLID_BSP ) )
	{
		GooDebris *p;
		Vector ang;
		p = new GooDebris;
		vectoangles( level.impact_trace.plane.normal, ang );
		p->setAngles( ang );
		p->setModel( this->model );
		p->ProcessInitCommands( p->edict->s.modelindex );
		p->setSize( Vector( -16.0f, -16.0f, 0.0f ) * p->edict->s.scale, Vector( 16.0f, 16.0f, 32.0f ) * p->edict->s.scale );
		p->setOrigin( this->origin );
		p->velocity = Vector( 0.0f, 0.0f, 0.0f );
		p->setMoveType( MOVETYPE_FLY );
		p->setSolidType( SOLID_TRIGGER );
		p->animate->RandomAnimate( "splat" );
		p->owner = this->owner;
		p->PostEvent( EV_GooDebris_Prethink, level.frametime ); // shrink out
	}
}