Example #1
0
static void CL_ParticleFunction (ptl_t *p, ptlCmd_t *cmd)
{
	int stackIdx;
	ptrdiff_t e;
	int type;
	int i, j, n;
	void *cmdData;
	float arg;
	ptl_t *pnew;

	/* test for null cmd */
	if (!cmd)
		return;

	/* run until finding PC_END */
	for (stackIdx = 0, e = 0; cmd->cmd != PC_END; cmd++) {
		if (cmd->ref > RSTACK)
			cmdData = CL_ParticleCommandGetDataLocation(p, cmd);
		else {
			if (!stackIdx)
				Com_Error(ERR_DROP, "CL_ParticleFunction: stack underflow");

			/* pop an element off the stack */
			e = (byte *) stackPtr[--stackIdx] - cmdStack;

			i = RSTACK - cmd->ref;
			if (!i) {
				/* normal stack reference */
				cmdData = stackPtr[stackIdx];
				cmd->type = stackType[stackIdx];
			} else {
				/* stack reference to element of vector */
				if ((1 << stackType[stackIdx]) & V_VECS) {
					cmd->type = V_FLOAT;
					cmdData = (float *) stackPtr[stackIdx] + (i - 1);
				} else {
					Com_Error(ERR_DROP, "CL_ParticleFunction: can't get components of a non-vector type (particle %s)", p->ctrl->name);
				}
			}
		}

		switch (cmd->cmd) {
		case PC_PUSH:
			/* check for stack overflow */
			if (stackIdx >= MAX_STACK_DEPTH)
				Com_Error(ERR_DROP, "CL_ParticleFunction: stack overflow");

			/* store the value in the stack */
			stackPtr[stackIdx] = &cmdStack[e];
			stackType[stackIdx] = cmd->type;
			e += Com_SetValue(stackPtr[stackIdx++], cmdData, (valueTypes_t)cmd->type, 0, 0);
			break;

		case PC_POP:
		case PC_KPOP:
			/* check for stack underflow */
			if (stackIdx == 0)
				Com_Error(ERR_DROP, "CL_ParticleFunction: stack underflow");

			/* get pics and models */
			if (offsetof(ptl_t, pic) == -cmd->ref) {
				if (stackType[--stackIdx] != V_STRING)
					Com_Error(ERR_DROP, "Bad type '%s' for pic (particle %s)", vt_names[stackType[stackIdx - 1]], p->ctrl->name);
				p->pic = CL_ParticleGetArt((char *) stackPtr[stackIdx], p->frame, ART_PIC);
				e = (byte *) stackPtr[stackIdx] - cmdStack;
				break;
			}
			if (offsetof(ptl_t, model) == -cmd->ref) {
				if (stackType[--stackIdx] != V_STRING)
					Com_Error(ERR_DROP, "Bad type '%s' for model (particle %s)", vt_names[stackType[stackIdx - 1]], p->ctrl->name);
				p->model = CL_ParticleGetArt((char *) stackPtr[stackIdx], p->frame, ART_MODEL);
				e = (byte *) stackPtr[stackIdx] - cmdStack;
				break;
			}
			if (offsetof(ptl_t, program) == -cmd->ref) {
				if (stackType[--stackIdx] != V_STRING)
					Com_Error(ERR_DROP, "Bad type '%s' for program (particle %s)", vt_names[stackType[stackIdx - 1]], p->ctrl->name);
				p->program = R_LoadProgram((char *) stackPtr[stackIdx], R_InitParticleProgram, R_UseParticleProgram);
				if (p->program)
					p->program->userdata = p;
				e = (byte *) stackPtr[stackIdx] - cmdStack;
				break;
			}

			/* get different data */
			if (cmd->cmd == PC_POP)
				e -= Com_SetValue(cmdData, stackPtr[--stackIdx], (valueTypes_t)cmd->type, 0, 0);
			else
				Com_SetValue(cmdData, stackPtr[stackIdx - 1], (valueTypes_t)cmd->type, 0, 0);
			break;

		case PC_ADD:
		case PC_SUB:
			/* check for stack underflow */
			if (stackIdx == 0)
				Com_Error(ERR_DROP, "CL_ParticleFunction: stack underflow");

			type = stackType[stackIdx - 1];
			if (!((1 << type) & V_VECS))
				Com_Error(ERR_DROP, "CL_ParticleFunction: bad type '%s' for add (particle %s)", vt_names[stackType[stackIdx - 1]], p->ctrl->name);

			/* float based vector addition */
			if (type != cmd->type)
				Com_Error(ERR_DROP, "CL_ParticleFunction: bad vector dimensions for add/sub (particle %s)", p->ctrl->name);

			n = type - V_FLOAT + 1;

			for (i = 0; i < n; i++) {
				if (cmd->cmd == PC_SUB)
					arg = -(*((float *) cmdData + i));
				else
					arg = *((float *) cmdData + i);
				*((float *) stackPtr[stackIdx - 1] + i) += arg;
			}
			break;

		case PC_MUL:
		case PC_DIV:
			/* check for stack underflow */
			if (stackIdx == 0)
				Com_Error(ERR_DROP, "CL_ParticleFunction: stack underflow");

			type = stackType[stackIdx - 1];
			if (!((1 << type) & V_VECS))
				Com_Error(ERR_DROP, "CL_ParticleFunction: bad type '%s' for add (particle %s)", vt_names[stackType[stackIdx - 1]], p->ctrl->name);

			n = type - V_FLOAT + 1;

			if (type > V_FLOAT && cmd->type > V_FLOAT) {
				/* component wise multiplication */
				if (type != cmd->type)
					Com_Error(ERR_DROP, "CL_ParticleFunction: bad vector dimensions for mul/div (particle %s)", p->ctrl->name);

				for (i = 0; i < n; i++) {
					if (cmd->cmd == PC_DIV)
						arg = 1.0 / (*((float *) cmdData + i));
					else
						arg = *((float *) cmdData + i);
					*((float *) stackPtr[stackIdx - 1] + i) *= arg;
				}
				break;
			}

			if (cmd->type > V_FLOAT)
				Com_Error(ERR_DROP, "CL_ParticleFunction: bad vector dimensions for mul/div (particle %s)", p->ctrl->name);

			/* scalar multiplication with scalar in second argument */
			if (cmd->cmd == PC_DIV)
				arg = 1.0 / (*(float *) cmdData);
			else
				arg = *(float *) cmdData;
			for (i = 0; i < n; i++)
				*((float *) stackPtr[stackIdx - 1] + i) *= arg;

			break;

		case PC_SIN:
			if (cmd->type != V_FLOAT)
				Com_Error(ERR_DROP, "CL_ParticleFunction: bad type '%s' for sin (particle %s)", vt_names[stackType[stackIdx - 1]], p->ctrl->name);
			stackPtr[stackIdx] = &cmdStack[e];
			stackType[stackIdx] = cmd->type;
			*(float *) stackPtr[stackIdx++] = sin(*(float *) cmdData * (2 * M_PI));
			e += sizeof(float);
			break;

		case PC_COS:
			if (cmd->type != V_FLOAT)
				Com_Error(ERR_DROP, "CL_ParticleFunction: bad type '%s' for cos (particle %s)", vt_names[stackType[stackIdx - 1]], p->ctrl->name);
			stackPtr[stackIdx] = &cmdStack[e];
			stackType[stackIdx] = cmd->type;
			*(float *) stackPtr[stackIdx++] = sin(*(float *) cmdData * (2 * M_PI));
			e += sizeof(float);
			break;

		case PC_TAN:
			if (cmd->type != V_FLOAT)
				Com_Error(ERR_DROP, "CL_ParticleFunction: bad type '%s' for tan (particle %s)", vt_names[stackType[stackIdx - 1]], p->ctrl->name);
			stackPtr[stackIdx] = &cmdStack[e];
			stackType[stackIdx] = cmd->type;
			*(float *) stackPtr[stackIdx++] = sin(*(float *) cmdData * (2 * M_PI));
			e += sizeof(float);
			break;

		case PC_RAND:
		case PC_CRAND:
			stackPtr[stackIdx] = &cmdStack[e];
			stackType[stackIdx] = cmd->type;

			n = cmd->type - V_FLOAT + 1;

			if (cmd->cmd == PC_RAND)
				for (i = 0; i < n; i++)
					*((float *) stackPtr[stackIdx] + i) = *((float *) cmdData + i) * frand();
			else
				for (i = 0; i < n; i++)
					*((float *) stackPtr[stackIdx] + i) = *((float *) cmdData + i) * crand();

			e += n * sizeof(float);
			stackIdx++;
			break;

		case PC_V2:
		case PC_V3:
		case PC_V4:
			n = cmd->cmd - PC_V2 + 2;
			j = 0;

			if (stackIdx < n)
				Com_Error(ERR_DROP, "CL_ParticleFunction: stack underflow");

			for (i = 0; i < n; i++) {
				if (!((1 << stackType[--stackIdx]) & V_VECS))
					Com_Error(ERR_DROP, "CL_ParticleFunction: bad type '%s' for vector creation (particle %s)", vt_names[stackType[stackIdx]], p->ctrl->name);
				j += stackType[stackIdx] - V_FLOAT + 1;
			}

			if (j > 4)
				Com_Error(ERR_DROP, "CL_ParticleFunction: created vector with dim > 4 (particle %s)", p->ctrl->name);

			stackType[stackIdx++] = V_FLOAT + j - 1;
			break;

		case PC_KILL:
			CL_ParticleFree(p);
			return;

		case PC_SPAWN:
			pnew = CL_ParticleSpawn((const char *) cmdData, p->levelFlags, p->s, p->v, p->a);
			if (!pnew)
				Com_Printf("PC_SPAWN: Could not spawn child particle for '%s' (%s)\n", p->ctrl->name, (const char *) cmdData);
			break;

		case PC_TNSPAWN:
			/* check for stack underflow */
			if (stackIdx < 2)
				Com_Error(ERR_DROP, "CL_ParticleFunction: stack underflow");

			/* pop elements off the stack */
			/* amount of timed particles */
			type = stackType[--stackIdx];
			if (type != V_INT)
				Com_Error(ERR_DROP, "CL_ParticleFunction: bad type '%s' int required for tnspawn (particle %s)", vt_names[stackType[stackIdx]], p->ctrl->name);
			n = *(int *) stackPtr[stackIdx];

			/* delta time */
			type = stackType[--stackIdx];
			if (type != V_INT)
				Com_Error(ERR_DROP, "CL_ParticleFunction: bad type '%s' int required for tnspawn (particle %s)", vt_names[stackType[stackIdx]], p->ctrl->name);
			i = *(int *) stackPtr[stackIdx];

			/** @todo make the children boolean configurable */
			CL_ParticleSpawnTimed((const char *) cmdData, p, true, i, n);

			e -= 2 * sizeof(int);

			break;

		case PC_NSPAWN:
			/* check for stack underflow */
			if (stackIdx == 0)
				Com_Error(ERR_DROP, "CL_ParticleFunction: stack underflow");

			type = stackType[--stackIdx];
			if (type != V_INT)
				Com_Error(ERR_DROP, "CL_ParticleFunction: bad type '%s' int required for nspawn (particle %s)", vt_names[stackType[stackIdx]], p->ctrl->name);

			n = *(int *) stackPtr[stackIdx];
			e -= sizeof(int);

			for (i = 0; i < n; i++) {
				pnew = CL_ParticleSpawn((const char *) cmdData, p->levelFlags, p->s, p->v, p->a);
				if (!pnew)
					Com_Printf("PC_NSPAWN: Could not spawn child particle for '%s'\n", p->ctrl->name);
			}
			break;

		case PC_CHILD:
			pnew = CL_ParticleSpawn((const char *)cmdData, p->levelFlags, p->s, p->v, p->a);
			if (pnew) {
				pnew->next = p->children;
				pnew->parent = p;
				p->children = pnew;
			} else {
				Com_Printf("PC_CHILD: Could not spawn child particle for '%s'\n", p->ctrl->name);
			}
			break;

		default:
			Com_Error(ERR_DROP, "CL_ParticleFunction: unknown cmd type %i", cmd->type);
			break;
		}
	}
}
Example #2
0
void CLQ2_RailTrail( vec3_t start, vec3_t end ) {
	byte clr = 0x74;

	vec3_t move;
	VectorCopy( start, move );
	vec3_t vec;
	VectorSubtract( end, start, vec );
	float len = VectorNormalize( vec );

	vec3_t right, up;
	MakeNormalVectors( vec, right, up );

	for ( int i = 0; i < len; i++ ) {
		cparticle_t* p = CL_AllocParticle();
		if ( !p ) {
			return;
		}

		p->type = pt_q2static;

		VectorClear( p->accel );

		float d = i * 0.1;
		float c = cos( d );
		float s = sin( d );

		vec3_t dir;
		VectorScale( right, c, dir );
		VectorMA( dir, s, up, dir );

		p->alpha = 1.0;
		p->alphavel = -1.0 / ( 1 + frand() * 0.2 );
		p->color = clr + ( rand() & 7 );
		for ( int j = 0; j < 3; j++ ) {
			p->org[ j ] = move[ j ] + dir[ j ] * 3;
			p->vel[ j ] = dir[ j ] * 6;
		}

		VectorAdd( move, vec, move );
	}

	float dec = 0.75;
	VectorScale( vec, dec, vec );
	VectorCopy( start, move );

	while ( len > 0 ) {
		len -= dec;

		cparticle_t* p = CL_AllocParticle();
		if ( !p ) {
			return;
		}
		p->type = pt_q2static;

		VectorClear( p->accel );

		p->alpha = 1.0;
		p->alphavel = -1.0 / ( 0.6 + frand() * 0.2 );
		p->color = rand() & 15;

		for ( int j = 0; j < 3; j++ ) {
			p->org[ j ] = move[ j ] + crand() * 3;
			p->vel[ j ] = crand() * 3;
			p->accel[ j ] = 0;
		}

		VectorAdd( move, vec, move );
	}
}
Example #3
0
void CLQ2_TrapParticles( vec3_t origin ) {
	origin[ 2 ] -= 14;
	vec3_t start;
	VectorCopy( origin, start );
	vec3_t end;
	VectorCopy( origin, end );
	origin[ 2 ] += 14;
	end[ 2 ] += 64;

	vec3_t move;
	VectorCopy( start, move );
	vec3_t vec;
	VectorSubtract( end, start, vec );
	float len = VectorNormalize( vec );

	int dec = 5;
	VectorScale( vec, 5, vec );

	// FIXME: this is a really silly way to have a loop
	while ( len > 0 ) {
		len -= dec;

		cparticle_t* p = CL_AllocParticle();
		if ( !p ) {
			return;
		}
		p->type = pt_q2static;
		VectorClear( p->accel );

		p->alpha = 1.0;
		p->alphavel = -1.0 / ( 0.3 + frand() * 0.2 );
		p->color = 0xe0;
		for ( int j = 0; j < 3; j++ ) {
			p->org[ j ] = move[ j ] + crand();
			p->vel[ j ] = crand() * 15;
			p->accel[ j ] = 0;
		}
		p->accel[ 2 ] = PARTICLE_GRAVITY;

		VectorAdd( move, vec, move );
	}

	vec3_t org;
	VectorCopy( origin, org );

	for ( int i = -2; i <= 2; i += 4 ) {
		for ( int j = -2; j <= 2; j += 4 ) {
			for ( int k = -2; k <= 2; k += 4 ) {
				cparticle_t* p = CL_AllocParticle();
				if ( !p ) {
					return;
				}
				p->type = pt_q2static;

				p->color = 0xe0 + ( rand() & 3 );

				p->alpha = 1.0;
				p->alphavel = -1.0 / ( 0.3 + ( rand() & 7 ) * 0.02 );

				p->org[ 0 ] = org[ 0 ] + i + ( ( rand() & 23 ) * crand() );
				p->org[ 1 ] = org[ 1 ] + j + ( ( rand() & 23 ) * crand() );
				p->org[ 2 ] = org[ 2 ] + k + ( ( rand() & 23 ) * crand() );

				vec3_t dir;
				dir[ 0 ] = j * 8;
				dir[ 1 ] = i * 8;
				dir[ 2 ] = k * 8;

				VectorNormalize( dir );
				float vel = 50 + ( rand() & 63 );
				VectorScale( dir, vel, p->vel );

				p->accel[ 0 ] = p->accel[ 1 ] = 0;
				p->accel[ 2 ] = -PARTICLE_GRAVITY;
			}
		}
	}
}
Example #4
0
void CL_Heatbeam (vec3_t start, vec3_t end)
{
	vec3_t		move;
	vec3_t		vec;
	float		len;
	int			j;
	cparticle_t	*p;
	vec3_t		forward, right, up;
	int			i;
	float		d, c, s;
	vec3_t		dir;
	float		ltime;
	float		step = 32.0, rstep;
	float		start_pt;
	float		rot;

	VectorCopy (start, move);
	VectorSubtract (end, start, vec);
	len = VectorNormalize (vec);

//	MakeNormalVectors (vec, right, up);
	VectorCopy (cl.v_forward, forward);
	VectorCopy (cl.v_right, right);
	VectorCopy (cl.v_up, up);
	VectorMA (move, -0.5, right, move);
	VectorMA (move, -0.5, up, move);

	for (i=0; i<8; i++)
	{
		if (!free_particles)
			return;

		p = free_particles;
		free_particles = p->next;
		p->next = active_particles;
		active_particles = p;
		
		p->time = cl.time;
		VectorClear (p->accel);
		
		d = crand()*M_PI;
		c = cos(d)*30;
		s = sin(d)*30;

		p->alpha = 1.0;
		p->alphavel = -5.0 / (1+frand());
		p->color = 223 - (rand()&7);

		for (j=0 ; j<3 ; j++)
		{
			p->org[j] = move[j];
		}
		VectorScale (vec, 450, p->vel);
		VectorMA (p->vel, c, right, p->vel);
		VectorMA (p->vel, s, up, p->vel);
	}
/*

	ltime = (float) cl.time/1000.0;
	start_pt = fmod(ltime*16.0,step);
	VectorMA (move, start_pt, vec, move);

	VectorScale (vec, step, vec);

//	Com_Printf ("%f\n", ltime);
	rstep = M_PI/12.0;
	for (i=start_pt ; i<len ; i+=step)
	{
		if (i>step*5) // don't bother after the 5th ring
			break;

		for (rot = 0; rot < M_PI*2; rot += rstep)
		{
			if (!free_particles)
				return;

			p = free_particles;
			free_particles = p->next;
			p->next = active_particles;
			active_particles = p;
			
			p->time = cl.time;
			VectorClear (p->accel);
//			rot+= fmod(ltime, 12.0)*M_PI;
//			c = cos(rot)/2.0;
//			s = sin(rot)/2.0;
			c = cos(rot)/1.5;
			s = sin(rot)/1.5;
			
			// trim it so it looks like it's starting at the origin
			if (i < 10)
			{
				VectorScale (right, c*(i/10.0), dir);
				VectorMA (dir, s*(i/10.0), up, dir);
			}
			else
			{
				VectorScale (right, c, dir);
				VectorMA (dir, s, up, dir);
			}
		
			p->alpha = 0.5;
	//		p->alphavel = -1.0 / (1+frand()*0.2);
			p->alphavel = -1000.0;
	//		p->color = 0x74 + (rand()&7);
			p->color = 223 - (rand()&7);
			for (j=0 ; j<3 ; j++)
			{
				p->org[j] = move[j] + dir[j]*3;
	//			p->vel[j] = dir[j]*6;
				p->vel[j] = 0;
			}
		}
		VectorAdd (move, vec, move);
	}
*/
}
Example #5
0
void CLQ2_DiminishingTrail( vec3_t start, vec3_t end, q2centity_t* old, int flags ) {
	vec3_t move;
	VectorCopy( start, move );
	vec3_t vec;
	VectorSubtract( end, start, vec );
	float len = VectorNormalize( vec );

	float dec = 0.5;
	VectorScale( vec, dec, vec );

	float orgscale;
	float velscale;
	if ( old->trailcount > 900 ) {
		orgscale = 4;
		velscale = 15;
	} else if ( old->trailcount > 800 ) {
		orgscale = 2;
		velscale = 10;
	} else {
		orgscale = 1;
		velscale = 5;
	}

	while ( len > 0 ) {
		len -= dec;

		// drop less particles as it flies
		if ( ( rand() & 1023 ) < old->trailcount ) {
			cparticle_t* p = CL_AllocParticle();
			if ( !p ) {
				return;
			}
			p->type = pt_q2static;
			VectorClear( p->accel );

			if ( flags & Q2EF_GIB ) {
				p->alpha = 1.0;
				p->alphavel = -1.0 / ( 1 + frand() * 0.4 );
				p->color = 0xe8 + ( rand() & 7 );
				for ( int j = 0; j < 3; j++ ) {
					p->org[ j ] = move[ j ] + crand() * orgscale;
					p->vel[ j ] = crand() * velscale;
					p->accel[ j ] = 0;
				}
				p->vel[ 2 ] -= PARTICLE_GRAVITY;
			} else if ( flags & Q2EF_GREENGIB ) {
				p->alpha = 1.0;
				p->alphavel = -1.0 / ( 1 + frand() * 0.4 );
				p->color = 0xdb + ( rand() & 7 );
				for ( int j = 0; j < 3; j++ ) {
					p->org[ j ] = move[ j ] + crand() * orgscale;
					p->vel[ j ] = crand() * velscale;
					p->accel[ j ] = 0;
				}
				p->vel[ 2 ] -= PARTICLE_GRAVITY;
			} else {
				p->alpha = 1.0;
				p->alphavel = -1.0 / ( 1 + frand() * 0.2 );
				p->color = 4 + ( rand() & 7 );
				for ( int j = 0; j < 3; j++ ) {
					p->org[ j ] = move[ j ] + crand() * orgscale;
					p->vel[ j ] = crand() * velscale;
				}
				p->accel[ 2 ] = 20;
			}
		}

		old->trailcount -= 5;
		if ( old->trailcount < 100 ) {
			old->trailcount = 100;
		}
		VectorAdd( move, vec, move );
	}
}
Example #6
0
/*
===============
CL_RailTrail

===============
*/
void CL_RailTrail (vec3_t start, vec3_t end)
{
	vec3_t		move;
	vec3_t		vec;
	float		len;
	int			j;
	cparticle_t	*p;
	float		dec;
	vec3_t		right, up;
	int			i;
	float		d, c, s;
	vec3_t		dir;
	byte		clr = 0x74;

	VectorCopy (start, move);
	VectorSubtract (end, start, vec);
	len = VectorNormalize (vec);

	MakeNormalVectors (vec, right, up);

	for (i=0 ; i<len ; i++)
	{
		if (!free_particles)
			return;

		p = free_particles;
		free_particles = p->next;
		p->next = active_particles;
		active_particles = p;

		p->time = cl.time;
		VectorClear (p->accel);

		d = i * 0.1;
		c = cos(d);
		s = sin(d);

		VectorScale (right, c, dir);
		VectorMA (dir, s, up, dir);

		p->alpha = 1.0;
		p->alphavel = -1.0 / (1+frand()*0.2);
		p->color = clr + (rand()&7);
		for (j=0 ; j<3 ; j++)
		{
			p->org[j] = move[j] + dir[j]*3;
			p->vel[j] = dir[j]*6;
		}

		VectorAdd (move, vec, move);
	}

	dec = 0.75;
	VectorScale (vec, dec, vec);
	VectorCopy (start, move);

	while (len > 0)
	{
		len -= dec;

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

		p->time = cl.time;
		VectorClear (p->accel);

		p->alpha = 1.0;
		p->alphavel = -1.0 / (0.6+frand()*0.2);
		p->color = 0x0 + rand()&15;

		for (j=0 ; j<3 ; j++)
		{
			p->org[j] = move[j] + crand()*3;
			p->vel[j] = crand()*3;
			p->accel[j] = 0;
		}

		VectorAdd (move, vec, move);
	}
}
Example #7
0
// RAFAEL
void CL_TrapParticles (entity_t *ent)
{
	vec3_t		move;
	vec3_t		vec;
	vec3_t		start, end;
	float		len;
	int			j;
	cparticle_t	*p;
	int			dec;

	ent->origin[2]-=14;
	VectorCopy (ent->origin, start);
	VectorCopy (ent->origin, end);
	end[2]+=64;

	VectorCopy (start, move);
	VectorSubtract (end, start, vec);
	len = VectorNormalize (vec);

	dec = 5;
	VectorScale (vec, 5, vec);

	// FIXME: this is a really silly way to have a loop
	while (len > 0)
	{
		len -= dec;

		if (!free_particles)
			return;
		p = free_particles;
		free_particles = p->next;
		p->next = active_particles;
		active_particles = p;
		VectorClear (p->accel);

		p->time = cl.time;

		p->alpha = 1.0;
		p->alphavel = -1.0 / (0.3+frand()*0.2);
		p->color = 0xe0;
		for (j=0 ; j<3 ; j++)
		{
			p->org[j] = move[j] + crand();
			p->vel[j] = crand()*15;
			p->accel[j] = 0;
		}
		p->accel[2] = PARTICLE_GRAVITY;

		VectorAdd (move, vec, move);
	}

	{


	int			i, j, k;
	cparticle_t	*p;
	float		vel;
	vec3_t		dir;
	vec3_t		org;


	ent->origin[2]+=14;
	VectorCopy (ent->origin, org);


	for (i=-2 ; i<=2 ; i+=4)
		for (j=-2 ; j<=2 ; j+=4)
			for (k=-2 ; k<=4 ; k+=4)
			{
				if (!free_particles)
					return;
				p = free_particles;
				free_particles = p->next;
				p->next = active_particles;
				active_particles = p;

				p->time = cl.time;
				p->color = 0xe0 + (rand()&3);

				p->alpha = 1.0;
				p->alphavel = -1.0 / (0.3 + (rand()&7) * 0.02);

				p->org[0] = org[0] + i + ((rand()&23) * crand());
				p->org[1] = org[1] + j + ((rand()&23) * crand());
				p->org[2] = org[2] + k + ((rand()&23) * crand());

				dir[0] = j * 8;
				dir[1] = i * 8;
				dir[2] = k * 8;

				VectorNormalize (dir);
				vel = 50 + rand()&63;
				VectorScale (dir, vel, p->vel);

				p->accel[0] = p->accel[1] = 0;
				p->accel[2] = -PARTICLE_GRAVITY;
			}
	}
}
Example #8
0
/*
===============
CL_RailTrail

===============
*/
void CL_RailTrail (const vec3_t start, const vec3_t end)
{
	vec3_t		move, vec, right, up, dir;
	float		len, dec, c, s;
	cparticle_t	*p;
	int			i;
	byte		clr = 0x74;
	cdlight_t *dl;

	VectorCopy (start, move);
	VectorSubtract (end, start, vec);
	len = VectorNormalize (vec);

	// add a light at the dest
	dl = CL_AllocDlight(0);
	VectorCopy(end, dl->origin);
	dl->radius = 100;
	dl->die = cl.time + 200;
	VectorSet(dl->color, 0.3, 0.5, 1.0);

	MakeNormalVectors (vec, right, up);

	for (i=0 ; i<len ; i++)
	{

		if(i % 3 == 0){
			VectorAdd(move, vec, move);
			continue;
		}

		if (!free_particles)
			return;

		p = free_particles;
		free_particles = p->next;
		p->next = active_particles;
		active_particles = p;
		
		p->time = cl.time;
		VectorClear (p->accel);

		Q_sincos(i * 0.1f, &s, &c);

		VectorScale (right, c, dir);
		VectorMA (dir, s, up, dir);

		p->alpha = 1.0f;
		p->alphavel = -1.0f / (1.0f+frand()*0.2f);
		p->color = clr + (rand()&7);

		p->org[0] = move[0] + dir[0]*3;
		p->org[1] = move[1] + dir[1]*3;
		p->org[2] = move[2] + dir[2]*3;
		p->vel[0] = dir[0]*6;
		p->vel[1] = dir[1]*6;
		p->vel[2] = dir[2]*6;

		VectorAdd (move, vec, move);
	}

	dec = 2.0f;
	VectorScale (vec, dec, vec);
	VectorCopy (start, move);

	while (len > 0)
	{
		len -= dec;

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

		p->time = cl.time;
		VectorClear (p->accel);

		p->alpha = 1.0f;
		p->alphavel = -1.0f / (0.6f+frand()*0.2f);
		p->color = 0x0 + (rand()&15);

		p->org[0] = move[0] + crand()*3;
		p->org[1] = move[1] + crand()*3;
		p->org[2] = move[2] + crand()*3;
		p->vel[0] = crand()*3;
		p->vel[1] = crand()*3;
		p->vel[2] = crand()*3;

		VectorAdd (move, vec, move);
	}
}
Example #9
0
/*
===============
CL_DiminishingTrail

===============
*/
void CL_DiminishingTrail (vec3_t start, vec3_t end, centity_t *old, int flags)
{
	vec3_t		move;
	vec3_t		vec;
	float		len;
	int			j;
	cparticle_t	*p;
	float		dec;
	float		orgscale;
	float		velscale;

	VectorCopy (start, move);
	VectorSubtract (end, start, vec);
	len = VectorNormalize (vec);

	dec = 0.5;
	VectorScale (vec, dec, vec);

	if (old->trailcount > 900)
	{
		orgscale = 4;
		velscale = 15;
	}
	else if (old->trailcount > 800)
	{
		orgscale = 2;
		velscale = 10;
	}
	else
	{
		orgscale = 1;
		velscale = 5;
	}

	while (len > 0)
	{
		len -= dec;

		if (!free_particles)
			return;

		// drop less particles as it flies
		if ((rand()&1023) < old->trailcount)
		{
			p = free_particles;
			free_particles = p->next;
			p->next = active_particles;
			active_particles = p;
			VectorClear (p->accel);

			p->time = cl.time;

			if (flags & EF_GIB)
			{
				p->alpha = 1.0;
				p->alphavel = -1.0 / (1+frand()*0.4);
				p->color = 0xe8 + (rand()&7);
				for (j=0 ; j<3 ; j++)
				{
					p->org[j] = move[j] + crand()*orgscale;
					p->vel[j] = crand()*velscale;
					p->accel[j] = 0;
				}
				p->vel[2] -= PARTICLE_GRAVITY;
			}
			else if (flags & EF_GREENGIB)
			{
				p->alpha = 1.0;
				p->alphavel = -1.0 / (1+frand()*0.4);
				p->color = 0xdb + (rand()&7);
				for (j=0; j< 3; j++)
				{
					p->org[j] = move[j] + crand()*orgscale;
					p->vel[j] = crand()*velscale;
					p->accel[j] = 0;
				}
				p->vel[2] -= PARTICLE_GRAVITY;
			}
			else
			{
				p->alpha = 1.0;
				p->alphavel = -1.0 / (1+frand()*0.2);
				p->color = 4 + (rand()&7);
				for (j=0 ; j<3 ; j++)
				{
					p->org[j] = move[j] + crand()*orgscale;
					p->vel[j] = crand()*velscale;
				}
				p->accel[2] = 20;
			}
		}

		old->trailcount -= 5;
		if (old->trailcount < 100)
			old->trailcount = 100;
		VectorAdd (move, vec, move);
	}
}
Example #10
0
uint32_t random_days(uint8_t hour, uint8_t min, uint8_t sec, uint32_t base_days)
{
	init_crand_consistent(hour,min,sec);
	uint32_t random = (crand(0) * 1000) / 0x7FFF;
	return (uint32_t)((base_days * random) / 1000);
}
Example #11
0
/**
 * @brief Updates weather for the time passed; handles particle creation/removal automatically
 */
