void DoDebrisSmoke (tObject *objP) { int nParts, i; float nScale = 2; vmsVector pos; i = OBJ_IDX (objP); if (!(SHOW_SMOKE && gameOpts->render.smoke.bDebris)) { if (gameData.smoke.objects [i] >= 0) KillObjectSmoke (i); return; } if ((objP->info.xShields < 0) || (objP->info.nFlags & (OF_SHOULD_BE_DEAD | OF_DESTROYED)) || (gameOpts->render.nDebrisLife && (nDebrisLife [gameOpts->render.nDebrisLife] * F1_0 - objP->info.xLifeLeft > 10 * F1_0))) nParts = 0; else nParts = DEBRIS_MAX_PARTS; if (nParts) { if (!gameOpts->render.smoke.bSyncSizes) { nParts = -MAX_PARTICLES (nParts, gameOpts->render.smoke.nDens [4]); nScale = PARTICLE_SIZE (gameOpts->render.smoke.nSize [4], nScale); } if (gameData.smoke.objects [i] < 0) { SetSmokeObject (i, CreateSmoke (&objP->info.position.vPos, NULL, NULL, objP->info.nSegment, 1, nParts / 2, nScale, -1, 1, DEBRIS_PART_LIFE, DEBRIS_PART_SPEED, SMOKE_PARTICLES, i, smokeColors, 0, -1)); } pos = objP->info.position.vPos + objP->info.position.mOrient[FVEC] * (-objP->info.xSize); SetSmokePos (gameData.smoke.objects [i], &pos, NULL, objP->info.nSegment); } else KillObjectSmoke (i); }
void DoDebrisSmoke (CObject *objP) { int nParts, nObject, nSmoke; float nScale = 2; CFixVector pos; nObject = objP->Index (); if (!(SHOW_SMOKE && gameOpts->render.particles.bDebris)) { if (particleManager.GetObjectSystem (nObject) >= 0) KillObjectSmoke (nObject); return; } if ((objP->info.xShields < 0) || (objP->info.nFlags & (OF_SHOULD_BE_DEAD | OF_DESTROYED)) || (gameOpts->render.nDebrisLife && (I2X (nDebrisLife [gameOpts->render.nDebrisLife]) - objP->info.xLifeLeft > I2X (10)))) nParts = 0; else nParts = DEBRIS_MAX_PARTS; if (nParts) { if (!gameOpts->render.particles.bSyncSizes) { nParts = -MAX_PARTICLES (nParts, gameOpts->render.particles.nDens [4]); nScale = PARTICLE_SIZE (gameOpts->render.particles.nSize [4], nScale); } if (0 > (nSmoke = particleManager.GetObjectSystem (nObject))) { nSmoke = particleManager.Create (&objP->info.position.vPos, NULL, NULL, objP->info.nSegment, 1, nParts / 2, nScale, -1, 1, DEBRIS_PART_LIFE, DEBRIS_PART_SPEED, SMOKE_PARTICLES, nObject, smokeColors, 0, -1); if (nSmoke < 0) return; particleManager.SetObjectSystem (nObject, nSmoke); } pos = objP->info.position.vPos + objP->info.position.mOrient.FVec () * (-objP->info.xSize); particleManager.SetPos (nSmoke, &pos, NULL, objP->info.nSegment); } else KillObjectSmoke (nObject); }
void DoRobotSmoke (CObject *objP) { int h = -1, nObject, nSmoke, nShields = 0, nParts; float nScale; CFixVector pos; nObject = objP->Index (); if (!(SHOW_SMOKE && gameOpts->render.particles.bRobots)) { if (particleManager.GetObjectSystem (nObject) >= 0) KillObjectSmoke (nObject); return; } if ((objP->info.xShields < 0) || (objP->info.nFlags & (OF_SHOULD_BE_DEAD | OF_DESTROYED))) nParts = 0; else { nShields = X2IR (RobotDefaultShields (objP)); h = X2IR (objP->info.xShields) * 100 / nShields; } if (h < 0) return; nParts = 10 - h / 5; if (nParts > 0) { if (nShields > 4000) nShields = 4000; else if (nShields < 1000) nShields = 1000; CreateDamageExplosion (nParts, nObject); //nParts *= nShields / 10; nParts = BOT_MAX_PARTS; nScale = (float) sqrt (8.0 / X2F (objP->info.xSize)); nScale *= 1.0f + h / 25.0f; if (!gameOpts->render.particles.bSyncSizes) { nParts = -MAX_PARTICLES (nParts, gameOpts->render.particles.nDens [2]); nScale = PARTICLE_SIZE (gameOpts->render.particles.nSize [2], nScale); } if (0 > (nSmoke = particleManager.GetObjectSystem (nObject))) { //PrintLog ("creating robot %d smoke\n", nObject); nSmoke = particleManager.Create (&objP->info.position.vPos, NULL, NULL, objP->info.nSegment, 1, nParts, nScale, gameOpts->render.particles.bSyncSizes ? -1 : gameOpts->render.particles.nSize [2], 1, BOT_PART_LIFE, BOT_PART_SPEED, SMOKE_PARTICLES, nObject, smokeColors, 1, -1); if (nSmoke < 0) return; particleManager.SetObjectSystem (nObject, nSmoke); } else { particleManager.SetScale (nSmoke, nScale); particleManager.SetDensity (nSmoke, nParts, gameOpts->render.particles.bSyncSizes ? -1 : gameOpts->render.particles.nSize [2]); particleManager.SetSpeed (nSmoke, !objP->mType.physInfo.velocity.IsZero () ? BOT_PART_SPEED : BOT_PART_SPEED * 2 / 3); } pos = objP->info.position.vPos + objP->info.position.mOrient.FVec () * (-objP->info.xSize / 2); particleManager.SetPos (nSmoke, &pos, NULL, objP->info.nSegment); } else KillObjectSmoke (nObject); }
void DoRobotSmoke (tObject *objP) { int h = -1, i, nShields = 0, nParts; float nScale; vmsVector pos; i = OBJ_IDX (objP); if (!(SHOW_SMOKE && gameOpts->render.smoke.bRobots)) { if (gameData.smoke.objects [i] >= 0) KillObjectSmoke (i); return; } if ((objP->shields < 0) || (objP->flags & (OF_SHOULD_BE_DEAD | OF_DESTROYED))) nParts = 0; else { nShields = f2ir (RobotDefaultShields (objP)); h = f2ir (objP->shields) * 100 / nShields; } if (h < 0) return; nParts = 10 - h / 5; if (nParts > 0) { if (nShields > 4000) nShields = 4000; else if (nShields < 1000) nShields = 1000; CreateDamageExplosion (nParts, i); //nParts *= nShields / 10; nParts = BOT_MAX_PARTS; nScale = (float) sqrt (8.0 / f2fl (objP->size)); nScale *= 1.0f + h / 25.0f; if (!gameOpts->render.smoke.bSyncSizes) { nParts = -MAX_PARTICLES (nParts, gameOpts->render.smoke.nDens [2]); nScale = PARTICLE_SIZE (gameOpts->render.smoke.nSize [2], nScale); } if (gameData.smoke.objects [i] < 0) { //PrintLog ("creating robot %d smoke\n", i); SetSmokeObject (i, CreateSmoke (&objP->position.vPos, NULL, NULL, objP->nSegment, 1, nParts, nScale, gameOpts->render.smoke.bSyncSizes ? -1 : gameOpts->render.smoke.nSize [2], 1, BOT_PART_LIFE, BOT_PART_SPEED, 0, i, NULL, 1, -1)); } else { SetSmokePartScale (gameData.smoke.objects [i], nScale); SetSmokeDensity (gameData.smoke.objects [i], nParts, gameOpts->render.smoke.bSyncSizes ? -1 : gameOpts->render.smoke.nSize [2]); SetSmokeSpeed (gameData.smoke.objects [i], (objP->mType.physInfo.velocity.p.x || objP->mType.physInfo.velocity.p.y || objP->mType.physInfo.velocity.p.z) ? BOT_PART_SPEED : BOT_PART_SPEED * 2 / 3); } VmVecScaleAdd (&pos, &objP->position.vPos, &objP->position.mOrient.fVec, -objP->size / 2); SetSmokePos (gameData.smoke.objects [i], &pos, NULL, objP->nSegment); } else KillObjectSmoke (i); }
void DoStaticParticles (CObject *objP) { int i, j, nObject, nSmoke, bBubbles = objP->rType.particleInfo.nType == SMOKE_TYPE_BUBBLES; CFixVector pos, offs, dir; static tRgbaColorf defaultColors [2] = {{0.5f, 0.5f, 0.5f, 0.0f}, {0.8f, 0.9f, 1.0f, 1.0f}}; nObject = (int) objP->Index (); if (!(SHOW_SMOKE && (bBubbles ? gameOpts->render.particles.bBubbles : gameOpts->render.particles.bStatic))) { if (particleManager.GetObjectSystem (nObject) >= 0) KillObjectSmoke (nObject); return; } if (0 > (nSmoke = particleManager.GetObjectSystem (nObject))) { tRgbaColorf color; int bColor; color.red = (float) objP->rType.particleInfo.color.red / 255.0f; color.green = (float) objP->rType.particleInfo.color.green / 255.0f; color.blue = (float) objP->rType.particleInfo.color.blue / 255.0f; if ((bColor = (color.red + color.green + color.blue > 0))) color.alpha = (float) -objP->rType.particleInfo.color.alpha / 255.0f; dir = objP->info.position.mOrient.FVec () * (objP->rType.particleInfo.nSpeed * I2X (2) / 55); nSmoke = particleManager.Create (&objP->info.position.vPos, &dir, &objP->info.position.mOrient, objP->info.nSegment, 1, -objP->rType.particleInfo.nParts, -PARTICLE_SIZE (objP->rType.particleInfo.nSize [gameOpts->render.particles.bDisperse], bBubbles ? 4.0f : 2.0f), -1, 3, STATIC_SMOKE_PART_LIFE * objP->rType.particleInfo.nLife, objP->rType.particleInfo.nDrift, bBubbles ? BUBBLE_PARTICLES : SMOKE_PARTICLES, nObject, bColor ? &color : defaultColors + bBubbles, 1, objP->rType.particleInfo.nSide - 1); if (nSmoke < 0) return; particleManager.SetObjectSystem (nObject, nSmoke); if (bBubbles) audio.CreateObjectSound (-1, SOUNDCLASS_GENERIC, nObject, 1, I2X (1) / 2, I2X (256), -1, -1, AddonSoundName (SND_ADDON_AIRBUBBLES)); else particleManager.SetBrightness (particleManager.GetObjectSystem (nObject), objP->rType.particleInfo.nBrightness); } if (objP->rType.particleInfo.nSide <= 0) { //don't vary emitter position for smoke emitting faces i = objP->rType.particleInfo.nDrift >> 4; i += objP->rType.particleInfo.nSize [0] >> 2; i /= 2; if (!(j = i - i / 2)) j = 2; i /= 2; offs [X] = (I2X (1) / 4 - d_rand ()) * (d_rand () % j + i); offs [Y] = (I2X (1) / 4 - d_rand ()) * (d_rand () % j + i); offs [Z] = (I2X (1) / 4 - d_rand ()) * (d_rand () % j + i); pos = objP->info.position.vPos + offs; particleManager.SetPos (nSmoke, &pos, NULL, objP->info.nSegment); }
void DoMissileSmoke (CObject *objP) { int nParts, nSpeed, nLife, nObject, nSmoke; float nScale = 1.75f; tThrusterInfo ti; nObject = objP->Index (); if (!(SHOW_SMOKE && gameOpts->render.particles.bMissiles)) { if (particleManager.GetObjectSystem (nObject) >= 0) KillObjectSmoke (nObject); return; } if ((objP->info.xShields < 0) || (objP->info.nFlags & (OF_SHOULD_BE_DEAD | OF_DESTROYED))) nParts = 0; else { nSpeed = WI_speed (objP->info.nId, gameStates.app.nDifficultyLevel); nLife = gameOpts->render.particles.nLife [3] + 1; #if 1 nParts = int (MSL_MAX_PARTS * X2F (nSpeed) / (34.0f * (4 - nLife))); if ((objP->info.nId == EARTHSHAKER_MEGA_ID) || (objP->info.nId == ROBOT_SHAKER_MEGA_ID)) nParts /= 2; #else nParts = (objP->info.nId == EARTHSHAKER_ID) ? 1500 : (objP->info.nId == MEGAMSL_ID) ? 1400 : (objP->info.nId == SMARTMSL_ID) ? 1300 : 1200; #endif } if (nParts) { if (0 > (nSmoke = particleManager.GetObjectSystem (nObject))) { if (!gameOpts->render.particles.bSyncSizes) { nParts = -MAX_PARTICLES (nParts, gameOpts->render.particles.nDens [3]); nScale = PARTICLE_SIZE (gameOpts->render.particles.nSize [3], nScale); } nSmoke = particleManager.Create (&objP->info.position.vPos, NULL, NULL, objP->info.nSegment, 1, nParts, nScale, gameOpts->render.particles.bSyncSizes ? -1 : gameOpts->render.particles.nSize [3], 1, nLife * MSL_PART_LIFE, MSL_PART_SPEED, SMOKE_PARTICLES, nObject, smokeColors + 1, 1, -1); if (nSmoke < 0) return; particleManager.SetObjectSystem (nObject, nSmoke); } CalcThrusterPos (objP, &ti, 0); particleManager.SetPos (nSmoke, ti.vPos, NULL, objP->info.nSegment); } else KillObjectSmoke (nObject); }
void CShrapnel::Create (CObject* parentObjP, CObject* objP) { static tRgbaColorf color = {1,1,1,0.5}; m_info.vDir = CFixVector::Random (); m_info.vPos = objP->info.position.vPos + m_info.vDir * (parentObjP->info.xSize / 4 + rand () % (parentObjP->info.xSize / 2)); m_info.nTurn = 1; m_info.xSpeed = 3 * (I2X (1) / 20 + rand () % (I2X (1) / 20)) / 4; m_info.xLife = m_info.xTTL = I2X (3) / 2 + rand (); m_info.tUpdate = gameStates.app.nSDLTicks; m_info.nSmoke = particleManager.Create (&m_info.vPos, NULL, NULL, objP->info.nSegment, 1, -SHRAPNEL_MAX_PARTS, -PARTICLE_SIZE (1, 4), -1, 1, SHRAPNEL_PART_LIFE, SHRAPNEL_PART_SPEED, SMOKE_PARTICLES, 0x7fffffff, &color, 1, -1); if (objP->info.xLifeLeft < m_info.xLife) objP->info.xLifeLeft = m_info.xLife; }
void DoMissileSmoke (tObject *objP) { int nParts, nSpeed, nLife, i; float nScale = 1.5f; tThrusterInfo ti; i = OBJ_IDX (objP); if (!(SHOW_SMOKE && gameOpts->render.smoke.bMissiles)) { if (gameData.smoke.objects [i] >= 0) KillObjectSmoke (i); return; } if ((objP->info.xShields < 0) || (objP->info.nFlags & (OF_SHOULD_BE_DEAD | OF_DESTROYED))) nParts = 0; else { nSpeed = WI_speed (objP->info.nId, gameStates.app.nDifficultyLevel); nLife = gameOpts->render.smoke.nLife [3] + 1; #if 1 nParts = (int) (MSL_MAX_PARTS * X2F (nSpeed) / (40.0f * (4 - nLife))); if ((objP->info.nId == EARTHSHAKER_MEGA_ID) || (objP->info.nId == ROBOT_SHAKER_MEGA_ID)) nParts /= 2; #else nParts = (objP->info.nId == EARTHSHAKER_ID) ? 1500 : (objP->info.nId == MEGAMSL_ID) ? 1400 : (objP->info.nId == SMARTMSL_ID) ? 1300 : 1200; #endif } if (nParts) { if (gameData.smoke.objects [i] < 0) { if (!gameOpts->render.smoke.bSyncSizes) { nParts = -MAX_PARTICLES (nParts, gameOpts->render.smoke.nDens [3]); nScale = PARTICLE_SIZE (gameOpts->render.smoke.nSize [3], nScale); } SetSmokeObject (i, CreateSmoke (&objP->info.position.vPos, NULL, NULL, objP->info.nSegment, 1, nParts, nScale, gameOpts->render.smoke.bSyncSizes ? -1 : gameOpts->render.smoke.nSize [3], 1, nLife * MSL_PART_LIFE, MSL_PART_SPEED, SMOKE_PARTICLES, i, smokeColors + 1, 1, -1)); } CalcThrusterPos (objP, &ti, 0); SetSmokePos (gameData.smoke.objects [i], ti.vPos, NULL, objP->info.nSegment); } else KillObjectSmoke (i); }
void DoStaticSmoke (tObject *objP) { int i, j, bBubbles = objP->rType.smokeInfo.nType == SMOKE_TYPE_BUBBLES; vmsVector pos, offs, dir; static tRgbaColorf defaultColors [2] = {{0.5f, 0.5f, 0.5f, 0.0f}, {0.8f, 0.9f, 1.0f, 1.0f}}; i = (int) OBJ_IDX (objP); if (!(SHOW_SMOKE && gameOpts->render.smoke.bStatic)) { if (gameData.smoke.objects [i] >= 0) KillObjectSmoke (i); return; } if (gameData.smoke.objects [i] < 0) { tRgbaColorf color; int bColor; color.red = (float) objP->rType.smokeInfo.color.red / 255.0f; color.green = (float) objP->rType.smokeInfo.color.green / 255.0f; color.blue = (float) objP->rType.smokeInfo.color.blue / 255.0f; if ((bColor = (color.red + color.green + color.blue > 0))) color.alpha = (float) -objP->rType.smokeInfo.color.alpha / 255.0f; dir = objP->info.position.mOrient [FVEC] * (objP->rType.smokeInfo.nSpeed * 2 * F1_0 / 55); SetSmokeObject (i, CreateSmoke (&objP->info.position.vPos, &dir, &objP->info.position.mOrient, objP->info.nSegment, 1, -objP->rType.smokeInfo.nParts, -PARTICLE_SIZE (objP->rType.smokeInfo.nSize [gameOpts->render.smoke.bDisperse], 2.0f), -1, 3, STATIC_SMOKE_PART_LIFE * objP->rType.smokeInfo.nLife, objP->rType.smokeInfo.nDrift, bBubbles ? BUBBLE_PARTICLES : SMOKE_PARTICLES, i, bColor ? &color : defaultColors + bBubbles, 1, objP->rType.smokeInfo.nSide - 1)); SetSmokeBrightness (gameData.smoke.objects [i], objP->rType.smokeInfo.nBrightness); } if (objP->rType.smokeInfo.nSide <= 0) { //don't vary emitter position for smoke emitting faces i = objP->rType.smokeInfo.nDrift >> 4; i += objP->rType.smokeInfo.nSize [0] >> 2; i /= 2; if (!(j = i - i / 2)) j = 2; i /= 2; offs [X] = (F1_0 / 4 - d_rand ()) * (d_rand () % j + i); offs [Y] = (F1_0 / 4 - d_rand ()) * (d_rand () % j + i); offs [Z] = (F1_0 / 4 - d_rand ()) * (d_rand () % j + i); pos = objP->info.position.vPos + offs; SetSmokePos (gameData.smoke.objects [i], &pos, NULL, objP->info.nSegment); }
void DoStaticSmoke (tObject *objP) { int i, j; vmsVector pos, offs, dir; i = (int) OBJ_IDX (objP); if (!(SHOW_SMOKE && gameOpts->render.smoke.bStatic)) { if (gameData.smoke.objects [i] >= 0) KillObjectSmoke (i); return; } if (gameData.smoke.objects [i] < 0) { tRgbaColorf color; int bColor; color.red = (float) objP->rType.smokeInfo.color.red / 255.0f; color.green = (float) objP->rType.smokeInfo.color.green / 255.0f; color.blue = (float) objP->rType.smokeInfo.color.blue / 255.0f; if ((bColor = (color.red + color.green + color.blue > 0))) color.alpha = (float) objP->rType.smokeInfo.color.alpha / 255.0f; VmVecCopyScale (&dir, &objP->position.mOrient.fVec, objP->rType.smokeInfo.nSpeed * 2 * F1_0 / 55); SetSmokeObject (i, CreateSmoke (&objP->position.vPos, &dir, NULL, objP->nSegment, 1, -objP->rType.smokeInfo.nParts, -PARTICLE_SIZE (objP->rType.smokeInfo.nSize [gameOpts->render.smoke.bDisperse], 2.0f), -1, 3, STATIC_SMOKE_PART_LIFE * objP->rType.smokeInfo.nLife, objP->rType.smokeInfo.nDrift, 2, i, bColor ? &color : NULL, 1, objP->rType.smokeInfo.nSide - 1)); SetSmokeBrightness (gameData.smoke.objects [i], objP->rType.smokeInfo.nBrightness); } if (objP->rType.smokeInfo.nSide <= 0) { //don't vary emitter position for smoke emitting faces i = objP->rType.smokeInfo.nDrift >> 4; i += objP->rType.smokeInfo.nSize [0] >> 2; i /= 2; if (!(j = i - i / 2)) j = 2; i /= 2; offs.p.x = (F1_0 / 4 - d_rand ()) * (d_rand () % j + i); offs.p.y = (F1_0 / 4 - d_rand ()) * (d_rand () % j + i); offs.p.z = (F1_0 / 4 - d_rand ()) * (d_rand () % j + i); VmVecAdd (&pos, &objP->position.vPos, &offs); SetSmokePos (gameData.smoke.objects [i], &pos, NULL, objP->nSegment); }
void DoPlayerSmoke (tObject *objP, int i) { int h, j, d, nParts, nType; float nScale; tCloud *pCloud; vmsVector fn, mn, vDir, *vDirP; tThrusterInfo ti; static int bForward = 1; if (i < 0) i = objP->info.nId; if ((gameData.multiplayer.players [i].flags & PLAYER_FLAGS_CLOAKED) || (gameStates.render.automap.bDisplay && IsMultiGame && !AM_SHOW_PLAYERS)) { KillObjectSmoke (i); return; } j = OBJ_IDX (objP); if (gameOpts->render.smoke.bDecreaseLag && (i == gameData.multiplayer.nLocalPlayer)) { fn = objP->info.position.mOrient[FVEC]; mn = objP->info.position.vPos - objP->info.vLastPos; vmsVector::Normalize(fn); vmsVector::Normalize(mn); d = vmsVector::Dot(fn, mn); if (d >= -F1_0 / 2) bForward = 1; else { if (bForward) { if ((h = gameData.smoke.objects [j]) >= 0) { KillObjectSmoke (j); DestroySmoke (h); } bForward = 0; nScale = 0; return; } } } #if 0 if (EGI_FLAG (bThrusterFlames, 1, 1, 0)) { if ((a <= F1_0 / 4) && (a || !gameStates.input.bControlsSkipFrame)) //no thruster flames if moving backward DropAfterburnerBlobs (objP, 2, I2X (1), -1, gameData.objs.consoleP, 1); //F1_0 / 4); } #endif if ((gameData.app.nGameMode & GM_NETWORK) && !gameData.multiplayer.players [i].connected) nParts = 0; else if (objP->info.nFlags & (OF_SHOULD_BE_DEAD | OF_DESTROYED)) nParts = 0; else if ((i == gameData.multiplayer.nLocalPlayer) && (gameStates.app.bPlayerIsDead || (gameData.multiplayer.players [i].shields < 0))) nParts = 0; else { h = X2IR (gameData.multiplayer.players [i].shields); nParts = 10 - h / 5; nScale = X2F (objP->info.xSize); if (h <= 25) nScale /= 1.5; else if (h <= 50) nScale /= 2; else nScale /= 3; if (nParts <= 0) { nType = 2; //nParts = (gameStates.entropy.nTimeLastMoved < 0) ? 250 : 125; } else { CreateDamageExplosion (nParts, j); nType = (h > 25); nParts *= 25; nParts += 75; } nParts = objP->mType.physInfo.thrust.IsZero() ? SHIP_MAX_PARTS : SHIP_MAX_PARTS / 2; if (SHOW_SMOKE && nParts && gameOpts->render.smoke.bPlayers) { if (gameOpts->render.smoke.bSyncSizes) { nParts = -MAX_PARTICLES (nParts, gameOpts->render.smoke.nDens [0]); nScale = PARTICLE_SIZE (gameOpts->render.smoke.nSize [0], nScale); } else { nParts = -MAX_PARTICLES (nParts, gameOpts->render.smoke.nDens [1]); nScale = PARTICLE_SIZE (gameOpts->render.smoke.nSize [1], nScale); } if (!objP->mType.physInfo.thrust.IsZero ()) vDirP = NULL; else { // if the ship is standing still, let the thruster smoke move away from it nParts /= 2; nScale /= 2; vDir = OBJPOS (objP)->mOrient [FVEC] * (F1_0 / 8); vDir = -vDir; vDirP = &vDir; } if (0 > (h = gameData.smoke.objects [j])) { //PrintLog ("creating tPlayer smoke\n"); h = SetSmokeObject (j, CreateSmoke (&objP->info.position.vPos, vDirP, NULL, objP->info.nSegment, 2, nParts, nScale, gameOpts->render.smoke.nSize [1], 2, PLR_PART_LIFE / (nType + 1) * (vDirP ? 2 : 1), PLR_PART_SPEED, SMOKE_PARTICLES, j, smokeColors + nType, 1, -1)); } else { if (vDirP) SetSmokeDir (h, vDirP); SetSmokeLife (h, PLR_PART_LIFE / (nType + 1) * (vDirP ? 2 : 1)); SetSmokeType (h, SMOKE_PARTICLES); SetSmokePartScale (h, -nScale); SetSmokeDensity (h, nParts, gameOpts->render.smoke.bSyncSizes ? -1 : gameOpts->render.smoke.nSize [1]); SetSmokeSpeed (gameData.smoke.objects [i], objP->mType.physInfo.thrust.IsZero () ? PLR_PART_SPEED * 2 : PLR_PART_SPEED); } CalcThrusterPos (objP, &ti, 0); for (j = 0; j < 2; j++) if ((pCloud = GetCloud (h, j))) SetCloudPos (pCloud, ti.vPos + j, NULL, objP->info.nSegment); DoGatlingSmoke (objP); return; } } KillObjectSmoke (i); KillGatlingSmoke (objP); }
int CParticle::Create (CFixVector *vPos, CFixVector *vDir, CFixMatrix *mOrient, short nSegment, int nLife, int nSpeed, char nParticleSystemType, char nClass, float nScale, tRgbaColorf *colorP, int nCurTime, int bBlowUp, float fBrightness, CFixVector *vEmittingFace) { static tRgbaColorf defaultColor = {1,1,1,1}; tRgbaColorf color; CFixVector vDrift; int nRad, nFrames, nType = particleImageManager.GetType (nParticleSystemType); if (nScale < 0) nRad = (int) -nScale; else if (gameOpts->render.particles.bSyncSizes) nRad = (int) PARTICLE_SIZE (gameOpts->render.particles.nSize [0], nScale); else nRad = (int) nScale; if (!nRad) nRad = I2X (1); m_nType = nType; m_bEmissive = (nParticleSystemType == LIGHT_PARTICLES); m_nClass = nClass; m_nSegment = nSegment; m_nBounce = 0; color = colorP ? *colorP : defaultColor; m_color [0] = m_color [1] = color; if ((nType == BULLET_PARTICLES) || (nType == BUBBLE_PARTICLES)) { m_bBright = 0; m_nFade = -1; } else { m_bBright = (nType == SMOKE_PARTICLES) ? (rand () % 50) == 0 : 0; if (colorP) { if (nType != LIGHT_PARTICLES) { m_color [0].red *= RANDOM_FADE; m_color [0].green *= RANDOM_FADE; m_color [0].blue *= RANDOM_FADE; } m_nFade = 0; } else { m_color [0].red = 1.0f; m_color [0].green = 0.5f; m_color [0].blue = 0.0f; m_nFade = 2; } if (m_bEmissive) m_color [0].alpha = (float) (SMOKE_START_ALPHA + 64) / 255.0f; else if (nParticleSystemType != GATLING_PARTICLES) { if (!colorP) m_color [0].alpha = (float) (SMOKE_START_ALPHA + randN (64)) / 255.0f; else { if (colorP->alpha < 0) m_color [0].alpha = -colorP->alpha; else { if (2 == (m_nFade = (char) colorP->alpha)) { m_color [0].red = 1.0f; m_color [0].green = 0.5f; m_color [0].blue = 0.0f; } m_color [0].alpha = (float) (SMOKE_START_ALPHA + randN (64)) / 255.0f; } } } #if 1 if (gameOpts->render.particles.bDisperse && !m_bBright) { fBrightness = 1.0f - fBrightness; m_color [0].alpha += fBrightness * fBrightness / 8.0f; } #endif } //nSpeed = (int) (sqrt (nSpeed) * (float) I2X (1)); nSpeed *= I2X (1); if (vDir) { CAngleVector a; CFixMatrix m; float d; a [PA] = randN (I2X (1) / 4) - I2X (1) / 8; a [BA] = randN (I2X (1) / 4) - I2X (1) / 8; a [HA] = randN (I2X (1) / 4) - I2X (1) / 8; m = CFixMatrix::Create (a); vDrift = m * (*vDir); CFixVector::Normalize (vDrift); d = (float) CFixVector::DeltaAngle (vDrift, *vDir, NULL); if (d) { d = (float) exp ((I2X (1) / 8) / d); nSpeed = (fix) ((float) nSpeed / d); } #if 0 if (!colorP) // hack for static particleSystem w/o user defined color m_color [0].green = m_color [0].blue = 1.0f; #endif vDrift *= nSpeed; if ((nType == SMOKE_PARTICLES) || (nType == BUBBLE_PARTICLES)) m_vDir = *vDir * (I2X (3) / 4 + I2X (randN (16)) / 64); else m_vDir = *vDir; m_bHaveDir = 1; } else { CFixVector vOffs; vDrift [X] = nSpeed - randN (2 * nSpeed); vDrift [Y] = nSpeed - randN (2 * nSpeed); vDrift [Z] = nSpeed - randN (2 * nSpeed); vOffs = vDrift; m_vDir.SetZero (); m_bHaveDir = 1; } m_vDrift = vDrift; if (vEmittingFace) m_vPos = *RandomPointOnQuad (vEmittingFace, vPos); else if (nType != BUBBLE_PARTICLES) m_vPos = *vPos + vDrift * (I2X (1) / 64); else { //m_vPos = *vPos + vDrift * (I2X (1) / 32); nSpeed = vDrift.Mag () / 16; vDrift = CFixVector::Avg ((*mOrient).RVec () * (nSpeed - randN (2 * nSpeed)), (*mOrient).UVec () * (nSpeed - randN (2 * nSpeed))); m_vPos = *vPos + vDrift + (*mOrient).FVec () * (I2X (1) / 2 - randN (I2X (1))); #if 1 m_vDrift.SetZero (); #else CFixVector::Normalize (m_vDrift); m_vDrift *= I2X (32); #endif } if ((nType != BUBBLE_PARTICLES) && mOrient) { CAngleVector vRot; CFixMatrix mRot; vRot [BA] = 0; vRot [PA] = 2048 - ((d_rand () % 9) * 512); vRot [HA] = 2048 - ((d_rand () % 9) * 512); mRot = CFixMatrix::Create (vRot); m_mOrient = *mOrient * mRot; } if (nLife < 0) nLife = -nLife; if (nType == SMOKE_PARTICLES) { if (gameOpts->render.particles.bDisperse) nLife = (nLife * 2) / 3; nLife = nLife / 2 + randN (nLife / 2); } m_nLife = m_nTTL = nLife; m_nMoved = nCurTime; m_nDelay = 0; //bStart ? randN (nLife) : 0; if (nType == SMOKE_PARTICLES) nRad += randN (nRad); else if (nType == BUBBLE_PARTICLES) nRad = nRad / 10 + randN (9 * nRad / 10); else nRad *= 2; if ((m_bBlowUp = bBlowUp)) { m_nRad = nRad / 2; m_nWidth = m_nHeight = m_nRad; m_nRad += m_nRad / bBlowUp; } else { m_nWidth = m_nHeight = nRad; m_nRad = nRad / 2; } nFrames = nParticleFrames [0][nType]; if (nType == BULLET_PARTICLES) { m_nFrame = 0; m_nRotFrame = 0; m_nOrient = 3; } else if (nType == BUBBLE_PARTICLES) { m_nFrame = rand () % (nFrames * nFrames); m_nRotFrame = 0; m_nOrient = 0; } else if (nType == LIGHT_PARTICLES) { m_nFrame = 0; m_nRotFrame = 0; m_nOrient = 0; } else { m_nFrame = rand () % (nFrames * nFrames); m_nRotFrame = m_nFrame / 2; m_nOrient = rand () % 4; } #if 1 if (m_bEmissive) m_color [0].alpha *= ParticleBrightness (colorP); else if (nParticleSystemType == SMOKE_PARTICLES) m_color [0].alpha /= colorP ? color.red + color.green + color.blue + 2 : 2; else if (nParticleSystemType == BUBBLE_PARTICLES) m_color [0].alpha /= 2; else if (nParticleSystemType == LIGHT_PARTICLES) m_color [0].alpha /= 5; # if 0 else if (nParticleSystemType == GATLING_PARTICLES) ;//m_color [0].alpha /= 6; # endif #endif return 1; }
int CParticle::Create (CFixVector *vPos, CFixVector *vDir, CFixMatrix *mOrient, short nSegment, int nLife, int nSpeed, char nParticleSystemType, char nClass, float nScale, tRgbaColorf *colorP, int nCurTime, int bBlowUp, char nFadeType, float fBrightness, CFixVector *vEmittingFace) { tRgbaColorf color; int nType = particleImageManager.GetType (nParticleSystemType); m_bChecked = 0; m_bBlowUp = bBlowUp && gameOpts->render.particles.bDisperse; if (nScale < 0) m_nRad = float (-nScale); else if (gameOpts->render.particles.bSyncSizes) m_nRad = float (PARTICLE_SIZE (gameOpts->render.particles.nSize [0], nScale, m_bBlowUp)); else m_nRad = float (nScale); if (!m_nRad) m_nRad = 1.0f; m_nType = nType; m_bEmissive = (nParticleSystemType == LIGHT_PARTICLES) ? 1 : (nParticleSystemType == FIRE_PARTICLES) ? 2 : 0; m_nClass = nClass; m_nFadeType = nFadeType; m_nSegment = nSegment; m_nBounce = ((m_nType == BUBBLE_PARTICLES) || (m_nType == WATERFALL_PARTICLES)) ? 1 : 2; m_bReversed = 0; m_nMoved = nCurTime; if (nLife < 0) nLife = -nLife; m_nLife = nLife; m_nDelay = 0; //bStart ? randN (nLife) : 0; m_color [0] = m_color [1] = color = (colorP && (m_bEmissive < 2)) ? *colorP : defaultParticleColor; if ((nType == BULLET_PARTICLES) || (nType == BUBBLE_PARTICLES)) { m_bBright = 0; m_nFadeState = -1; } else { m_bBright = (nType <= SMOKE_PARTICLES) ? (rand () % 50) == 0 : 0; if (colorP) { if (!m_bEmissive) { m_color [0].red *= RANDOM_FADE; m_color [0].green *= RANDOM_FADE; m_color [0].blue *= RANDOM_FADE; } m_nFadeState = 0; } else { m_color [0].red = 1.0f; m_color [0].green = 0.5f; m_color [0].blue = 0.0f; m_nFadeState = 2; } if (m_bEmissive) m_color [0].alpha = float (SMOKE_START_ALPHA + 64) / 255.0f; else if (nParticleSystemType != GATLING_PARTICLES) { if (!colorP) m_color [0].alpha = float (3 * SMOKE_START_ALPHA / 4 + randN (SMOKE_START_ALPHA / 2)) / 255.0f; else { if (colorP->alpha < 0) { ubyte a = ubyte (-colorP->alpha * 255.0f * 0.25f + 0.5f); m_color [0].alpha = float (3 * a + randN (2 * a)) / 255.0f; } else { if (2 == (m_nFadeState = char (colorP->alpha))) { m_color [0].red = 1.0f; m_color [0].green = 0.5f; m_color [0].blue = 0.0f; } m_color [0].alpha = float (3 * SMOKE_START_ALPHA / 4 + randN (SMOKE_START_ALPHA / 2)) / 255.0f; } } if (m_bBlowUp && !m_bBright) { fBrightness = 1.0f - fBrightness; m_color [0].alpha += fBrightness * fBrightness / 8.0f; } } } #if 0 if (nType == FIRE_PARTICLES) nSpeed = int (sqrt (double (nSpeed)) * float (I2X (1))); else #endif nSpeed *= I2X (1); if (!vDir) { m_vDrift [X] = nSpeed - randN (2 * nSpeed); m_vDrift [Y] = nSpeed - randN (2 * nSpeed); m_vDrift [Z] = nSpeed - randN (2 * nSpeed); m_vDir.SetZero (); m_bHaveDir = 1; } else { m_vDir = *vDir; CAngleVector a; CFixMatrix m; a [PA] = randN (I2X (1) / 4) - I2X (1) / 8; a [BA] = randN (I2X (1) / 4) - I2X (1) / 8; a [HA] = randN (I2X (1) / 4) - I2X (1) / 8; m = CFixMatrix::Create (a); if (nType == WATERFALL_PARTICLES) CFixVector::Normalize (m_vDir); m_vDrift = m * m_vDir; CFixVector::Normalize (m_vDrift); if (nType == WATERFALL_PARTICLES) { fix dot = CFixVector::Dot (m_vDir, m_vDrift); if (dot < I2X (1) / 2) return 0; } float d = float (CFixVector::DeltaAngle (m_vDrift, m_vDir, NULL)); if (d) { d = (float) exp ((I2X (1) / 8) / d); nSpeed = (fix) ((float) nSpeed / d); } m_vDrift *= nSpeed; if (nType <= FIRE_PARTICLES) m_vDir *= (I2X (3) / 4 + I2X (randN (16)) / 64); #if DBG if (CFixVector::Dot (m_vDrift, m_vDir) < 0) d = 0; #endif m_bHaveDir = 1; } if (vEmittingFace) m_vPos = *RandomPointOnQuad (vEmittingFace, vPos); else if (nType != BUBBLE_PARTICLES) m_vPos = *vPos + m_vDrift * (I2X (1) / 64); else { //m_vPos = *vPos + vDrift * (I2X (1) / 32); nSpeed = m_vDrift.Mag () / 16; CFixVector v = CFixVector::Avg ((*mOrient).RVec () * (nSpeed - randN (2 * nSpeed)), (*mOrient).UVec () * (nSpeed - randN (2 * nSpeed))); m_vPos = *vPos + v + (*mOrient).FVec () * (I2X (1) / 2 - randN (I2X (1))); } if ((nType != BUBBLE_PARTICLES) && mOrient) { CAngleVector vRot; CFixMatrix mRot; vRot [BA] = 0; vRot [PA] = 2048 - ((d_rand () % 9) * 512); vRot [HA] = 2048 - ((d_rand () % 9) * 512); mRot = CFixMatrix::Create (vRot); m_mOrient = *mOrient * mRot; } if (nType <= SMOKE_PARTICLES) { if (m_bBlowUp) m_nLife = 2 * m_nLife / 3; m_nLife = 4 * m_nLife / 5 + randN (2 * m_nLife / 5); m_nRad += float (randN (int (m_nRad))); } else if (nType == FIRE_PARTICLES) { m_nLife = 3 * m_nLife / 4 + randN (m_nLife / 4); m_nRad += float (randN (int (m_nRad))); } else if (nType == BUBBLE_PARTICLES) m_nRad = m_nRad / 10 + float (randN (int (9 * m_nRad / 10))); else m_nRad *= 2; //m_nRad *= 0.5f; m_vStartPos = m_vPos; if (m_bBlowUp) { m_nWidth = (nType == WATERFALL_PARTICLES) ? m_nRad * 0.6666667f : m_nRad; m_nHeight = m_nRad; } else { m_nWidth = (nType == WATERFALL_PARTICLES) ? m_nRad * 0.3333333f : m_nRad * 2; m_nHeight = m_nRad * 2; } m_nWidth /= 65536.0f; m_nHeight /= 65536.0f; m_nRad /= 65536.0f; m_nFrames = ParticleImageInfo (nType).nFrames; m_deltaUV = 1.0f / float (m_nFrames); if (nType == BULLET_PARTICLES) { m_iFrame = 0; m_nRotFrame = 0; m_nOrient = 3; } else if (nType == BUBBLE_PARTICLES) { m_iFrame = rand () % (m_nFrames * m_nFrames); m_nRotFrame = 0; m_nOrient = 0; } else if ((nType == LIGHT_PARTICLES) /*|| (nType == WATERFALL_PARTICLES)*/) { m_iFrame = 0; m_nRotFrame = 0; m_nOrient = 0; } else if (nType == FIRE_PARTICLES) { m_iFrame = (rand () % 10 < 6) ? 0 : 2; // more fire than smoke (60:40) if (m_iFrame < 2) m_nLife = 9 * m_nLife / 10; else m_nLife = 10 * m_nLife / 9; m_nRotFrame = rand () % PARTICLE_POSITIONS; m_nOrient = rand () % 4; } else { m_iFrame = rand () % (m_nFrames * m_nFrames); m_nRotFrame = rand () % PARTICLE_POSITIONS; m_nOrient = rand () % 4; #if 1 #endif } m_nTTL = m_nLife; m_nRenderType = RenderType (); m_bAnimate = (nType != FIRE_PARTICLES) && (gameOpts->render.particles.nQuality > 1) && (m_nFrames > 1); m_bRotate = (m_nRenderType <= SMOKE_PARTICLES) ? 1 : (m_nRenderType == FIRE_PARTICLES + PARTICLE_TYPES) ? -1 : 0; UpdateDecay (); UpdateTexCoord (); #if 0 if (colorP && (colorP->alpha < 0)) m_color [0].alpha /= 2.0f; else #endif { if (m_bEmissive) m_color [0].alpha = 1.0f; else if (nParticleSystemType == SIMPLE_SMOKE_PARTICLES) m_color [0].alpha /= 3.5f - float (gameOpts->render.particles.nQuality) / 2.0f; //colorP ? 2.0f + (color.red + color.green + color.blue) / 3.0f : 2.0f; else if (nParticleSystemType == SMOKE_PARTICLES) m_color [0].alpha /= colorP ? 3.0f - (color.red + color.green + color.blue) / 3.0f : 2.5f; else if (nParticleSystemType == BUBBLE_PARTICLES) m_color [0].alpha /= 2.0f; else if (nParticleSystemType == GATLING_PARTICLES) m_color [0].alpha /= 4.0f; # if 0 else if (nParticleSystemType == GATLING_PARTICLES) ;//m_color [0].alpha /= 6; # endif } SetupColor (fBrightness); return 1; }
void DoPlayerSmoke (CObject *objP, int nPlayer) { int nObject, nSmoke, d, nParts, nType; float nScale; CParticleEmitter *emitterP; CFixVector fn, mn, vDir, *vDirP; tThrusterInfo ti; static int bForward = 1; if (nPlayer < 0) nPlayer = objP->info.nId; if ((gameData.multiplayer.players [nPlayer].flags & PLAYER_FLAGS_CLOAKED) || (automap.m_bDisplay && IsMultiGame && !AM_SHOW_PLAYERS)) { KillObjectSmoke (nPlayer); return; } nObject = objP->Index (); if (gameOpts->render.particles.bDecreaseLag && (nPlayer == gameData.multiplayer.nLocalPlayer)) { fn = objP->info.position.mOrient.FVec (); mn = objP->info.position.vPos - objP->info.vLastPos; CFixVector::Normalize (fn); CFixVector::Normalize (mn); d = CFixVector::Dot (fn, mn); if (d >= -I2X (1) / 2) bForward = 1; else { if (bForward) { if ((nSmoke = particleManager.GetObjectSystem (nObject)) >= 0) { KillObjectSmoke (nObject); particleManager.Destroy (nSmoke); } bForward = 0; nScale = 0; return; } } } #if 0 if (EGI_FLAG (bThrusterFlames, 1, 1, 0)) { if ((a <= I2X (1) / 4) && (a || !gameStates.input.bControlsSkipFrame)) //no thruster flames if moving backward DropAfterburnerBlobs (objP, 2, I2X (1), -1, gameData.objs.consoleP, 1); //I2X (1) / 4); } #endif if ((gameData.app.nGameMode & GM_NETWORK) && !gameData.multiplayer.players [nPlayer].connected) nParts = 0; else if (objP->info.nFlags & (OF_SHOULD_BE_DEAD | OF_DESTROYED)) nParts = 0; else if ((nPlayer == gameData.multiplayer.nLocalPlayer) && (gameStates.app.bPlayerIsDead || (gameData.multiplayer.players [nPlayer].shields < 0))) nParts = 0; else { nSmoke = X2IR (gameData.multiplayer.players [nPlayer].shields); nParts = 10 - nSmoke / 5; nScale = X2F (objP->info.xSize); if (nSmoke <= 25) nScale /= 1.5; else if (nSmoke <= 50) nScale /= 2; else nScale /= 3; if (nParts <= 0) { nType = 2; //nParts = (gameStates.entropy.nTimeLastMoved < 0) ? 250 : 125; } else { CreateDamageExplosion (nParts, nObject); nType = (nSmoke > 25); nParts *= 25; nParts += 75; } nParts = objP->mType.physInfo.thrust.IsZero () ? SHIP_MAX_PARTS : SHIP_MAX_PARTS / 2; if (SHOW_SMOKE && nParts && gameOpts->render.particles.bPlayers) { if (gameOpts->render.particles.bSyncSizes) { nParts = -MAX_PARTICLES (nParts, gameOpts->render.particles.nDens [0]); nScale = PARTICLE_SIZE (gameOpts->render.particles.nSize [0], nScale); } else { nParts = -MAX_PARTICLES (nParts, gameOpts->render.particles.nDens [1]); nScale = PARTICLE_SIZE (gameOpts->render.particles.nSize [1], nScale); } if (!objP->mType.physInfo.thrust.IsZero ()) vDirP = NULL; else { // if the ship is standing still, let the thruster smoke move away from it nParts /= 2; nScale /= 2; vDir = OBJPOS (objP)->mOrient.FVec () * (I2X (1) / 8); vDir = -vDir; vDirP = &vDir; } if (0 > (nSmoke = particleManager.GetObjectSystem (nObject))) { //PrintLog ("creating CPlayerData smoke\n"); nSmoke = particleManager.Create (&objP->info.position.vPos, vDirP, NULL, objP->info.nSegment, 2, nParts, nScale, gameOpts->render.particles.nSize [1], 2, PLR_PART_LIFE / (nType + 1) * (vDirP ? 2 : 1), PLR_PART_SPEED, SMOKE_PARTICLES, nObject, smokeColors + nType, 1, -1); if (nSmoke < 0) return; particleManager.SetObjectSystem (nObject, nSmoke); } else { if (vDirP) particleManager.SetDir (nSmoke, vDirP); particleManager.SetLife (nSmoke, PLR_PART_LIFE / (nType + 1) * (vDirP ? 2 : 1)); particleManager.SetType (nSmoke, SMOKE_PARTICLES); particleManager.SetScale (nSmoke, -nScale); particleManager.SetDensity (nSmoke, nParts, gameOpts->render.particles.bSyncSizes ? -1 : gameOpts->render.particles.nSize [1]); particleManager.SetSpeed (particleManager.GetObjectSystem (nObject), objP->mType.physInfo.thrust.IsZero () ? PLR_PART_SPEED * 2 : PLR_PART_SPEED); } CalcThrusterPos (objP, &ti, 0); for (int i = 0; i < 2; i++) if ((emitterP = particleManager.GetEmitter (nSmoke, i))) emitterP->SetPos (ti.vPos + i, NULL, objP->info.nSegment); DoGatlingSmoke (objP); return; } } KillObjectSmoke (nObject); KillGatlingSmoke (objP); }
void DoPlayerSmoke (tObject *objP, int i) { int h, j, d, nParts, nType; float nScale; tCloud *pCloud; vmsVector fn, mn; tThrusterInfo ti; static int bForward = 1; if (i < 0) i = objP->id; if ((gameData.multiplayer.players [i].flags & PLAYER_FLAGS_CLOAKED) || (gameStates.render.automap.bDisplay && IsMultiGame && !AM_SHOW_PLAYERS)) { KillObjectSmoke (i); return; } j = OBJ_IDX (objP); if (gameOpts->render.smoke.bDecreaseLag && (i == gameData.multiplayer.nLocalPlayer)) { fn = objP->position.mOrient.fVec; VmVecSub (&mn, &objP->position.vPos, &objP->vLastPos); VmVecNormalize (&fn); VmVecNormalize (&mn); d = VmVecDot (&fn, &mn); if (d >= -F1_0 / 2) bForward = 1; else { if (bForward) { if ((h = gameData.smoke.objects [j]) >= 0) { KillObjectSmoke (i); DestroySmoke (h); } bForward = 0; nScale = 0; return; } } } #if 0 if (EGI_FLAG (bThrusterFlames, 1, 1, 0)) { if ((a <= F1_0 / 4) && (a || !gameStates.input.bControlsSkipFrame)) //no thruster flames if moving backward DropAfterburnerBlobs (objP, 2, i2f (1), -1, gameData.objs.console, 1); //F1_0 / 4); } #endif if ((gameData.app.nGameMode & GM_NETWORK) && !gameData.multiplayer.players [i].connected) nParts = 0; else if (objP->flags & (OF_SHOULD_BE_DEAD | OF_DESTROYED)) nParts = 0; else if ((i == gameData.multiplayer.nLocalPlayer) && (gameStates.app.bPlayerIsDead || (gameData.multiplayer.players [i].shields < 0))) nParts = 0; else { h = f2ir (gameData.multiplayer.players [i].shields); nParts = 10 - h / 5; nScale = f2fl (objP->size); if (h <= 25) nScale /= 1.5; else if (h <= 50) nScale /= 2; else nScale /= 3; if (nParts <= 0) { nType = 2; //nParts = (gameStates.entropy.nTimeLastMoved < 0) ? 250 : 125; } else { CreateDamageExplosion (nParts, j); nType = (h > 25); nParts *= 25; nParts += 75; } nParts = (gameStates.entropy.nTimeLastMoved < 0) ? SHIP_MAX_PARTS * 2 : SHIP_MAX_PARTS; if (SHOW_SMOKE && nParts && gameOpts->render.smoke.bPlayers) { if (gameOpts->render.smoke.bSyncSizes) { nParts = -MAX_PARTICLES (nParts, gameOpts->render.smoke.nDens [0]); nScale = PARTICLE_SIZE (gameOpts->render.smoke.nSize [0], nScale); } else { nParts = -MAX_PARTICLES (nParts, gameOpts->render.smoke.nDens [1]); nScale = PARTICLE_SIZE (gameOpts->render.smoke.nSize [1], nScale); } if (!(objP->mType.physInfo.thrust.p.x || objP->mType.physInfo.thrust.p.y || objP->mType.physInfo.thrust.p.z)) { nParts /= 2; nScale /= 2; } if (0 > (h = gameData.smoke.objects [j])) { //PrintLog ("creating tPlayer smoke\n"); h = SetSmokeObject (j, CreateSmoke (&objP->position.vPos, NULL, NULL, objP->nSegment, 2, nParts, nScale, gameOpts->render.smoke.nSize [1], 2, PLR_PART_LIFE / (nType + 1), PLR_PART_SPEED, nType, j, NULL, 1, -1)); } else { SetSmokeType (h, nType); SetSmokePartScale (h, -nScale); SetSmokeDensity (h, nParts, gameOpts->render.smoke.bSyncSizes ? -1 : gameOpts->render.smoke.nSize [1]); SetSmokeSpeed (gameData.smoke.objects [i], (objP->mType.physInfo.velocity.p.x || objP->mType.physInfo.velocity.p.y || objP->mType.physInfo.velocity.p.z) ? PLR_PART_SPEED : PLR_PART_SPEED * 2); } CalcThrusterPos (objP, &ti, 0); for (j = 0; j < 2; j++) if ((pCloud = GetCloud (h, j))) SetCloudPos (pCloud, ti.vPos + j, NULL, objP->nSegment); return; } } KillObjectSmoke (i); }