/* =============== R_ColoredParticleExplosion =============== */ void R_ColoredParticleExplosion (vec3_t org,int color,int radius,int counter) { int i, j; particle_t *p; for (i=0 ; i<counter ; i++) { p = AllocParticle(); if (!p) return; p->die = cl.time + 3; p->color = color; p->ramp = (rand()&3); if (i & 1) { p->type = pt_c_explode; for (j=0 ; j<3 ; j++) { p->org[j] = org[j] + ((rand()%(radius*2))-radius); p->vel[j] = (rand()&511)-256; } } else { p->type = pt_c_explode2; for (j=0 ; j<3 ; j++) { p->org[j] = org[j] + ((rand()%(radius*2))-radius); p->vel[j] = (rand()&511)-256; } } } }
/* =============== R_RunQuakeEffect =============== */ void R_RunQuakeEffect (vec3_t org, float distance) { int i, j; particle_t *p; float num,num2; for (i=0 ; i<100 ; i++) { p = AllocParticle(); if (!p) return; p->die = cl.time + 0.3*(rand()%5); p->color = (rand() &3) + ((rand() % 3)*16) + (13 * 16) + 256 + 11; p->type = pt_quake; p->ramp = 0; num = rand()*(1.0/RAND_MAX);//(rand ()&0x7fff) / ((float)0x7fff); num2 = distance * num; num = rand()*(1.0/RAND_MAX);//(rand ()&0x7fff) / ((float)0x7fff); p->org[0] = org[0] + cos(num * 2 * M_PI)*num2; p->org[1] = org[1] + sin(num * 2 * M_PI)*num2; num = rand()*(1.0/RAND_MAX);//(rand ()&0x7fff) / ((float)0x7fff); p->org[2] = org[2] + 15*num; p->org[2] = org[2]; num = rand()*(1.0/RAND_MAX);//(rand ()&0x7fff) / ((float)0x7fff); p->vel[0] = (num * 40) - 20; num = rand()*(1.0/RAND_MAX);//(rand ()&0x7fff) / ((float)0x7fff); p->vel[1] = (num * 40) - 20; num = rand()*(1.0/RAND_MAX);//(rand ()&0x7fff) / ((float)0x7fff); p->vel[2] = 65*num + 80; } }
/* =============== R_TeleportSplash =============== */ void R_TeleportSplash (vec3_t org) { int i, j, k; particle_t *p; float vel; vec3_t dir; for (i=-16 ; i<16 ; i+=4) for (j=-16 ; j<16 ; j+=4) for (k=-24 ; k<32 ; k+=4) { p = AllocParticle(); if (!p) return; p->die = cl.time + 0.2 + (rand()&7) * 0.02; p->color = 7 + (rand()&7); p->type = pt_slowgrav; dir[0] = j*8; dir[1] = i*8; dir[2] = k*8; p->org[0] = org[0] + i + (rand()&3); p->org[1] = org[1] + j + (rand()&3); p->org[2] = org[2] + k + (rand()&3); VectorNormalize (dir); vel = 50 + (rand()&63); VectorScale (dir, vel, p->vel); } }
/* =============== R_RunParticleEffect4 =============== */ void R_RunParticleEffect4 (vec3_t org, float radius, int color, int effect, int count) { int i, j; particle_t *p; float num; for (i=0 ; i<count ; i++) { p = AllocParticle(); if (!p) { return; } // p->die = cl.time + 0.1*(rand()%5); p->die = cl.time + 2;//0.1*(rand()%5); p->color = color; p->type = effect; p->ramp = 0; for (j=0 ; j<3 ; j++) { num = rand()*(1.0/RAND_MAX);//(rand ()&0x7fff) / ((float)0x7fff); p->org[j] = org[j] + ((rand()&15)-8); p->vel[j] = (radius * num * 2) - radius; } } }
/* =============== R_LavaSplash =============== */ void R_LavaSplash (vec3_t org) { int i, j, k; particle_t *p; float vel; vec3_t dir; for (i=-16 ; i<16 ; i++) for (j=-16 ; j<16 ; j++) for (k=0 ; k<1 ; k++) { p = AllocParticle(); if (!p) return; p->die = cl.time + 2 + (rand()&31) * 0.02; p->color = 224 + (rand()&7); p->type = pt_slowgrav; dir[0] = j*8 + (rand()&7); dir[1] = i*8 + (rand()&7); dir[2] = 256; p->org[0] = org[0] + dir[0]; p->org[1] = org[1] + dir[1]; p->org[2] = org[2] + (rand()&63); VectorNormalize (dir); vel = 50 + (rand()&63); VectorScale (dir, vel, p->vel); } }
/* =============== R_RainEffect =============== */ void R_RainEffect (vec3_t org, vec3_t e_size, int x_dir, int y_dir, int color, int count) { int i, holdint; particle_t *p; float z_time; for (i = 0; i < count; i++) { p = AllocParticle(); if (!p) return; p->vel[0] = x_dir; // X and Y motion p->vel[1] = y_dir; p->vel[2] = -(rand() % 956); if (p->vel[2] > -256) { p->vel[2] += -256; } z_time = -(e_size[2]/p->vel[2]); p->die = cl.time + z_time; p->color = color; p->ramp = rand() & 3; //p->veer = veer; p->type = pt_rain; holdint = e_size[0]; p->org[0] = org[0] + (rand() % holdint); holdint = e_size[1]; p->org[1] = org[1] + (rand() % holdint); p->org[2] = org[2]; } }
/* =============== R_RunParticleEffect2 =============== */ void R_RunParticleEffect2 (vec3_t org, vec3_t dmin, vec3_t dmax, int color, int effect, int count) { int i, j; particle_t *p; float num; for (i=0 ; i<count ; i++) { p = AllocParticle(); if (!p) return; // p->die = cl.time + 0.1*(rand()%5); p->die = cl.time + 2;//0.1*(rand()%5); p->color = color; p->type = effect; p->ramp = 0; for (j=0 ; j<3 ; j++) { num = rand()*(1.0/RAND_MAX);//(rand ()&0x7fff) / ((float)0x7fff); p->org[j] = org[j] + ((rand()&8)-4); //added randomness to org p->vel[j] = dmin[j] + ((dmax[j] - dmin[j]) * num); } } }
void RiderParticle(int count, vec3_t origin) { int i, j; particle_t *p; float num; float radius,angle; VectorCopy(origin, rider_origin); for (i=0 ; i<count ; i++) { p = AllocParticle(); if (!p) return; p->die = cl.time + 4; p->color = 256+16+15; p->type = pt_rd; p->ramp = 0; VectorCopy(origin,p->org); //num = (rand ()&0x7fff) / ((float)0x7fff); angle = (rand() % 360) / (2 * M_PI); radius = 300 + rand() & 255; p->org[0] += sin(angle) * radius; p->org[1] += cos(angle) * radius; p->org[2] += (rand() & 255) - 30; p->vel[0] = (rand() & 255) - 127; p->vel[1] = (rand() & 255) - 127; p->vel[2] = (rand() & 255) - 127; } }
/* =============== R_ParticleExplosion =============== */ void R_ParticleExplosion (vec3_t org) { int i, j; particle_t *p; for (i=0 ; i<1024 ; i++) { p = AllocParticle(); if (!p) return; p->die = cl.time + 5; p->color = ramp1[0]; p->ramp = rand()&3; if (i & 1) { p->type = pt_explode; for (j=0 ; j<3 ; j++) { p->org[j] = org[j] + ((rand()&31)-16); p->vel[j] = (rand()&511)-256; } } else { p->type = pt_explode2; for (j=0 ; j<3 ; j++) { p->org[j] = org[j] + ((rand()&31)-16); p->vel[j] = (rand()&511)-256; } } } }
/* =============== R_RunParticleEffect3 =============== */ void R_RunParticleEffect3 (vec3_t org, vec3_t box, int color, ptype_t effect, int count) { int i, j; particle_t *p; float num; for (i = 0; i < count; i++) { p = AllocParticle(); if (!p) return; // p->die = cl.time + 0.1 * (rand() % 5); p->die = cl.time + 2; p->color = color; p->type = effect; p->ramp = 0; for (j = 0; j < 3; j++) { // num = (rand() & 0x7fff) / ((float)0x7fff); num = rand() * (1.0 / RAND_MAX); p->org[j] = org[j] + ((rand() & 15) - 8); p->vel[j] = (box[j] * num * 2) - box[j]; } } }
/* =============== R_BlobExplosion tarbaby explosion =============== */ void R_BlobExplosion (vec3_t org) { int i, j; particle_t *p; for (i = 0; i < 1024; i++) { p = AllocParticle(); if (!p) return; p->die = cl.time + 1 + (rand() & 8) * 0.05; if (i & 1) { p->type = pt_blob; p->color = 66 + (rand() % 6); for (j = 0; j < 3; j++) { p->org[j] = org[j] + ((rand() & 31) - 16); p->vel[j] = (rand() & 511) - 256; } } else { p->type = pt_blob2; p->color = 150 + (rand() % 6); for (j = 0; j < 3; j++) { p->org[j] = org[j] + ((rand() & 31) - 16); p->vel[j] = (rand() & 511) - 256; } } } }
void GravityWellParticle(int count, vec3_t origin, int color) { int i, j; particle_t *p; float num; float radius,angle; VectorCopy(origin, rider_origin); for (i=0 ; i<count ; i++) { p = AllocParticle(); if (!p) return; p->die = cl.time + 4; p->color = color + (rand() & 15); p->type = pt_gravwell; p->ramp = 0; VectorCopy(origin,p->org); angle = (rand() % 360) / (2 * M_PI); radius = 300 + rand() & 255; p->org[0] += sin(angle) * radius; p->org[1] += cos(angle) * radius; p->org[2] += (rand() & 255) - 30; p->vel[0] = (rand() & 255) - 127; p->vel[1] = (rand() & 255) - 127; p->vel[2] = (rand() & 255) - 127; } }
/* =============== R_RunParticleEffect =============== */ void R_RunParticleEffect (vec3_t org, vec3_t dir, int color, int count) { int i, j; particle_t *p; for (i=0 ; i<count ; i++) { p = AllocParticle(); if (!p) return; if (count == 1024) { // rocket explosion p->die = cl.time + 5; p->color = ramp1[0]; p->ramp = rand()&3; if (i & 1) { p->type = pt_explode; for (j=0 ; j<3 ; j++) { p->org[j] = org[j] + ((rand()&31)-16); p->vel[j] = (rand()&511)-256; } } else { p->type = pt_explode2; for (j=0 ; j<3 ; j++) { p->org[j] = org[j] + ((rand()&31)-16); p->vel[j] = (rand()&511)-256; } } } else { p->die = cl.time + 0.1*(rand()%5); // p->color = (color&~7) + (rand()&7); // p->color = 265 + (rand() % 9); p->color = 256 + 16 + 12 + (rand() & 3); p->type = pt_slowgrav; for (j=0 ; j<3 ; j++) { p->org[j] = org[j] + ((rand()&15)-8); p->vel[j] = dir[j]*15;// + (rand()%300)-150; } } } }
void R_ReadPointFile_f (void) { FILE *f; vec3_t org; int r; int c; particle_t *p; char name[MAX_QPATH]; byte color; if (cls.state != ca_connected) return; // need an active map. color = (byte)Cvar_VariableValue("leak_color"); q_snprintf (name, sizeof(name), "maps/%s.pts", cl.mapname); FS_OpenFile (name, &f, NULL); if (!f) { Con_Printf ("couldn't open %s\n", name); return; } Con_Printf ("Reading %s...\n", name); c = 0; VectorClear (org); // silence pesky compiler warnings for ( ;; ) { r = fscanf (f,"%f %f %f\n", &org[0], &org[1], &org[2]); if (r != 3) break; c++; p = AllocParticle(); if (!p) { Con_Printf ("Not enough free particles\n"); break; } p->die = 99999; p->color = color; // (-c)&15; p->type = pt_static; VectorClear (p->vel); VectorCopy (org, p->org); } fclose (f); Con_Printf ("%i points read\n", c); }
void R_EntityParticles (entity_t *ent) { int i; particle_t *p; float angle, dist; float sp, sy, cp, cy; vec3_t forward; dist = 64; if (!avelocities[0][0]) { for (i = 0; i < NUMVERTEXNORMALS; i++) { avelocities[i][0] = (rand() & 255) * 0.01; avelocities[i][1] = (rand() & 255) * 0.01; avelocities[i][2] = (rand() & 255) * 0.01; } } for (i = 0; i < NUMVERTEXNORMALS; i++) { angle = cl.time * avelocities[i][0]; sy = sin(angle); cy = cos(angle); angle = cl.time * avelocities[i][1]; sp = sin(angle); cp = cos(angle); angle = cl.time * avelocities[i][2]; forward[0] = cp*cy; forward[1] = cp*sy; forward[2] = -sp; p = AllocParticle(); if (!p) return; p->die = cl.time + 0.01; p->color = 0x6f; p->type = pt_fireball; //pt_explode; p->org[0] = ent->origin[0] + r_avertexnormals[i][0]*dist + forward[0]*beamlength; p->org[1] = ent->origin[1] + r_avertexnormals[i][1]*dist + forward[1]*beamlength; p->org[2] = ent->origin[2] + r_avertexnormals[i][2]*dist + forward[2]*beamlength; } }
void R_ReadPointFile_f (void) { FILE *f; vec3_t org; int r; int c; particle_t *p; char name[MAX_OSPATH]; byte color; color = (byte)Cvar_VariableValue("leak_color"); sprintf (name,"maps/%s.pts", sv.name); COM_FOpenFile (name, &f, false); if (!f) { Con_Printf ("couldn't open %s\n", name); return; } Con_Printf ("Reading %s...\n", name); c = 0; for ( ;; ) { r = fscanf (f,"%f %f %f\n", &org[0], &org[1], &org[2]); if (r != 3) break; c++; p = AllocParticle(); if (!p) { Con_Printf ("Not enough free particles\n"); break; } p->die = 99999; p->color = color; // (-c)&15; p->type = pt_static; VectorCopy (vec3_origin, p->vel); VectorCopy (org, p->org); } fclose (f); Con_Printf ("%i points read\n", c); }
void R_SunStaffTrail(vec3_t source, vec3_t dest) { int i; vec3_t vec, dist; float length, size; particle_t *p; VectorSubtract(dest, source, vec); length = VectorNormalize(vec); dist[0] = vec[0]; dist[1] = vec[1]; dist[2] = vec[2]; size = 10; while(length > 0) { length -= size; if((p = AllocParticle()) == NULL) { return; } p->die = cl.time+2; p->ramp = rand()&3; p->color = ramp6[(int)(p->ramp)]; p->type = pt_spit; for(i = 0; i < 3; i++) { p->org[i] = source[i] + ((rand()&3)-2); } p->vel[0] = (rand()%10)-5; p->vel[1] = (rand()%10)-5; p->vel[2] = (rand()%10); VectorAdd(source, dist, source); } }
void R_DarkFieldParticles (entity_t *ent) { int i, j, k; particle_t *p; float vel; vec3_t dir; vec3_t org; org[0] = ent->origin[0]; org[1] = ent->origin[1]; org[2] = ent->origin[2]; for (i = -16; i < 16; i += 8) { for (j = -16; j < 16; j += 8) { for (k = 0; k < 32; k += 8) { p = AllocParticle(); if (!p) return; p->die = cl.time + 0.2 + (rand() & 7) * 0.02; p->color = 150 + (rand() % 6); p->type = pt_slowgrav; dir[0] = j * 8; dir[1] = i * 8; dir[2] = k * 8; p->org[0] = org[0] + i + (rand() & 3); p->org[1] = org[1] + j + (rand() & 3); p->org[2] = org[2] + k + (rand() & 3); VectorNormalize (dir); vel = 50 + (rand() & 63); VectorScale (dir, vel, p->vel); } } } }
/* =============== R_ParticleExplosion2 color mapped explosion =============== */ void R_ParticleExplosion2 (vec3_t org, int colorStart, int colorLength) { int i, j; particle_t *p; int colorMod = 0; for (i = 0; i < 512; i++) { p = AllocParticle(); if (!p) return; p->die = cl.time + 0.3; p->color = colorStart + (colorMod % colorLength); colorMod++; p->type = pt_blob; for (j = 0; j < 3; j++) { p->org[j] = org[j] + ((rand() & 31) - 16); p->vel[j] = (rand() & 511) - 256; } } }
/* ==================== CreateParticle ==================== */ void CParticleEngine::CreateParticle( particle_system_t *pSystem, float *flOrigin, float *flNormal ) { vec3_t vBaseOrigin; vec3_t vForward, vUp, vRight; cl_particle_t *pParticle = AllocParticle(pSystem); if(!pParticle) return; pParticle->pSystem = pSystem; pParticle->spawntime = gEngfuncs.GetClientTime(); pParticle->frame = -1; if(pSystem->shapetype == SYSTEM_SHAPE_PLANE_ABOVE_PLAYER) { vForward[0] = 0; vForward[1] = 0; vForward[2] = -1; } else if(pSystem->randomdir) { vForward[0] = gEngfuncs.pfnRandomFloat(-1, 1); vForward[1] = gEngfuncs.pfnRandomFloat(-1, 1); vForward[2] = gEngfuncs.pfnRandomFloat(-1, 1); } else if(flOrigin && flNormal) { vForward[0] = flNormal[0]; vForward[1] = flNormal[1]; vForward[2] = flNormal[2]; } else { vForward[0] = pSystem->dir[0]; vForward[1] = pSystem->dir[1]; vForward[2] = pSystem->dir[2]; } if(flNormal) { pParticle->normal[0] = flNormal[0]; pParticle->normal[1] = flNormal[1]; pParticle->normal[2] = flNormal[2]; } else { pParticle->normal[0] = pSystem->dir[0]; pParticle->normal[1] = pSystem->dir[1]; pParticle->normal[2] = pSystem->dir[2]; } VectorClear(vUp); VectorClear(vRight); gBSPRenderer.GetUpRight(vForward, vUp, vRight); VectorMASSE(pParticle->velocity, gEngfuncs.pfnRandomFloat(pSystem->minvel, pSystem->maxvel), vForward, pParticle->velocity); VectorMASSE(pParticle->velocity, gEngfuncs.pfnRandomFloat(-pSystem->maxofs, pSystem->maxofs), vRight, pParticle->velocity); VectorMASSE(pParticle->velocity, gEngfuncs.pfnRandomFloat(-pSystem->maxofs, pSystem->maxofs), vUp, pParticle->velocity); if(pSystem->maxlife == -1) pParticle->life = pSystem->maxlife; else pParticle->life = gEngfuncs.GetClientTime() + pSystem->maxlife + gEngfuncs.pfnRandomFloat(-pSystem->maxlifevar, pSystem->maxlifevar); pParticle->scale = pSystem->scale + gEngfuncs.pfnRandomFloat(-pSystem->scalevar, pSystem->scalevar); pParticle->rotationvel = pSystem->rotationvel + gEngfuncs.pfnRandomFloat(-pSystem->rotationvar, pSystem->rotationvar); pParticle->rotxvel = pSystem->rotxvel + gEngfuncs.pfnRandomFloat(-pSystem->rotxvar, pSystem->rotxvar); pParticle->rotyvel = pSystem->rotyvel + gEngfuncs.pfnRandomFloat(-pSystem->rotyvar, pSystem->rotyvar); if(flOrigin) { VectorCopy(flOrigin, vBaseOrigin); if(flNormal) VectorMA(vBaseOrigin, 0.1, flNormal, vBaseOrigin); } else { VectorCopy(pSystem->origin, vBaseOrigin); } if(pSystem->shapetype == SYSTEM_SHAPE_POINT) { VectorCopy(vBaseOrigin, pParticle->origin); } else if(pSystem->shapetype == SYSTEM_SHAPE_BOX) { pParticle->origin[0] = vBaseOrigin[0] + gEngfuncs.pfnRandomLong(-pSystem->systemsize, pSystem->systemsize); pParticle->origin[1] = vBaseOrigin[1] + gEngfuncs.pfnRandomLong(-pSystem->systemsize, pSystem->systemsize); pParticle->origin[2] = vBaseOrigin[2] + gEngfuncs.pfnRandomLong(-pSystem->systemsize, pSystem->systemsize); } else if(pSystem->shapetype == SYSTEM_SHAPE_PLANE_ABOVE_PLAYER) { if(!flOrigin) { vec3_t vPlayer = gEngfuncs.GetLocalPlayer()->origin; pParticle->origin[0] = vPlayer[0] + gEngfuncs.pfnRandomLong(-pSystem->systemsize, pSystem->systemsize); pParticle->origin[1] = vPlayer[1] + gEngfuncs.pfnRandomLong(-pSystem->systemsize, pSystem->systemsize); if(pSystem->maxheight) { pParticle->origin[2] = vPlayer[2] + pSystem->maxheight; if(pParticle->origin[2] > pSystem->skyheight) pParticle->origin[2] = pSystem->skyheight; } else { pParticle->origin[2] = pSystem->skyheight; } } else { VectorCopy(flOrigin, pParticle->origin); } } if(pParticle->rotationvel) pParticle->rotation = gEngfuncs.pfnRandomFloat(0, 360); if(pParticle->rotxvel) pParticle->rotx = gEngfuncs.pfnRandomFloat(0, 360); if(pParticle->rotyvel) pParticle->roty = gEngfuncs.pfnRandomFloat(0, 360); if(!pSystem->fadeintime) pParticle->alpha = 1; if(pSystem->fadeoutdelay) pParticle->fadeoutdelay = pSystem->fadeoutdelay; if(pSystem->scaledampdelay) pParticle->scaledampdelay = gEngfuncs.GetClientTime() + pSystem->scaledampdelay + gEngfuncs.pfnRandomFloat(-pSystem->scalevar, pSystem->scalevar); if(pSystem->transitiondelay && pSystem->transitiontime) { pParticle->secondarydelay = gEngfuncs.GetClientTime() + pSystem->transitiondelay + gEngfuncs.pfnRandomFloat(-pSystem->transitionvar, pSystem->transitionvar); pParticle->secondarytime = pSystem->transitiontime + gEngfuncs.pfnRandomFloat(-pSystem->transitionvar, pSystem->transitionvar); } if(pSystem->windtype) { pParticle->windmult = pSystem->windmult + gEngfuncs.pfnRandomFloat(-pSystem->windmultvar, pSystem->windmultvar); pParticle->windxvel = pSystem->windx + gEngfuncs.pfnRandomFloat(-pSystem->windvar, pSystem->windvar); pParticle->windyvel = pSystem->windy + gEngfuncs.pfnRandomFloat(-pSystem->windvar, pSystem->windvar); } if(!pSystem->numframes) { pParticle->texcoords[0][0] = 0; pParticle->texcoords[0][1] = 0; pParticle->texcoords[1][0] = 1; pParticle->texcoords[1][1] = 0; pParticle->texcoords[2][0] = 1; pParticle->texcoords[2][1] = 1; pParticle->texcoords[3][0] = 0; pParticle->texcoords[3][1] = 1; } else { // Calculate these only once float flFractionWidth = (float)pSystem->framesizex/(float)pSystem->texture->iWidth; float flFractionHeight = (float)pSystem->framesizey/(float)pSystem->texture->iHeight; // Calculate top left coordinate pParticle->texcoords[0][0] = flFractionWidth; pParticle->texcoords[0][1] = 0; // Calculate top right coordinate pParticle->texcoords[1][0] = 0; pParticle->texcoords[1][1] = 0; // Calculate bottom right coordinate pParticle->texcoords[2][0] = 0; pParticle->texcoords[2][1] = flFractionHeight; // Calculate bottom left coordinate pParticle->texcoords[3][0] = flFractionWidth; pParticle->texcoords[3][1] = flFractionHeight; } VectorCopy(pSystem->primarycolor, pParticle->color); VectorCopy(pSystem->secondarycolor, pParticle->scolor); VectorCopy(pParticle->origin, pParticle->lastspawn); for(int i = 0; i < 3; i++) { if(pParticle->scolor[i] == -1) pParticle->scolor[i] = gEngfuncs.pfnRandomFloat(0, 1); } if(pSystem->lightcheck != PARTICLE_LIGHTCHECK_NONE) { if(pSystem->lightcheck == PARTICLE_LIGHTCHECK_NORMAL) { pParticle->color = LightForParticle(pParticle); } else if(pSystem->lightcheck == PARTICLE_LIGHTCHECK_SCOLOR) { pParticle->scolor = LightForParticle(pParticle); } else if(pSystem->lightcheck == PARTICLE_LIGHTCHECK_MIXP) { pParticle->color = LightForParticle(pParticle); pParticle->color.x = pParticle->color.x*pSystem->primarycolor.x; pParticle->color.y = pParticle->color.y*pSystem->primarycolor.y; pParticle->color.z = pParticle->color.z*pSystem->primarycolor.z; } } }
void R_RocketTrail (vec3_t start, vec3_t end, int type) { vec3_t vec, dist; float len,size,lifetime; int j; particle_t *p; static int tracercount; VectorSubtract (end, start, vec); len = VectorNormalize (vec); dist[0] = vec[0]; dist[1] = vec[1]; dist[2] = vec[2]; size = 1; lifetime = 2; switch(type) { case 9: // Spit break; case 8: // Ice size *= 5*3; dist[0] *= 5*3; dist[1] *= 5*3; dist[2] *= 5*3; break; case rt_acidball: // Ice size=5; lifetime = .8; break; default: size = 3; dist[0] *= 3; dist[1] *= 3; dist[2] *= 3; break; } while (len > 0) { len -= size; p = AllocParticle(); if (!p) return; VectorCopy (vec3_origin, p->vel); p->die = cl.time + lifetime; switch(type) { case rt_rocket_trail: // rocket trail p->ramp = (rand()&3); p->color = ramp3[(int)p->ramp]; p->type = pt_fire; for (j=0 ; j<3 ; j++) p->org[j] = start[j] + ((rand()%6)-3); break; case rt_smoke: // smoke smoke p->ramp = (rand()&3) + 2; p->color = ramp3[(int)p->ramp]; p->type = pt_fire; for (j=0 ; j<3 ; j++) p->org[j] = start[j] + ((rand()%6)-3); break; case rt_blood: // blood p->type = pt_slowgrav; p->color = 134 + (rand()&7); for (j=0 ; j<3 ; j++) p->org[j] = start[j] + ((rand()%6)-3); break; case rt_tracer:; case rt_tracer2:;// tracer p->die = cl.time + 0.5; p->type = pt_static; if (type == 3) p->color = 130 + (rand() & 6); // p->color = 243 + (rand() & 3); else p->color = 230 + ((tracercount&4)<<1); tracercount++; VectorCopy (start, p->org); if (tracercount & 1) { p->vel[0] = 30*vec[1]; p->vel[1] = 30*-vec[0]; } else { p->vel[0] = 30*-vec[1]; p->vel[1] = 30*vec[0]; } break; case rt_slight_blood:// slight blood p->type = pt_slowgrav; p->color = 134 + (rand()&7); for (j=0 ; j<3 ; j++) p->org[j] = start[j] + ((rand()%6)-3); len -= size; break; case rt_bloodshot:// bloodshot trail p->type = pt_darken; p->color = 136 + (rand()&5); for (j=0 ; j<3 ; j++) p->org[j] = start[j] + ((rand()&3)-2); len -= size; break; case rt_voor_trail:// voor trail p->color = 9*16 + 8 + (rand()&3); p->type = pt_static; p->die = cl.time + 0.3; for (j=0 ; j<3 ; j++) p->org[j] = start[j] + ((rand()&15)-8); break; case rt_fireball: // Fireball p->ramp = rand()&3; p->color = ramp4[(int)(p->ramp)]; p->type = pt_fireball; for (j=0 ; j<3 ; j++) p->org[j] = start[j] + ((rand()&3)-2); p->org[2] += 2; // compensate for model p->vel[0] = (rand() % 200) - 100; p->vel[1] = (rand() % 200) - 100; p->vel[2] = (rand() % 200) - 100; break; case rt_acidball: // Acid ball p->ramp = rand()&3; p->color = ramp10[(int)(p->ramp)]; p->type = pt_acidball; p->die = cl.time + 0.5; for (j=0 ; j<3 ; j++) p->org[j] = start[j] + ((rand()&3)-2); p->org[2] += 2; // compensate for model p->vel[0] = (rand() % 40) - 20; p->vel[1] = (rand() % 40) - 20; p->vel[2] = (rand() % 40) - 20; break; case rt_ice: // Ice p->ramp = rand()&3; p->color = ramp5[(int)(p->ramp)]; p->type = pt_ice; for (j=0 ; j<3 ; j++) p->org[j] = start[j] + ((rand()&3)-2); p->org[2] += 2; // compensate for model p->vel[0] = (rand() % 16) - 8; p->vel[1] = (rand() % 16) - 8; p->vel[2] = (rand() % 20) - 40; break; case rt_spit: // Spit p->ramp = rand()&3; p->color = ramp6[(int)(p->ramp)]; p->type = pt_spit; for (j=0 ; j<3 ; j++) p->org[j] = start[j] + ((rand()&3)-2); p->org[2] += 2; // compensate for model p->vel[0] = (rand() % 10) - 5; p->vel[1] = (rand() % 10) - 5; p->vel[2] = (rand() % 10); break; case rt_spell: // Spell p->ramp = rand()&3; p->color = ramp6[(int)(p->ramp)]; p->type = pt_spell; for (j=0 ; j<3 ; j++) p->org[j] = start[j] + ((rand()&3)-2); p->vel[0] = (rand() % 10) - 5; p->vel[1] = (rand() % 10) - 5; p->vel[2] = (rand() % 10); p->vel[0] = vec[0]*-10; p->vel[1] = vec[1]*-10; p->vel[2] = vec[2]*-10; break; case rt_vorpal: // vorpal missile p->type = pt_vorpal; p->color = 44 + (rand()&3) + 256; for (j=0 ; j<2 ; j++) p->org[j] = start[j] + ((rand()%48)-24); p->org[2] = start[2] + ((rand()&15)-8); break; case rt_setstaff: // set staff p->type = pt_setstaff; p->color = ramp9[0]; p->ramp = rand()&3; for (j=0 ; j<2 ; j++) p->org[j] = start[j] + ((rand()%6)-3); p->org[2] = start[2] + ((rand()%10)-5); p->vel[0] = (rand() &7) - 4; p->vel[1] = (rand() &7) - 4; break; case rt_magicmissile: // magic missile p->type = pt_magicmissile; p->color = 148 + (rand()&11); p->ramp = rand()&3; for (j=0 ; j<2 ; j++) p->org[j] = start[j] + ((rand()%48)-24); p->org[2] = start[2] + ((rand()%48)-24); p->vel[2] = -((rand()&15)+8); break; case rt_boneshard: // bone shard p->type = pt_boneshard; p->color = 368 + (rand()&16); for (j=0 ; j<2 ; j++) p->org[j] = start[j] + ((rand()%48)-24); p->org[2] = start[2] + ((rand()%48)-24); p->vel[2] = -((rand()&15)+8); break; case rt_scarab: // scarab staff p->type = pt_scarab; p->color = 250 + (rand()&3); for (j=0 ; j<3 ; j++) p->org[j] = start[j] + (rand()&7); p->vel[2] = -(rand()&7); break; } VectorAdd (start, dist, start); } }
/* =============== R_SnowEffect MG =============== */ void R_SnowEffect (vec3_t org1,vec3_t org2,int flags,vec3_t alldir,int count) { int i,j,holdint; particle_t *p; mleaf_t *l; count *= Cvar_VariableValue("snow_active"); for (i=0 ; i<count ; i++) { p = AllocParticle(); if (!p) return; p->vel[0] = alldir[0]; //X and Y motion p->vel[1] = alldir[1]; p->vel[2] = alldir[2] * ((rand() & 15) + 7)/10; p->flags = flags; #ifdef GLQUAKE if(rand()&0x7f<=1)//have a console variable 'happy_snow' that makes all snowflakes happy snow! p->count = 69; //happy snow! else if(flags & SFL_FLUFFY || (flags&SFL_MIXED && (rand()&3))) p->count = (rand()&31)+10;//From 10 to 41 scale, will be divided else p->count = 10; #else if(flags & SFL_FLUFFY || (flags&SFL_MIXED && (rand()&3))) p->count = (rand()&3)+2;//From 2 to 5 extra else p->count = 1; //Only one particle #endif if(flags&SFL_HALF_BRIGHT)//Start darker p->color = 26 + (rand()%5); else p->color = 18 + (rand()%12); if(!(flags&SFL_NO_TRANS))//Start translucent p->color += 256; p->die = cl.time + 7; p->ramp = (rand()&3); //p->veer = veer; p->type = pt_snow; holdint=org2[0] - org1[0]; p->org[0] = org1[0] + (rand() % holdint); holdint=org2[1] - org1[1]; p->org[1] = org1[1] + (rand() % holdint); p->org[2] = org2[2]; j=50; l = Mod_PointInLeaf (p->org, cl.worldmodel); // while(SV_PointContents(p->org)!=CONTENTS_EMPTY && j<50) while(l->contents!=CONTENTS_EMPTY && j) {//Make sure it doesn't start in a solid holdint=org2[0] - org1[0]; p->org[0] = org1[0] + (rand() % holdint); holdint=org2[1] - org1[1]; p->org[1] = org1[1] + (rand() % holdint); j--;//No infinite loops l = Mod_PointInLeaf (p->org, cl.worldmodel); } if(l->contents!=CONTENTS_EMPTY) Sys_Error ("Snow entity top plane is not in an empty area (sorry!)"); VectorCopy(org1,p->min_org); VectorCopy(org2,p->max_org); } }