//----------------------------------------------------------------------------- // Purpose: Updates and renders all effects //----------------------------------------------------------------------------- int C_HopwireExplosion::DrawModel( int flags ) { AddParticles(); #ifndef C17 CMatRenderContextPtr pRenderContext( materials ); pRenderContext->Flush(); UpdateRefractTexture(); IMaterial *pMat = materials->FindMaterial( "effects/strider_pinch_dudv", TEXTURE_GROUP_CLIENT_EFFECTS ); float refract = m_FXCoreAlpha.Interp( gpGlobals->curtime ); float scale = m_FXCoreScale.Interp( gpGlobals->curtime ); IMaterialVar *pVar = pMat->FindVar( "$refractamount", NULL ); pVar->SetFloatValue( refract ); pRenderContext->Bind( pMat, (IClientRenderable*)this ); float sin1 = sinf( gpGlobals->curtime * 10 ); float sin2 = sinf( gpGlobals->curtime ); float scaleY = ( sin1 * sin2 ) * 32.0f; float scaleX = (sin2 * sin2) * 32.0f; // FIXME: The ball needs to sort properly at all times static color32 white = {255,255,255,255}; DrawSpriteTangentSpace( GetRenderOrigin() + ( CurrentViewForward() * 128.0f ), scale+scaleX, scale+scaleY, white ); #endif return 1; }
void CPreviewDlg::BuildTree() { CWaitCursor cursor; quickTree.Clear(); treeMedia.DeleteAllItems(); idFileList *files; if ( currentMode == GUIS ) { files = fileSystem->ListFilesTree( "guis", ".gui" ); AddStrList( "base", files->GetList(), GUIS ); fileSystem->FreeFileList( files ); } else if ( currentMode == MODELS ) { files = fileSystem->ListFilesTree( "models", ".lwo" ); AddStrList( "base", files->GetList(), MODELS ); fileSystem->FreeFileList( files ); files = fileSystem->ListFilesTree( "models", ".ase" ); AddStrList( "base", files->GetList(), MODELS ); fileSystem->FreeFileList( files ); files = fileSystem->ListFilesTree( "models", ".ma" ); AddStrList( "base", files->GetList(), MODELS ); fileSystem->FreeFileList( files ); } else if ( currentMode == SOUNDS ) { AddSounds( true ); } else if ( currentMode == MATERIALS ) { AddMaterials( true ); } else if ( currentMode == PARTICLES ) { AddParticles( true ); } else if ( currentMode == SKINS ) { AddSkins( true ); } }
///===================================================== /// ///===================================================== void ParticleEmitter::Update(double deltaSeconds){ double currentTime = GetCurrentSeconds(); //update existing particles for (Particles::iterator particleIter = m_particles.begin(); particleIter != m_particles.end();){ Particle* particle = *particleIter; //delete expired particles if (particle->m_expirationTime < currentTime){ delete particle; particleIter = m_particles.erase(particleIter); continue; } particle->Update(deltaSeconds); ++particleIter; } //add new particles m_timeSinceParticleEmission += deltaSeconds; if (m_timeSinceParticleEmission >= m_timeBetweenParticleEmissions){ AddParticles(); m_timeSinceParticleEmission -= m_timeBetweenParticleEmissions; } }
///========================================================================================================================================== /// Debris ///========================================================================================================================================== void DebrisEmitter::Update(double deltaSeconds){ double currentTime = GetCurrentSeconds(); //update existing particles for (Particles::iterator particleIter = m_particles.begin(); particleIter != m_particles.end();){ Particle* particle = *particleIter; //delete expired particles if (particle->m_expirationTime < currentTime){ delete particle; particleIter = m_particles.erase(particleIter); continue; } particle->m_velocity.y -= m_acceleration * (float)deltaSeconds; particle->Update(deltaSeconds); if (particle->m_position.y < m_position.y){ particle->m_velocity.y = -particle->m_velocity.y * GetRandomFloatInRange(0.6f, 0.8f); } ++particleIter; } //add new particles m_timeSinceParticleEmission += deltaSeconds; if (m_timeSinceParticleEmission >= m_timeBetweenParticleEmissions){ AddParticles(); m_timeSinceParticleEmission -= m_timeBetweenParticleEmissions; } }
DBOOL CParticleStreamFX::CreateObject(CClientDE *pClientDE) { if(!pClientDE ) return DFALSE; if(m_hstrTexture) m_pTextureName = pClientDE->GetStringData(m_hstrTexture); DBOOL bRet = CBaseParticleSystemFX::CreateObject(pClientDE); if(m_hServerObject) { DVector vPos; DRotation rRot; m_pClientDE->GetObjectPos(m_hServerObject, &vPos); m_pClientDE->SetObjectPos(m_hObject, &vPos); m_pClientDE->GetObjectRotation(m_hServerObject, &rRot); m_pClientDE->GetRotationVectors(&rRot, &m_vU, &m_vR, &m_vDir); } else return DFALSE; if(bRet) { DFLOAT r, g, b, a; m_pClientDE->GetObjectColor(m_hObject, &r, &g, &b, &a); m_pClientDE->SetObjectColor(m_hObject, r, g, b, m_fAlpha); if(m_bState) AddParticles(); } return bRet; }
/* ================ 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( "model_detonate" ); if ( *temp != '\0' ) { AddParticles( temp, false ); } 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 ); } }
///===================================================== /// ///===================================================== void WaveEmitter::Update(double deltaSeconds){ double currentTime = GetCurrentSeconds(); //update existing particles for (Particles::iterator particleIter = m_particles.begin(); particleIter != m_particles.end();){ Particle* particle = *particleIter; //delete expired particles if (particle->m_expirationTime < currentTime){ delete particle; particleIter = m_particles.erase(particleIter); continue; } //COLORFUL SPIRAL LOL Vec2 tempVel(particle->m_velocity.x, particle->m_velocity.z); tempVel.RotateDegrees(32.0f * (float)deltaSeconds * 90.0f / (float)m_duration); particle->m_velocity = Vec3(tempVel.x, 0.0f, tempVel.y); Vec2 tempPos(particle->m_position.x, particle->m_position.z); tempPos.RotateDegrees(32.0f * (float)deltaSeconds * 90.0f / (float)m_duration); particle->m_position = Vec3(tempPos.x, particle->m_position.y, tempPos.y); if (GetRandomFloatInRange(0.0f, 1.0f) > cos(currentTime)){ particle->m_color.r -= (unsigned char)GetRandomIntInRange(0, 3); particle->m_color.g -= (unsigned char)GetRandomIntInRange(2, 6); particle->m_color.b += (unsigned char)GetRandomIntInRange(1, 9); } particle->m_position.y = m_position.y + m_waveHeight * cos((CalcDistance(Vec2(m_position.x, m_position.z), Vec2(particle->m_position.x, particle->m_position.z)) - (float)currentTime) * m_waveSpeed); particle->Update(deltaSeconds); ++particleIter; } //add new particles m_timeSinceParticleEmission += deltaSeconds; if (m_timeSinceParticleEmission >= m_timeBetweenParticleEmissions){ AddParticles(); m_timeSinceParticleEmission -= m_timeBetweenParticleEmissions; } }
bool GameOverScene::init() { auto backgroundStartColor = m_type == EndType::SUCCESS ? BACKGROUND_GRADIENT_FROM_SUCCESS : BACKGROUND_GRADIENT_FROM_FAIL; if (!LayerGradient::initWithColor(backgroundStartColor, BACKGROUND_GRADIENT_TO)) { return false; } m_visibleSize = Director::getInstance()->getVisibleSize(); m_origin = Director::getInstance()->getVisibleOrigin(); AddLabels(); AddMenu(); if (m_type == EndType::SUCCESS) { AddParticles(); } return true; }
/* ================ idExplodingBarrel::StartBurning ================ */ void idExplodingBarrel::StartBurning( void ) { state = BURNING; AddParticles( "barrelfire.prt", true ); }
/* ================ idExplodingBarrel::StartBurning (ROE) ================ */ void idExplodingBarrel::StartBurning( void ) { state = BURNING; StartSound( "snd_burn", SND_CHANNEL_ANY, 0, false, NULL ); AddParticles( spawnArgs.GetString ( "model_burn", "" ), true ); }
LTBOOL CParticleExplosionFX::Update() { if (!m_hObject || !m_pClientDE) return LTFALSE; if (!CBaseParticleSystemFX::Update()) return LTFALSE; LTFLOAT fTime = m_pClientDE->GetTime(); if (m_bFirstUpdate) { m_bFirstUpdate = LTFALSE; m_fStartTime = fTime; m_fLastTime = fTime; } // Check to see if we should start fading the system... if (fTime > m_fStartTime + m_fFadeTime) { LTFLOAT fEndTime = m_fStartTime + m_fLifeTime; if (fTime > fEndTime) { return LTFALSE; } LTFLOAT fScale = (fEndTime - fTime) / (m_fLifeTime - m_fFadeTime); LTFLOAT r, g, b, a; m_pClientDE->GetObjectColor(m_hObject, &r, &g, &b, &a); m_pClientDE->SetObjectColor(m_hObject, r, g, b, fScale); } // See if it is time to create a new Particle puff... if (fTime >= m_fLastTime + m_fOffsetTime) { // Loop over our list of emmitters, creating new particles... for (int i=0; i < m_nNumEmmitters; i++) { if (m_ActiveEmmitters[i]) { AddParticles(&m_Emmitters[i]); } } m_fLastTime = fTime; } // Loop over our list of emmitters, updating the position of each for (int i=0; i < m_nNumEmmitters; i++) { if (m_ActiveEmmitters[i]) { LTBOOL bBounced = LTFALSE; if (bBounced = UpdateEmmitter(&m_Emmitters[i])) { if (!(m_Emmitters[i].m_PhysicsFlags & MO_LIQUID) && (m_hDebris[i])) { char* pSound = GetDebrisBounceSound(DBT_STONE_BIG); // Play appropriate sound... PlaySoundFromPos(&m_Emmitters[i].m_Pos, pSound, 300.0f, SOUNDPRIORITY_MISC_LOW); } m_BounceCount[i]--; if (m_BounceCount[i] <= 0) { m_Emmitters[i].m_PhysicsFlags |= MO_RESTING; } } if (m_Emmitters[i].m_PhysicsFlags & MO_RESTING) { m_ActiveEmmitters[i] = LTFALSE; if (m_hDebris[i]) { m_pClientDE->RemoveObject(m_hDebris[i]); m_hDebris[i] = LTNULL; } } else if (m_hDebris[i]) { m_pClientDE->SetObjectPos(m_hDebris[i], &(m_Emmitters[i].m_Pos)); if (m_bRotateDebris) { if (bBounced) { // Adjust due to the bounce... m_fPitchVel = GetRandom(-MATH_CIRCLE, MATH_CIRCLE); m_fYawVel = GetRandom(-MATH_CIRCLE, MATH_CIRCLE); } if (m_fPitchVel != 0 || m_fYawVel != 0) { LTFLOAT fDeltaTime = m_pClientDE->GetFrameTime(); m_fPitch += m_fPitchVel * fDeltaTime; m_fYaw += m_fYawVel * fDeltaTime; LTRotation rRot; m_pClientDE->Common()->SetupEuler(rRot, m_fPitch, m_fYaw, 0.0f); m_pClientDE->SetObjectRotation(m_hDebris[i], &rRot); } } } } } return LTTRUE; }
/* ================ 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 ); } }
//#define collisions ///========================================================================================================================================== /// Fireworks ///========================================================================================================================================== void FireworksEmitter::Update(double deltaSeconds){ double currentTime = GetCurrentSeconds(); #if defined collisions Vec3s initialPositions; Vec3s finalPositions; #endif //update existing particles for (Particles::iterator particleIter = m_particles.begin(); particleIter != m_particles.end();){ Particle* particle = *particleIter; //delete expired particles if (particle->m_expirationTime < currentTime){ delete particle; particleIter = m_particles.erase(particleIter); continue; } #if defined collisions initialPositions.push_back(particle->m_position); #endif particle->m_velocity.y -= m_acceleration * (float)deltaSeconds; particle->Update(deltaSeconds); #if defined collisions finalPositions.push_back(particle->m_position); #endif ++particleIter; } #if defined collisions int count1 = 0; int count2 = 0; for (Particles::iterator particleIter = m_particles.begin(); particleIter != m_particles.end();){ Particle* particle = *particleIter; Vec3 p1 = initialPositions.at(count1); if (CalcDistanceSquared(p1, m_position) < 0.5f){ ++particleIter; ++count1; continue; } Vec3 p2 = finalPositions.at(count1); count2 = ++count1; float R1 = 0.00000001f; for (Particles::iterator particleIter2 = ++particleIter; particleIter2 != m_particles.end(); ++particleIter2, ++count2){ Particle* particle2 = *particleIter2; Vec3 q1 = initialPositions.at(count2); if (CalcDistanceSquared(q1, m_position) < 0.5f){ continue; } Vec3 q2 = finalPositions.at(count2); float R2 = 0.00000001f; Vec3 x0(q1 - p1); Vec3 e(q2 - q1 - (p2 - p1)); float R = R1 + R2; float collisionTest = (DotProduct(e, x0) * DotProduct(e, x0)) - (DotProduct(e, e) * (DotProduct(x0, x0) - (R * R))); if (collisionTest >= 0.0f){ //did collide float collisionTime = (-DotProduct(e, x0) - sqrt(collisionTest)) / DotProduct(e, e); if (collisionTime < 0.0f) collisionTime = 0.0f; particle2->m_color = RGBAchars::YELLOW; particle->m_color = RGBAchars::YELLOW; particle->m_position = initialPositions.at(count1 - 1); particle2->m_position = initialPositions.at(count2); Vec3 collisionNormal = particle->m_position - particle2->m_position; float length = collisionNormal.Normalize(); if (length <= 0.001f) continue; float v1Parallel = DotProduct(particle->m_velocity, collisionNormal); Vec3 v1Perp = particle->m_velocity - v1Parallel * collisionNormal; float v2Parallel = DotProduct(particle2->m_velocity, collisionNormal); Vec3 v2Perp = particle2->m_velocity - v2Parallel * collisionNormal; float e = 0.7f; Vec3 v1ParralelFinal = (0.5f * (v1Parallel + v2Parallel + e * (v2Parallel - v1Parallel))) * collisionNormal; Vec3 v2ParralelFinal = (0.5f * (v1Parallel + v2Parallel - e * (v2Parallel - v1Parallel))) * collisionNormal; particle->m_velocity = v1ParralelFinal + v1Perp; particle2->m_velocity = v2ParralelFinal + v2Perp; } } } #endif //add new particles m_timeSinceParticleEmission += deltaSeconds; if (m_timeSinceParticleEmission >= m_timeBetweenParticleEmissions){ AddParticles(); m_timeSinceParticleEmission -= m_timeBetweenParticleEmissions; } }
DBOOL CParticleStreamFX::Update() { if(!m_hObject || !m_pClientDE) return DFALSE; // Update the position and direction of the particle stream based on the server object if(m_hServerObject) { DVector vPos; DRotation rRot; m_pClientDE->GetObjectPos(m_hServerObject, &vPos); m_pClientDE->SetObjectPos(m_hObject, &vPos); m_pClientDE->GetObjectRotation(m_hServerObject, &rRot); m_pClientDE->GetRotationVectors(&rRot, &m_vU, &m_vR, &m_vDir); } else return DFALSE; // Check to see if the server object is visible (determines on/off state of effect) DDWORD dwFlags; m_pClientDE->GetObjectUserFlags(m_hServerObject, &dwFlags); if(dwFlags & USRFLG_VISIBLE) { if((m_bState == 0) || (m_bState == 3)) { m_fTriggerTime = m_pClientDE->GetTime(); if(m_fRampTime) m_bState = 1; else m_bState = 2; } } else { if((m_bState == 1) || (m_bState == 2)) { m_fTriggerTime = m_pClientDE->GetTime(); if(m_fRampTime) m_bState = 3; else m_bState = 0; } } // Play the correct sound according to the current state switch(m_bState) { case 1: if(m_hstrSound1) { if(m_hsSound) m_pClientDE->KillSound(m_hsSound); m_hsSound = PlaySoundFromObject(m_hObject, m_pClientDE->GetStringData(m_hstrSound1), m_fSoundRadius, SOUNDPRIORITY_MISC_MEDIUM, DFALSE, DTRUE); } break; case 2: if(m_hstrSound2 && !m_hsSound) { m_hsSound = PlaySoundFromObject(m_hObject, m_pClientDE->GetStringData(m_hstrSound2), m_fSoundRadius, SOUNDPRIORITY_MISC_MEDIUM, DTRUE, DTRUE); } break; case 3: if(m_hstrSound3) { if(m_hsSound) m_pClientDE->KillSound(m_hsSound); m_hsSound = PlaySoundFromObject(m_hObject, m_pClientDE->GetStringData(m_hstrSound3), m_fSoundRadius, SOUNDPRIORITY_MISC_MEDIUM, DFALSE, DTRUE); } break; } // See if it's time to add more particles... and do so if(m_pClientDE->GetTime() > m_fLastAddTime + m_fDelay) AddParticles(); return DTRUE; }
void BemGame::DrawFrame() { AddText( engine ); int i; // The whole demo works because it takes exactly 12 ticks for a // Drone or Brain to walk one tile. So every 12 subticks // we calculate a new direction for the actor. subtick++; tick++; teleFrame++; if ( subtick == SUBTICK ) { subtick = 0; for ( i=0; i<numActors; i++ ) { ProcessMap( &actor[i] ); } } // calculate the tinting, from map 4.5,4.5 float rad = float( tick ) / 45.0; float fred = fabs( sin( rad*1.5 ) ) * 0.5; float fgreen = fabs( sin( rad*2.5 ) ) * 0.5; float fblue = fabs( sin( rad*3.5 ) ) * 0.5; float falpha = fabs( sin( rad ) ) * 0.3; KrColorTransform gizmoColor; gizmoColor.TintRed( U8( fred * 255.0 )); gizmoColor.TintGreen( U8( fgreen * 255.0 )); gizmoColor.TintBlue( U8( fblue * 255.0 )); gizmoColor.TintAlpha( U8( falpha * 255.0 )); gizmo->SetColor( gizmoColor ); // update all the actors. for( i=0; i<numActors; i++ ) { KrColorTransform actorColor; float d = DistanceFromCenter( &actor[i] ); if ( d < 3.0 ) { float fraction = 1.0 - d / 3.0; actorColor.TintRed( U8( fred * 255.0 * fraction )); actorColor.TintGreen( U8( fgreen * 255.0 * fraction )); actorColor.TintBlue( U8( fblue * 255.0 * fraction )); actorColor.TintAlpha( U8( falpha * 255.0 * fraction )); } actor[i].sprite->SetColor( actorColor ); actor[i].sprite->DoStep(); // In order to sort with the particles, sort with // the world Y. GlFixed wx, wy, wz, tx, ty; isoMath->ScreenToFlatTile( actor[i].sprite->X(), actor[i].sprite->Y(), 0, &tx, &ty ); isoMath->TileToWorld( tx, ty, 0, &wx, &wy, &wz ); actor[i].sprite->SetZDepth( -wy.v ); } // The teleport in and out special effect. Done "by hand" // counting frames with a switch. Looks cool and tests // the visibility stuff. if ( teleFrame > 9 && numActors > 0 ) { KrColorTransform cform; switch ( teleFrame ) { case 10: teleSprite = actor[ random.Rand( numActors ) ].sprite; cform.Brighten( 128 ); break; case 11: cform.Brighten( 200 ); cform.SetAlpha( 220 ); break; case 12: case 13: cform.Brighten( 255 ); cform.SetAlpha( 200 ); break; case 14: { GlFixed x, y; isoMath->ScreenToFlatTile( teleSprite->X(), teleSprite->Y(), 0, &x, &y ); AddParticles( x, y ); teleSprite->SetVisible( false ); } break; case 35: case 36: case 37: case 38: case 39: case 40: teleSprite->SetVisible( true ); cform.TintBlue( 240 - 30 * ( teleFrame - 35 ) ); cform.SetAlpha( 100 + 20 * ( teleFrame - 35 ) ); break; case 41: teleFrame = 0; break; default: break; } teleSprite->SetColor( cform ); } MoveParticles(); // Since the map coordinates only change if the subtick rolled // over, we only change the mini map every 12 frames. if ( subtick == 0 ) DrawMiniMap(); if ( UseWindows() ) ProcessRightWindow(); engine->Draw(); }
/* ================ 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 ); } }
/* ================ 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(); }