Esempio n. 1
0
/*
================
idObjectiveComplete::Event_Trigger - Nicemice: modified
================
*/
void idObjectiveComplete::Event_Trigger( idEntity *activator ) {

  if ( gameLocal.isServer ) {
    ServerSendEvent( EVENT_TRIGGER, NULL, false, -1 );
  }

	if ( !spawnArgs.GetBool( "objEnabled" ) ) {
		return;
	}
	idPlayer *player = gameLocal.GetLocalPlayer();
	if ( !player )
    return;
  
		RemoveItem( player );

	if ( !spawnArgs.GetString( "inv_objective", NULL ) )
    return;
  
	if ( !player->hud )
    return;

				player->hud->SetStateString( "objective", "2" );
				player->hud->SetStateString( "objectivetext", spawnArgs.GetString( "objectivetext" ) );
				player->hud->SetStateString( "objectivetitle", spawnArgs.GetString( "objectivetitle" ) );
				player->CompleteObjective( spawnArgs.GetString( "objectivetitle" ) );
				PostEventMS( &EV_GetPlayerPos, 2000 );
			}
Esempio n. 2
0
/*
================
idObjectiveComplete::Event_HideObjective - Nicemice: modified
================
*/
void idObjectiveComplete::Event_HideObjective( idEntity *e ) {

  if ( gameLocal.isServer ) {
    ServerSendEvent( EVENT_HIDEOBJECTIVE, NULL, false, -1 );
  }

	idPlayer *player = gameLocal.GetLocalPlayer();
  if ( !gameLocal.isMultiplayer ) {
	  if ( !player )
      return;

    idVec3 v = player->GetPhysics()->GetOrigin() - playerPos;
		if ( v.Length() > 64.0f ) {
      if ( player->hud ) {
			player->hud->HandleNamedEvent( "closeObjective" );
      }
			PostEventMS( &EV_Remove, 0 );
		} else {
			PostEventMS( &EV_HideObjective, 100, player );
		}
  } else {
    if ( player ) {
      player->hud->HandleNamedEvent( "closeObjective" );
      PostEventMS( &EV_Remove, 100 );
    }
	}
}
Esempio n. 3
0
/*
================
idObjective::Event_Screenshot
================
*/
void idObjective::Event_CamShot( ) {

  // Nicemice: added
  if ( gameLocal.isServer )
  {
    ServerSendEvent( EVENT_CAMSHOT, NULL,false, -1);
  }
	const char *camName;
	idStr shotName = gameLocal.GetMapName();
	shotName.StripFileExtension();
	shotName += "/";
	shotName += spawnArgs.GetString( "screenshot" );
	shotName.SetFileExtension( ".tga" );
	if ( spawnArgs.GetString( "camShot", "", &camName ) ) {
		idEntity *ent = gameLocal.FindEntity( camName );
		if ( ent && ent->cameraTarget ) {
			const renderView_t *view = ent->cameraTarget->GetRenderView();
			renderView_t fullView = *view;
			fullView.width = SCREEN_WIDTH;
			fullView.height = SCREEN_HEIGHT;
			// draw a view to a texture
			renderSystem->CropRenderSize( 256, 256, true );
			gameRenderWorld->RenderScene( &fullView );
			renderSystem->CaptureRenderToFile( shotName );
			renderSystem->UnCrop();
		}
	}
}
Esempio n. 4
0
/*
================
idBrittleFracture::Shatter
================
*/
void idBrittleFracture::Shatter( const idVec3 &point, const idVec3 &impulse, const int time ) {
	int i;
	idVec3 dir;
	shard_t *shard;
	float m;

	if ( gameLocal.isServer ) {
		idBitMsg	msg;
		byte		msgBuf[MAX_EVENT_PARAM_SIZE];

		msg.Init( msgBuf, sizeof( msgBuf ) );
		msg.BeginWriting();
		msg.WriteFloat( point[0] );
		msg.WriteFloat( point[1] );
		msg.WriteFloat( point[2] );
		msg.WriteFloat( impulse[0] );
		msg.WriteFloat( impulse[1] );
		msg.WriteFloat( impulse[2] );
		ServerSendEvent( EVENT_SHATTER, &msg, true, -1 );
	}

	if ( time > ( gameLocal.time - SHARD_ALIVE_TIME ) ) {
		StartSound( "snd_shatter", SND_CHANNEL_ANY, 0, false, NULL );
	}

	if ( !IsBroken() ) {
		Break();
	}

	if ( fxFracture.Length() ) {
		idEntityFx::StartFx( fxFracture, &point, &GetPhysics()->GetAxis(), this, true );
	}

	dir = impulse;
	m = dir.Normalize();

	for ( i = 0; i < shards.Num(); i++ ) {
		shard = shards[i];

		if ( shard->droppedTime != -1 ) {
			continue;
		}

		if ( ( shard->clipModel->GetOrigin() - point ).LengthSqr() > Square( maxShatterRadius ) ) {
			continue;
		}

		DropShard( shard, point, dir, m, time );
	}

	DropFloatingIslands( point, impulse, time );

	//trigger it.
	if (!firedTargets)
	{
		firedTargets = true;
		ActivateTargets(this);
	}
}
Esempio n. 5
0
/*
================
idItem::Event_RespawnFx
================
*/
void idItem::Event_RespawnFx( void ) {
	if ( gameLocal.isServer ) {
		ServerSendEvent( EVENT_RESPAWNFX, NULL, false, -1 );
	}
	const char *sfx = spawnArgs.GetString( "fxRespawn" );
	if ( sfx && *sfx ) {
		idEntityFx::StartFx( sfx, NULL, NULL, this, true );
	}
}
Esempio n. 6
0
/*
================
idLight::BecomeBroken
================
*/
void idLight::BecomeBroken( idEntity *activator ) {
	const char *damageDefName;

	fl.takedamage = false;

	if ( brokenModel.Length() ) {
		SetModel( brokenModel );

		if ( !spawnArgs.GetBool( "nonsolid" ) ) {
			GetPhysics()->SetClipModel( new idClipModel( brokenModel.c_str() ), 1.0f );
			GetPhysics()->SetContents( CONTENTS_SOLID );
		}
	} else if ( spawnArgs.GetBool( "hideModelOnBreak" ) ) {
		SetModel( "" );
		GetPhysics()->SetContents( 0 );
	}

	if ( gameLocal.isServer ) {

		ServerSendEvent( EVENT_BECOMEBROKEN, NULL, true, -1 );

		if ( spawnArgs.GetString( "def_damage", "", &damageDefName ) ) {
			idVec3 origin = renderEntity.origin + renderEntity.bounds.GetCenter() * renderEntity.axis;
			gameLocal.RadiusDamage( origin, activator, activator, this, this, damageDefName );
		}

	}

	ActivateTargets( activator );

	// offset the start time of the shader to sync it to the game time
	renderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time );
	renderLight.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.time );

	// set the state parm
	renderEntity.shaderParms[ SHADERPARM_MODE ] = 1;
	renderLight.shaderParms[ SHADERPARM_MODE ] = 1;

	// if the light has a sound, either start the alternate (broken) sound, or stop the sound
	const char *parm = spawnArgs.GetString( "snd_broken" );
	if ( refSound.shader || ( parm && *parm ) ) {
		StopSound( SND_CHANNEL_ANY, false );
		const idSoundShader *alternate = refSound.shader ? refSound.shader->GetAltSound() : declManager->FindSound( parm );
		if ( alternate ) {
			// start it with no diversity, so the leadin break sound plays
			refSound.referenceSound->StartSound( alternate, SND_CHANNEL_ANY, 0.0, 0 );
		}
	}

	parm = spawnArgs.GetString( "mtr_broken" );
	if ( parm && *parm ) {
		SetShader( parm );
	}

	UpdateVisuals();
}
Esempio n. 7
0
/*
================
idItem::Pickup
================
*/
bool idItem::Pickup(idPlayer *player)
{

	if (!GiveToPlayer(player)) {
		return false;
	}

	if (gameLocal.isServer) {
		ServerSendEvent(EVENT_PICKUP, NULL, false, -1);
	}

	// play pickup sound
	StartSound("snd_acquire", SND_CHANNEL_ITEM, 0, false, NULL);

	// trigger our targets
	ActivateTargets(player);

	// clear our contents so the object isn't picked up twice
	GetPhysics()->SetContents(0);

	// hide the model
	Hide();

	// add the highlight shell
	if (itemShellHandle != -1) {
		gameRenderWorld->FreeEntityDef(itemShellHandle);
		itemShellHandle = -1;
	}

	float respawn = spawnArgs.GetFloat("respawn");
	bool dropped = spawnArgs.GetBool("dropped");
	bool no_respawn = spawnArgs.GetBool("no_respawn");

	if (gameLocal.isMultiplayer && respawn == 0.0f) {
		respawn = 20.0f;
	}

	if (respawn && !dropped && !no_respawn) {
		const char *sfx = spawnArgs.GetString("fxRespawn");

		if (sfx && *sfx) {
			PostEventSec(&EV_RespawnFx, respawn - 0.5f);
		}

		PostEventSec(&EV_RespawnItem, respawn);
	} else if (!spawnArgs.GetBool("inv_objective") && !no_respawn) {
		// give some time for the pickup sound to play
		// FIXME: Play on the owner
		if (!spawnArgs.GetBool("inv_carry")) {
			PostEventMS(&EV_Remove, 5000);
		}
	}

	BecomeInactive(TH_THINK);
	return true;
}
/*
================
hhWeaponAutoCannon::Event_OverHeatNetEvent
================
*/
void hhWeaponAutoCannon::Event_OverHeatNetEvent() { //rww
    if (gameLocal.isClient) {
        return;
    }

    idBitMsg	msg;
    byte		msgBuf[MAX_EVENT_PARAM_SIZE];

    msg.Init( msgBuf, sizeof( msgBuf ) );
    ServerSendEvent( EVENT_OVERHEAT, &msg, false, -1 );
}
Esempio n. 9
0
/*
================
idItem::Event_Respawn
================
*/
void idItem::Event_Respawn( void ) {
	if ( gameLocal.isServer ) {
		ServerSendEvent( EVENT_RESPAWN, NULL, false, -1 );
	}
	BecomeActive( TH_THINK );
	Show();
	inViewTime = -1000;
	lastCycle = -1;
	GetPhysics()->SetContents( CONTENTS_TRIGGER );
	SetOrigin( orgOrigin );
	StartSound( "snd_respawn", SND_CHANNEL_ITEM, 0, false, NULL );
	CancelEvents( &EV_RespawnItem ); // don't double respawn
}
Esempio n. 10
0
/*
================
idObjective::Event_Trigger
================
*/
void idObjective::Event_Trigger( idEntity *activator ) {





  // Nicemice: added
  if ( gameLocal.isServer )
  {
    ServerSendEvent( EVENT_TRIGGER, NULL, false,-1);
  }

	idPlayer *player = gameLocal.GetLocalPlayer();
	if ( player ) {

		//Pickup( player );

		if ( spawnArgs.GetString( "inv_objective", NULL ) ) {
			if ( player && player->hud ) {
				idStr shotName = gameLocal.GetMapName();
				shotName.StripFileExtension();
				shotName += "/";
				shotName += spawnArgs.GetString( "screenshot" );
				shotName.SetFileExtension( ".tga" );
				player->hud->SetStateString( "screenshot", shotName );
				player->hud->SetStateString( "objective", "1" );
				player->hud->SetStateString( "objectivetext", spawnArgs.GetString( "objectivetext" ) );
				player->hud->SetStateString( "objectivetitle", spawnArgs.GetString( "objectivetitle" ) );
				player->GiveObjective( spawnArgs.GetString( "objectivetitle" ), spawnArgs.GetString( "objectivetext" ), shotName );

				// a tad slow but keeps from having to update all objectives in all maps with a name ptr
				for( int i = 0; i < gameLocal.num_entities; i++ ) {
					if ( gameLocal.entities[ i ] && gameLocal.entities[ i ]->IsType( idObjectiveComplete::Type ) ) {
						if ( idStr::Icmp( spawnArgs.GetString( "objectivetitle" ), gameLocal.entities[ i ]->spawnArgs.GetString( "objectivetitle" ) ) == 0 ){
							gameLocal.entities[ i ]->spawnArgs.SetBool( "objEnabled", true );
							break;
						}
					}
				}

				PostEventMS( &EV_GetPlayerPos, 2000 );
			}
		}
	}
}
Esempio n. 11
0
/*
================
idTrigger_Fade::Event_Trigger - Nicemice: modified
================
*/
void idTrigger_Fade::Event_Trigger( idEntity *activator ) {




  // Nicemice: added
  if ( gameLocal.isServer )
    ServerSendEvent( EVENT_TRIGGER_FADE, NULL, false, -1 );

	int fadeTime = SEC2MS( spawnArgs.GetFloat( "fadeTime", "0.5" ) );
	idPlayer *player = gameLocal.GetLocalPlayer();
   
	if ( player )
  {
    idVec4 fadeColor = spawnArgs.GetVec4( "fadeColor", "0, 0, 0, 1" );
    player->playerView.Fade( fadeColor, fadeTime );
  }

  if ( !gameLocal.isClient )
    PostEventMS( &EV_ActivateTargets, fadeTime, activator );
}
Esempio n. 12
0
/*
================
idMoveablePDAItem::Event_GivePDA
================
*/
void idMoveablePDAItem::Event_GivePDA(idPlayer *player)
{
  if ( gameLocal.isServer )
  {
    idBitMsg	msg;
		byte		msgBuf[ MAX_GAME_MESSAGE_SIZE ];

		msg.Init( msgBuf, sizeof( msgBuf ) );
		msg.WriteBits( gameLocal.GetSpawnId( player ), 32 );
    ServerSendEvent( EVENT_GIVEPDA, &msg, false, -1 );

    // Nicemice: DEBUG
    //gameLocal.DPrintf(" Server: ");
  }

  // Nicemice: DEBUG
  //gameLocal.DPrintf("idMoveablePDAItem::Event_GivePDA\n");

	const char *str = spawnArgs.GetString( "pda_name" );
	if ( player ) {
		player->GivePDA( str, &spawnArgs );
	}
}
Esempio n. 13
0
/*
================
idObjective::Event_HideObjective
================
*/
void idObjective::Event_HideObjective(idEntity *e) {
  // Nicemice: added
  if ( gameLocal.isServer )
  {
    ServerSendEvent( EVENT_HIDEOBJECTIVE, NULL, false, -1);
  }

	idPlayer *player = gameLocal.GetLocalPlayer();

  if ( !gameLocal.isMultiplayer ) {
    
    if ( !player ) {
		  PostEventMS( &EV_Remove, 0 );
      return;
    }
    
		idVec3 v = player->GetPhysics()->GetOrigin() - playerPos;
		if ( v.Length() > 64.0f ) {
			player->HideObjective();
			PostEventMS( &EV_Remove, 0 );
		} else {
			PostEventMS( &EV_HideObjective, 100, player );
		}
  } else {
    // Nicemice: here we differ between multiplayer and singleplayer.
    // In singleplayer the objective will be hidden when the player
    // moves 64 units away from its origin.
    // Since we don't want to calculate the distance to each player
    // we just hide the objective after a timelimit
    if ( player ) {
      player->HideObjective();
    }

		PostEventMS( &EV_Remove, 100 );
	}
}
Esempio n. 14
0
/*
================
idExplodingBarrel::Killed
================
*/
void idExplodingBarrel::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) {

	if ( IsHidden() || state == EXPLODING || state == BURNING ) {
		return;
	}

	float f = spawnArgs.GetFloat( "burn" );
	if ( f > 0.0f && state == NORMAL ) {
		state = BURNING;
		PostEventSec( &EV_Explode, f );
		StartSound( "snd_burn", SND_CHANNEL_ANY, 0, false, NULL );
		AddParticles( spawnArgs.GetString ( "model_burn", "" ), true );
		return;
	} else {
		state = EXPLODING;
		if ( gameLocal.isServer ) {
			idBitMsg	msg;
			byte		msgBuf[MAX_EVENT_PARAM_SIZE];

			msg.Init( msgBuf, sizeof( msgBuf ) );
			msg.WriteLong( gameLocal.time );
			ServerSendEvent( EVENT_EXPLODE, &msg, false, -1 );
		}
	}

	// do this before applying radius damage so the ent can trace to any damagable ents nearby
	Hide();
	physicsObj.SetContents( 0 );

	const char *splash = spawnArgs.GetString( "def_splash_damage", "damage_explosion" );
	if ( splash && *splash ) {
		gameLocal.RadiusDamage( GetPhysics()->GetOrigin(), this, attacker, this, this, splash );
	}

	ExplodingEffects( );

	//FIXME: need to precache all the debris stuff here and in the projectiles
	const idKeyValue *kv = spawnArgs.MatchPrefix( "def_debris" );
	// bool first = true;
	while ( kv ) {
		const idDict *debris_args = gameLocal.FindEntityDefDict( kv->GetValue(), false );
		if ( debris_args ) {
			idEntity *ent;
			idVec3 dir;
			idDebris *debris;
			//if ( first ) {
				dir = physicsObj.GetAxis()[1];
			//	first = false;
			//} else {
				dir.x += gameLocal.random.CRandomFloat() * 4.0f;
				dir.y += gameLocal.random.CRandomFloat() * 4.0f;
				//dir.z = gameLocal.random.RandomFloat() * 8.0f;
			//}
			dir.Normalize();

			gameLocal.SpawnEntityDef( *debris_args, &ent, false );
			if ( !ent || !ent->IsType( idDebris::Type ) ) {
				gameLocal.Error( "'projectile_debris' is not an idDebris" );
			}

			debris = static_cast<idDebris *>(ent);
			debris->Create( this, physicsObj.GetOrigin(), dir.ToMat3() );
			debris->Launch();
			debris->GetRenderEntity()->shaderParms[ SHADERPARM_TIME_OF_DEATH ] = ( gameLocal.time + 1500 ) * 0.001f;
			debris->UpdateVisuals();

		}
		kv = spawnArgs.MatchPrefix( "def_debris", kv );
	}

	physicsObj.PutToRest();
	CancelEvents( &EV_Explode );
	CancelEvents( &EV_Activate );

	f = spawnArgs.GetFloat( "respawn" );
	if ( f > 0.0f ) {
		PostEventSec( &EV_Respawn, f );
	} else {
		PostEventMS( &EV_Remove, 5000 );
	}

	if ( spawnArgs.GetBool( "triggerTargets" ) ) {
		ActivateTargets( this );
	}
}
Esempio n. 15
0
/*
================
idBrittleFracture::ProjectDecal
================
*/
void idBrittleFracture::ProjectDecal( const idVec3 &point, const idVec3 &dir, const int time, const char *damageDefName ) {
	int i, j, bits, clipBits;
	float a, c, s;
	idVec2 st[MAX_POINTS_ON_WINDING];
	idVec3 origin;
	idMat3 axis, axistemp;
	idPlane textureAxis[2];

	if ( gameLocal.isServer ) {
		idBitMsg	msg;
		byte		msgBuf[MAX_EVENT_PARAM_SIZE];

		msg.Init( msgBuf, sizeof( msgBuf ) );
		msg.BeginWriting();
		msg.WriteFloat( point[0] );
		msg.WriteFloat( point[1] );
		msg.WriteFloat( point[2] );
		msg.WriteFloat( dir[0] );
		msg.WriteFloat( dir[1] );
		msg.WriteFloat( dir[2] );
		ServerSendEvent( EVENT_PROJECT_DECAL, &msg, true, -1 );
	}

	if ( time >= gameLocal.time ) {
		// try to get the sound from the damage def
		const idDeclEntityDef *damageDef = NULL;
		const idSoundShader *sndShader = NULL;
		if ( damageDefName ) {
			damageDef = gameLocal.FindEntityDef( damageDefName, false );
			if ( damageDef ) {
				sndShader = declManager->FindSound( damageDef->dict.GetString( "snd_shatter", "" ) );
			}
		}

		if ( sndShader ) {
			StartSoundShader( sndShader, SND_CHANNEL_ANY, 0, false, NULL );
		} else {
			StartSound( "snd_bullethole", SND_CHANNEL_ANY, 0, false, NULL );
		}
	}

	a = gameLocal.random.RandomFloat() * idMath::TWO_PI;
	c = cos( a );
	s = -sin( a );

	axis[2] = -dir;
	axis[2].Normalize();
	axis[2].NormalVectors( axistemp[0], axistemp[1] );
	axis[0] = axistemp[ 0 ] * c + axistemp[ 1 ] * s;
	axis[1] = axistemp[ 0 ] * s + axistemp[ 1 ] * -c;

	textureAxis[0] = axis[0] * ( 1.0f / decalSize );
	textureAxis[0][3] = -( point * textureAxis[0].Normal() ) + 0.5f;

	textureAxis[1] = axis[1] * ( 1.0f / decalSize );
	textureAxis[1][3] = -( point * textureAxis[1].Normal() ) + 0.5f;

	for ( i = 0; i < shards.Num(); i++ ) {
		idFixedWinding &winding = shards[i]->winding;
		origin = shards[i]->clipModel->GetOrigin();
		axis = shards[i]->clipModel->GetAxis();
		float d0, d1;

		clipBits = -1;
		for ( j = 0; j < winding.GetNumPoints(); j++ ) {
			idVec3 p = origin + winding[j].ToVec3() * axis;

			st[j].x = d0 = textureAxis[0].Distance( p );
			st[j].y = d1 = textureAxis[1].Distance( p );

			bits = FLOATSIGNBITSET( d0 );
			d0 = 1.0f - d0;
			bits |= FLOATSIGNBITSET( d1 ) << 2;
			d1 = 1.0f - d1;
			bits |= FLOATSIGNBITSET( d0 ) << 1;
			bits |= FLOATSIGNBITSET( d1 ) << 3;

			clipBits &= bits;
		}

		if ( clipBits ) {
			continue;
		}

		idFixedWinding *decal = new idFixedWinding;
		shards[i]->decals.Append( decal );

		decal->SetNumPoints( winding.GetNumPoints() );
		for ( j = 0; j < winding.GetNumPoints(); j++ ) {
			(*decal)[j].ToVec3() = winding[j].ToVec3();
			(*decal)[j].s = st[j].x;
			(*decal)[j].t = st[j].y;
		}
	}

	BecomeActive( TH_UPDATEVISUALS );
}
Esempio n. 16
0
/*
================
idBrittleFracture::Shatter
================
*/
void idBrittleFracture::Shatter( const idVec3& point, const idVec3& impulse, const int time )
{
	int i;
	idVec3 dir;
	shard_t* shard;
	float m;
	
	if( common->IsServer() )
	{
		idBitMsg	msg;
		byte		msgBuf[MAX_EVENT_PARAM_SIZE];
		
		msg.InitWrite( msgBuf, sizeof( msgBuf ) );
		msg.BeginWriting();
		msg.WriteFloat( point[0] );
		msg.WriteFloat( point[1] );
		msg.WriteFloat( point[2] );
		msg.WriteFloat( impulse[0] );
		msg.WriteFloat( impulse[1] );
		msg.WriteFloat( impulse[2] );
		ServerSendEvent( EVENT_SHATTER, &msg, true );
	}
	
	// Store off the event so we can rebuilt the object if we reload a savegame
	fractureEvent_s fractureEvent;
	fractureEvent.eventType = EVENT_SHATTER;
	fractureEvent.point = point;
	fractureEvent.vector = impulse;
	storedEvents.Append( fractureEvent );
	
	if( time > ( gameLocal.time - SHARD_ALIVE_TIME ) )
	{
		StartSound( "snd_shatter", SND_CHANNEL_ANY, 0, false, NULL );
	}
	
	if( !IsBroken() )
	{
		Break();
	}
	
	if( fxFracture.Length() )
	{
		idEntityFx::StartFx( fxFracture, &point, &GetPhysics()->GetAxis(), this, true );
	}
	
	dir = impulse;
	m = dir.Normalize();
	
	for( i = 0; i < shards.Num(); i++ )
	{
		shard = shards[i];
		
		if( shard->droppedTime != -1 )
		{
			continue;
		}
		
		if( ( shard->clipModel->GetOrigin() - point ).LengthSqr() > Square( maxShatterRadius ) )
		{
			continue;
		}
		
		DropShard( shard, point, dir, m, time );
	}
	
	DropFloatingIslands( point, impulse, time );
}
Esempio n. 17
0
/*
================
idExplodingBarrel::Killed
================
*/
void idExplodingBarrel::Killed( idEntity *inflictor, idEntity *attacker, int damage, const idVec3 &dir, int location ) {

	// This simple condition causes a barrel to explode when shot while burning
#ifdef _DENTONMOD
	if ( IsHidden() || state == EXPLODING ) {
#else
	if ( IsHidden() || state == EXPLODING || state == BURNING ) {
#endif
		return;
	}

	float f = spawnArgs.GetFloat( "burn" );

#ifdef _DENTONMOD
	int explodeHealth = spawnArgs.GetInt( "explode_health" );

	if ( f > 0.0f && state == NORMAL && health > explodeHealth ) {
#else
	if ( f > 0.0f && state == NORMAL ) {
#endif
		state = BURNING;
		PostEventSec( &EV_Explode, f );
		StartSound( "snd_burn", SND_CHANNEL_ANY, 0, false, NULL );
		AddParticles( spawnArgs.GetString ( "model_burn", "" ), true );
		return;
	} else {
		
#ifdef _DENTONMOD	
		if( state == BURNING && health > explodeHealth ) { 
			return;
		}
#endif

		state = EXPLODING;
		if ( gameLocal.isServer ) {
			idBitMsg	msg;
			byte		msgBuf[MAX_EVENT_PARAM_SIZE];

			msg.Init( msgBuf, sizeof( msgBuf ) );
			msg.WriteLong( gameLocal.time );
			ServerSendEvent( EVENT_EXPLODE, &msg, false, -1 );
		}
	}

	// do this before applying radius damage so the ent can trace to any damagable ents nearby
	Hide();
#ifdef _DENTONMOD
	BecomeInactive(TH_PHYSICS); // This causes the physics not to update after explosion
#else					
	physicsObj.SetContents( 0 ); // Set physics content 0 after spawining debris.
#endif
	
	const char *splash = spawnArgs.GetString( "def_splash_damage", "damage_explosion" );
	if ( splash && *splash ) {
		gameLocal.RadiusDamage( GetPhysics()->GetOrigin(), this, attacker, this, this, splash );
	}

	ExplodingEffects( );

	//FIXME: need to precache all the debris stuff here and in the projectiles
	const idKeyValue *kv = spawnArgs.MatchPrefix( "def_debris" );
	// bool first = true;
	while ( kv ) {
		const idDict *debris_args = gameLocal.FindEntityDefDict( kv->GetValue(), false );
		if ( debris_args ) {
			idEntity *ent;
			idVec3 dir;
			idDebris *debris;
			//if ( first ) {
				dir = physicsObj.GetAxis()[1];
			//	first = false;
			//} else {
				dir.x += gameLocal.random.CRandomFloat() * 4.0f;
				dir.y += gameLocal.random.CRandomFloat() * 4.0f;
				//dir.z = gameLocal.random.RandomFloat() * 8.0f;
			//}
			dir.Normalize();

			gameLocal.SpawnEntityDef( *debris_args, &ent, false );
			if ( !ent || !ent->IsType( idDebris::Type ) ) {
				gameLocal.Error( "'projectile_debris' is not an idDebris" );
			}

			debris = static_cast<idDebris *>(ent);
			debris->Create( this, physicsObj.GetOrigin(), dir.ToMat3() );
			debris->Launch();
			debris->GetRenderEntity()->shaderParms[ SHADERPARM_TIME_OF_DEATH ] = ( gameLocal.time + 1500 ) * 0.001f;
			debris->UpdateVisuals();

		}
		kv = spawnArgs.MatchPrefix( "def_debris", kv );
	}
	
	SpawnDrops(); //ivan

#ifdef _DENTONMOD
	physicsObj.SetContents( 0 );
#endif

	physicsObj.PutToRest();

	CancelEvents( &EV_Explode );
	CancelEvents( &EV_Activate );

	f = spawnArgs.GetFloat( "respawn" );
	if ( f > 0.0f ) {
		PostEventSec( &EV_Respawn, f );
	} else {
		PostEventMS( &EV_Remove, 5000 );
	}

	if ( spawnArgs.GetBool( "triggerTargets" ) ) {
		ActivateTargets( this );
	}

	//ivan start - add score only if player is the killer
	if ( attacker && attacker->IsType( idPlayer::Type ) ) {
		static_cast< idPlayer* >( attacker )->AddScore( spawnArgs.GetInt( "score", "100" ) ); 
	}
	//ivan end
}

/*
================
idExplodingBarrel::Damage
================
*/
void idExplodingBarrel::Damage( idEntity *inflictor, idEntity *attacker, const idVec3 &dir,
					  const char *damageDefName, const float damageScale, const int location ) {

	const idDict *damageDef = gameLocal.FindEntityDefDict( damageDefName );
	if ( !damageDef ) {
		gameLocal.Error( "Unknown damageDef '%s'\n", damageDefName );
	}
#ifdef _DENTONMOD		// Following condition means, if inflictor's got a radius damage then explode immediately, 
						// which could cause explosions when barrel's health is greater than 0 so I am disabling it.
#else
	if ( damageDef->FindKey( "radius" ) && GetPhysics()->GetContents() != 0 && GetBindMaster() == NULL ) {
		PostEventMS( &EV_Explode, 400 );
	} else {
#endif
		idEntity::Damage( inflictor, attacker, dir, damageDefName, damageScale, location );
#ifdef _DENTONMOD	
#else
	}
#endif
}

/*
================
idExplodingBarrel::Event_TriggerTargets
================
*/
void idExplodingBarrel::Event_TriggerTargets() {
	ActivateTargets( this );
}

/*
================
idExplodingBarrel::Event_Explode
================
*/
void idExplodingBarrel::Event_Explode() {
	if ( state == NORMAL || state == BURNING ) {
		state = BURNEXPIRED;
		Killed( NULL, NULL, 0, vec3_zero, 0 );
	}
}

/*
================
idExplodingBarrel::Event_Respawn
================
*/
void idExplodingBarrel::Event_Respawn() {
	int i;
	int minRespawnDist = spawnArgs.GetInt( "respawn_range", "256" );
	if ( minRespawnDist ) {
		float minDist = -1;
		for ( i = 0; i < gameLocal.numClients; i++ ) {
			if ( !gameLocal.entities[ i ] || !gameLocal.entities[ i ]->IsType( idPlayer::Type ) ) {
				continue;
			}
			idVec3 v = gameLocal.entities[ i ]->GetPhysics()->GetOrigin() - GetPhysics()->GetOrigin();
			float dist = v.Length();
			if ( minDist < 0 || dist < minDist ) {
				minDist = dist;
			}
		}
		if ( minDist < minRespawnDist ) {
			PostEventSec( &EV_Respawn, spawnArgs.GetInt( "respawn_again", "10" ) );
			return;
		}
	}
	const char *temp = spawnArgs.GetString( "model" );
	if ( temp && *temp ) {
		SetModel( temp );
	}
	health = spawnArgs.GetInt( "health", "5" );
	fl.takedamage = true;
	physicsObj.SetOrigin( spawnOrigin );
	physicsObj.SetAxis( spawnAxis );
	physicsObj.SetContents( CONTENTS_SOLID );
	physicsObj.DropToFloor();
	state = NORMAL;
	Show();
	UpdateVisuals();
}