/** * 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 }
/* ================= 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; }
/* ================= 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; }
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; }
/* ================= 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; }
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; }
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); }
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; }
/* ================= 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; }
/* ================= 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; }