void Weather::update (int milliseconds)
{
	/* Don't play the weather particles if the user doesn't want them */
	if (!Cvar_GetInteger("cl_particleweather")) {
		/* This makes weather look very weird if it is enabled mid-battle */
		/* clearParticles(); */
		return;
	}

	size_t dead = 0;
	/* physics: check for ttl and move live particles */
	for (size_t i = 0; i < Weather::MAX_PARTICLES; i++) {
		Weather::particle &prt = particles[i];
		if (prt.ttl < 0) {
			dead++;
			continue;
		} else { /** @todo creates vanishing-before-impact particles at low framerates -- should improve that somehow */
			int restOfLife = prt.ttl -= milliseconds;
			if (restOfLife < 0) {
				if (fabs(prt.vz) < 0.001f || splashTime < 1) {
					/* either no splash or is a splash particle dying */
					dead++;
					continue;
				}
				/* convert it into splash particle */
				/* technically, we should complete the last frame of movement, but with current particle types it looks good even without it */
				prt.vz = 0; prt.vx = 0; prt.vy = 0;
				prt.ttl += splashTime;
			}
		}
		/* if we got so far, particle is alive and probably needs a physics update */
		const int timeAfterUpdate = prt.timeout -= milliseconds;
		const float moveDuration = milliseconds * 0.001f;

		prt.x += prt.vx * moveDuration; prt.y += prt.vy * moveDuration; prt.z += prt.vz * moveDuration;

		if (timeAfterUpdate > 0) {
			/* just move linearly */
			continue;
		}
		/* alter motion vector */
		/** @todo */
	}
	/* create new ones in place of dead */
	if (dead) {
		const float windX = cos(windDirection) * (windStrength + crand() * windTurbulence);
		const float windY = sin(windDirection) * (windStrength + crand() * windTurbulence);

		AABB weatherZone; /** < extents of zone in which weather particles will be rendered */
		weatherZone = cl.mapData->mapBox;
		weatherZone.expandXY(256);
		weatherZone.maxs[2] += 512;

		Line prtPath;

		if (dead > 200) dead = 200; /* avoid creating too much particles in the single frame, it could kill the low-end hardware */

		int debugCreated = 0;
		for (size_t i = 0; dead &&  i < Weather::MAX_PARTICLES && i < weatherStrength * Weather::MAX_PARTICLES; i++) {
			Weather::particle &prt = particles[i];
			if (prt.ttl >= 0)
				continue;
			prt.x = (frand() * (weatherZone.getMaxX() - weatherZone.getMinX())) + weatherZone.getMinX();
			prt.y = (frand() * (weatherZone.getMaxY() - weatherZone.getMinY())) + weatherZone.getMinY();
			prt.z = weatherZone.getMaxZ();

			prt.vx = windX;
			prt.vy = windY;
			prt.vz = -fallingSpeed * (frand() * 0.2f + 0.9f);

			float lifeTime = (weatherZone.getMaxZ() - weatherZone.getMinZ()) / -prt.vz; /* default */

			VectorSet(prtPath.start, prt.x, prt.y, prt.z);
			VectorSet(prtPath.stop, prt.x + prt.vx * lifeTime, prt.y + prt.vy * lifeTime, prt.z + prt.vz * lifeTime);

			trace_t trace = CL_Trace(prtPath, AABB::EMPTY, nullptr, nullptr, MASK_SOLID, cl.mapMaxLevel - 1); /* find the collision point */
			lifeTime *= trace.fraction;

			prt.ttl = 1000 * lifeTime; /* convert to milliseconds */

			prt.timeout = prt.ttl + 1000000; /** @todo proper code for physics */
			debugCreated++;
			dead--;
		}
	}
#if 0
	if (debugCreated) Com_Printf("created %i weather particles\n", debugCreated);
#endif
}
Example #12
0
/*
===============
CL_BubbleTrail2 (lets you control the # of bubbles by setting the distance between the spawns)

===============
*/
void CL_BubbleTrail2 (vec3_t start, vec3_t end, int dist)
{
	vec3_t		move;
	vec3_t		vec;
	float		len;
	int			i;
#ifndef QMAX
	int j;
	cparticle_t	*p;
#endif
	float		dec;

	VectorCopy (start, move);
	VectorSubtract (end, start, vec);
	len = VectorNormalize (vec);

	dec = dist;
	VectorScale (vec, dec, vec);

	for (i=0 ; i<len ; i+=dec)
	{
#ifdef QMAX
		setupParticle (
			0,	0,	0,
			move[0]+crand()*2,	move[1]+crand()*2,	move[2]+crand()*2,
			crand()*5,	crand()*5,	crand()*5+6,
			0,		0,		0,
			255,	255,	255,
			0,	0,	0,
			0.75,		-1.0 / (1 + frand() * 0.2),
			(frand()>0.25)? 1 : (frand()>0.5) ? 2 : (frand()>0.75) ? 3 : 4,			1,			
			particle_bubble,
			PART_TRANS|PART_SHADED,
			NULL,0);
#else
		if (!free_particles)
		  return;
		
		p = free_particles;
		free_particles = p->next;
		p->next = active_particles;
		active_particles = p;

		VectorClear (p->accel);
		p->time = cl.time;

		p->alpha = 1.0;
		p->alphavel = -1.0 / (1+frand()*0.1);
		p->color = 4 + (rand()&7);
		for (j=0 ; j<3 ; j++)
		{
			p->org[j] = move[j] + crand()*2;
			p->vel[j] = crand()*10;
		}
		p->org[2] -= 4;
//		p->vel[2] += 6;
		p->vel[2] += 20;
#endif
		VectorAdd (move, vec, move);
	}
}
Example #13
0
void CL_FlameEffects (centity_t *ent, vec3_t origin)
{
	int			n, count;
	int			j;
	cparticle_t	*p;

	count = rand() & 0xF;

	for(n=0;n<count;n++)
	{
		if (!free_particles)
			return;
			
		p = free_particles;
		free_particles = p->next;
		p->next = active_particles;
		active_particles = p;
		
		VectorClear (p->accel);
		p->time = cl.time;

		p->alpha = 1.0;
		p->alphavel = -1.0 / (1+frand()*0.2);
#ifndef QMAX
		p->color = 226 + (rand() % 4);
#endif
		for (j=0 ; j<3 ; j++)
		{
			p->org[j] = origin[j] + crand()*5;
			p->vel[j] = crand()*5;
		}
		p->vel[2] = crand() * -10;
		p->accel[2] = -PARTICLE_GRAVITY;
	}

	count = rand() & 0x7;

	for(n=0;n<count;n++)
	{
		if (!free_particles)
			return;
		p = free_particles;
		free_particles = p->next;
		p->next = active_particles;
		active_particles = p;
		VectorClear (p->accel);
		
		p->time = cl.time;

		p->alpha = 1.0;
		p->alphavel = -1.0 / (1+frand()*0.5);
#ifndef QMAX
		p->color = 0 + (rand() % 4);
#endif		
		for (j=0 ; j<3 ; j++)
		{
			p->org[j] = origin[j] + crand()*3;
		}
		p->vel[2] = 20 + crand()*5;
	}

}
Example #14
0
void CL_ForceWall (vec3_t start, vec3_t end, int color8)
{
	vec3_t		move;
	vec3_t		vec;
#ifdef QMAX
	vec3_t color = { color8red(color8), color8green(color8), color8blue(color8)};
#else
	int			j;
	cparticle_t	*p;
#endif

	float		len;

	VectorCopy (start, move);
	VectorSubtract (end, start, vec);
	len = VectorNormalize (vec);

	VectorScale (vec, 4, vec);

	// FIXME: this is a really silly way to have a loop
	while (len > 0)
	{
		len -= 4;

		if (!free_particles)
			return;
		
		if (frand() > 0.3)
		{
#ifdef QMAX
		  setupParticle (
				 0,	0,	0,
				 move[0] + crand()*3,	move[1] + crand()*3,	move[2] + crand()*3,
				 0,	0,	-40 - (crand()*10),
				 0,		0,		0,
				 color[0]+5,	color[1]+5,	color[2]+5,
				 0,	0,	0,
				 1,		-1.0 / (3.0+frand()*0.5),
				 5,			0,			
				 particle_generic,
				 0,
				 NULL,0);
#else	
		  p = free_particles;
		  free_particles = p->next;
		  p->next = active_particles;
		  active_particles = p;
		  VectorClear (p->accel);
		  
		  p->time = cl.time;
		  
		  p->alpha = 1.0;
		  p->alphavel =  -1.0 / (3.0+frand()*0.5);
		  p->color = color8;
		  for (j=0 ; j<3 ; j++)
		    {
		      p->org[j] = move[j] + crand()*3;
		      p->accel[j] = 0;
		    }
		  p->vel[0] = 0;
		  p->vel[1] = 0;
		  p->vel[2] = -40 - (crand()*10);
#endif

		}

		VectorAdd (move, vec, move);
	}
}