Esempio n. 1
0
/*
================
idBrittleFracture::Think
================
*/
void idBrittleFracture::Think( void ) {
	int i, startTime, endTime, droppedTime;
	shard_t *shard;
	bool atRest = true, fading = false;

	// remove overdue shards
	for ( i = 0; i < shards.Num(); i++ ) {
		droppedTime = shards[i]->droppedTime;
		if ( droppedTime != -1 ) {
			if ( gameLocal.time - droppedTime > SHARD_ALIVE_TIME ) {
				RemoveShard( i );
				i--;
			}
			fading = true;
		}
	}

	// remove the entity when nothing is visible
	if ( !shards.Num() ) {
		PostEventMS( &EV_Remove, 0 );
		return;
	}

	if ( thinkFlags & TH_PHYSICS ) {

		startTime = gameLocal.previousTime;
		endTime = gameLocal.time;

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

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

			shard->physicsObj.Evaluate( endTime - startTime, endTime );

			if ( !shard->physicsObj.IsAtRest() ) {
				atRest = false;
			}
		}

		if ( atRest ) {
			BecomeInactive( TH_PHYSICS );
		} else {
			BecomeActive( TH_PHYSICS );
		}
	}

	if ( !atRest || bounds.IsCleared() ) {
		bounds.Clear();
		for ( i = 0; i < shards.Num(); i++ ) {
			bounds.AddBounds( shards[i]->clipModel->GetAbsBounds() );
		}
	}

	if ( fading ) {
		BecomeActive( TH_UPDATEVISUALS | TH_THINK );
	} else {
		BecomeInactive( TH_THINK );
	}

	RunPhysics();
	Present();
}
Esempio n. 2
0
/*
================
idTrigger_Touch::Disable
================
*/
void idTrigger_Touch::Disable() {
	BecomeInactive( TH_THINK );
}
Esempio n. 3
0
/*
================
idSecurityCamera::Think
================
*/
void idSecurityCamera::Think( void ) {
	float pct;
	float travel;

	if ( thinkFlags & TH_THINK ) {
		if ( g_showEntityInfo.GetBool() ) {
			DrawFov();
		}

		if (health <= 0) {
			BecomeInactive( TH_THINK );
			return;
		}
	}

	// run physics
	RunPhysics();

	if ( thinkFlags & TH_THINK ) {
		if (CanSeePlayer()) {
			if (alertMode == SCANNING) {
				float	sightTime;

				SetAlertMode(ALERT);
				stopSweeping = gameLocal.time;
				if (sweeping) {
					CancelEvents( &EV_SecurityCam_Pause );
				} else {
					CancelEvents( &EV_SecurityCam_ReverseSweep );
				}
				sweeping = false;
				StopSound( SND_CHANNEL_ANY, false );
				StartSound( "snd_sight", SND_CHANNEL_BODY, 0, false, NULL );

				sightTime = spawnArgs.GetFloat( "sightTime", "5" );
				PostEventSec(&EV_SecurityCam_Alert, sightTime);
			}
		} else {
			if (alertMode == ALERT) {
				float	sightResume;

				SetAlertMode(LOSINGINTEREST);
				CancelEvents( &EV_SecurityCam_Alert );
				
				sightResume = spawnArgs.GetFloat( "sightResume", "1.5" );
				PostEventSec( &EV_SecurityCam_ContinueSweep, sightResume );
			}

			if ( sweeping ) {
				idAngles a = GetPhysics()->GetAxis().ToAngles();

				pct = ( gameLocal.time - sweepStart ) / ( sweepEnd - sweepStart );
				travel = pct * sweepAngle;
				if ( negativeSweep ) {
					a.yaw = angle + travel;
				} else {
					a.yaw = angle - travel;
				}

				SetAngles( a );
			}
		}
	}
	Present();
}
Esempio n. 4
0
/*
================
hhSpring::UnLinkSpring
	HUMANHEAD
================
*/
void hhSpring::UnLinkSpring() {
	BecomeInactive(TH_THINK);
}
Esempio n. 5
0
/*
================
idExplodingBarrel::Think
================
*/
void idExplodingBarrel::Think( void ) {
	idBarrel::BarrelThink();

	#ifdef _DENTONMOD
		if ( thinkFlags & TH_UPDATEWOUNDPARTICLES )
			UpdateParticles();
	#endif

	if ( lightDefHandle >= 0 ){
		if ( state == BURNING ) {
			// ramp the color up over 250 ms
			float pct = (gameLocal.time - lightTime) / 250.f;
			if ( pct > 1.0f ) {
				pct = 1.0f;
			}
			light.origin = physicsObj.GetAbsBounds().GetCenter();
			light.axis = mat3_identity;
			light.shaderParms[ SHADERPARM_RED ] = pct;
			light.shaderParms[ SHADERPARM_GREEN ] = pct;
			light.shaderParms[ SHADERPARM_BLUE ] = pct;
			light.shaderParms[ SHADERPARM_ALPHA ] = pct;
			gameRenderWorld->UpdateLightDef( lightDefHandle, &light );
		} else {
			if ( gameLocal.time - lightTime > 250 ) {
				gameRenderWorld->FreeLightDef( lightDefHandle );
				lightDefHandle = -1;
			}
			return;
		}
	}

	if ( !gameLocal.isClient && state != BURNING && state != EXPLODING ) {
		BecomeInactive( TH_THINK );
		return;
	}

	// This condition fixes the problem where particleRenderEntity is used for explosion effect 
	// and it still tries to track the physics origin even after physics is put to rest.
#ifdef _DENTONMOD 
	if ( particleModelDefHandle >= 0 && state == BURNING ){
#else
	if ( particleModelDefHandle >= 0 ){
#endif
		particleRenderEntity.origin = physicsObj.GetAbsBounds().GetCenter();
		particleRenderEntity.axis = mat3_identity;
		gameRenderWorld->UpdateEntityDef( particleModelDefHandle, &particleRenderEntity );

	}
}

/*
================
idExplodingBarrel::AddParticles
================
*/
void idExplodingBarrel::AddParticles( const char *name, bool burn ) {
	if ( name && *name ) {
		if ( particleModelDefHandle >= 0 ){
			gameRenderWorld->FreeEntityDef( particleModelDefHandle );
		}
		memset( &particleRenderEntity, 0, sizeof ( particleRenderEntity ) );
		const idDeclModelDef *modelDef = static_cast<const idDeclModelDef *>( declManager->FindType( DECL_MODELDEF, name ) );
		if ( modelDef ) {
			particleRenderEntity.origin = physicsObj.GetAbsBounds().GetCenter();
			particleRenderEntity.axis = mat3_identity;
			particleRenderEntity.hModel = modelDef->ModelHandle();
			float rgb = ( burn ) ? 0.0f : 1.0f;
			particleRenderEntity.shaderParms[ SHADERPARM_RED ] = rgb;
			particleRenderEntity.shaderParms[ SHADERPARM_GREEN ] = rgb;
			particleRenderEntity.shaderParms[ SHADERPARM_BLUE ] = rgb;
			particleRenderEntity.shaderParms[ SHADERPARM_ALPHA ] = rgb;
			particleRenderEntity.shaderParms[ SHADERPARM_TIMEOFFSET ] = -MS2SEC( gameLocal.realClientTime );
			particleRenderEntity.shaderParms[ SHADERPARM_DIVERSITY ] = ( burn ) ? 1.0f : gameLocal.random.RandomInt( 90 );
			if ( !particleRenderEntity.hModel ) {
				particleRenderEntity.hModel = renderModelManager->FindModel( name );
			}
			particleModelDefHandle = gameRenderWorld->AddEntityDef( &particleRenderEntity );
			if ( burn ) {
				BecomeActive( TH_THINK );
			}
			particleTime = gameLocal.realClientTime;
		}
	}
}

/*
================
idExplodingBarrel::AddLight
================
*/
void idExplodingBarrel::AddLight( const char *name, bool burn ) {
	if ( lightDefHandle >= 0 ){
		gameRenderWorld->FreeLightDef( lightDefHandle );
	}
	memset( &light, 0, sizeof ( light ) );
	light.axis = mat3_identity;
	light.lightRadius.x = spawnArgs.GetFloat( "light_radius" );
	light.lightRadius.y = light.lightRadius.z = light.lightRadius.x;
	light.origin = physicsObj.GetOrigin();
	light.origin.z += 128;
	light.pointLight = true;
	light.shader = declManager->FindMaterial( name );
	light.shaderParms[ SHADERPARM_RED ] = 2.0f;
	light.shaderParms[ SHADERPARM_GREEN ] = 2.0f;
	light.shaderParms[ SHADERPARM_BLUE ] = 2.0f;
	light.shaderParms[ SHADERPARM_ALPHA ] = 2.0f;
	lightDefHandle = gameRenderWorld->AddLightDef( &light );
	lightTime = gameLocal.realClientTime;
	BecomeActive( TH_THINK );
}

/*
================
idExplodingBarrel::ExplodingEffects
================
*/
void idExplodingBarrel::ExplodingEffects( void ) {
	const char *temp;

	StartSound( "snd_explode", SND_CHANNEL_ANY, 0, false, NULL );

	temp = spawnArgs.GetString( "model_damage" );
	if ( *temp != '\0' ) {
		SetModel( temp );
		Show();
	}

	temp = spawnArgs.GetString( "mtr_lightexplode" );
	if ( *temp != '\0' ) {
		AddLight( temp, false );
	}

	temp = spawnArgs.GetString( "mtr_burnmark" );
	if ( *temp != '\0' ) {
		gameLocal.ProjectDecal( GetPhysics()->GetOrigin(), GetPhysics()->GetGravity(), 128.0f, true, 96.0f, temp );
	}
	// put the explosion particle effect to the end -- By Clone JCD
	temp = spawnArgs.GetString( "model_detonate" );
	if ( *temp != '\0' ) {
		AddParticles( temp, false );
	}
}

//ivan start
/*
================
idExplodingBarrel::SpawnDrops
================
*/
void idExplodingBarrel::SpawnDrops( void ){
	idVec3 offset;
	idStr offsetKey;
	const idKeyValue *kv = spawnArgs.MatchPrefix( "def_dropItem", NULL );
	while( kv ) {

		//get the offset
		offsetKey = kv->GetKey().c_str() + 4;
		offsetKey += "Offset";
		offset = spawnArgs.GetVector( offsetKey.c_str(), "0 0 0" );

		idMoveableItem::DropItem( kv->GetValue().c_str(), physicsObj.GetAbsBounds().GetCenter() + offset,physicsObj.GetAxis(), vec3_origin, 0, 0, false ); //don't drop to floor so offset is respected
		kv = spawnArgs.MatchPrefix( "def_dropItem", kv );
	}
}
Esempio n. 6
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();
}