Ejemplo n.º 1
0
// NERVE - SMF :: the core of the dirt explosion
void CG_ParticleDirtBulletDebris_Core(vec3_t org, vec3_t vel, int duration, float width, float height, float alpha,
									  qhandle_t shader)
{
	cparticle_t    *p;

	if(!free_particles)
	{
		return;
	}
	p = free_particles;
	free_particles = p->next;
	p->next = active_particles;
	active_particles = p;

	p->time = cg.time;
	p->endtime = cg.time + duration;
	p->startfade = cg.time + duration / 2;

	p->color = EMISIVEFADE;
	p->alpha = alpha;
	p->alphavel = 0;

	p->height = width;
	p->width = height;
	p->endheight = p->height;
	p->endwidth = p->width;

	p->rotate = 0;

	p->type = P_SMOKE;

	p->pshader = shader;
	if(cg_fxflags & 1)
	{
		p->pshader = getTestShader();
		p->rotate = 0;
		p->roll = 0;
		p->type = P_SPRITE;
	}

	VectorCopy(org, p->org);
	VectorCopy(vel, p->vel);
	VectorSet(p->accel, 0, 0, -330);
}
Ejemplo n.º 2
0
//----(SA)	modified
localEntity_t *CG_SmokePuff(const vec3_t p, const vec3_t vel,
                            float radius,
                            float r, float g, float b, float a,
                            float duration,
                            int startTime,
                            int fadeInTime,
                            int leFlags,
                            qhandle_t hShader)
{
	static int    seed = 0x92;
	localEntity_t *le;
	refEntity_t   *re;

	le          = CG_AllocLocalEntity();
	le->leFlags = leFlags;
	le->radius  = radius;

	re             = &le->refEntity;
	re->rotation   = Q_random(&seed) * 360;
	re->radius     = radius;
	re->shaderTime = startTime / 1000.0f;

	le->leType     = LE_MOVE_SCALE_FADE;
	le->startTime  = startTime;
	le->endTime    = startTime + duration;
	le->fadeInTime = fadeInTime;
	if (fadeInTime > startTime)
	{
		le->lifeRate = 1.0 / (le->endTime - le->fadeInTime);
	}
	else
	{
		le->lifeRate = 1.0 / (le->endTime - le->startTime);
	}
	le->color[0] = r;
	le->color[1] = g;
	le->color[2] = b;
	le->color[3] = a;


	le->pos.trType = TR_LINEAR;
	le->pos.trTime = startTime;
	VectorCopy(vel, le->pos.trDelta);
	VectorCopy(p, le->pos.trBase);

	VectorCopy(p, re->origin);
	re->customShader = hShader;

	// rage pro can't alpha fade, so use a different shader
	if (cgs.glconfig.hardwareType == GLHW_RAGEPRO)
	{
		re->customShader  = cgs.media.smokePuffRageProShader;
		re->shaderRGBA[0] = 0xff;
		re->shaderRGBA[1] = 0xff;
		re->shaderRGBA[2] = 0xff;
		re->shaderRGBA[3] = 0xff;
	}
	else
	{
		re->shaderRGBA[0] = le->color[0] * 0xff;
		re->shaderRGBA[1] = le->color[1] * 0xff;
		re->shaderRGBA[2] = le->color[2] * 0xff;
		re->shaderRGBA[3] = 0xff;
	}
// JPW NERVE
	if (cg_fxflags & 1)
	{
		re->customShader = getTestShader();
		re->rotation     = 180;
	}
// jpw

	re->reType = RT_SPRITE;
	re->radius = le->radius;

	return le;
}
Ejemplo n.º 3
0
void CG_AddParticleToScene(cparticle_t *p, vec3_t org) {

	vec3_t     point;
	polyVert_t verts[4];
	float      width;
	float      height;
	float      time, time2;
	float      ratio;
	float      invratio;
	vec3_t     color;
	polyVert_t TRIverts[3];
	vec3_t     rright2, rup2;

	if (p->type == P_WEATHER || p->type == P_WEATHER_TURBULENT || p->type == P_WEATHER_FLURRY
	    || p->type == P_BUBBLE || p->type == P_BUBBLE_TURBULENT) {   // create a front facing polygon
		if (p->type != P_WEATHER_FLURRY) {
			if (p->type == P_BUBBLE || p->type == P_BUBBLE_TURBULENT) {
				if (org[2] > p->end) {
					p->time = cg.time;
					VectorCopy(org, p->org);   // Ridah, fixes rare snow flakes that flicker on the ground

					p->org[2] = (p->start + crandom() * 4);


					if (p->type == P_BUBBLE_TURBULENT) {
						p->vel[0] = crandom() * 4;
						p->vel[1] = crandom() * 4;
					}

				}
			} else {
				if (org[2] < p->end) {
					p->time = cg.time;
					VectorCopy(org, p->org);   // Ridah, fixes rare snow flakes that flicker on the ground

					while (p->org[2] < p->end) {
						p->org[2] += (p->start - p->end);
					}


					if (p->type == P_WEATHER_TURBULENT) {
						p->vel[0] = crandom() * 16;
						p->vel[1] = crandom() * 16;
					}

				}
			}


			// Rafael snow pvs check
			if (!p->link) {
				return;
			}

			p->alpha = 1;
		}

		// Ridah, had to do this or MAX_POLYS is being exceeded in village1.bsp
		if (VectorDistanceSquared(cg.snap->ps.origin, org) > SQR(1024)) {
			return;
		}
		// done.

		if (p->type == P_BUBBLE || p->type == P_BUBBLE_TURBULENT) {
			VectorMA(org, -p->height, vup, point);
			VectorMA(point, -p->width, vright, point);
			VectorCopy(point, verts[0].xyz);
			verts[0].st[0]       = 0;
			verts[0].st[1]       = 0;
			verts[0].modulate[0] = 255;
			verts[0].modulate[1] = 255;
			verts[0].modulate[2] = 255;
			verts[0].modulate[3] = 255 * p->alpha;

			VectorMA(org, -p->height, vup, point);
			VectorMA(point, p->width, vright, point);
			VectorCopy(point, verts[1].xyz);
			verts[1].st[0]       = 0;
			verts[1].st[1]       = 1;
			verts[1].modulate[0] = 255;
			verts[1].modulate[1] = 255;
			verts[1].modulate[2] = 255;
			verts[1].modulate[3] = 255 * p->alpha;

			VectorMA(org, p->height, vup, point);
			VectorMA(point, p->width, vright, point);
			VectorCopy(point, verts[2].xyz);
			verts[2].st[0]       = 1;
			verts[2].st[1]       = 1;
			verts[2].modulate[0] = 255;
			verts[2].modulate[1] = 255;
			verts[2].modulate[2] = 255;
			verts[2].modulate[3] = 255 * p->alpha;

			VectorMA(org, p->height, vup, point);
			VectorMA(point, -p->width, vright, point);
			VectorCopy(point, verts[3].xyz);
			verts[3].st[0]       = 1;
			verts[3].st[1]       = 0;
			verts[3].modulate[0] = 255;
			verts[3].modulate[1] = 255;
			verts[3].modulate[2] = 255;
			verts[3].modulate[3] = 255 * p->alpha;
		} else {
			VectorMA(org, -p->height, vup, point);
			VectorMA(point, -p->width, vright, point);
			VectorCopy(point, TRIverts[0].xyz);
			TRIverts[0].st[0]       = 1;
			TRIverts[0].st[1]       = 0;
			TRIverts[0].modulate[0] = 255;
			TRIverts[0].modulate[1] = 255;
			TRIverts[0].modulate[2] = 255;
			TRIverts[0].modulate[3] = 255 * p->alpha;

			VectorMA(org, p->height, vup, point);
			VectorMA(point, -p->width, vright, point);
			VectorCopy(point, TRIverts[1].xyz);
			TRIverts[1].st[0]       = 0;
			TRIverts[1].st[1]       = 0;
			TRIverts[1].modulate[0] = 255;
			TRIverts[1].modulate[1] = 255;
			TRIverts[1].modulate[2] = 255;
			TRIverts[1].modulate[3] = 255 * p->alpha;

			VectorMA(org, p->height, vup, point);
			VectorMA(point, p->width, vright, point);
			VectorCopy(point, TRIverts[2].xyz);
			TRIverts[2].st[0]       = 0;
			TRIverts[2].st[1]       = 1;
			TRIverts[2].modulate[0] = 255;
			TRIverts[2].modulate[1] = 255;
			TRIverts[2].modulate[2] = 255;
			TRIverts[2].modulate[3] = 255 * p->alpha;
		}

	} else if (p->type == P_SPRITE) {
		vec3_t rr, ru;
		vec3_t rotate_ang;

		VectorSet(color, 1.0, 1.0, 1.0);
		time  = cg.time - p->time;
		time2 = p->endtime - p->time;
		ratio = time / time2;

		width  = p->width + (ratio * (p->endwidth - p->width));
		height = p->height + (ratio * (p->endheight - p->height));

		if (p->roll) {
			vectoangles(cg.refdef_current->viewaxis[0], rotate_ang);
			rotate_ang[ROLL] += p->roll;
			AngleVectors(rotate_ang, NULL, rr, ru);
		}

		if (p->roll) {
			VectorMA(org, -height, ru, point);
			VectorMA(point, -width, rr, point);
		} else {
			VectorMA(org, -height, vup, point);
			VectorMA(point, -width, vright, point);
		}
		VectorCopy(point, verts[0].xyz);
		verts[0].st[0]       = 0;
		verts[0].st[1]       = 0;
		verts[0].modulate[0] = 255;
		verts[0].modulate[1] = 255;
		verts[0].modulate[2] = 255;
		verts[0].modulate[3] = 255;

		if (p->roll) {
			VectorMA(point, 2 * height, ru, point);
		} else {
			VectorMA(point, 2 * height, vup, point);
		}
		VectorCopy(point, verts[1].xyz);
		verts[1].st[0]       = 0;
		verts[1].st[1]       = 1;
		verts[1].modulate[0] = 255;
		verts[1].modulate[1] = 255;
		verts[1].modulate[2] = 255;
		verts[1].modulate[3] = 255;

		if (p->roll) {
			VectorMA(point, 2 * width, rr, point);
		} else {
			VectorMA(point, 2 * width, vright, point);
		}
		VectorCopy(point, verts[2].xyz);
		verts[2].st[0]       = 1;
		verts[2].st[1]       = 1;
		verts[2].modulate[0] = 255;
		verts[2].modulate[1] = 255;
		verts[2].modulate[2] = 255;
		verts[2].modulate[3] = 255;

		if (p->roll) {
			VectorMA(point, -2 * height, ru, point);
		} else {
			VectorMA(point, -2 * height, vup, point);
		}
		VectorCopy(point, verts[3].xyz);
		verts[3].st[0]       = 1;
		verts[3].st[1]       = 0;
		verts[3].modulate[0] = 255;
		verts[3].modulate[1] = 255;
		verts[3].modulate[2] = 255;
		verts[3].modulate[3] = 255;
	} else if (p->type == P_SMOKE || p->type == P_SMOKE_IMPACT) {         // create a front rotating facing polygon
		if (p->type == P_SMOKE_IMPACT && VectorDistanceSquared(cg.snap->ps.origin, org) > SQR(1024)) {
			return;
		}

		if (p->color == MUSTARD) {
			VectorSet(color, 0.42, 0.33, 0.19);
		} else if (p->color == BLOODRED) {
			VectorSet(color, 0.22, 0, 0);
		} else if (p->color == ZOMBIE) {
			VectorSet(color, 0.4, 0.28, 0.23);
		} else if (p->color == GREY75) {
			float len;
			float greyit;
			float val;
			len = Distance(cg.snap->ps.origin, org);
			if (!len) {
				len = 1;
			}

			val    = 4096 / len;
			greyit = 0.25 * val;
			if (greyit > 0.5) {
				greyit = 0.5;
			}

			VectorSet(color, greyit, greyit, greyit);
		} else {
			VectorSet(color, 1.0, 1.0, 1.0);
		}

		time  = cg.time - p->time;
		time2 = p->endtime - p->time;
		ratio = time / time2;

		if (cg.time > p->startfade) {
			invratio = 1 - ((cg.time - p->startfade) / (p->endtime - p->startfade));

			if (p->color == EMISIVEFADE) {
				float fval;
				fval = (invratio * invratio);
				if (fval < 0) {
					fval = 0;
				}
				VectorSet(color, fval, fval, fval);
			}
			invratio *= p->alpha;
		} else {
			invratio = 1 * p->alpha;
		}

		if (cgs.glconfig.hardwareType == GLHW_RAGEPRO) {
			invratio = 1;
		}

		if (invratio > 1) {
			invratio = 1;
		}

		width  = p->width + (ratio * (p->endwidth - p->width));
		height = p->height + (ratio * (p->endheight - p->height));

		{
			vec3_t temp;

			vectoangles(rforward, temp);
			p->accumroll += p->roll;
			temp[ROLL]   += p->accumroll * 0.1;
			AngleVectors(temp, NULL, rright2, rup2);
		}

		if (p->rotate) {
			VectorMA(org, -height, rup2, point);
			VectorMA(point, -width, rright2, point);
		} else {
			VectorMA(org, -p->height, vup, point);
			VectorMA(point, -p->width, vright, point);
		}
		VectorCopy(point, verts[0].xyz);
		verts[0].st[0]       = 0;
		verts[0].st[1]       = 0;
		verts[0].modulate[0] = 255 * color[0];
		verts[0].modulate[1] = 255 * color[1];
		verts[0].modulate[2] = 255 * color[2];
		verts[0].modulate[3] = 255 * invratio;

		if (p->rotate) {
			VectorMA(org, -height, rup2, point);
			VectorMA(point, width, rright2, point);
		} else {
			VectorMA(org, -p->height, vup, point);
			VectorMA(point, p->width, vright, point);
		}
		VectorCopy(point, verts[1].xyz);
		verts[1].st[0]       = 0;
		verts[1].st[1]       = 1;
		verts[1].modulate[0] = 255 * color[0];
		verts[1].modulate[1] = 255 * color[1];
		verts[1].modulate[2] = 255 * color[2];
		verts[1].modulate[3] = 255 * invratio;

		if (p->rotate) {
			VectorMA(org, height, rup2, point);
			VectorMA(point, width, rright2, point);
		} else {
			VectorMA(org, p->height, vup, point);
			VectorMA(point, p->width, vright, point);
		}
		VectorCopy(point, verts[2].xyz);
		verts[2].st[0]       = 1;
		verts[2].st[1]       = 1;
		verts[2].modulate[0] = 255 * color[0];
		verts[2].modulate[1] = 255 * color[1];
		verts[2].modulate[2] = 255 * color[2];
		verts[2].modulate[3] = 255 * invratio;

		if (p->rotate) {
			VectorMA(org, height, rup2, point);
			VectorMA(point, -width, rright2, point);
		} else {
			VectorMA(org, p->height, vup, point);
			VectorMA(point, -p->width, vright, point);
		}
		VectorCopy(point, verts[3].xyz);
		verts[3].st[0]       = 1;
		verts[3].st[1]       = 0;
		verts[3].modulate[0] = 255 * color[0];
		verts[3].modulate[1] = 255 * color[1];
		verts[3].modulate[2] = 255 * color[2];
		verts[3].modulate[3] = 255  * invratio;

	} else if (p->type == P_FLAT_SCALEUP) {
		float width, height;
		float sinR, cosR;

		if (p->color == BLOODRED) {
			VectorSet(color, 1, 1, 1);
		} else {
			VectorSet(color, 0.5, 0.5, 0.5);
		}

		time  = cg.time - p->time;
		time2 = p->endtime - p->time;
		ratio = time / time2;

		width  = p->width + (ratio * (p->endwidth - p->width));
		height = p->height + (ratio * (p->endheight - p->height));

		if (width > p->endwidth) {
			width = p->endwidth;
		}

		if (height > p->endheight) {
			height = p->endheight;
		}

		sinR = height * sin(DEG2RAD(p->roll)) * ROOT_2;
		cosR = width * cos(DEG2RAD(p->roll)) * ROOT_2;

		VectorCopy(org, verts[0].xyz);
		verts[0].xyz[0]     -= sinR;
		verts[0].xyz[1]     -= cosR;
		verts[0].st[0]       = 0;
		verts[0].st[1]       = 0;
		verts[0].modulate[0] = 255 * color[0];
		verts[0].modulate[1] = 255 * color[1];
		verts[0].modulate[2] = 255 * color[2];
		verts[0].modulate[3] = 255;

		VectorCopy(org, verts[1].xyz);
		verts[1].xyz[0]     -= cosR;
		verts[1].xyz[1]     += sinR;
		verts[1].st[0]       = 0;
		verts[1].st[1]       = 1;
		verts[1].modulate[0] = verts[0].modulate[0];
		verts[1].modulate[1] = verts[0].modulate[1];
		verts[1].modulate[2] = verts[0].modulate[2];
		verts[1].modulate[3] = verts[0].modulate[3];

		VectorCopy(org, verts[2].xyz);
		verts[2].xyz[0]     += sinR;
		verts[2].xyz[1]     += cosR;
		verts[2].st[0]       = 1;
		verts[2].st[1]       = 1;
		verts[2].modulate[0] = verts[0].modulate[0];
		verts[2].modulate[1] = verts[0].modulate[1];
		verts[2].modulate[2] = verts[0].modulate[2];
		verts[2].modulate[3] = verts[0].modulate[3];

		VectorCopy(org, verts[3].xyz);
		verts[3].xyz[0]     += cosR;
		verts[3].xyz[1]     -= sinR;
		verts[3].st[0]       = 1;
		verts[3].st[1]       = 0;
		verts[3].modulate[0] = verts[0].modulate[0];
		verts[3].modulate[1] = verts[0].modulate[1];
		verts[3].modulate[2] = verts[0].modulate[2];
		verts[3].modulate[3] = verts[0].modulate[3];
	} else if (p->type == P_FLAT) {

		VectorCopy(org, verts[0].xyz);
		verts[0].xyz[0]     -= p->height;
		verts[0].xyz[1]     -= p->width;
		verts[0].st[0]       = 0;
		verts[0].st[1]       = 0;
		verts[0].modulate[0] = 255;
		verts[0].modulate[1] = 255;
		verts[0].modulate[2] = 255;
		verts[0].modulate[3] = 255;

		VectorCopy(org, verts[1].xyz);
		verts[1].xyz[0]     -= p->height;
		verts[1].xyz[1]     += p->width;
		verts[1].st[0]       = 0;
		verts[1].st[1]       = 1;
		verts[1].modulate[0] = 255;
		verts[1].modulate[1] = 255;
		verts[1].modulate[2] = 255;
		verts[1].modulate[3] = 255;

		VectorCopy(org, verts[2].xyz);
		verts[2].xyz[0]     += p->height;
		verts[2].xyz[1]     += p->width;
		verts[2].st[0]       = 1;
		verts[2].st[1]       = 1;
		verts[2].modulate[0] = 255;
		verts[2].modulate[1] = 255;
		verts[2].modulate[2] = 255;
		verts[2].modulate[3] = 255;

		VectorCopy(org, verts[3].xyz);
		verts[3].xyz[0]     += p->height;
		verts[3].xyz[1]     -= p->width;
		verts[3].st[0]       = 1;
		verts[3].st[1]       = 0;
		verts[3].modulate[0] = 255;
		verts[3].modulate[1] = 255;
		verts[3].modulate[2] = 255;
		verts[3].modulate[3] = 255;

	}
	// Ridah
	else if (p->type == P_ANIM || p->type == P_DLIGHT_ANIM) {    // ydnar
		vec3_t rr, ru;
		vec3_t rotate_ang;
		int    i, j;

		time  = cg.time - p->time;
		time2 = p->endtime - p->time;
		ratio = time / time2;
		if (ratio >= 1.0) {
			ratio = 0.9999;
		} else if (ratio < 0.0) {
			// rain - make sure that ratio isn't negative or
			// we'll walk out of bounds when j is calculated below
			ratio = 0.0001;
		}

		width  = p->width + (ratio * (p->endwidth - p->width));
		height = p->height + (ratio * (p->endheight - p->height));

		// ydnar: add dlight if necessary
		if (p->type == P_DLIGHT_ANIM) {
			// fixme: support arbitrary color
			trap_R_AddLightToScene(org, 320,    //%	1.5 * (width > height ? width : height),
			                       1.25 * (1.0 - ratio), 1.0, 0.95, 0.85, 0, 0);
		}

		// if we are "inside" this sprite, don't draw
		if (VectorDistanceSquared(cg.snap->ps.origin, org) < SQR(width / 1.5f)) {
			return;
		}

		i          = p->shaderAnim;
		j          = (int)floor(ratio * shaderAnimCounts[p->shaderAnim]);
		p->pshader = shaderAnims[i][j];

		// JPW NERVE more particle testing
		if (cg_fxflags & 1) {
			p->roll          = 0;
			p->pshader       = getTestShader();
			rotate_ang[ROLL] = 90;
		}
		// jpw

		if (p->roll) {
			vectoangles(cg.refdef_current->viewaxis[0], rotate_ang);
			rotate_ang[ROLL] += p->roll;
			AngleVectors(rotate_ang, NULL, rr, ru);
		}

		if (p->roll) {
			VectorMA(org, -height, ru, point);
			VectorMA(point, -width, rr, point);
		} else {
			VectorMA(org, -height, vup, point);
			VectorMA(point, -width, vright, point);
		}
		VectorCopy(point, verts[0].xyz);
		verts[0].st[0]       = 0;
		verts[0].st[1]       = 0;
		verts[0].modulate[0] = 255;
		verts[0].modulate[1] = 255;
		verts[0].modulate[2] = 255;
		verts[0].modulate[3] = 255;

		if (p->roll) {
			VectorMA(point, 2 * height, ru, point);
		} else {
			VectorMA(point, 2 * height, vup, point);
		}
		VectorCopy(point, verts[1].xyz);
		verts[1].st[0]       = 0;
		verts[1].st[1]       = 1;
		verts[1].modulate[0] = 255;
		verts[1].modulate[1] = 255;
		verts[1].modulate[2] = 255;
		verts[1].modulate[3] = 255;

		if (p->roll) {
			VectorMA(point, 2 * width, rr, point);
		} else {
			VectorMA(point, 2 * width, vright, point);
		}
		VectorCopy(point, verts[2].xyz);
		verts[2].st[0]       = 1;
		verts[2].st[1]       = 1;
		verts[2].modulate[0] = 255;
		verts[2].modulate[1] = 255;
		verts[2].modulate[2] = 255;
		verts[2].modulate[3] = 255;

		if (p->roll) {
			VectorMA(point, -2 * height, ru, point);
		} else {
			VectorMA(point, -2 * height, vup, point);
		}
		VectorCopy(point, verts[3].xyz);
		verts[3].st[0]       = 1;
		verts[3].st[1]       = 0;
		verts[3].modulate[0] = 255;
		verts[3].modulate[1] = 255;
		verts[3].modulate[2] = 255;
		verts[3].modulate[3] = 255;
	}
	// done.

	if (!cg_wolfparticles.integer) {
		return;
	}

	if (!p->pshader) {
		return;
	}

	if (p->type == P_WEATHER || p->type == P_WEATHER_TURBULENT || p->type == P_WEATHER_FLURRY) {
		trap_R_AddPolyToScene(p->pshader, 3, TRIverts);
	} else {
		trap_R_AddPolyToScene(p->pshader, 4, verts);
	}

}