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