예제 #1
0
/**
 * Create special startup message for some devices
 */
void XCSoarInterface::StartupInfo() {
  // TODO speed: TB: this slows down the bootup process because of sleep()
#ifdef CREDITS_FIVV
  CreateProgressDialog(gettext(TEXT("Special ITA version")));
  Sleep(1000);
#endif
#ifdef PNA // VENTA-ADDON
  TCHAR sTmp[MAX_PATH];
  _stprintf(sTmp, TEXT("PNA MODEL=%s (%d)"), GlobalModelName, GlobalModelType);
  CreateProgressDialog(sTmp); Sleep(3000);
#endif // non PNA

  if (is_simulator()) {
    CreateProgressDialog(TEXT("SIMULATION"));
    Sleep(2000);
  }

#ifdef PNA
  if ( SetBacklight() == true )
    CreateProgressDialog(TEXT("AUTOMATIC BACKLIGHT CONTROL"));
  else
    CreateProgressDialog(TEXT("NO BACKLIGHT CONTROL"));
  Sleep(3000);

  // this should work ok for all pdas as well
  if ( SetSoundVolume() == true )
    CreateProgressDialog(TEXT("AUTOMATIC SOUND LEVEL CONTROL"));
  else
    CreateProgressDialog(TEXT("NO SOUND LEVEL CONTROL"));
  Sleep(3000);
#endif
}
예제 #2
0
파일: Moveable.cpp 프로젝트: c4tnt/DLR
/*
=================
idMoveable::Collide
=================
*/
impactEffect_t idMoveable::Collide( const trace_t &collision, const idVec3 &velocity ) {
	float v, f;
	idVec3 dir;
	idEntity *ent;

	v = -( velocity * collision.c.normal );
	if ( v > BOUNCE_SOUND_MIN_VELOCITY && gameLocal.time > nextSoundTime ) {
		f = v > BOUNCE_SOUND_MAX_VELOCITY ? 1.0f : idMath::Sqrt( v - BOUNCE_SOUND_MIN_VELOCITY ) * ( 1.0f / idMath::Sqrt( BOUNCE_SOUND_MAX_VELOCITY - BOUNCE_SOUND_MIN_VELOCITY ) );
		if ( StartSound( "snd_bounce", SND_CHANNEL_ANY, 0, false, NULL ) ) {
			// don't set the volume unless there is a bounce sound as it overrides the entire channel
			// which causes footsteps on ai's to not honor their shader parms
			SetSoundVolume( f );
		}
		nextSoundTime = gameLocal.time + 500;
	}

	if ( !gameLocal.isClient && canDamage && gameLocal.time > nextDamageTime ) {
		bool hasDamage = damage.Length() > 0;
		bool hasMonsterDamage = monsterDamage.Length() > 0;

		if ( hasDamage || hasMonsterDamage ) {
			ent = gameLocal.entities[ collision.c.entityNum ];
			if ( ent && v > minDamageVelocity ) {
				f = v > maxDamageVelocity ? 1.0f : idMath::Sqrt( (v - minDamageVelocity) / (maxDamageVelocity - minDamageVelocity) );
				dir = velocity;
				dir.Normalize(); //c4tnt: more precision
				if ( ent->IsType( idAI::Type ) && hasMonsterDamage ) {

					if ( attacker ) {
						ent->Damage( this, attacker, dir, monsterDamage, f, INVALID_JOINT );
					}
					else {

						ent->Damage( this, GetPhysics()->GetClipModel()->GetOwner(), dir, monsterDamage, f, INVALID_JOINT );
					}
				} else if ( hasDamage ) {
					// in multiplayer, scale damage wrt mass of object
					if ( gameLocal.isMultiplayer ) {
						f *= GetPhysics()->GetMass() * g_moveableDamageScale.GetFloat();
					}

					if ( attacker ) {
						ent->Damage( this, attacker, dir, damage, f, INVALID_JOINT );
					}
					else {
						ent->Damage( this, GetPhysics()->GetClipModel()->GetOwner(), dir, damage, f, INVALID_JOINT );
					}
				}
				nextDamageTime = gameLocal.time + 1000;
			}
		}
	}

	if ( fxCollide.Length() && gameLocal.time > nextCollideFxTime ) {
		idEntityFx::StartFx( fxCollide, &collision.c.point, NULL, this, false );
		nextCollideFxTime = gameLocal.time + 3500;
	}

	return IMP_BOUNCE;
}
예제 #3
0
/*
=================
idMoveable::Collide
=================
*/
bool idMoveable::Collide( const trace_t &collision, const idVec3 &velocity ) {
	float v, f;
	idVec3 dir;
	idEntity *ent;

	v = -( velocity * collision.c.normal );
	if ( v > BOUNCE_SOUND_MIN_VELOCITY && gameLocal.time > nextSoundTime ) {
		f = v > BOUNCE_SOUND_MAX_VELOCITY ? 1.0f : idMath::Sqrt( v - BOUNCE_SOUND_MIN_VELOCITY ) * ( 1.0f / idMath::Sqrt( BOUNCE_SOUND_MAX_VELOCITY - BOUNCE_SOUND_MIN_VELOCITY ) );
		if ( StartSound( "snd_bounce", SND_CHANNEL_ANY, 0, false, NULL ) ) {
			// don't set the volume unless there is a bounce sound as it overrides the entire channel
			// which causes footsteps on ai's to not honor their shader parms
			SetSoundVolume( f );
		}
		nextSoundTime = gameLocal.time + 500;
	}

	if ( canDamage && damage.Length() && gameLocal.time > nextDamageTime ) {
		ent = gameLocal.entities[ collision.c.entityNum ];
		if ( ent && v > minDamageVelocity ) {
			f = v > maxDamageVelocity ? 1.0f : idMath::Sqrt( v - minDamageVelocity ) * ( 1.0f / idMath::Sqrt( maxDamageVelocity - minDamageVelocity ) );
			dir = velocity;
			dir.NormalizeFast();
			ent->Damage( this, GetPhysics()->GetClipModel()->GetOwner(), dir, damage, f, INVALID_JOINT );
			nextDamageTime = gameLocal.time + 1000;
		}
	}

	if ( fxCollide.Length() && gameLocal.time > nextCollideFxTime ) {
		idEntityFx::StartFx( fxCollide, &collision.c.point, NULL, this, false );
		nextCollideFxTime = gameLocal.time + 3500;
	}

	return false;
}
예제 #4
0
bool cAudio :: Init( void )
{
	if( bInitialised || ( !bMusic && !bSounds ) )
	{
		return 0;
	}

	if( bDebug )
	{
		printf( "Initialising Audio System ,Buffer (%i), Frequenzy (%i)\n", iBuffer, iHz );
	}

	/*	Initialising prefered Audio System specs with Mixer Standard format (Stereo)
	*
	*	format		: Output sample format.
	*	channels	: Number of sound channels in output.
	*	Set this to 2 for stereo, 1 for mono.
	*	chunksize	: Bytes used per output sample.
	*/

	if( Mix_OpenAudio( iHz, MIX_DEFAULT_FORMAT , iChannels, iBuffer ) < 0 ) 
	{
		printf( "Warning : Could not init 16-bit Audio\n- Reason : %s\n", SDL_GetError() );
		return 0;
	}

	bInitialised = 1;
	SetMusicVolume( Music_Volume );
	SetSoundVolume( Sound_Volume );

	return 1;
}
/*
=================
idMoveableItem::Collide
=================
*/
bool idMoveableItem::Collide( const trace_t &collision, const idVec3 &velocity ) {
	float v, f;

	v = -( velocity * collision.c.normal );
	if ( v > 80 && gameLocal.time > nextSoundTime ) {
		f = v > 200 ? 1.0f : idMath::Sqrt( v - 80 ) * 0.091f;
		if ( StartSound( "snd_bounce", SND_CHANNEL_ANY, 0, false, NULL ) ) {
			// don't set the volume unless there is a bounce sound as it overrides the entire channel
			// which causes footsteps on ai's to not honor their shader parms
			SetSoundVolume( f );
		}
		nextSoundTime = gameLocal.time + 500;
	}

	return false;
}
예제 #6
0
/*
=================
idMoveable::Collide
=================
*/
bool idMoveable::Collide( const trace_t &collision, const idVec3 &velocity ) {
	float len, f;
	idVec3 dir;
	idEntity *ent;

	dir = velocity;
	len = dir.NormalizeFast();

	if ( len > BOUNCE_SOUND_MIN_VELOCITY ) {
		if ( gameLocal.time > nextCollideFxTime ) {
			PlayEffect ( gameLocal.GetEffect(spawnArgs,"fx_collide",collision.c.materialType), collision.c.point, collision.c.normal.ToMat3() );
// RAVEN BEGIN
// jscott: fixed negative sqrt call
			if( len > BOUNCE_SOUND_MAX_VELOCITY ) {
				f = 1.0f;
			} else if( len <= BOUNCE_SOUND_MIN_VELOCITY ) {
				f = 0.0f;
			} else {
				f = ( len - BOUNCE_SOUND_MIN_VELOCITY ) * ( 1.0f / ( BOUNCE_SOUND_MAX_VELOCITY - BOUNCE_SOUND_MIN_VELOCITY ) );
			}
// RAVEN END
			SetSoundVolume( f );
			StartSound( "snd_bounce", SND_CHANNEL_BODY, 0, false, NULL );

			nextCollideFxTime = gameLocal.time + BOUNCE_SOUND_DELAY_MIN + gameLocal.random.RandomInt(BOUNCE_SOUND_DELAY_MAX - BOUNCE_SOUND_DELAY_MIN);
		}
	}

	if ( canDamage && damage.Length() ) {
		ent = gameLocal.entities[ collision.c.entityNum ];
		if ( ent && len > minDamageVelocity ) {
// RAVEN BEGIN
// jscott: fixed negative sqrt call
			if( len > maxDamageVelocity ) {
				f = 1.0f;
			} else if( len <= minDamageVelocity ) {
				f = 0.0f;
			} else {
				f = idMath::Sqrt( len - minDamageVelocity ) * ( 1.0f / idMath::Sqrt( maxDamageVelocity - minDamageVelocity ) );
			}
// RAVEN END
			ent->Damage( this, GetPhysics()->GetClipModel()->GetOwner(), dir, damage, f, INVALID_JOINT );
		}
	}

	return false;
}
예제 #7
0
int CSound::Initialise(int rate,int channels,int svol,int mvol)
{
	if((channels > 16) || (channels < 0))
	{
		return 1;
	}
	FSOUND_SetOutput(FSOUND_OUTPUT_DSOUND);
	FSOUND_Init(rate,channels,FSOUND_INIT_USEDEFAULTMIDISYNTH);

	songname = "Empty";


	SetSoundVolume(svol);
	SetMusicVolume(mvol);

	CurrentSong = NULL;
	CurrentSound = 0;
	
	pan = 127;
	freq = 11250;

	FSOUND_Sample_Load(0,"sfx/click.wav",FSOUND_LOOP_OFF,0);
	FSOUND_Sample_Load(1,"sfx/dong.wav",FSOUND_LOOP_OFF,0);

	FSOUND_Sample_Load(3,"sfx/computer.wav",FSOUND_LOOP_OFF,0);
	FSOUND_Sample_Load(4,"sfx/scitech.wav",FSOUND_LOOP_OFF,0);
	FSOUND_Sample_Load(5,"sfx/speed.wav",FSOUND_LOOP_OFF,0);
	FSOUND_Sample_Load(6,"sfx/placetrack.wav",FSOUND_LOOP_OFF,0);
	FSOUND_Sample_Load(7,"sfx/removetrack.wav",FSOUND_LOOP_OFF,0);

	FSOUND_Sample_Load(8, "sfx/click3.wav",FSOUND_LOOP_OFF,0);
	FSOUND_Sample_Load(9, "sfx/pickuptrack.wav",FSOUND_LOOP_OFF,0);

	FSOUND_Sample_Load(10, "sfx/cartexplode.wav",FSOUND_LOOP_OFF,0);
	FSOUND_Sample_Load(11, "sfx/cart-good.wav",FSOUND_LOOP_OFF,0);
	FSOUND_Sample_Load(12, "sfx/pickup.wav",FSOUND_LOOP_OFF,0);

	FSOUND_Sample_Load(13, "sfx/crusher.wav",FSOUND_LOOP_OFF, 0);

	return 0;

}
예제 #8
0
SoundEngine::SoundEngine(bool disableSound) :
	nosound(disableSound),
	mutesound(false),
	musicFinished(true),
	currentTrack(playlist.begin())
{
    if (nosound){
        return;
    }


	// Warning the Mix_OpenAudio uses libmikmod witch seems to create the music.raw file
    if (Mix_OpenAudio(SOUND_FREQUENCY, SOUND_FORMAT, SOUND_CHANNELS, 1024 /*4096*/) < 0) {
        logger->error("%s line %i: Unable to open sound: %s\n", __FILE__, __LINE__, Mix_GetError());
        nosound = true;
    }

    // Set volumes to half of max by default; this should be a fallback, real setting should be read from config
    SetSoundVolume(MIX_MAX_VOLUME / 2);
    SetMusicVolume(MIX_MAX_VOLUME / 2);
}
예제 #9
0
파일: c_fmod.cpp 프로젝트: jbworley/dlstorm
char CFMOD::InitializeSound()
{
    char x;
    FSOUND_SetMinHardwareChannels(8);
    FSOUND_SetMaxHardwareChannels(MAX_SND_CHANNELS);
    x = FSOUND_Init(44100, MAX_SND_CHANNELS, 0);
    Log->AddEntry(va("FMOD Version: %.2f started",FSOUND_GetVersion()));
    if(x)
    {
        bfmod=1;
        maxchannels=FSOUND_GetMaxChannels();
        Log->AddEntry(va("FMOD Max Channels [%d]",maxchannels));
    }
    else
    {
        bfmod=0;
        return 0;
    }
    SetSoundVolume(svol);

    return x;
}
예제 #10
0
/*
=================
idMoveable::Collide
=================
*/
bool idMoveable::Collide( const trace_t &collision, const idVec3 &velocity ) {
	float v, f;
	idVec3 dir;
	idEntity *ent;
	v = -( velocity * collision.c.normal );
	if( v > BOUNCE_SOUND_MIN_VELOCITY && gameLocal.time > nextSoundTime ) {
		f = v > BOUNCE_SOUND_MAX_VELOCITY ? 1.0f : idMath::Sqrt( v - BOUNCE_SOUND_MIN_VELOCITY ) * ( 1.0f / idMath::Sqrt( BOUNCE_SOUND_MAX_VELOCITY - BOUNCE_SOUND_MIN_VELOCITY ) );
		if( StartSound( "snd_bounce", SND_CHANNEL_ANY, 0, false, NULL ) ) {
			// don't set the volume unless there is a bounce sound as it overrides the entire channel
			// which causes footsteps on ai's to not honor their shader parms
			SetSoundVolume( f );
		}
		nextSoundTime = gameLocal.time + 500;
	}
	if( canDamage && damage.Length() && gameLocal.time > nextDamageTime ) {
		ent = gameLocal.entities[ collision.c.entityNum ];
		if( ent && v > minDamageVelocity ) {
			f = v > maxDamageVelocity ? 1.0f : idMath::Sqrt( v - minDamageVelocity ) * ( 1.0f / idMath::Sqrt( maxDamageVelocity - minDamageVelocity ) );
			dir = velocity;
			dir.NormalizeFast();
			ent->Damage( this, GetPhysics()->GetClipModel()->GetOwner(), dir, damage, f, INVALID_JOINT );
			nextDamageTime = gameLocal.time + 1000;
		}
	}
	// grimm --> Over the top blood & moveable effects.
	if( fxCollide.Length() && gameLocal.time > nextCollideFxTime ) {
		idEntityFx::StartFx( fxCollide, &collision.c.point, NULL, this, false );
		nextCollideFxTime = gameLocal.time + 1500;
	}
	if( mtr_collide.Length() && last_spraytime < gameLocal.GetTime() && !IsAtRest() ) {
		float ranScale;
		ranScale = 128.0f * ( 0.35 + gameLocal.random.CRandomFloat() );
		last_spraytime = gameLocal.GetTime() + 1500;
		gameLocal.ProjectDecal( GetPhysics()->GetOrigin(), -collision.c.normal, 128.0f, true, 96.0f, mtr_collide.c_str() );
	}
	// <-- grimm
	return false;
}
bool idMoveable::Collide( const trace_t &collision, const idVec3 &velocity ) {
	// greebo: Check whether we are colliding with the nearly exact same point again
	bool sameCollisionAgain = ( lastCollision.fraction != -1 && lastCollision.c.point.Compare( collision.c.point, 0.05f ) );
	// greebo: Save the collision info for the next call
	lastCollision = collision;
	float v = -( velocity * collision.c.normal );
	if( !sameCollisionAgain ) {
		float bounceSoundMinVelocity = cv_bounce_sound_min_vel.GetFloat();
		float bounceSoundMaxVelocity = cv_bounce_sound_max_vel.GetFloat();
		if( ( v > bounceSoundMinVelocity ) && ( gameLocal.time > nextSoundTime ) ) {
			// grayman #3331 - some moveables should not bother with bouncing sounds
			if( !spawnArgs.GetBool( "no_bounce_sound", "0" ) ) {
				const idMaterial *material = collision.c.material;
				idStr sndNameLocal;
				idStr surfaceName; // "tile", "glass", etc.
				if( material != NULL ) {
					surfaceName = g_Global.GetSurfName( material );
					// Prepend the snd_bounce_ prefix to check for a surface-specific sound
					idStr sndNameWithSurface = "snd_bounce_" + surfaceName;
					if( spawnArgs.FindKey( sndNameWithSurface ) != NULL ) {
						sndNameLocal = sndNameWithSurface;
					} else {
						sndNameLocal = "snd_bounce";
					}
				}
				const char *sound = spawnArgs.GetString( sndNameLocal );
				const idSoundShader *sndShader = declManager->FindSound( sound );
				//f = v > BOUNCE_SOUND_MAX_VELOCITY ? 1.0f : idMath::Sqrt( v - BOUNCE_SOUND_MIN_VELOCITY ) * ( 1.0f / idMath::Sqrt( BOUNCE_SOUND_MAX_VELOCITY - BOUNCE_SOUND_MIN_VELOCITY ) );
				// angua: modify the volume set in the def instead of setting a fixed value.
				// At minimum velocity, the volume should be "min_velocity_volume_decrease" lower (in db) than the one specified in the def
				float f = ( v > bounceSoundMaxVelocity ) ? 0.0f : spawnArgs.GetFloat( "min_velocity_volume_decrease", "0" ) * ( idMath::Sqrt( v - bounceSoundMinVelocity ) * ( 1.0f / idMath::Sqrt( bounceSoundMaxVelocity - bounceSoundMinVelocity ) ) - 1 );
				float volume = sndShader->GetParms()->volume + f;
				if( cv_moveable_collision.GetBool() ) {
					gameRenderWorld->DrawText( va( "Velocity: %f", v ), ( physicsObj.GetOrigin() + idVec3( 0, 0, 20 ) ), 0.25f, colorGreen, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, 100 * gameLocal.msec );
					gameRenderWorld->DrawText( va( "Volume: %f", volume ), ( physicsObj.GetOrigin() + idVec3( 0, 0, 10 ) ), 0.25f, colorGreen, gameLocal.GetLocalPlayer()->viewAngles.ToMat3(), 1, 100 * gameLocal.msec );
					gameRenderWorld->DebugArrow( colorMagenta, collision.c.point, ( collision.c.point + 30 * collision.c.normal ), 4.0f, 1 );
				}
				SetSoundVolume( volume );
				// greebo: We don't use StartSound() here, we want to do the sound propagation call manually
				StartSoundShader( sndShader, SND_CHANNEL_ANY, 0, false, NULL );
				// grayman #2603 - don't propagate a sound if this is a doused torch dropped by an AI
				if( !spawnArgs.GetBool( "is_torch", "0" ) ) {
					idStr sndPropName = GetSoundPropNameForMaterial( surfaceName );
					// Propagate a suspicious sound, using the "group" convention (soft, hard, small, med, etc.)
					PropSoundS( NULL, sndPropName, f, 0 ); // grayman #3355
				}
				SetSoundVolume( 0.0f );
				nextSoundTime = gameLocal.time + 500;
			}
		}
		// tels:
		//DM_LOG(LC_ENTITY, LT_INFO)LOGSTRING("Moveable %s might call script_collide %s because m_collideScriptCounter = %i and v = %f and time (%d) > m_nextCollideScriptTime (%d)\r",
		//		name.c_str(), m_scriptCollide.c_str(), m_collideScriptCounter, v, gameLocal.time, m_nextCollideScriptTime );
		if( ( m_collideScriptCounter != 0 ) && ( v > m_minScriptVelocity ) && ( gameLocal.time > m_nextCollideScriptTime ) ) {
			if( m_collideScriptCounter > 0 ) {
				// if positive, decrement it, so -1 stays as it is (for 0, we never come here)
				m_collideScriptCounter--;
			}
			// call the script
			const function_t *pScriptFun = scriptObject.GetFunction( m_scriptCollide.c_str() );
			if( pScriptFun == NULL ) {
				// Local function not found, check in global namespace
				pScriptFun = gameLocal.program.FindFunction( m_scriptCollide.c_str() );
			}
			if( pScriptFun != NULL ) {
				DM_LOG( LC_ENTITY, LT_INFO )LOGSTRING( "Moveable %s calling script_collide %s.\r",
													   name.c_str(), m_scriptCollide.c_str() );
				idThread *pThread = new idThread( pScriptFun );
				pThread->CallFunctionArgs( pScriptFun, true, "e", this );
				pThread->DelayedStart( 0 );
			} else {
				// script function not found!
				DM_LOG( LC_ENTITY, LT_ERROR )LOGSTRING( "Moveable %s could not find script_collide %s.\r",
														name.c_str(), m_scriptCollide.c_str() );
				m_collideScriptCounter = 0;
			}
			m_nextCollideScriptTime = gameLocal.time + 300;
		}
	}
	idEntity *ent = gameLocal.entities[collision.c.entityNum];
	trace_t newCollision = collision; // grayman #2816 - in case we need to modify collision
	// grayman #2816 - if we hit the world, skip all the damage work
	if( ent && ( ent != gameLocal.world ) ) {
		idActor *entActor = NULL;
		if( ent->IsType( idActor::Type ) ) {
			entActor = static_cast<idActor *>( ent ); // the object hit an actor directly
		} else if( ent->IsType( idAFAttachment::Type ) ) {
			newCollision.c.id = JOINT_HANDLE_TO_CLIPMODEL_ID( static_cast<idAFAttachment *>( ent )->GetAttachJoint() );
		}
		// go up the bindMaster chain to see if an Actor is lurking
		if( entActor == NULL ) { // no actor yet, so ent is an attachment or an attached moveable
			idEntity *bindMaster = ent->GetBindMaster();
			while( bindMaster != NULL ) {
				if( bindMaster->IsType( idActor::Type ) ) {
					entActor = static_cast<idActor *>( bindMaster ); // the object hit something attached to an actor
					// If ent is an idAFAttachment, we can leave ent alone
					// and pass the damage to it. It will, in turn, pass the
					// damage to the actor it's attached to. (helmets)
					// If ent is NOT an attachment, we have to change it to
					// be the actor we just found. Inventor goggles are an
					// example of when we have to do this, because they're
					// an idMoveable, and they DON'T transfer their damage
					// to the actor they're attached to.
					if( !ent->IsType( idAFAttachment::Type ) ) {
						ent = bindMaster;
					}
					break;
				}
				bindMaster = bindMaster->GetBindMaster(); // go up the chain
			}
		}
		// grayman #2816 - in order to allow knockouts from dropped objects,
		// we have to allow collisions where the velocity is < minDamageVelocity,
		// because dropped objects can have low velocity, while at the same time
		// carrying enough damage to warrant a KO possibility.
		if( canDamage && damage.Length() && ( gameLocal.time > nextDamageTime ) ) {
			if( !entActor || !entActor->AI_DEAD ) {
				float f;
				if( v < minDamageVelocity ) {
					f = 0.0f;
				} else if( v < maxDamageVelocity ) {
					f = idMath::Sqrt( ( v - minDamageVelocity ) / ( maxDamageVelocity - minDamageVelocity ) );
				} else {
					f = 1.0f; // capped when v >= maxDamageVelocity
				}
				// scale the damage by the surface type multiplier, if any
				idStr SurfTypeName;
				g_Global.GetSurfName( newCollision.c.material, SurfTypeName );
				SurfTypeName = "damage_mult_" + SurfTypeName;
				f *= spawnArgs.GetFloat( SurfTypeName.c_str(), "1.0" );
				idVec3 dir = velocity;
				dir.NormalizeFast();
				// Use a technique similar to what's used for a melee collision
				// to find a better joint (location), because when the head is
				// hit, the joint isn't identified correctly w/o it.
				int location = JOINT_HANDLE_TO_CLIPMODEL_ID( newCollision.c.id );
				// If this moveable is attached to an AI, identify that AI.
				// Otherwise, assume it was put in motion by someone.
				idEntity *attacker = GetPhysics()->GetClipModel()->GetOwner();
				if( attacker == NULL ) {
					attacker = m_SetInMotionByActor.GetEntity();
				}
				// grayman #3370 - if the entity being hit is the attacker, don't do damage
				if( attacker != ent ) {
					int preHealth = ent->health;
					ent->Damage( this, attacker, dir, damage, f, location, const_cast<trace_t *>( &newCollision ) );
					if( ent->health < preHealth ) { // only set the timer if there was damage
						nextDamageTime = gameLocal.time + 1000;
					}
				}
			}
		}
		// Darkmod: Collision stims and a tactile alert if it collides with an AI
		ProcCollisionStims( ent, newCollision.c.id ); // grayman #2816 - use new collision
		if( entActor && entActor->IsType( idAI::Type ) ) {
			static_cast<idAI *>( entActor )->TactileAlert( this );
		}
	}
	if( fxCollide.Length() && ( gameLocal.time > nextCollideFxTime ) ) {
		idEntityFx::StartFx( fxCollide, &collision.c.point, NULL, this, false );
		nextCollideFxTime = gameLocal.time + 3500;
	}
	return false;
}
예제 #12
0
/*
=================
idMoveable::Collide
=================
*/
bool idMoveable::Collide( const trace_t &collision, const idVec3 &velocity ) {
	float v, f;
	idVec3 dir;
	idEntity *ent;

	v = -( velocity * collision.c.normal );
	if ( v > BOUNCE_SOUND_MIN_VELOCITY && gameLocal.time > nextSoundTime ) {
		f = v > BOUNCE_SOUND_MAX_VELOCITY ? 1.0f : idMath::Sqrt( v - BOUNCE_SOUND_MIN_VELOCITY ) * ( 1.0f / idMath::Sqrt( BOUNCE_SOUND_MAX_VELOCITY - BOUNCE_SOUND_MIN_VELOCITY ) );
		if ( StartSound( "snd_bounce", SND_CHANNEL_ANY, 0, false, NULL ) ) {
			// don't set the volume unless there is a bounce sound as it overrides the entire channel
			// which causes footsteps on ai's to not honor their shader parms
			SetSoundVolume( f );
		}
		nextSoundTime = gameLocal.time + 500;
	}

	// _D3XP :: changes relating to the addition of monsterDamage
	if ( !gameLocal.isClient && canDamage && gameLocal.time > nextDamageTime ) {
		bool hasDamage = damage.Length() > 0;
		bool hasMonsterDamage = monsterDamage.Length() > 0;

		if ( hasDamage || hasMonsterDamage ) {
			ent = gameLocal.entities[ collision.c.entityNum ];
			if ( ent && v > minDamageVelocity ) {
				f = v > maxDamageVelocity ? 1.0f : idMath::Sqrt( v - minDamageVelocity ) * ( 1.0f / idMath::Sqrt( maxDamageVelocity - minDamageVelocity ) );
				dir = velocity;
				dir.NormalizeFast();
				if ( ent->IsType( idAI::Type ) && hasMonsterDamage ) {
#ifdef _D3XP
					if ( attacker ) {
						ent->Damage( this, attacker, dir, monsterDamage, f, INVALID_JOINT );
					}
					else {
						ent->Damage( this, GetPhysics()->GetClipModel()->GetOwner(), dir, monsterDamage, f, INVALID_JOINT );
					}
#else
					ent->Damage( this, GetPhysics()->GetClipModel()->GetOwner(), dir, monsterDamage, f, INVALID_JOINT );
#endif
				} else if ( hasDamage ) {
#ifdef _D3XP
					// in multiplayer, scale damage wrt mass of object
					if ( gameLocal.isMultiplayer ) {
						f *= GetPhysics()->GetMass() * g_moveableDamageScale.GetFloat();
					}

					if ( attacker ) {
						ent->Damage( this, attacker, dir, damage, f, INVALID_JOINT );
					}
					else {
						ent->Damage( this, GetPhysics()->GetClipModel()->GetOwner(), dir, damage, f, INVALID_JOINT );
					}
#else
					ent->Damage( this, GetPhysics()->GetClipModel()->GetOwner(), dir, damage, f, INVALID_JOINT );
#endif
				}

				nextDamageTime = gameLocal.time + 1000;
			}
		}
	}

#ifdef _D3XP
	if ( this->IsType( idExplodingBarrel::Type ) ) {
		idExplodingBarrel *ebarrel = static_cast<idExplodingBarrel*>(this);

		if ( !ebarrel->IsStable() ) {
			PostEventSec( &EV_Explode, 0.04f );
		}
	}
#endif

	if ( fxCollide.Length() && gameLocal.time > nextCollideFxTime ) {
		idEntityFx::StartFx( fxCollide, &collision.c.point, NULL, this, false );
		nextCollideFxTime = gameLocal.time + 3500;
	}

	return false;
}