예제 #1
0
 /* ========================================================================= */
 void
 CL_ParseParticles ( void )
 {
   q_int32_t color, count;
   vec3_t pos, dir;
   MSG_ReadPos ( &net_message, pos );
   MSG_ReadDir ( &net_message, dir );
   color = MSG_ReadByte ( &net_message );
   count = MSG_ReadByte ( &net_message );
   CL_ParticleEffect ( pos, dir, color, count );
 }
예제 #2
0
void CL_ParseTEnt (void)
{
	int32_t		type;
	vec3_t	pos, pos2, dir;
	explosion_t	*ex;
	int32_t		cnt;
	int32_t		color;
	int32_t		r, i;
	int32_t		ent;
	int32_t		magnitude;

	type = MSG_ReadByte (&net_message);

	switch (type)
	{
	case TE_BLOOD:			// bullet hitting flesh
		MSG_ReadPos (&net_message, pos);
		MSG_ReadDir (&net_message, dir);
	// Psychospaz's enhanced particle code
		CL_BloodHit (pos, dir);
		break;

	case TE_GUNSHOT:			// bullet hitting wall
	case TE_SPARKS:
	case TE_BULLET_SPARKS:
		MSG_ReadPos (&net_message, pos);
		MSG_ReadDir (&net_message, dir);
	// Psychospaz's enhanced particle code
		if (type == TE_BULLET_SPARKS)
			VectorScale(dir, 2, dir);
		{
			vec3_t color = { 255, 125, 10 };
			CL_ParticleEffectSparks (pos, dir, color, (type == TE_GUNSHOT)? 5 : 10);
		}

		if (type != TE_SPARKS)
		{
			CL_GunSmokeEffect (pos, dir);
			if (type == TE_GUNSHOT || type == TE_BULLET_SPARKS)
				CL_ParticleBulletDecal(pos, dir, 2.5);
			// impact sound
			cnt = rand()&15;
			if (cnt == 1)
				S_StartSound (pos, 0, 0, clMedia.sfx_ric[0], 1, ATTN_NORM, 0);
			else if (cnt == 2)
				S_StartSound (pos, 0, 0, clMedia.sfx_ric[1], 1, ATTN_NORM, 0);
			else if (cnt == 3)
				S_StartSound (pos, 0, 0, clMedia.sfx_ric[2], 1, ATTN_NORM, 0);
		}
		break;
				
	case TE_SHOTGUN:			// bullet hitting wall
		MSG_ReadPos (&net_message, pos);
		MSG_ReadDir (&net_message, dir);
	// Psychospaz's enhanced particle code
		CL_GunSmokeEffect (pos, dir);
		CL_ParticleBulletDecal(pos, dir, 2.8);
		{
			vec3_t color = { 200, 100, 10 };
			CL_ParticleEffectSparks (pos, dir, color, 8);
		}
		break;

	case TE_SCREEN_SPARKS:
	case TE_SHIELD_SPARKS:
		MSG_ReadPos (&net_message, pos);
		MSG_ReadDir (&net_message, dir);
		if (type == TE_SCREEN_SPARKS)
			CL_ParticleEffect (pos, dir, 0xd0, 40);
		else
			CL_ParticleEffect (pos, dir, 0xb0, 40);
		//FIXME : replace or remove this sound
		S_StartSound (pos, 0, 0, clMedia.sfx_lashit, 1, ATTN_NORM, 0);
		break;

	case TE_SPLASH:			// bullet hitting water
		cnt = MSG_ReadByte (&net_message);
		cnt = min(cnt, 40); // cap at 40
		MSG_ReadPos (&net_message, pos);
		MSG_ReadDir (&net_message, dir);
		r = MSG_ReadByte (&net_message);
		if (r > 6)
			color = 0x00;
		else
			color = splash_color[r];
		// Psychospaz's enhanced particle code
		if (r == SPLASH_SPARKS)
		{
			CL_ParticleEffectSplashSpark (pos, dir, color, cnt);
			r = rand() & 3;
			if (r == 0)
				S_StartSound (pos, 0, 0, clMedia.sfx_spark[0], 1, ATTN_STATIC, 0);
			else if (r == 1)
				S_StartSound (pos, 0, 0, clMedia.sfx_spark[1], 1, ATTN_STATIC, 0);
			else
				S_StartSound (pos, 0, 0, clMedia.sfx_spark[2], 1, ATTN_STATIC, 0);
		} else {
			CL_ParticleEffectSplash (pos, dir, color, cnt);
		}
		break;

	case TE_LASER_SPARKS:
		cnt = MSG_ReadByte (&net_message);
		MSG_ReadPos (&net_message, pos);
		MSG_ReadDir (&net_message, dir);
		color = MSG_ReadByte (&net_message);
		CL_ParticleEffect2 (pos, dir, color, cnt);
		break;

	case TE_RAILTRAIL:			// railgun effect
		MSG_ReadPos (&net_message, pos);
		MSG_ReadPos (&net_message, pos2);
		CL_RailTrail (pos, pos2, false);
		S_StartSound (pos2, 0, 0, clMedia.sfx_railg, 1, ATTN_NORM, 0);
		break;
	// 12/23/2001 - red railgun trail
	case TE_RAILTRAIL2:			// red railgun effect
		MSG_ReadPos (&net_message, pos);
		MSG_ReadPos (&net_message, pos2);
		CL_RailTrail (pos, pos2, true);
		S_StartSound (pos2, 0, 0, clMedia.sfx_railg, 1, ATTN_NORM, 0);
		break;

	case TE_EXPLOSION2:
	case TE_GRENADE_EXPLOSION:
	case TE_GRENADE_EXPLOSION_WATER:
		MSG_ReadPos (&net_message, pos);
		ex = CL_AllocExplosion ();
		VectorCopy (pos, ex->ent.origin);
		ex->type = ex_poly;
		ex->ent.flags = RF_FULLBRIGHT|RF_NOSHADOW; // noshadow flag
		ex->start = cl.frame.servertime - 100;
		ex->light = 350;
		ex->lightcolor[0] = 1.0;
		ex->lightcolor[1] = 0.5;
		ex->lightcolor[2] = 0.5;
		ex->ent.model = clMedia.mod_explo;
		ex->frames = 19;
		ex->baseframe = 30;
		ex->ent.angles[1] = rand() % 360;
		CL_Explosion_Sparks (pos, 16, 128);
		if (type != TE_EXPLOSION2)
			CL_Explosion_Decal (pos, 50, particle_burnmark);
		if (type == TE_GRENADE_EXPLOSION_WATER)
			S_StartSound (pos, 0, 0, clMedia.sfx_watrexp, 1, ATTN_NORM, 0);
		else
			S_StartSound (pos, 0, 0, clMedia.sfx_grenexp, 1, ATTN_NORM, 0);
		break;

		// RAFAEL
	case TE_PLASMA_EXPLOSION:
		MSG_ReadPos (&net_message, pos);
		ex = CL_AllocExplosion ();
		VectorCopy (pos, ex->ent.origin);
		ex->type = ex_poly;
		ex->ent.flags = RF_FULLBRIGHT|RF_NOSHADOW; // noshadow flag
		ex->start = cl.frame.servertime - 100;
		ex->light = 350;
		ex->lightcolor[0] = 1.0; 
		ex->lightcolor[1] = 0.5;
		ex->lightcolor[2] = 0.5;
		ex->ent.angles[1] = rand() % 360;
		ex->ent.model = clMedia.mod_explo;
		if (frand() < 0.5)
			ex->baseframe = 15;
		ex->frames = 15;
		CL_Explosion_Sparks (pos, 16, 128);
		CL_Explosion_Decal (pos, 50, particle_burnmark);
		if (cl_plasma_explo_sound->value)
			S_StartSound (pos, 0, 0, clMedia.sfx_plasexp, 1, ATTN_NORM, 0);
		else
			S_StartSound (pos, 0, 0, clMedia.sfx_rockexp, 1, ATTN_NORM, 0);
		break;

	case TE_EXPLOSION1_BIG:						// PMM
		MSG_ReadPos (&net_message, pos);
		ex = CL_AllocExplosion ();
		VectorCopy (pos, ex->ent.origin);
		ex->type = ex_poly;
		ex->ent.flags = RF_FULLBRIGHT|RF_NOSHADOW; // noshadow flag
		ex->start = cl.frame.servertime - 100;
		ex->light = 350;
		ex->lightcolor[0] = 1.0;
		ex->lightcolor[1] = 0.5;
		ex->lightcolor[2] = 0.5;
		ex->ent.angles[1] = rand() % 360;
		ex->ent.model = clMedia.mod_explo_big;
		if (frand() < 0.5)
			ex->baseframe = 15;
		ex->frames = 15;
		CL_Explosion_Sparks (pos, 48, 128);
		S_StartSound (pos, 0, 0, clMedia.sfx_rockexp, 1, ATTN_NORM, 0);
		break;

	case TE_EXPLOSION1_NP:						// PMM
		MSG_ReadPos (&net_message, pos);
		ex = CL_AllocExplosion ();
		VectorCopy (pos, ex->ent.origin);
		ex->type = ex_poly;
		ex->ent.flags = RF_FULLBRIGHT|RF_NOSHADOW; // noshadow flag
		ex->start = cl.frame.servertime - 100;
		ex->light = 350;
		ex->lightcolor[0] = 1.0;
		ex->lightcolor[1] = 0.5;
		ex->lightcolor[2] = 0.5;
		ex->ent.angles[1] = rand() % 360;
		ex->ent.model = clMedia.mod_explo;
		if (frand() < 0.5)
			ex->baseframe = 15;
		ex->frames = 15;
		CL_Explosion_Sparks (pos, 10, 128);
		S_StartSound (pos, 0, 0, clMedia.sfx_grenexp, 1, ATTN_NORM, 0);
		break;

	case TE_EXPLOSION1:
	case TE_PLAIN_EXPLOSION:
	case TE_ROCKET_EXPLOSION:
	case TE_ROCKET_EXPLOSION_WATER:
		MSG_ReadPos (&net_message, pos);
		ex = CL_AllocExplosion ();
		VectorCopy (pos, ex->ent.origin);
		ex->type = ex_poly;
		ex->ent.flags = RF_FULLBRIGHT|RF_NOSHADOW; // noshadow flag
		ex->start = cl.frame.servertime - 100;
		ex->light = 350;
		ex->lightcolor[0] = 1.0;
		ex->lightcolor[1] = 0.5;
		ex->lightcolor[2] = 0.5;
		ex->ent.angles[1] = rand() % 360;
		ex->ent.model = clMedia.mod_explo;
		if (frand() < 0.5)
			ex->baseframe = 15;
		ex->frames = 15;
		CL_Explosion_Sparks (pos, 16, 128);
		if (type == TE_ROCKET_EXPLOSION || type == TE_ROCKET_EXPLOSION_WATER)
			CL_Explosion_Decal (pos, 50, particle_burnmark);
		if (type == TE_ROCKET_EXPLOSION_WATER)
			S_StartSound (pos, 0, 0, clMedia.sfx_watrexp, 1, ATTN_NORM, 0);
		else
			S_StartSound (pos, 0, 0, clMedia.sfx_rockexp, 1, ATTN_NORM, 0);
		break;

	case TE_BFG_EXPLOSION:
		MSG_ReadPos (&net_message, pos);
		ex = CL_AllocExplosion ();
		VectorCopy (pos, ex->ent.origin);
		ex->type = ex_poly;
		ex->ent.flags |= RF_FULLBRIGHT;
		ex->start = cl.frame.servertime - 100;
		ex->light = 350;
		ex->lightcolor[0] = 0.0;
		ex->lightcolor[1] = 1.0;
		ex->lightcolor[2] = 0.0;
		ex->ent.model = clMedia.mod_bfg_explo;
		ex->ent.flags |= RF_TRANSLUCENT | RF_TRANS_ADDITIVE;
		ex->ent.alpha = 0.30;
		ex->frames = 4;
		break;

	case TE_BFG_BIGEXPLOSION:
		MSG_ReadPos (&net_message, pos);
		CL_BFGExplosionParticles (pos);
		CL_Explosion_Decal (pos, 75, particle_bfgmark);
		break;

	case TE_BFG_LASER:
		CL_ParseLaser (0xd0d1d2d3);
		break;

	case TE_BUBBLETRAIL:
		MSG_ReadPos (&net_message, pos);
		MSG_ReadPos (&net_message, pos2);
		CL_BubbleTrail (pos, pos2);
		break;

	case TE_PARASITE_ATTACK:
	case TE_MEDIC_CABLE_ATTACK:
		ent = CL_ParseBeam (clMedia.mod_parasite_segment);
		break;

	case TE_BOSSTPORT:			// boss teleporting to station
		MSG_ReadPos (&net_message, pos);
		CL_BigTeleportParticles (pos);
		S_StartSound (pos, 0, 0, S_RegisterSound ("misc/bigtele.wav"), 1, ATTN_NONE, 0);
		break;

	case TE_GRAPPLE_CABLE:
		ent = CL_ParseBeam2 (clMedia.mod_grapple_cable);
		break;

	// RAFAEL
	case TE_WELDING_SPARKS:
		cnt = MSG_ReadByte (&net_message);
		MSG_ReadPos (&net_message, pos);
		MSG_ReadDir (&net_message, dir);
		color = MSG_ReadByte (&net_message);
	// Psychospaz's enhanced particle code
		{
			vec3_t sparkcolor = {color8red(color), color8green(color), color8blue(color)};
			CL_ParticleEffectSparks (pos, dir, sparkcolor, 40);
		}
		ex = CL_AllocExplosion ();
		VectorCopy (pos, ex->ent.origin);
		ex->type = ex_flash;
		// note to self
		// we need a better no draw flag
		ex->ent.flags |= RF_BEAM;
		ex->start = cl.frame.servertime - 0.1;
		ex->light = 100 + (rand()%75);
		ex->lightcolor[0] = 1.0;
		ex->lightcolor[1] = 1.0;
		ex->lightcolor[2] = 0.3;
		ex->ent.model = clMedia.mod_flash;
		ex->frames = 2;
		break;

	case TE_GREENBLOOD:
		MSG_ReadPos (&net_message, pos);
		MSG_ReadDir (&net_message, dir);
	// Psychospaz's enhanced particle code
		CL_GreenBloodHit (pos, dir);
		break;

	// RAFAEL
	case TE_TUNNEL_SPARKS:
		cnt = MSG_ReadByte (&net_message);
		MSG_ReadPos (&net_message, pos);
		MSG_ReadDir (&net_message, dir);
		color = MSG_ReadByte (&net_message);
		CL_ParticleEffect3 (pos, dir, color, cnt);
		break;

//=============
//PGM
	// PMM -following code integrated for flechette (different color)
	case TE_BLASTER:			// blaster hitting wall
	case TE_BLASTER2:			// green blaster hitting wall
	case TE_BLUEHYPERBLASTER:	// blue blaster hitting wall
	case TE_REDBLASTER:			// red blaster hitting wall
	case TE_FLECHETTE:			// flechette hitting wall
		MSG_ReadPos (&net_message, pos);
		MSG_ReadDir (&net_message, dir);
		ex = CL_AllocExplosion ();
		VectorCopy (pos, ex->ent.origin);
		ex->ent.angles[0] = acos(dir[2])/M_PI*180;
		if (dir[0]) // PMM - fixed to correct for pitch of 0
			ex->ent.angles[1] = atan2(dir[1], dir[0])/M_PI*180;
		else if (dir[1] > 0)
			ex->ent.angles[1] = 90;
		else if (dir[1] < 0)
			ex->ent.angles[1] = 270;
		else
			ex->ent.angles[1] = 0;

		ex->type = ex_misc;
		ex->ent.flags |= RF_FULLBRIGHT|RF_TRANSLUCENT|RF_NOSHADOW; // no shadow on these

		if (type == TE_BLASTER2)
			ex->ent.skinnum = 1;
		else if (type == TE_REDBLASTER)
			ex->ent.skinnum = 3;
		else if (type == TE_FLECHETTE || type == TE_BLUEHYPERBLASTER)
			ex->ent.skinnum = 2;
		else // TE_BLASTER
			ex->ent.skinnum = 0;

		ex->start = cl.frame.servertime - 100;
		ex->light = 150;

		if (type == TE_BLASTER2) {
			ex->lightcolor[0] = 0.15;
			ex->lightcolor[1] = 1;
			ex->lightcolor[2] = 0.15;
		}
		else if (type == TE_BLUEHYPERBLASTER) {
			ex->lightcolor[0] = 0.19;
			ex->lightcolor[1] = 0.41;
			ex->lightcolor[2] = 0.75;
		}
		else if (type == TE_REDBLASTER) {
			ex->lightcolor[0] = 0.75;
			ex->lightcolor[1] = 0.41;
			ex->lightcolor[2] = 0.19;
		}
		else if (type == TE_FLECHETTE) {
			ex->lightcolor[0] = 0.39;
			ex->lightcolor[1] = 0.61;
			ex->lightcolor[2] = 0.75;
		}
		else { // TE_BLASTER	
			ex->lightcolor[0] = 1;
			ex->lightcolor[1] = 1;
			ex->lightcolor[2] = 0;
		}

		ex->ent.model = clMedia.mod_explode;
		ex->frames = 4;
		
		// Psychospaz's enhanced particle code	
		{
			int32_t		red, green, blue, numparts;
			float	partsize = 4;
			numparts = (32 / max(cl_particle_scale->value/2, 1));
			if (type == TE_BLASTER2) {
				CL_BlasterParticles (pos, dir, numparts, partsize, 50, 235, 50, -10, 0, -10);
				red=50; green=235; blue=50; }
			else if (type == TE_BLUEHYPERBLASTER) {
				CL_BlasterParticles (pos, dir, numparts, partsize, 50, 50, 235, -10, 0, -10);
				red=50; green=50; blue=235; }
			else if (type == TE_REDBLASTER) {
				CL_BlasterParticles (pos, dir, numparts, partsize, 235, 50, 50, 0, -90, -30);
				red=235; green=50; blue=50; }
			else if (type == TE_FLECHETTE) {
 				CL_BlasterParticles (pos, dir, numparts, partsize, 100, 100, 195, -10, 0, -10);
				red=100; green=100; blue=195; }
			else { // TE_BLASTER
				CL_BlasterParticles (pos, dir, numparts, partsize, 255, 150, 50, 0, -90, -30); // was 40
				red=255; green=150; blue=50; }
			CL_ParticleBlasterDecal(pos, dir, 10, red, green, blue);
		}
		S_StartSound (pos,  0, 0, clMedia.sfx_lashit, 1, ATTN_NORM, 0);
		break;

	// shockwave impact effect
	case TE_SHOCKSPLASH:
		MSG_ReadPos (&net_message, pos);
		MSG_ReadDir (&net_message, dir);
		// Spawn 5 rings
		for (i = 0; i < 5; i++)
		{
			ex = CL_AllocExplosion ();
			VectorMA (pos, 16.0*(i+1), dir, ex->ent.origin);
			vectoangles2(dir, ex->ent.angles);
			//VectorCopy (dir, ex->ent.angles);
			ex->type = ex_poly2;
			ex->ent.flags |= RF_FULLBRIGHT|RF_TRANSLUCENT|RF_NOSHADOW;
			ex->start = cl.frame.servertime - 100;

			ex->light = 75;
			ex->lightcolor[0] = 0.39;
			ex->lightcolor[1] = 0.61;
			ex->lightcolor[2] = 0.75;

			ex->ent.model = clMedia.mod_shocksplash;
			ex->ent.alpha = 0.70;
			ex->baseframe = 4-i;
			ex->frames = 4+i;
		}
		S_StartSound (pos,  0, 0, clMedia.sfx_shockhit, 1, ATTN_NONE, 0);
		break;

	case TE_LIGHTNING:
		// Psychospaz's enhanced particle code
		ent = CL_ParseLightning ();
		S_StartSound (NULL, ent, CHAN_WEAPON, clMedia.sfx_lightning, 1, ATTN_NORM, 0);
		break;

	case TE_DEBUGTRAIL:
		MSG_ReadPos (&net_message, pos);
		MSG_ReadPos (&net_message, pos2);
		CL_DebugTrail (pos, pos2);
		break;

	case TE_FLASHLIGHT:
		MSG_ReadPos(&net_message, pos);
		ent = MSG_ReadShort(&net_message);
		CL_Flashlight(ent, pos);
		break;

	case TE_FORCEWALL:
		MSG_ReadPos(&net_message, pos);
		MSG_ReadPos(&net_message, pos2);
		color = MSG_ReadByte (&net_message);
		CL_ForceWall(pos, pos2, color);
		break;

	case TE_HEATBEAM:
		ent = CL_ParsePlayerBeam (clMedia.mod_heatbeam);
		break;

	case TE_MONSTER_HEATBEAM:
		ent = CL_ParsePlayerBeam (clMedia.mod_monster_heatbeam);
		break;

	case TE_HEATBEAM_SPARKS:
		cnt = 50;
		MSG_ReadPos (&net_message, pos);
		MSG_ReadDir (&net_message, dir);
		r = 8;
		magnitude = 60;
		CL_ParticleSteamEffect (pos, dir, 240, 240, 240, -20, -20, -20, cnt, magnitude);
		S_StartSound (pos,  0, 0, clMedia.sfx_lashit, 1, ATTN_NORM, 0);
		break;
	
	case TE_HEATBEAM_STEAM:
		cnt = 20;
		MSG_ReadPos (&net_message, pos);
		MSG_ReadDir (&net_message, dir);
		magnitude = 60;
		CL_ParticleSteamEffect (pos, dir, 255, 150, 50, 0, -90, -30, cnt, magnitude);
		CL_ParticlePlasmaBeamDecal (pos, dir, 10); // added burnmark
		S_StartSound (pos,  0, 0, clMedia.sfx_lashit, 1, ATTN_NORM, 0);
		break;

	case TE_STEAM:
		CL_ParseSteam();
		break;

	case TE_BUBBLETRAIL2:
		cnt = 3; // was 8
		MSG_ReadPos (&net_message, pos);
		MSG_ReadPos (&net_message, pos2);
		CL_BubbleTrail2 (pos, pos2, cnt);
		S_StartSound (pos,  0, 0, clMedia.sfx_lashit, 1, ATTN_NORM, 0);
		break;

	case TE_MOREBLOOD:
		MSG_ReadPos (&net_message, pos);
		MSG_ReadDir (&net_message, dir);
	// Psychospaz's enhanced particle code
		CL_BloodHit (pos, dir);
		CL_BloodHit (pos, dir);
		break;

	case TE_CHAINFIST_SMOKE:
		dir[0]=0; dir[1]=0; dir[2]=1;
		MSG_ReadPos(&net_message, pos);
	// Psychospaz's enhanced particle code
		CL_ParticleSmokeEffect (pos, dir, 8);
		break;

	case TE_ELECTRIC_SPARKS:
		MSG_ReadPos (&net_message, pos);
		MSG_ReadDir (&net_message, dir);
	// new blue electric sparks
		CL_ElectricParticles (pos, dir, 40);
		//FIXME : replace or remove this sound
		S_StartSound (pos, 0, 0, clMedia.sfx_lashit, 1, ATTN_NORM, 0);
		break;

	case TE_TRACKER_EXPLOSION:
		MSG_ReadPos (&net_message, pos);
		CL_ColorFlash (pos, 0, 150, -1, -1, -1);
	//	CL_ColorExplosionParticles (pos, 0, 1);
		CL_Tracker_Explode (pos);
		CL_Explosion_Decal (pos, 14, particle_trackermark);
		S_StartSound (pos, 0, 0, clMedia.sfx_disrexp, 1, ATTN_NORM, 0);
		break;

	case TE_TELEPORT_EFFECT:
	case TE_DBALL_GOAL:
		MSG_ReadPos (&net_message, pos);
		CL_TeleportParticles (pos);
		break;

	case TE_WIDOWBEAMOUT:
		CL_ParseWidow ();
		break;

	case TE_NUKEBLAST:
		CL_ParseNuke ();
		break;

	case TE_WIDOWSPLASH:
		MSG_ReadPos (&net_message, pos);
		CL_WidowSplash (pos);
		break;
//PGM
//==============

	default:
		Com_Error (ERR_DROP, "CL_ParseTEnt: bad type");
	}
}
예제 #3
0
//=============
//ROGUE
void CL_ParseSteam (void)
{
	vec3_t	pos, dir;
	int32_t		id, i;
	int32_t		r;
	int32_t		cnt;
	int32_t		color;
	int32_t		magnitude;
	cl_sustain_t	*s, *free_sustain;

	id = MSG_ReadShort (&net_message);		// an id of -1 is an instant effect
	if (id != -1) // sustains
	{
		//Com_Printf ("Sustain effect id %d\n", id);
		free_sustain = NULL;
		for (i=0, s=cl_sustains; i<MAX_SUSTAINS; i++, s++)
		{
			if (s->id == 0)
			{
				free_sustain = s;
				break;
			}
		}
		if (free_sustain)
		{
			s->id = id;
			s->count = MSG_ReadByte (&net_message);
			MSG_ReadPos (&net_message, s->org);
			MSG_ReadDir (&net_message, s->dir);
			r = MSG_ReadByte (&net_message);
			s->color = r & 0xff;
			s->magnitude = MSG_ReadShort (&net_message);
			s->endtime = cl.time + MSG_ReadLong (&net_message);
			s->think = CL_ParticleSteamEffect2;
			s->thinkinterval = 100;
			s->nextthink = cl.time;
		}
		else
		{
			//Com_Printf ("No free sustains!\n");
			// FIXME - read the stuff anyway
			cnt = MSG_ReadByte (&net_message);
			MSG_ReadPos (&net_message, pos);
			MSG_ReadDir (&net_message, dir);
			r = MSG_ReadByte (&net_message);
			magnitude = MSG_ReadShort (&net_message);
			magnitude = MSG_ReadLong (&net_message); // really interval
		}
	}
	else // instant
	{
		cnt = MSG_ReadByte (&net_message);
		MSG_ReadPos (&net_message, pos);
		MSG_ReadDir (&net_message, dir);
		r = MSG_ReadByte (&net_message);
		magnitude = MSG_ReadShort (&net_message);
		color = r & 0xff;
		CL_ParticleSteamEffect (pos, dir,
			color8red(color), color8green(color), color8blue(color),
			-20, -20, -20, cnt, magnitude);
		//CL_ParticleSteamEffect (pos, dir, 240, 240, 240, -20, -20, -20, cnt, magnitude);
		//S_StartSound (pos,  0, 0, clMedia.sfx_lashit, 1, ATTN_NORM, 0);
	}
}
예제 #4
0
파일: sv_main.cpp 프로젝트: RkShaRkz/Quake2
sizebuf_t *SV_MulticastHook(sizebuf_t *original, sizebuf_t *ext)
{
	CVec3	v1, v2;
	const char *s;

	guard(SV_MulticastHook);

	original->BeginReading();

	// check for interesting messages
	if (MSG_ReadByte(original) != svc_temp_entity)
		return original;

	ext->Clear();
	byte cmd = MSG_ReadByte(original);
	switch (cmd)
	{
	case TE_RAILTRAIL:
		{
			MSG_ReadPos(original, v1);		// start
			MSG_ReadPos(original, v2);		// end

			client_t *cl = FindClient(v1, 18*18);
			int rType = 1;
			int rColor = 0;
			if (cl)
			{
				if (s = Info_ValueForKey(cl->Userinfo, "railcolor"))
				{
					rColor = atoi(s);
					rColor = bound(rColor, 0, 7);
				}
				if (s = Info_ValueForKey(cl->Userinfo, "railtype"))
				{
					rType = atoi(s);
					rType = bound(rType, 0, 3);
				}
			}
			if (!rType) return original;	// type==0 -> original rail trail

			MSG_WriteByte(ext, svc_temp_entity);
			MSG_WriteByte(ext, TE_RAILTRAIL_EXT);
			MSG_WritePos(ext, v1);
			MSG_WritePos(ext, v2);
			MSG_WriteByte(ext, rColor);
			MSG_WriteByte(ext, rType);
		}
		return ext;

	case TE_GUNSHOT:
	case TE_SPARKS:
	case TE_BULLET_SPARKS:
		{
			if (shotLevel != 2) return original;

			MSG_ReadPos(original, v1);
			MSG_ReadDir(original, v2);

			// compute reflection vector
//			appPrintf("sp: (%g %g %g) -> (%g %g %g)\n",VECTOR_ARG(v1),VECTOR_ARG(v2));//!!
			CVec3 d;
			VectorSubtract(shotStart, shotEnd, d);
			d.NormalizeFast();
			float back = dot(d, v2);
			for (int i = 0; i < 3; i++)
				v2[i] = d[i] - 2 * (d[i] - back * v2[i]);

			MSG_WriteByte(ext, svc_temp_entity);
			MSG_WriteByte(ext, cmd);
			MSG_WritePos(ext, v1);
			MSG_WriteDir(ext, v2);
		}
		return ext;

	case TE_SPLASH:
		{
			int count = MSG_ReadByte(original);
			MSG_ReadPos(original, v1);			// pos
			int tmp = MSG_ReadByte(original);	// dir
			int type = MSG_ReadByte(original);
			if (type != SPLASH_BLUE_WATER && type != SPLASH_BROWN_WATER)
				return original;			// not bullet effect

			// find splash origin in static map splashes to avoid bullethit sounds for waterfalls etc.
			for (const originInfo_t *spl = bspfile.splashes; spl; spl = spl->next)
			{
				if (fabs(spl->origin[0] - v1[0]) < 1 &&
					fabs(spl->origin[1] - v1[1]) < 1 &&
					fabs(spl->origin[2] - v1[2]) < 1)		// dir is quantized, so - make inprecisious compare
					return original;
			}

			//?? can add ripple effect on water, water smoke
			MSG_WriteByte(ext, svc_temp_entity);
			MSG_WriteByte(ext, TE_SPLASH);
			MSG_WriteByte(ext, count);
			MSG_WritePos(ext, v1);
			MSG_WriteByte(ext, tmp);
			MSG_WriteByte(ext, type - SPLASH_BLUE_WATER + SPLASH_BULLET_BLUE_WATER);
		}
		return ext;
	}

	return original;
	unguard;
}