Exemple #1
0
void ClientReliableWrite_Angle(client_t *cl, float f)
{
	if (cl->num_backbuf) {
		MSG_WriteAngle(&cl->backbuf, f);
		ClientReliable_FinishWrite(cl);
	} else
		MSG_WriteAngle(&cl->netchan.message, f);
}
Exemple #2
0
// 2000-05-02 NVS SVC by Maddes
void NVS_WriteAngle (int dest, float f, sizebuf_t *sb)
{
	int	i;

	switch (dest)
	{
	case MSG_INIT:
		if (sv.nvs_msgsignon->conversion_tab[sv.nvs_msgserver->numwrites-sv.nvs_msgwrites])
		{
			if (sb)				// special signon
			{
				MSG_WriteAngle(sb, f);
			}
			else
			{
				MSG_WriteAngle (&sv.signon, f);
			}
		}
		break;

	case MSG_ONE:
	case MSG_ALL:
	case MSG_BROADCAST:
		for (i=0 ; i<svs.maxclients ; i++)
		{
			if (NVS_CheckClient(&svs.clients[i]))
			{
				if (dest == MSG_BROADCAST)	// unreliable
				{
					MSG_WriteAngle (&svs.clients[i].datagram, f);
				}
				else if (dest == MSG_ONE && sb)	// special reliable MSG_ONE
				{
					MSG_WriteAngle (sb, f);
				}
				else				// reliable MSG_ONE, MSG_ALL
				{
					MSG_WriteAngle (&svs.clients[i].message, f);
				}
			}
		}
		break;

	default:
		Host_Error ("NVS_WriteAngle: bad destination");
		break;
	}

	NVS_CheckCounter();
}
Exemple #3
0
/*
================
SV_CreateBaseline

Entity baselines are used to compress the update messages
to the clients -- only the fields that differ from the
baseline will be transmitted
================
*/
void SV_CreateBaseline (void)
{
	int			i;
	edict_t			*svent;
	int				entnum;	
		
	for (entnum = 0; entnum < sv.num_edicts ; entnum++)
	{
		svent = EDICT_NUM(entnum);
		if (svent->free)
			continue;
		// create baselines for all player slots,
		// and any other edict that has a visible model
		if (entnum > MAX_CLIENTS && !svent->v.modelindex)
			continue;

		//
		// create entity baseline
		//
		VectorCopy (svent->v.origin, svent->baseline.origin);
		VectorCopy (svent->v.angles, svent->baseline.angles);
		svent->baseline.frame = svent->v.frame;
		svent->baseline.skinnum = svent->v.skin;
		if (entnum > 0 && entnum <= MAX_CLIENTS)
		{
			svent->baseline.colormap = entnum;
			svent->baseline.modelindex = SV_ModelIndex("progs/player.mdl");
		}
		else
		{
			svent->baseline.colormap = 0;
			svent->baseline.modelindex =
				SV_ModelIndex(PR_GetString(svent->v.model));
		}

		CRITICAL_MESSAGE(sv_signon_lock, SV_SIGNON_LOCK, 0, {
			//
			// flush the signon message out to a seperate buffer if
			// nearly full
			//
			SV_FlushSignon ();

			//
			// add to the message
			//
			MSG_WriteByte (&sv.signon,svc_spawnbaseline);		
			MSG_WriteShort (&sv.signon,entnum);

			MSG_WriteByte (&sv.signon, svent->baseline.modelindex);
			MSG_WriteByte (&sv.signon, svent->baseline.frame);
			MSG_WriteByte (&sv.signon, svent->baseline.colormap);
			MSG_WriteByte (&sv.signon, svent->baseline.skinnum);
			for (i=0 ; i<3 ; i++)
			{
				MSG_WriteCoord(&sv.signon, svent->baseline.origin[i]);
				MSG_WriteAngle(&sv.signon, svent->baseline.angles[i]);
			}
		});
Exemple #4
0
/*
===================
SV_ReadClientMove
===================
*/
void SV_ReadClientMove (usercmd_t *move)
{
	int		i;
	vec3_t	angle;
	int		bits;

// read ping time
	host_client->ping_times[host_client->num_pings%NUM_PING_TIMES]
		= sv.time - MSG_ReadFloat ();
	host_client->num_pings++;

// read current angles
	if (host_client->netconnection->proquake_connection == MOD_PROQUAKE) 
	{
		for (i = 0; i<3; i++)
			angle[i] = MSG_ReadPreciseAngle();
	}
	else
	{
		for (i = 0; i<3; i++)
			angle[i] = MSG_ReadAngle();
	}

// ProQuake - server-side fullpitch fix
	if (!pq_fullpitch.value)
	{
		if (angle[PITCH] > 80 || angle[PITCH] < -70)
		{
			angle[PITCH] = COM_Clamp(angle[PITCH], -70, 80);

			MSG_WriteByte (&host_client->message, svc_setangle);
			for (i=0 ; i < 3 ; i++)
				MSG_WriteAngle (&host_client->message, angle[i] );
		}
	}
	
	VectorCopy (angle, host_client->edict->v.v_angle);

// read movement
	move->forwardmove = MSG_ReadShort ();
	move->sidemove = MSG_ReadShort ();
	move->upmove = MSG_ReadShort ();

// read buttons
	bits = MSG_ReadByte ();
	host_client->edict->v.button0 = bits & 1;
	host_client->edict->v.button2 = (bits & 2)>>1;

	i = MSG_ReadByte ();
	if (i)
		host_client->edict->v.impulse = i;

#ifdef QUAKE2
// read light level
	host_client->edict->v.light_level = MSG_ReadByte ();
#endif
}
void Server_MakeStatic(ServerEntity_t *ent)
{
	int	i,bits=0;

	if(ent->alpha == ENTALPHA_ZERO)
	{
		ED_Free(ent);
		return;
	}

	if(SV_ModelIndex(ent->v.model) & 0xFF00)
		bits |= B_LARGEMODEL;
	if((int)(ent->v.frame) & 0xFF00)
		bits |= B_LARGEFRAME;
	if(ent->alpha != ENTALPHA_DEFAULT)
		bits |= B_ALPHA;

	if(bits)
	{
		MSG_WriteByte(&sv.signon, SVC_SPAWNSTATIC2);
		MSG_WriteByte(&sv.signon, bits);
	}
	else
		MSG_WriteByte(&sv.signon, svc_spawnstatic);

	if(bits & B_LARGEMODEL)
		MSG_WriteShort(&sv.signon, SV_ModelIndex(ent->v.model));
	else
		MSG_WriteByte(&sv.signon, SV_ModelIndex(ent->v.model));

	if(bits & B_LARGEFRAME)
		MSG_WriteShort(&sv.signon,ent->v.frame);
	else
		MSG_WriteByte(&sv.signon,ent->v.frame);

	MSG_WriteByte(&sv.signon,ent->Model.fScale);
	MSG_WriteByte(&sv.signon,ent->v.colormap);
	MSG_WriteByte(&sv.signon,ent->Model.iSkin);
	for (i=0 ; i<3 ; i++)
	{
		MSG_WriteCoord(&sv.signon, ent->v.origin[i]);
		MSG_WriteAngle(&sv.signon, ent->v.angles[i]);
	}

	if (bits & B_ALPHA)
		MSG_WriteByte (&sv.signon, ent->alpha);

	ED_Free (ent);
}
Exemple #6
0
/*
================
SV_CreateBaseline

Entity baselines are used to compress the update messages
to the clients -- only the fields that differ from the
baseline will be transmitted
================
*/
void SV_CreateBaseline (void)
{
	int i, entnum, max_edicts;	
	edict_t *svent;

	// because baselines for entnum >= 512 don't make sense
	// FIXME, translate baselines nums as well as packet entity nums?
	max_edicts = min (sv.num_edicts, 512);

	for (entnum = 0; entnum < max_edicts ; entnum++) {
		svent = EDICT_NUM(entnum);
		if (svent->free)
			continue;
		// create baselines for all player slots, and any other edict that has a visible model
		if (entnum > MAX_CLIENTS && !svent->v.modelindex)
			continue;

		// create entity baseline
		VectorCopy (svent->v.origin, svent->baseline.origin);
		VectorCopy (svent->v.angles, svent->baseline.angles);
		svent->baseline.frame = svent->v.frame;
		svent->baseline.skinnum = svent->v.skin;
		if (entnum > 0 && entnum <= MAX_CLIENTS) {
			svent->baseline.colormap = entnum;
			svent->baseline.modelindex = SV_ModelIndex("progs/player.mdl");
		} else {
			svent->baseline.colormap = 0;
			svent->baseline.modelindex = SV_ModelIndex(PR_GetString(svent->v.model));
		}

		// flush the signon message out to a separate buffer if
		// nearly full
		SV_FlushSignon ();

		// add to the message
		MSG_WriteByte (&sv.signon,svc_spawnbaseline);		
		MSG_WriteShort (&sv.signon,entnum);

		MSG_WriteByte (&sv.signon, svent->baseline.modelindex);
		MSG_WriteByte (&sv.signon, svent->baseline.frame);
		MSG_WriteByte (&sv.signon, svent->baseline.colormap);
		MSG_WriteByte (&sv.signon, svent->baseline.skinnum);
		for (i = 0; i < 3; i++) {
			MSG_WriteCoord(&sv.signon, svent->baseline.origin[i]);
			MSG_WriteAngle(&sv.signon, svent->baseline.angles[i]);
		}
	}
}
Exemple #7
0
// All changes need to be in SV_SendEffect(), SV_ParseEffect(),
// SV_SaveEffects(), SV_LoadEffects(), CL_ParseEffect()
static void SV_SendEffect (sizebuf_t *sb, int idx)
{
	qboolean	DoTest;
	vec3_t		TestO1, Diff;
	float		Size, TestDistance;
	int		i, count;

	if (sb == &sv.reliable_datagram && sv_ce_scale.value > 0)
		DoTest = true;
	else
		DoTest = false;

	VectorClear(TestO1);
	TestDistance = 0;

	switch (sv.Effects[idx].type)
	{
	case CE_RAIN:
	case CE_SNOW:
		DoTest = false;
		break;

	case CE_FOUNTAIN:
		DoTest = false;
		break;

	case CE_QUAKE:
		VectorCopy(sv.Effects[idx].ef.Quake.origin, TestO1);
		TestDistance = 700;
		break;

	case CE_WHITE_SMOKE:
	case CE_GREEN_SMOKE:
	case CE_GREY_SMOKE:
	case CE_RED_SMOKE:
	case CE_SLOW_WHITE_SMOKE:
	case CE_TELESMK1:
	case CE_TELESMK2:
	case CE_GHOST:
	case CE_REDCLOUD:
	case CE_FLAMESTREAM:
	case CE_ACID_MUZZFL:
	case CE_FLAMEWALL:
	case CE_FLAMEWALL2:
	case CE_ONFIRE:
		VectorCopy(sv.Effects[idx].ef.Smoke.origin, TestO1);
		TestDistance = 250;
		break;

	case CE_SM_WHITE_FLASH:
	case CE_YELLOWRED_FLASH:
	case CE_BLUESPARK:
	case CE_YELLOWSPARK:
	case CE_SM_CIRCLE_EXP:
	case CE_BG_CIRCLE_EXP:
	case CE_SM_EXPLOSION:
	case CE_LG_EXPLOSION:
	case CE_FLOOR_EXPLOSION:
	case CE_BLUE_EXPLOSION:
	case CE_REDSPARK:
	case CE_GREENSPARK:
	case CE_ICEHIT:
	case CE_MEDUSA_HIT:
	case CE_MEZZO_REFLECT:
	case CE_FLOOR_EXPLOSION2:
	case CE_XBOW_EXPLOSION:
	case CE_NEW_EXPLOSION:
	case CE_MAGIC_MISSILE_EXPLOSION:
	case CE_BONE_EXPLOSION:
	case CE_BLDRN_EXPL:
	case CE_ACID_HIT:
	case CE_LBALL_EXPL:
	case CE_FIREWALL_SMALL:
	case CE_FIREWALL_MEDIUM:
	case CE_FIREWALL_LARGE:
	case CE_ACID_SPLAT:
	case CE_ACID_EXPL:
	case CE_FBOOM:
	case CE_BRN_BOUNCE:
	case CE_LSHOCK:
	case CE_BOMB:
	case CE_FLOOR_EXPLOSION3:
		VectorCopy(sv.Effects[idx].ef.Smoke.origin, TestO1);
		TestDistance = 250;
		break;

	case CE_WHITE_FLASH:
	case CE_BLUE_FLASH:
	case CE_SM_BLUE_FLASH:
	case CE_RED_FLASH:
		VectorCopy(sv.Effects[idx].ef.Smoke.origin, TestO1);
		TestDistance = 250;
		break;

	case CE_RIDER_DEATH:
		DoTest = false;
		break;

	case CE_GRAVITYWELL:
		DoTest = false;
		break;

	case CE_TELEPORTERPUFFS:
		VectorCopy(sv.Effects[idx].ef.Teleporter.origin, TestO1);
		TestDistance = 350;
		break;

	case CE_TELEPORTERBODY:
		VectorCopy(sv.Effects[idx].ef.Teleporter.origin, TestO1);
		TestDistance = 350;
		break;

	case CE_BONESHARD:
	case CE_BONESHRAPNEL:
		VectorCopy(sv.Effects[idx].ef.Missile.origin, TestO1);
		TestDistance = 600;
		break;

	case CE_CHUNK:
		VectorCopy(sv.Effects[idx].ef.Chunk.origin, TestO1);
		TestDistance = 600;
		break;

	default:
		PR_RunError ("%s: bad type", __thisfunc__);
		break;
	}

	if (!DoTest)
		count = 1;
	else
	{
		count = svs.maxclients;
		TestDistance = (float)TestDistance * sv_ce_scale.value;
		TestDistance *= TestDistance;
	}

	for (i = 0 ; i < count ; i++)
	{
		if (DoTest)
		{
			if (svs.clients[i].active)
			{
				sb = &svs.clients[i].datagram;
				VectorSubtract(svs.clients[i].edict->v.origin, TestO1, Diff);
				Size = (Diff[0]*Diff[0]) + (Diff[1]*Diff[1]) + (Diff[2]*Diff[2]);

				if (Size > TestDistance)
					continue;

				if (sv_ce_max_size.value > 0 && sb->cursize > sv_ce_max_size.value)
					continue;
			}
			else
				continue;
		}

		MSG_WriteByte (sb, svc_start_effect);
		MSG_WriteByte (sb, idx);
		MSG_WriteByte (sb, sv.Effects[idx].type);

		switch (sv.Effects[idx].type)
		{
		case CE_RAIN:
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Rain.min_org[0]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Rain.min_org[1]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Rain.min_org[2]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Rain.max_org[0]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Rain.max_org[1]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Rain.max_org[2]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Rain.e_size[0]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Rain.e_size[1]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Rain.e_size[2]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Rain.dir[0]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Rain.dir[1]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Rain.dir[2]);
			MSG_WriteShort(sb, sv.Effects[idx].ef.Rain.color);
			MSG_WriteShort(sb, sv.Effects[idx].ef.Rain.count);
			MSG_WriteFloat(sb, sv.Effects[idx].ef.Rain.wait);
			break;

		case CE_SNOW:
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Rain.min_org[0]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Rain.min_org[1]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Rain.min_org[2]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Rain.max_org[0]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Rain.max_org[1]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Rain.max_org[2]);
			MSG_WriteByte(sb, sv.Effects[idx].ef.Rain.flags);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Rain.dir[0]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Rain.dir[1]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Rain.dir[2]);
			MSG_WriteByte(sb, sv.Effects[idx].ef.Rain.count);
			//MSG_WriteShort(sb, sv.Effects[idx].ef.Rain.veer);
			break;

		case CE_FOUNTAIN:
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Fountain.pos[0]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Fountain.pos[1]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Fountain.pos[2]);
			MSG_WriteAngle(sb, sv.Effects[idx].ef.Fountain.angle[0]);
			MSG_WriteAngle(sb, sv.Effects[idx].ef.Fountain.angle[1]);
			MSG_WriteAngle(sb, sv.Effects[idx].ef.Fountain.angle[2]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Fountain.movedir[0]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Fountain.movedir[1]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Fountain.movedir[2]);
			MSG_WriteShort(sb, sv.Effects[idx].ef.Fountain.color);
			MSG_WriteByte(sb, sv.Effects[idx].ef.Fountain.cnt);
			break;

		case CE_QUAKE:
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Quake.origin[0]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Quake.origin[1]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Quake.origin[2]);
			MSG_WriteFloat(sb, sv.Effects[idx].ef.Quake.radius);
			break;

		case CE_WHITE_SMOKE:
		case CE_GREEN_SMOKE:
		case CE_GREY_SMOKE:
		case CE_RED_SMOKE:
		case CE_SLOW_WHITE_SMOKE:
		case CE_TELESMK1:
		case CE_TELESMK2:
		case CE_GHOST:
		case CE_REDCLOUD:
		case CE_FLAMESTREAM:
		case CE_ACID_MUZZFL:
		case CE_FLAMEWALL:
		case CE_FLAMEWALL2:
		case CE_ONFIRE:
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Smoke.origin[0]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Smoke.origin[1]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Smoke.origin[2]);
			MSG_WriteFloat(sb, sv.Effects[idx].ef.Smoke.velocity[0]);
			MSG_WriteFloat(sb, sv.Effects[idx].ef.Smoke.velocity[1]);
			MSG_WriteFloat(sb, sv.Effects[idx].ef.Smoke.velocity[2]);
			MSG_WriteFloat(sb, sv.Effects[idx].ef.Smoke.framelength);
			/* smoke frame is a mission pack thing only. */
			if (sv_protocol > PROTOCOL_RAVEN_111)
				MSG_WriteFloat(sb, sv.Effects[idx].ef.Smoke.frame);
			break;

		case CE_SM_WHITE_FLASH:
		case CE_YELLOWRED_FLASH:
		case CE_BLUESPARK:
		case CE_YELLOWSPARK:
		case CE_SM_CIRCLE_EXP:
		case CE_BG_CIRCLE_EXP:
		case CE_SM_EXPLOSION:
		case CE_LG_EXPLOSION:
		case CE_FLOOR_EXPLOSION:
		case CE_FLOOR_EXPLOSION3:
		case CE_BLUE_EXPLOSION:
		case CE_REDSPARK:
		case CE_GREENSPARK:
		case CE_ICEHIT:
		case CE_MEDUSA_HIT:
		case CE_MEZZO_REFLECT:
		case CE_FLOOR_EXPLOSION2:
		case CE_XBOW_EXPLOSION:
		case CE_NEW_EXPLOSION:
		case CE_MAGIC_MISSILE_EXPLOSION:
		case CE_BONE_EXPLOSION:
		case CE_BLDRN_EXPL:
		case CE_ACID_HIT:
		case CE_ACID_SPLAT:
		case CE_ACID_EXPL:
		case CE_LBALL_EXPL:
		case CE_FIREWALL_SMALL:
		case CE_FIREWALL_MEDIUM:
		case CE_FIREWALL_LARGE:
		case CE_FBOOM:
		case CE_BOMB:
		case CE_BRN_BOUNCE:
		case CE_LSHOCK:
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Smoke.origin[0]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Smoke.origin[1]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Smoke.origin[2]);
			break;

		case CE_WHITE_FLASH:
		case CE_BLUE_FLASH:
		case CE_SM_BLUE_FLASH:
		case CE_RED_FLASH:
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Smoke.origin[0]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Smoke.origin[1]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Smoke.origin[2]);
			break;

		case CE_RIDER_DEATH:
			MSG_WriteCoord(sb, sv.Effects[idx].ef.RD.origin[0]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.RD.origin[1]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.RD.origin[2]);
			break;

		case CE_TELEPORTERPUFFS:
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Teleporter.origin[0]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Teleporter.origin[1]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Teleporter.origin[2]);
			break;

		case CE_TELEPORTERBODY:
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Teleporter.origin[0]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Teleporter.origin[1]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Teleporter.origin[2]);
			MSG_WriteFloat(sb, sv.Effects[idx].ef.Teleporter.velocity[0][0]);
			MSG_WriteFloat(sb, sv.Effects[idx].ef.Teleporter.velocity[0][1]);
			MSG_WriteFloat(sb, sv.Effects[idx].ef.Teleporter.velocity[0][2]);
			MSG_WriteFloat(sb, sv.Effects[idx].ef.Teleporter.skinnum);
			break;

		case CE_BONESHARD:
		case CE_BONESHRAPNEL:
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Missile.origin[0]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Missile.origin[1]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Missile.origin[2]);
			MSG_WriteFloat(sb, sv.Effects[idx].ef.Missile.velocity[0]);
			MSG_WriteFloat(sb, sv.Effects[idx].ef.Missile.velocity[1]);
			MSG_WriteFloat(sb, sv.Effects[idx].ef.Missile.velocity[2]);
			MSG_WriteFloat(sb, sv.Effects[idx].ef.Missile.angle[0]);
			MSG_WriteFloat(sb, sv.Effects[idx].ef.Missile.angle[1]);
			MSG_WriteFloat(sb, sv.Effects[idx].ef.Missile.angle[2]);
			MSG_WriteFloat(sb, sv.Effects[idx].ef.Missile.avelocity[0]);
			MSG_WriteFloat(sb, sv.Effects[idx].ef.Missile.avelocity[1]);
			MSG_WriteFloat(sb, sv.Effects[idx].ef.Missile.avelocity[2]);
			break;

		case CE_GRAVITYWELL:
			MSG_WriteCoord(sb, sv.Effects[idx].ef.RD.origin[0]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.RD.origin[1]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.RD.origin[2]);
			MSG_WriteShort(sb, sv.Effects[idx].ef.RD.color);
			MSG_WriteFloat(sb, sv.Effects[idx].ef.RD.lifetime);
			break;

		case CE_CHUNK:
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Chunk.origin[0]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Chunk.origin[1]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Chunk.origin[2]);
			MSG_WriteByte (sb, sv.Effects[idx].ef.Chunk.type);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Chunk.srcVel[0]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Chunk.srcVel[1]);
			MSG_WriteCoord(sb, sv.Effects[idx].ef.Chunk.srcVel[2]);
			MSG_WriteByte (sb, sv.Effects[idx].ef.Chunk.numChunks);
		//	Con_Printf ("Adding %d chunks on server...\n", sv.Effects[idx].Chunk.numChunks);
			break;

		default:
			PR_RunError ("%s: bad type", __thisfunc__);
			break;
		}
	}
}
Exemple #8
0
/*
====================
CL_Record_f

record <demoname> <server>
====================
*/
void CL_Record_f (void)
{
	int		c;
	char	name[MAX_OSPATH];
	sizebuf_t	buf;
	char	buf_data[MAX_MSGLEN];
	int n, i, j;
	char *s;
	entity_t *ent;
	entity_state_t *es, blankes;
	player_info_t *player;
	extern	char gamedirfile[];
	int seq = 1;

	c = Cmd_Argc();
	if (c != 2)
	{
		Con_Printf ("record <demoname>\n");
		return;
	}

	if (cls.state != ca_active) {
		Con_Printf ("You must be connected to record.\n");
		return;
	}

	if (cls.demorecording)
		CL_Stop_f();
  
	sprintf (name, "%s/%s", com_gamedir, Cmd_Argv(1));

//
// open the demo file
//
	COM_DefaultExtension (name, ".qwd");

	cls.demofile = fopen (name, "wb");
	if (!cls.demofile)
	{
		Con_Printf ("ERROR: couldn't open.\n");
		return;
	}

	Con_Printf ("recording to %s.\n", name);
	cls.demorecording = true;

/*-------------------------------------------------*/

// serverdata
	// send the info about the new client to all connected clients
	memset(&buf, 0, sizeof(buf));
	buf.data = buf_data;
	buf.maxsize = sizeof(buf_data);

// send the serverdata
	MSG_WriteByte (&buf, svc_serverdata);
	MSG_WriteLong (&buf, PROTOCOL_VERSION);
	MSG_WriteLong (&buf, cl.servercount);
	MSG_WriteString (&buf, gamedirfile);

	if (cl.spectator)
		MSG_WriteByte (&buf, cl.playernum | 128);
	else
		MSG_WriteByte (&buf, cl.playernum);

	// send full levelname
	MSG_WriteString (&buf, cl.levelname);

	// send the movevars
	MSG_WriteFloat(&buf, movevars.gravity);
	MSG_WriteFloat(&buf, movevars.stopspeed);
	MSG_WriteFloat(&buf, movevars.maxspeed);
	MSG_WriteFloat(&buf, movevars.spectatormaxspeed);
	MSG_WriteFloat(&buf, movevars.accelerate);
	MSG_WriteFloat(&buf, movevars.airaccelerate);
	MSG_WriteFloat(&buf, movevars.wateraccelerate);
	MSG_WriteFloat(&buf, movevars.friction);
	MSG_WriteFloat(&buf, movevars.waterfriction);
	MSG_WriteFloat(&buf, movevars.entgravity);

	// send music
	MSG_WriteByte (&buf, svc_cdtrack);
	MSG_WriteByte (&buf, 0); // none in demos

	// send server info string
	MSG_WriteByte (&buf, svc_stufftext);
	MSG_WriteString (&buf, va("fullserverinfo \"%s\"\n", cl.serverinfo) );

	// flush packet
	CL_WriteRecordDemoMessage (&buf, seq++);
	SZ_Clear (&buf); 

// soundlist
	MSG_WriteByte (&buf, svc_soundlist);
	MSG_WriteByte (&buf, 0);

	n = 0;
	s = cl.sound_name[n+1];
	while (*s) {
		MSG_WriteString (&buf, s);
		if (buf.cursize > MAX_MSGLEN/2) {
			MSG_WriteByte (&buf, 0);
			MSG_WriteByte (&buf, n);
			CL_WriteRecordDemoMessage (&buf, seq++);
			SZ_Clear (&buf); 
			MSG_WriteByte (&buf, svc_soundlist);
			MSG_WriteByte (&buf, n + 1);
		}
		n++;
		s = cl.sound_name[n+1];
	}
	if (buf.cursize) {
		MSG_WriteByte (&buf, 0);
		MSG_WriteByte (&buf, 0);
		CL_WriteRecordDemoMessage (&buf, seq++);
		SZ_Clear (&buf); 
	}

// modellist
	MSG_WriteByte (&buf, svc_modellist);
	MSG_WriteByte (&buf, 0);

	n = 0;
	s = cl.model_name[n+1];
	while (*s) {
		MSG_WriteString (&buf, s);
		if (buf.cursize > MAX_MSGLEN/2) {
			MSG_WriteByte (&buf, 0);
			MSG_WriteByte (&buf, n);
			CL_WriteRecordDemoMessage (&buf, seq++);
			SZ_Clear (&buf); 
			MSG_WriteByte (&buf, svc_modellist);
			MSG_WriteByte (&buf, n + 1);
		}
		n++;
		s = cl.model_name[n+1];
	}
	if (buf.cursize) {
		MSG_WriteByte (&buf, 0);
		MSG_WriteByte (&buf, 0);
		CL_WriteRecordDemoMessage (&buf, seq++);
		SZ_Clear (&buf); 
	}

// spawnstatic

	for (i = 0; i < cl.num_statics; i++) {
		ent = cl_static_entities + i;

		MSG_WriteByte (&buf, svc_spawnstatic);

		for (j = 1; j < MAX_MODELS; j++)
			if (ent->model == cl.model_precache[j])
				break;
		if (j == MAX_MODELS)
			MSG_WriteByte (&buf, 0);
		else
			MSG_WriteByte (&buf, j);

		MSG_WriteByte (&buf, ent->frame);
		MSG_WriteByte (&buf, 0);
		MSG_WriteByte (&buf, ent->skinnum);
		for (j=0 ; j<3 ; j++)
		{
			MSG_WriteCoord (&buf, ent->origin[j]);
			MSG_WriteAngle (&buf, ent->angles[j]);
		}

		if (buf.cursize > MAX_MSGLEN/2) {
			CL_WriteRecordDemoMessage (&buf, seq++);
			SZ_Clear (&buf); 
		}
	}

// spawnstaticsound
	// static sounds are skipped in demos, life is hard

// baselines

	memset(&blankes, 0, sizeof(blankes));
	for (i = 0; i < MAX_EDICTS; i++) {
		es = cl_baselines + i;

		if (memcmp(es, &blankes, sizeof(blankes))) {
			MSG_WriteByte (&buf,svc_spawnbaseline);		
			MSG_WriteShort (&buf, i);

			MSG_WriteByte (&buf, es->modelindex);
			MSG_WriteByte (&buf, es->frame);
			MSG_WriteByte (&buf, es->colormap);
			MSG_WriteByte (&buf, es->skinnum);
			for (j=0 ; j<3 ; j++)
			{
				MSG_WriteCoord(&buf, es->origin[j]);
				MSG_WriteAngle(&buf, es->angles[j]);
			}

			if (buf.cursize > MAX_MSGLEN/2) {
				CL_WriteRecordDemoMessage (&buf, seq++);
				SZ_Clear (&buf); 
			}
		}
	}

	MSG_WriteByte (&buf, svc_stufftext);
	MSG_WriteString (&buf, va("cmd spawn %i 0\n", cl.servercount) );

	if (buf.cursize) {
		CL_WriteRecordDemoMessage (&buf, seq++);
		SZ_Clear (&buf); 
	}

// send current status of all other players

	for (i = 0; i < MAX_CLIENTS; i++) {
		player = cl.players + i;

		MSG_WriteByte (&buf, svc_updatefrags);
		MSG_WriteByte (&buf, i);
		MSG_WriteShort (&buf, player->frags);
		
		MSG_WriteByte (&buf, svc_updateping);
		MSG_WriteByte (&buf, i);
		MSG_WriteShort (&buf, player->ping);
		
		MSG_WriteByte (&buf, svc_updatepl);
		MSG_WriteByte (&buf, i);
		MSG_WriteByte (&buf, player->pl);
		
		MSG_WriteByte (&buf, svc_updateentertime);
		MSG_WriteByte (&buf, i);
		MSG_WriteFloat (&buf, player->entertime);

		MSG_WriteByte (&buf, svc_updateuserinfo);
		MSG_WriteByte (&buf, i);
		MSG_WriteLong (&buf, player->userid);
		MSG_WriteString (&buf, player->userinfo);

		if (buf.cursize > MAX_MSGLEN/2) {
			CL_WriteRecordDemoMessage (&buf, seq++);
			SZ_Clear (&buf); 
		}
	}
	
// send all current light styles
	for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
	{
		MSG_WriteByte (&buf, svc_lightstyle);
		MSG_WriteByte (&buf, (char)i);
		MSG_WriteString (&buf, cl_lightstyle[i].map);
	}

	for (i = 0; i < MAX_CL_STATS; i++) {
		MSG_WriteByte (&buf, svc_updatestatlong);
		MSG_WriteByte (&buf, i);
		MSG_WriteLong (&buf, cl.stats[i]);
		if (buf.cursize > MAX_MSGLEN/2) {
			CL_WriteRecordDemoMessage (&buf, seq++);
			SZ_Clear (&buf); 
		}
	}

#if 0
	MSG_WriteByte (&buf, svc_updatestatlong);
	MSG_WriteByte (&buf, STAT_TOTALMONSTERS);
	MSG_WriteLong (&buf, cl.stats[STAT_TOTALMONSTERS]);

	MSG_WriteByte (&buf, svc_updatestatlong);
	MSG_WriteByte (&buf, STAT_SECRETS);
	MSG_WriteLong (&buf, cl.stats[STAT_SECRETS]);

	MSG_WriteByte (&buf, svc_updatestatlong);
	MSG_WriteByte (&buf, STAT_MONSTERS);
	MSG_WriteLong (&buf, cl.stats[STAT_MONSTERS]);
#endif

	// get the client to check and download skins
	// when that is completed, a begin command will be issued
	MSG_WriteByte (&buf, svc_stufftext);
	MSG_WriteString (&buf, va("skins\n") );

	CL_WriteRecordDemoMessage (&buf, seq++);

	CL_WriteSetDemoMessage();

	// done
}
Exemple #9
0
/*
==============
CL_SendMove
==============
*/
void CL_SendMove (usercmd_t *cmd)
{
	int		i;
	int		bits;
	sizebuf_t	buf;
	byte	data[128];
	
	buf.maxsize = 128;
	buf.cursize = 0;
	buf.data = data;
	
	cl.cmd = *cmd;

//
// send the movement message
//
    MSG_WriteByte (&buf, clc_move);

	MSG_WriteFloat (&buf, cl.mtime[0]);	// so server can get ping times

	for (i=0 ; i<3 ; i++)
		MSG_WriteAngle (&buf, cl.viewangles[i]);
	
    MSG_WriteShort (&buf, cmd->forwardmove);
    MSG_WriteShort (&buf, cmd->sidemove);
    MSG_WriteShort (&buf, cmd->upmove);

//
// send button bits
//
	bits = 0;
	
	if ( in_attack.state & 3 )
		bits |= 1;
	in_attack.state &= ~2;
	
	if (in_jump.state & 3)
		bits |= 2;
	in_jump.state &= ~2;
	
    MSG_WriteByte (&buf, bits);

    MSG_WriteByte (&buf, in_impulse);
	in_impulse = 0;

//
// deliver the message
//
	if (cls.demoplayback)
		return;

//
// allways dump the first two message, because it may contain leftover inputs
// from the last level
//
	if (++cl.movemessages <= 2)
		return;
	
	if (NET_SendUnreliableMessage (cls.netcon, &buf) == -1)
	{
		Con_Printf ("CL_SendMove: lost server connection\n");
		CL_Disconnect ();
	}
}
Exemple #10
0
// All changes need to be in SV_SendEffect(), SV_ParseEffect(),
// SV_SaveEffects(), SV_LoadEffects(), CL_ParseEffect()
void SV_SendEffect(sizebuf_t *sb, int index)
{
	qboolean	DoTest;
	vec3_t		TestO;
	int			TestDistance;
	int			i;

	if (sv_ce_scale.value > 0)
		DoTest = true;
	else
		DoTest = false;

	VectorCopy(vec3_origin, TestO);

	switch(sv.Effects[index].type)
	{
		case CE_HWSHEEPINATOR:
		case CE_HWXBOWSHOOT:
			VectorCopy(sv.Effects[index].Xbow.origin[5], TestO);
			TestDistance = 900;
			break;
		case CE_SCARABCHAIN:
			VectorCopy(sv.Effects[index].Chain.origin, TestO);
			TestDistance = 900;
			break;

		case CE_TRIPMINE:
			VectorCopy(sv.Effects[index].Chain.origin, TestO);
//			DoTest = false;
			break;

			//ACHTUNG!!!!!!! setting DoTest to false here does not insure that effect will be sent to everyone!
		case CE_TRIPMINESTILL:
			TestDistance = 10000;
			DoTest = false;
			break;

		case CE_RAIN:
			TestDistance = 10000;
			DoTest = false;
			break;

		case CE_FOUNTAIN:
			TestDistance = 10000;
			DoTest = false;
			break;

		case CE_QUAKE:
			VectorCopy(sv.Effects[index].Quake.origin, TestO);
			TestDistance = 700;
			break;

		case CE_WHITE_SMOKE:
		case CE_GREEN_SMOKE:
		case CE_GREY_SMOKE:
		case CE_RED_SMOKE:
		case CE_SLOW_WHITE_SMOKE:
		case CE_TELESMK1:
		case CE_TELESMK2:
		case CE_GHOST:
		case CE_REDCLOUD:
		case CE_FLAMESTREAM:
		case CE_ACID_MUZZFL:
		case CE_FLAMEWALL:
		case CE_FLAMEWALL2:
		case CE_ONFIRE:
		case CE_RIPPLE:
			VectorCopy(sv.Effects[index].Smoke.origin, TestO);
			TestDistance = 250;
			break;

		case CE_SM_WHITE_FLASH:
		case CE_YELLOWRED_FLASH:
		case CE_BLUESPARK:
		case CE_YELLOWSPARK:
		case CE_SM_CIRCLE_EXP:
		case CE_BG_CIRCLE_EXP:
		case CE_SM_EXPLOSION:
		case CE_SM_EXPLOSION2:
		case CE_BG_EXPLOSION:
		case CE_FLOOR_EXPLOSION:
		case CE_BLUE_EXPLOSION:
		case CE_REDSPARK:
		case CE_GREENSPARK:
		case CE_ICEHIT:
		case CE_MEDUSA_HIT:
		case CE_MEZZO_REFLECT:
		case CE_FLOOR_EXPLOSION2:
		case CE_XBOW_EXPLOSION:
		case CE_NEW_EXPLOSION:
		case CE_MAGIC_MISSILE_EXPLOSION:
		case CE_BONE_EXPLOSION:
		case CE_BLDRN_EXPL:
		case CE_ACID_HIT:
		case CE_LBALL_EXPL:
		case CE_FIREWALL_SMALL:
		case CE_FIREWALL_MEDIUM:
		case CE_FIREWALL_LARGE:
		case CE_ACID_SPLAT:
		case CE_ACID_EXPL:
		case CE_FBOOM:
		case CE_BRN_BOUNCE:
		case CE_LSHOCK:
		case CE_BOMB:
		case CE_FLOOR_EXPLOSION3:
			VectorCopy(sv.Effects[index].Smoke.origin, TestO);
			TestDistance = 250;
			break;

		case CE_WHITE_FLASH:
		case CE_BLUE_FLASH:
		case CE_SM_BLUE_FLASH:
		case CE_HWSPLITFLASH:
		case CE_RED_FLASH:
			VectorCopy(sv.Effects[index].Smoke.origin, TestO);
			TestDistance = 250;
			break;


		case CE_RIDER_DEATH:
			DoTest = false;
			break;

		case CE_TELEPORTERPUFFS:
			VectorCopy(sv.Effects[index].Teleporter.origin, TestO);
			TestDistance = 350;
			break;

		case CE_TELEPORTERBODY:
			VectorCopy(sv.Effects[index].Teleporter.origin, TestO);
			TestDistance = 350;
			break;

		case CE_DEATHBUBBLES:
			if (sv.Effects[index].Bubble.owner < 0 || sv.Effects[index].Bubble.owner >= sv.num_edicts)
			{
				return;
			}
			VectorCopy(PROG_TO_EDICT(sv.Effects[index].Bubble.owner)->v.origin, TestO);
			TestDistance = 400;
			break;

		case CE_HWDRILLA:
		case CE_BONESHARD:
		case CE_BONESHRAPNEL:
		case CE_HWBONEBALL:
		case CE_HWRAVENSTAFF:
		case CE_HWRAVENPOWER:

			VectorCopy(sv.Effects[index].Missile.origin, TestO);
			TestDistance = 900;
			break;

		case CE_HWMISSILESTAR:
		case CE_HWEIDOLONSTAR:
			VectorCopy(sv.Effects[index].Missile.origin, TestO);
			TestDistance = 600;
			break;
		default:
//			Sys_Error ("SV_SendEffect: bad type");
			PR_RunError ("SV_SendEffect: bad type");
			break;
	}

	MSG_WriteByte (&sv.multicast, svc_start_effect);
	MSG_WriteByte (&sv.multicast, index);
	MSG_WriteByte (&sv.multicast, sv.Effects[index].type);

	switch(sv.Effects[index].type)
	{
		case CE_RAIN:
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.min_org[0]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.min_org[1]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.min_org[2]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.max_org[0]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.max_org[1]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.max_org[2]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.e_size[0]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.e_size[1]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.e_size[2]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.dir[0]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.dir[1]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Rain.dir[2]);
			MSG_WriteShort(&sv.multicast, sv.Effects[index].Rain.color);
			MSG_WriteShort(&sv.multicast, sv.Effects[index].Rain.count);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Rain.wait);
			break;

		case CE_FOUNTAIN:
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Fountain.pos[0]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Fountain.pos[1]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Fountain.pos[2]);
			MSG_WriteAngle(&sv.multicast, sv.Effects[index].Fountain.angle[0]);
			MSG_WriteAngle(&sv.multicast, sv.Effects[index].Fountain.angle[1]);
			MSG_WriteAngle(&sv.multicast, sv.Effects[index].Fountain.angle[2]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Fountain.movedir[0]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Fountain.movedir[1]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Fountain.movedir[2]);
			MSG_WriteShort(&sv.multicast, sv.Effects[index].Fountain.color);
			MSG_WriteByte(&sv.multicast, sv.Effects[index].Fountain.cnt);
			break;

		case CE_QUAKE:
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Quake.origin[0]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Quake.origin[1]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Quake.origin[2]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Quake.radius);
			break;

		case CE_WHITE_SMOKE:
		case CE_GREEN_SMOKE:
		case CE_GREY_SMOKE:
		case CE_RED_SMOKE:
		case CE_SLOW_WHITE_SMOKE:
		case CE_TELESMK1:
		case CE_TELESMK2:
		case CE_GHOST:
		case CE_REDCLOUD:
		case CE_FLAMESTREAM:
		case CE_ACID_MUZZFL:
		case CE_FLAMEWALL:
		case CE_FLAMEWALL2:
		case CE_ONFIRE:
		case CE_RIPPLE:
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Smoke.origin[0]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Smoke.origin[1]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Smoke.origin[2]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Smoke.velocity[0]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Smoke.velocity[1]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Smoke.velocity[2]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Smoke.framelength);
			break;

		case CE_SM_WHITE_FLASH:
		case CE_YELLOWRED_FLASH:
		case CE_BLUESPARK:
		case CE_YELLOWSPARK:
		case CE_SM_CIRCLE_EXP:
		case CE_BG_CIRCLE_EXP:
		case CE_SM_EXPLOSION:
		case CE_SM_EXPLOSION2:
		case CE_BG_EXPLOSION:
		case CE_FLOOR_EXPLOSION:
		case CE_BLUE_EXPLOSION:
		case CE_REDSPARK:
		case CE_GREENSPARK:
		case CE_ICEHIT:
		case CE_MEDUSA_HIT:
		case CE_MEZZO_REFLECT:
		case CE_FLOOR_EXPLOSION2:
		case CE_XBOW_EXPLOSION:
		case CE_NEW_EXPLOSION:
		case CE_MAGIC_MISSILE_EXPLOSION:
		case CE_BONE_EXPLOSION:
		case CE_BLDRN_EXPL:
		case CE_ACID_HIT:
		case CE_ACID_SPLAT:
		case CE_ACID_EXPL:
		case CE_LBALL_EXPL:	
		case CE_FIREWALL_SMALL:
		case CE_FIREWALL_MEDIUM:
		case CE_FIREWALL_LARGE:
		case CE_FBOOM:
		case CE_BOMB:
		case CE_BRN_BOUNCE:
		case CE_LSHOCK:

			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Smoke.origin[0]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Smoke.origin[1]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Smoke.origin[2]);
			break;

		case CE_WHITE_FLASH:
		case CE_BLUE_FLASH:
		case CE_SM_BLUE_FLASH:			
		case CE_HWSPLITFLASH:
		case CE_RED_FLASH:
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Smoke.origin[0]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Smoke.origin[1]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Smoke.origin[2]);
			break;


		case CE_RIDER_DEATH:
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].RD.origin[0]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].RD.origin[1]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].RD.origin[2]);
			break;

		case CE_TELEPORTERPUFFS:
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Teleporter.origin[0]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Teleporter.origin[1]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Teleporter.origin[2]);
			break;

		case CE_TELEPORTERBODY:
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Teleporter.origin[0]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Teleporter.origin[1]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Teleporter.origin[2]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Teleporter.velocity[0][0]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Teleporter.velocity[0][1]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Teleporter.velocity[0][2]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Teleporter.skinnum);
			break;
		case CE_BONESHRAPNEL:
		case CE_HWBONEBALL:
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Missile.origin[0]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Missile.origin[1]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Missile.origin[2]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.velocity[0]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.velocity[1]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.velocity[2]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.angle[0]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.angle[1]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.angle[2]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.avelocity[0]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.avelocity[1]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.avelocity[2]);

			break;
		case CE_BONESHARD:
		case CE_HWRAVENSTAFF:
		case CE_HWMISSILESTAR:
		case CE_HWEIDOLONSTAR:
		case CE_HWRAVENPOWER:
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Missile.origin[0]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Missile.origin[1]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Missile.origin[2]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.velocity[0]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.velocity[1]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Missile.velocity[2]);
			break;
		case CE_HWDRILLA:
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Missile.origin[0]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Missile.origin[1]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Missile.origin[2]);
			MSG_WriteAngle(&sv.multicast, sv.Effects[index].Missile.angle[0]);
			MSG_WriteAngle(&sv.multicast, sv.Effects[index].Missile.angle[1]);
			MSG_WriteShort(&sv.multicast, sv.Effects[index].Missile.speed);
			break;
		case CE_DEATHBUBBLES:
			MSG_WriteShort(&sv.multicast, sv.Effects[index].Bubble.owner);
			MSG_WriteByte(&sv.multicast, sv.Effects[index].Bubble.offset[0]);
			MSG_WriteByte(&sv.multicast, sv.Effects[index].Bubble.offset[1]);
			MSG_WriteByte(&sv.multicast, sv.Effects[index].Bubble.offset[2]);
			MSG_WriteByte(&sv.multicast, sv.Effects[index].Bubble.count);
			break;
		case CE_SCARABCHAIN:
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Chain.origin[0]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Chain.origin[1]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Chain.origin[2]);
			MSG_WriteShort(&sv.multicast, sv.Effects[index].Chain.owner+sv.Effects[index].Chain.material);
			MSG_WriteByte(&sv.multicast, sv.Effects[index].Chain.tag);
			break;
		case CE_TRIPMINESTILL:
		case CE_TRIPMINE:
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Chain.origin[0]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Chain.origin[1]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Chain.origin[2]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Chain.velocity[0]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Chain.velocity[1]);
			MSG_WriteFloat(&sv.multicast, sv.Effects[index].Chain.velocity[2]);
			break;
		case CE_HWSHEEPINATOR:
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Xbow.origin[5][0]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Xbow.origin[5][1]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Xbow.origin[5][2]);
			MSG_WriteAngle(&sv.multicast, sv.Effects[index].Xbow.angle[0]);
			MSG_WriteAngle(&sv.multicast, sv.Effects[index].Xbow.angle[1]);

			//now send the guys that have turned
			MSG_WriteByte(&sv.multicast, sv.Effects[index].Xbow.turnedbolts);
			MSG_WriteByte(&sv.multicast, sv.Effects[index].Xbow.activebolts);
			for (i=0;i<5;i++)
			{
				if ((1<<i)&sv.Effects[index].Xbow.turnedbolts)
				{
					MSG_WriteCoord(&sv.multicast, sv.Effects[index].Xbow.origin[i][0]);
					MSG_WriteCoord(&sv.multicast, sv.Effects[index].Xbow.origin[i][1]);
					MSG_WriteCoord(&sv.multicast, sv.Effects[index].Xbow.origin[i][2]);
					MSG_WriteAngle(&sv.multicast, sv.Effects[index].Xbow.vel[i][0]);
					MSG_WriteAngle(&sv.multicast, sv.Effects[index].Xbow.vel[i][1]);
				}
			}
			break;
		case CE_HWXBOWSHOOT:
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Xbow.origin[5][0]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Xbow.origin[5][1]);
			MSG_WriteCoord(&sv.multicast, sv.Effects[index].Xbow.origin[5][2]);
			MSG_WriteAngle(&sv.multicast, sv.Effects[index].Xbow.angle[0]);
			MSG_WriteAngle(&sv.multicast, sv.Effects[index].Xbow.angle[1]);
//				MSG_WriteFloat(&sv.multicast, sv.Effects[index].Xbow.angle[2]);
			MSG_WriteByte(&sv.multicast, sv.Effects[index].Xbow.bolts);
			MSG_WriteByte(&sv.multicast, sv.Effects[index].Xbow.randseed);

			//now send the guys that have turned
			MSG_WriteByte(&sv.multicast, sv.Effects[index].Xbow.turnedbolts);
			MSG_WriteByte(&sv.multicast, sv.Effects[index].Xbow.activebolts);
			for (i=0;i<5;i++)
			{
				if ((1<<i)&sv.Effects[index].Xbow.turnedbolts)
				{
					MSG_WriteCoord(&sv.multicast, sv.Effects[index].Xbow.origin[i][0]);
					MSG_WriteCoord(&sv.multicast, sv.Effects[index].Xbow.origin[i][1]);
					MSG_WriteCoord(&sv.multicast, sv.Effects[index].Xbow.origin[i][2]);
					MSG_WriteAngle(&sv.multicast, sv.Effects[index].Xbow.vel[i][0]);
					MSG_WriteAngle(&sv.multicast, sv.Effects[index].Xbow.vel[i][1]);
				}
			}
			break;
		default:
//			Sys_Error ("SV_SendEffect: bad type");
			PR_RunError ("SV_SendEffect: bad type");
			break;
	}

	if (sb)
	{
		SZ_Write (sb, sv.multicast.data, sv.multicast.cursize);
		SZ_Clear (&sv.multicast);
	}
	else
	{
		if (DoTest)
		{
			SV_Multicast (TestO, MULTICAST_PVS_R);
		}
		else
		{
			SV_Multicast (TestO, MULTICAST_ALL_R);
		}
		sv.Effects[index].client_list = clients_multicast;
	}
}
void EXT_FUNC MSG_WriteAngle_api(sizebuf_t *sb, float f) {
	MSG_WriteAngle(sb, f);
}
Exemple #12
0
static qbool SV_MVD_Record (mvddest_t *dest)
{
	sizebuf_t	buf;
	byte buf_data[MAX_MSGLEN];
	int n, i;
	char *s, info[MAX_INFO_STRING];
	client_t *player;
	char *gamedir;

	if (!dest)
		return false;

	DestFlush(true);

	if (!sv.mvdrecording)
	{
		memset(&demo, 0, sizeof(demo));
		for (i = 0; i < UPDATE_BACKUP; i++)
		{
			demo.recorder.frames[i] = demo_frames[i];
			demo.recorder.frames[i].entities.entities = demo_entities[i];
		}

		MVDBuffer_Init(&demo.dbuffer, demo.buffer, sizeof(demo.buffer));
		MVDSetMsgBuf(NULL, &demo.frames[0].buf);

		demo.datagram.maxsize = sizeof(demo.datagram_data);
		demo.datagram.data = demo.datagram_data;

		sv.mvdrecording = true;
	}
//	else
//		SV_WriteRecordMVDMessage(&buf);

	demo.pingtime = demo.time = sv.time;

	dest->nextdest = demo.dest;
	demo.dest = dest;

	singledest = dest;

/*-------------------------------------------------*/

// serverdata
	// send the info about the new client to all connected clients
	SZ_Init (&buf, buf_data, sizeof(buf_data));

// send the serverdata

	gamedir = Info_ValueForKey (svs.info, "*gamedir");
	if (!gamedir[0])
		gamedir = "qw";

	MSG_WriteByte (&buf, svc_serverdata);

	MSG_WriteLong (&buf, PROTOCOL_VERSION);
	MSG_WriteLong (&buf, svs.spawncount);
	MSG_WriteString (&buf, gamedir);

	MSG_WriteFloat (&buf, sv.time);

	// send full levelname
	MSG_WriteString (&buf, sv.mapname);

	// send the movevars
	MSG_WriteFloat(&buf, sv.movevars.gravity);
	MSG_WriteFloat(&buf, sv.movevars.stopspeed);
	MSG_WriteFloat(&buf, sv.movevars.maxspeed);
	MSG_WriteFloat(&buf, sv.movevars.spectatormaxspeed);
	MSG_WriteFloat(&buf, sv.movevars.accelerate);
	MSG_WriteFloat(&buf, sv.movevars.airaccelerate);
	MSG_WriteFloat(&buf, sv.movevars.wateraccelerate);
	MSG_WriteFloat(&buf, sv.movevars.friction);
	MSG_WriteFloat(&buf, sv.movevars.waterfriction);
	MSG_WriteFloat(&buf, sv.movevars.entgravity);

	// send music
	MSG_WriteByte (&buf, svc_cdtrack);
	MSG_WriteByte (&buf, 0); // none in demos

	// send server info string
	MSG_WriteByte (&buf, svc_stufftext);
	MSG_WriteString (&buf, va("fullserverinfo \"%s\"\n", svs.info) );

	// flush packet
	SV_WriteRecordMVDMessage (&buf);
	SZ_Clear (&buf);

// soundlist
	MSG_WriteByte (&buf, svc_soundlist);
	MSG_WriteByte (&buf, 0);

	n = 0;
	s = sv.sound_name[n+1];
	while (s)
	{
		MSG_WriteString (&buf, s);
		if (buf.cursize > MAX_MSGLEN/2)
		{
			MSG_WriteByte (&buf, 0);
			MSG_WriteByte (&buf, n);
			SV_WriteRecordMVDMessage (&buf);
			SZ_Clear (&buf);
			MSG_WriteByte (&buf, svc_soundlist);
			MSG_WriteByte (&buf, n + 1);
		}
		n++;
		s = sv.sound_name[n+1];
	}

	if (buf.cursize)
	{
		MSG_WriteByte (&buf, 0);
		MSG_WriteByte (&buf, 0);
		SV_WriteRecordMVDMessage (&buf);
		SZ_Clear (&buf);
	}

// modellist
	MSG_WriteByte (&buf, svc_modellist);
	MSG_WriteByte (&buf, 0);

	n = 0;
	s = sv.model_name[n+1];
	while (s)
	{
		MSG_WriteString (&buf, s);
		if (buf.cursize > MAX_MSGLEN/2)
		{
			MSG_WriteByte (&buf, 0);
			MSG_WriteByte (&buf, n);
			SV_WriteRecordMVDMessage (&buf);
			SZ_Clear (&buf);
			MSG_WriteByte (&buf, svc_modellist);
			MSG_WriteByte (&buf, n + 1);
		}
		n++;
		s = sv.model_name[n+1];
	}
	if (buf.cursize)
	{
		MSG_WriteByte (&buf, 0);
		MSG_WriteByte (&buf, 0);
		SV_WriteRecordMVDMessage (&buf);
		SZ_Clear (&buf);
	}

// baselines
	{
		entity_state_t from;
		edict_t *ent;
		entity_state_t *state;

		memset(&from, 0, sizeof(from));

		for (n = 0; n < sv.num_edicts; n++)
		{
			ent = EDICT_NUM(n);
			state = &ent->baseline;

			if (!state->number || !state->modelindex)
			{	//ent doesn't have a baseline
				continue;
			}

			if (!ent)
			{
				MSG_WriteByte(&buf, svc_spawnbaseline);

				MSG_WriteShort (&buf, n);

				MSG_WriteByte (&buf, 0);

				MSG_WriteByte (&buf, 0);
				MSG_WriteByte (&buf, 0);
				MSG_WriteByte (&buf, 0);
				for (i=0 ; i<3 ; i++)
				{
					MSG_WriteCoord(&buf, 0);
					MSG_WriteAngle(&buf, 0);
				}
			}
			else
			{
				MSG_WriteByte(&buf, svc_spawnbaseline);

				MSG_WriteShort (&buf, n);

				MSG_WriteByte (&buf, state->modelindex&255);

				MSG_WriteByte (&buf, state->frame);
				MSG_WriteByte (&buf, (int)state->colormap);
				MSG_WriteByte (&buf, (int)state->skinnum);
				for (i=0 ; i<3 ; i++)
				{
					MSG_WriteCoord(&buf, state->s_origin[i]);
					MSG_WriteAngle(&buf, state->s_angles[i]);
				}
			}
			if (buf.cursize > MAX_MSGLEN/2)
			{
				SV_WriteRecordMVDMessage (&buf);
				SZ_Clear (&buf);
			}
		}
	}

	//prespawn

	for (n = 0; n < sv.num_signon_buffers; n++)
	{
		if (buf.cursize+sv.signon_buffer_size[n] > MAX_MSGLEN/2)
		{
			SV_WriteRecordMVDMessage (&buf);
			SZ_Clear (&buf);
		}
		SZ_Write (&buf, sv.signon_buffers[n], sv.signon_buffer_size[n]);
	}

	if (buf.cursize > MAX_MSGLEN/2)
	{
		SV_WriteRecordMVDMessage (&buf);
		SZ_Clear (&buf);
	}

	MSG_WriteByte (&buf, svc_stufftext);
	MSG_WriteString (&buf, va("cmd spawn %i\n",svs.spawncount) );

	if (buf.cursize)
	{
		SV_WriteRecordMVDMessage (&buf);
		SZ_Clear (&buf);
	}

// send current status of all other players

	for (i = 0; i < MAX_CLIENTS; i++)
	{
		player = svs.clients + i;

		MSG_WriteByte (&buf, svc_updatefrags);
		MSG_WriteByte (&buf, i);
		MSG_WriteShort (&buf, player->old_frags);

		MSG_WriteByte (&buf, svc_updateping);
		MSG_WriteByte (&buf, i);
		MSG_WriteShort (&buf, SV_CalcPing(player));

		MSG_WriteByte (&buf, svc_updatepl);
		MSG_WriteByte (&buf, i);
		MSG_WriteByte (&buf, player->lossage);

		MSG_WriteByte (&buf, svc_updateentertime);
		MSG_WriteByte (&buf, i);
		MSG_WriteFloat (&buf, svs.realtime - player->connection_started);

		Q_strncpyz (info, player->userinfo, MAX_INFO_STRING);
		Info_RemovePrefixedKeys (info, '_');	// server passwords, etc

		MSG_WriteByte (&buf, svc_updateuserinfo);
		MSG_WriteByte (&buf, i);
		MSG_WriteLong (&buf, player->userid);
		MSG_WriteString (&buf, info);

		if (buf.cursize > MAX_MSGLEN/2)
		{
			SV_WriteRecordMVDMessage (&buf);
			SZ_Clear (&buf);
		}
	}

// send all current light styles
	for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
	{
		MSG_WriteByte (&buf, svc_lightstyle);
		MSG_WriteByte (&buf, (char)i);
		MSG_WriteString (&buf, sv.lightstyles[i]);
	}

	// get the client to check and download skins
	// when that is completed, a begin command will be issued
	MSG_WriteByte (&buf, svc_stufftext);
	MSG_WriteString (&buf, "skins\n");

	SV_WriteRecordMVDMessage (&buf);

	SV_WriteSetMVDMessage();

	singledest = NULL;

	// done
	return true;
}
Exemple #13
0
void SV_Begin_f (void)
{
	unsigned pmodel = 0, emodel = 0;
	int		i;

	if (host_client->state == cs_spawned)
		return; // don't begin again

	host_client->state = cs_spawned;
	
	// handle the case of a level changing while a client was connecting
	if ( atoi(Cmd_Argv(1)) != svs.spawncount )
	{
		Con_Printf ("SV_Begin_f from different level\n");
		SV_New_f ();
		return;
	}

	if (host_client->spectator)
	{
		SV_SpawnSpectator ();

		if (SpectatorConnect) {
			// copy spawn parms out of the client_t
			for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
				(&pr_global_struct->parm1)[i] = host_client->spawn_parms[i];
	
			// call the spawn function
			pr_global_struct->time = sv.time;
			pr_global_struct->self = EDICT_TO_PROG(sv_player);
			PR_ExecuteProgram (SpectatorConnect);
		}
	}
	else
	{
		// copy spawn parms out of the client_t
		for (i=0 ; i< NUM_SPAWN_PARMS ; i++)
			(&pr_global_struct->parm1)[i] = host_client->spawn_parms[i];

		// call the spawn function
		pr_global_struct->time = sv.time;
		pr_global_struct->self = EDICT_TO_PROG(sv_player);
		PR_ExecuteProgram (pr_global_struct->ClientConnect);

		// actually spawn the player
		pr_global_struct->time = sv.time;
		pr_global_struct->self = EDICT_TO_PROG(sv_player);
		PR_ExecuteProgram (pr_global_struct->PutClientInServer);	
	}

	// clear the net statistics, because connecting gives a bogus picture
	host_client->netchan.frame_latency = 0;
	host_client->netchan.frame_rate = 0;
	host_client->netchan.drop_count = 0;
	host_client->netchan.good_count = 0;

	//check he's not cheating

	pmodel = atoi(Info_ValueForKey (host_client->userinfo, "pmodel"));
	emodel = atoi(Info_ValueForKey (host_client->userinfo, "emodel"));

	if (pmodel != sv.model_player_checksum ||
		emodel != sv.eyes_player_checksum)
		SV_BroadcastPrintf (PRINT_HIGH, "%s WARNING: non standard player/eyes model detected\n", host_client->name);

	// if we are paused, tell the client
	if (sv.paused) {
		ClientReliableWrite_Begin (host_client, svc_setpause, 2);
		ClientReliableWrite_Byte (host_client, sv.paused);
		SV_ClientPrintf(host_client, PRINT_HIGH, "Server is paused.\n");
	}

#if 0
//
// send a fixangle over the reliable channel to make sure it gets there
// Never send a roll angle, because savegames can catch the server
// in a state where it is expecting the client to correct the angle
// and it won't happen if the game was just loaded, so you wind up
// with a permanent head tilt
	ent = EDICT_NUM( 1 + (host_client - svs.clients) );
	MSG_WriteByte (&host_client->netchan.message, svc_setangle);
	for (i=0 ; i < 2 ; i++)
		MSG_WriteAngle (&host_client->netchan.message, ent->v.angles[i] );
	MSG_WriteAngle (&host_client->netchan.message, 0 );
#endif
}
void Game_WriteAngle(int mode,float f)
{
	MSG_WriteAngle(Game_WriteDest(mode),f);
}
Exemple #15
0
/*
====================
CL_Record

Called by CL_Record_f and CL_EasyRecord_f
====================
*/
static void CL_Record (void)
{
	sizebuf_t	buf;
	byte	buf_data[MAX_MSGLEN];
	int n, i, j;
	char *s;
	entity_t *ent;
	entity_state_t *es, blankes;
	player_info_t *player;
	int seq = 1;

#ifdef MVDPLAY
	if (cls.mvdplayback) {
		Com_Printf ("Can't record while playing MVD demo.\n");
		return;
	}
#endif
	cls.demorecording = true;

/*-------------------------------------------------*/

// serverdata
	// send the info about the new client to all connected clients
	SZ_Init (&buf, buf_data, sizeof(buf_data));

// send the serverdata
	MSG_WriteByte (&buf, svc_serverdata);
	MSG_WriteLong (&buf, PROTOCOL_VERSION);
	MSG_WriteLong (&buf, cl.servercount);
	MSG_WriteString (&buf, cls.gamedirfile);

	if (cl.spectator)
		MSG_WriteByte (&buf, cl.playernum | 128);
	else
		MSG_WriteByte (&buf, cl.playernum);

	// send full levelname
	MSG_WriteString (&buf, cl.levelname);

	// send the movevars
	MSG_WriteFloat(&buf, movevars.gravity);
	MSG_WriteFloat(&buf, movevars.stopspeed);
	MSG_WriteFloat(&buf, cl.maxspeed);
	MSG_WriteFloat(&buf, movevars.spectatormaxspeed);
	MSG_WriteFloat(&buf, movevars.accelerate);
	MSG_WriteFloat(&buf, movevars.airaccelerate);
	MSG_WriteFloat(&buf, movevars.wateraccelerate);
	MSG_WriteFloat(&buf, movevars.friction);
	MSG_WriteFloat(&buf, movevars.waterfriction);
	MSG_WriteFloat(&buf, cl.entgravity);

	// send music
	MSG_WriteByte (&buf, svc_cdtrack);
	MSG_WriteByte (&buf, 0); // none in demos

	// send server info string
	MSG_WriteByte (&buf, svc_stufftext);
	MSG_WriteString (&buf, va("fullserverinfo \"%s\"\n", cl.serverinfo) );

	// flush packet
	CL_WriteRecordDemoMessage (&buf, seq++);
	SZ_Clear (&buf); 

// soundlist
	MSG_WriteByte (&buf, svc_soundlist);
	MSG_WriteByte (&buf, 0);

	n = 0;
	s = cl.sound_name[n+1];
	while (*s) {
		MSG_WriteString (&buf, s);
		if (buf.cursize > MAX_MSGLEN/2) {
			MSG_WriteByte (&buf, 0);
			MSG_WriteByte (&buf, n);
			CL_WriteRecordDemoMessage (&buf, seq++);
			SZ_Clear (&buf); 
			MSG_WriteByte (&buf, svc_soundlist);
			MSG_WriteByte (&buf, n + 1);
		}
		n++;
		s = cl.sound_name[n+1];
	}
	if (buf.cursize) {
		MSG_WriteByte (&buf, 0);
		MSG_WriteByte (&buf, 0);
		CL_WriteRecordDemoMessage (&buf, seq++);
		SZ_Clear (&buf); 
	}

#ifdef VWEP_TEST
// vwep modellist
	if ((cl.z_ext & Z_EXT_VWEP) && cl.vw_model_name[0][0]) {
		// send VWep precaches
		// pray we don't overflow
		for (i = 0; i < MAX_VWEP_MODELS; i++) {
			s = cl.vw_model_name[i];
			if (!*s)
				continue;
			MSG_WriteByte (&buf, svc_serverinfo);
			MSG_WriteString (&buf, "#vw");
			MSG_WriteString (&buf, va("%i %s", i, TrimModelName(s)));
		}
		// send end-of-list messsage
		MSG_WriteByte (&buf, svc_serverinfo);
		MSG_WriteString (&buf, "#vw");
		MSG_WriteString (&buf, "");
	}
	// don't bother flushing, the vwep list is not that large (I hope)
#endif

// modellist
	MSG_WriteByte (&buf, svc_modellist);
	MSG_WriteByte (&buf, 0);

	n = 0;
	s = cl.model_name[n+1];
	while (*s) {
		MSG_WriteString (&buf, s);
		if (buf.cursize > MAX_MSGLEN/2) {
			MSG_WriteByte (&buf, 0);
			MSG_WriteByte (&buf, n);
			CL_WriteRecordDemoMessage (&buf, seq++);
			SZ_Clear (&buf); 
			MSG_WriteByte (&buf, svc_modellist);
			MSG_WriteByte (&buf, n + 1);
		}
		n++;
		s = cl.model_name[n+1];
	}
	if (buf.cursize) {
		MSG_WriteByte (&buf, 0);
		MSG_WriteByte (&buf, 0);
		CL_WriteRecordDemoMessage (&buf, seq++);
		SZ_Clear (&buf); 
	}

// spawnstatic

	for (i = 0; i < cl.num_statics; i++) {
		ent = cl_static_entities + i;

		MSG_WriteByte (&buf, svc_spawnstatic);

		for (j = 1; j < MAX_MODELS; j++)
			if (ent->model == cl.model_precache[j])
				break;
		if (j == MAX_MODELS)
			MSG_WriteByte (&buf, 0);
		else
			MSG_WriteByte (&buf, j);

		MSG_WriteByte (&buf, ent->frame);
		MSG_WriteByte (&buf, 0);
		MSG_WriteByte (&buf, ent->skinnum);
		for (j=0 ; j<3 ; j++)
		{
			MSG_WriteCoord (&buf, ent->origin[j]);
			MSG_WriteAngle (&buf, ent->angles[j]);
		}

		if (buf.cursize > MAX_MSGLEN/2) {
			CL_WriteRecordDemoMessage (&buf, seq++);
			SZ_Clear (&buf); 
		}
	}

// spawnstaticsound

	for (i = 0; i < cl.num_static_sounds; i++) {
		static_sound_t *ss = &cl.static_sounds[i];
		MSG_WriteByte (&buf, svc_spawnstaticsound);
		for (j = 0; j < 3; j++)
			MSG_WriteCoord (&buf, ss->org[j]);
		MSG_WriteByte (&buf, ss->sound_num);
		MSG_WriteByte (&buf, ss->vol);
		MSG_WriteByte (&buf, ss->atten);

		if (buf.cursize > MAX_MSGLEN/2) {
			CL_WriteRecordDemoMessage (&buf, seq++);
			SZ_Clear (&buf); 
		}
	}

// baselines

	memset(&blankes, 0, sizeof(blankes));
	for (i = 0; i < MAX_CL_EDICTS; i++) {
		es = &cl_entities[i].baseline;

		if (memcmp(es, &blankes, sizeof(blankes))) {
			MSG_WriteByte (&buf,svc_spawnbaseline);		
			MSG_WriteShort (&buf, i);

			MSG_WriteByte (&buf, es->modelindex);
			MSG_WriteByte (&buf, es->frame);
			MSG_WriteByte (&buf, es->colormap);
			MSG_WriteByte (&buf, es->skinnum);
			for (j=0 ; j<3 ; j++)
			{
				MSG_WriteShort (&buf, es->s_origin[j]);
				MSG_WriteByte (&buf, es->s_angles[j]);
			}

			if (buf.cursize > MAX_MSGLEN/2) {
				CL_WriteRecordDemoMessage (&buf, seq++);
				SZ_Clear (&buf); 
			}
		}
	}

	MSG_WriteByte (&buf, svc_stufftext);
	MSG_WriteString (&buf, va("cmd spawn %i 0\n", cl.servercount) );

	if (buf.cursize) {
		CL_WriteRecordDemoMessage (&buf, seq++);
		SZ_Clear (&buf); 
	}

// send current status of all other players

	for (i = 0; i < MAX_CLIENTS; i++) {
		player = cl.players + i;

		MSG_WriteByte (&buf, svc_updatefrags);
		MSG_WriteByte (&buf, i);
		MSG_WriteShort (&buf, player->frags);
		
		MSG_WriteByte (&buf, svc_updateping);
		MSG_WriteByte (&buf, i);
		MSG_WriteShort (&buf, player->ping);
		
		MSG_WriteByte (&buf, svc_updatepl);
		MSG_WriteByte (&buf, i);
		MSG_WriteByte (&buf, player->pl);
		
		MSG_WriteByte (&buf, svc_updateentertime);
		MSG_WriteByte (&buf, i);
		MSG_WriteFloat (&buf, cls.realtime - player->entertime);

		MSG_WriteByte (&buf, svc_updateuserinfo);
		MSG_WriteByte (&buf, i);
		MSG_WriteLong (&buf, player->userid);
		MSG_WriteString (&buf, player->userinfo);

		if (buf.cursize > MAX_MSGLEN/2) {
			CL_WriteRecordDemoMessage (&buf, seq++);
			SZ_Clear (&buf); 
		}
	}
	
// send all current light styles
	for (i=0 ; i<MAX_LIGHTSTYLES ; i++)
	{
		if (!cl_lightstyle[i].length)
			continue;		// don't send empty lightstyle strings
		MSG_WriteByte (&buf, svc_lightstyle);
		MSG_WriteByte (&buf, (char)i);
		MSG_WriteString (&buf, cl_lightstyle[i].map);
	}

	for (i = 0; i < MAX_CL_STATS; i++) {
		if (!cl.stats[i])
			continue;		// no need to send zero values
		if (cl.stats[i] >= 0 && cl.stats[i] <= 255) {
			MSG_WriteByte (&buf, svc_updatestat);
			MSG_WriteByte (&buf, i);
			MSG_WriteByte (&buf, cl.stats[i]);
		} else {
			MSG_WriteByte (&buf, svc_updatestatlong);
			MSG_WriteByte (&buf, i);
			MSG_WriteLong (&buf, cl.stats[i]);
		}
		if (buf.cursize > MAX_MSGLEN/2) {
			CL_WriteRecordDemoMessage (&buf, seq++);
			SZ_Clear (&buf); 
		}
	}

	// get the client to check and download skins
	// when that is completed, a begin command will be issued
	MSG_WriteByte (&buf, svc_stufftext);
	MSG_WriteString (&buf, va("skins\n") );

	CL_WriteRecordDemoMessage (&buf, seq++);

	CL_WriteSetDemoMessage();

	// done
}
Exemple #16
0
static void VM_M_WriteAngle (prvm_prog_t *prog)
{
	VM_SAFEPARMCOUNT(1, VM_M_WriteAngle);
	MSG_WriteAngle (VM_M_WriteDest(prog), PRVM_G_FLOAT(OFS_PARM0), sv.protocol);
}
Exemple #17
0
void ClientReliableWrite_Angle (float f)
{
	assert (backbuf_write_started);
	MSG_WriteAngle (&backbuf, f);
}
/*
==================
SV_Begin_f
==================
*/
static void SV_Begin_f (void)
{
	int		i;

	host_client->state = cs_spawned;

	// handle the case of a level changing while a client was connecting
	if ( atoi(Cmd_Argv(1)) != svs.spawncount )
	{
		Con_Printf ("%s from different level\n", __thisfunc__);
		SV_New_f ();
		return;
	}

	if (host_client->spectator)
	{
		SV_SpawnSpectator ();

		if (SpectatorConnect)
		{
			// copy spawn parms out of the client_t
			for (i = 0; i < NUM_SPAWN_PARMS; i++)
				(&pr_global_struct->parm1)[i] = host_client->spawn_parms[i];

			// call the spawn function
			pr_global_struct->time = sv.time;
			pr_global_struct->self = EDICT_TO_PROG(sv_player);
			PR_ExecuteProgram (SpectatorConnect);
		}
	}
	else
	{
		// copy spawn parms out of the client_t
		for (i = 0; i < NUM_SPAWN_PARMS; i++)
			(&pr_global_struct->parm1)[i] = host_client->spawn_parms[i];

		host_client->send_all_v = true;

		// call the spawn function
		pr_global_struct->time = sv.time;
		pr_global_struct->self = EDICT_TO_PROG(sv_player);
		PR_ExecuteProgram (pr_global_struct->ClientConnect);

		// actually spawn the player
		pr_global_struct->time = sv.time;
		pr_global_struct->self = EDICT_TO_PROG(sv_player);
		PR_ExecuteProgram (pr_global_struct->PutClientInServer);
	}

	// clear the net statistics, because connecting gives a bogus picture
	host_client->netchan.frame_latency = 0;
	host_client->netchan.frame_rate = 0;
	host_client->netchan.drop_count = 0;
	host_client->netchan.good_count = 0;
#if 0
//
// send a fixangle over the reliable channel to make sure it gets there
// Never send a roll angle, because savegames can catch the server
// in a state where it is expecting the client to correct the angle
// and it won't happen if the game was just loaded, so you wind up
// with a permanent head tilt
	ent = EDICT_NUM( 1 + (host_client - svs.clients) );
	MSG_WriteByte (&host_client->netchan.message, svc_setangle);
	for (i = 0; i < 2; i++)
		MSG_WriteAngle (&host_client->netchan.message, ent->v.angles[i] );
	MSG_WriteAngle (&host_client->netchan.message, 0 );
#endif
}
Exemple #19
0
static void
Host_Spawn_f (void)
{
	int         i;
	client_t   *client;
	edict_t    *ent;
	float      *sendangles;

	if (cmd_source == src_command) {
		Sys_Printf ("spawn is not valid from the console\n");
		return;
	}

	if (host_client->spawned) {
		Sys_Printf ("Spawn not valid -- already spawned\n");
		return;
	}
	// run the entrance script
	if (sv.loadgame) {				// loaded games are fully inited already
		// if this is the last client to be connected, unpause
		sv.paused = false;
	} else {
		// set up the edict
		ent = host_client->edict;
		memset (&ent->v, 0, sv_pr_state.progs->entityfields * 4);
		SVfloat (ent, colormap) = NUM_FOR_EDICT (&sv_pr_state, ent);
		SVfloat (ent, team) = (host_client->colors & 15) + 1;
		SVstring (ent, netname) = PR_SetString (&sv_pr_state,
												host_client->name);

		// copy spawn parms out of the client_t
		for (i = 0; i < NUM_SPAWN_PARMS; i++)
			sv_globals.parms[i] = host_client->spawn_parms[i];

		// call the spawn function
		*sv_globals.time = sv.time;
		*sv_globals.self = EDICT_TO_PROG (&sv_pr_state, sv_player);
		PR_ExecuteProgram (&sv_pr_state, sv_funcs.ClientConnect);
		if ((Sys_DoubleTime () - host_client->netconnection->connecttime) <=
			sv.time) Sys_Printf ("%s entered the game\n", host_client->name);
		PR_ExecuteProgram (&sv_pr_state, sv_funcs.PutClientInServer);
	}

	// send all current names, colors, and frag counts
	SZ_Clear (&host_client->message);

	// send time of update
	MSG_WriteByte (&host_client->message, svc_time);
	MSG_WriteFloat (&host_client->message, sv.time);

	for (i = 0, client = svs.clients; i < svs.maxclients; i++, client++) {
		MSG_WriteByte (&host_client->message, svc_updatename);
		MSG_WriteByte (&host_client->message, i);
		MSG_WriteString (&host_client->message, client->name);
		MSG_WriteByte (&host_client->message, svc_updatefrags);
		MSG_WriteByte (&host_client->message, i);
		MSG_WriteShort (&host_client->message, client->old_frags);
		MSG_WriteByte (&host_client->message, svc_updatecolors);
		MSG_WriteByte (&host_client->message, i);
		MSG_WriteByte (&host_client->message, client->colors);
	}

	// send all current light styles
	for (i = 0; i < MAX_LIGHTSTYLES; i++) {
		MSG_WriteByte (&host_client->message, svc_lightstyle);
		MSG_WriteByte (&host_client->message, (char) i);
		MSG_WriteString (&host_client->message, sv.lightstyles[i]);
	}

	// send some stats
	MSG_WriteByte (&host_client->message, svc_updatestat);
	MSG_WriteByte (&host_client->message, STAT_TOTALSECRETS);
	MSG_WriteLong (&host_client->message,
				   *sv_globals.total_secrets);

	MSG_WriteByte (&host_client->message, svc_updatestat);
	MSG_WriteByte (&host_client->message, STAT_TOTALMONSTERS);
	MSG_WriteLong (&host_client->message,
				   *sv_globals.total_monsters);

	MSG_WriteByte (&host_client->message, svc_updatestat);
	MSG_WriteByte (&host_client->message, STAT_SECRETS);
	MSG_WriteLong (&host_client->message,
				   *sv_globals.found_secrets);

	MSG_WriteByte (&host_client->message, svc_updatestat);
	MSG_WriteByte (&host_client->message, STAT_MONSTERS);
	MSG_WriteLong (&host_client->message,
				   *sv_globals.killed_monsters);

	// send a fixangle
	// Never send a roll angle, because savegames can catch the server
	// in a state where it is expecting the client to correct the angle
	// and it won't happen if the game was just loaded, so you wind up
	// with a permanent head tilt
	ent = EDICT_NUM (&sv_pr_state, 1 + (host_client - svs.clients));
	MSG_WriteByte (&host_client->message, svc_setangle);
	sendangles = sv.loadgame ? SVvector (ent, v_angle): SVvector (ent, angles);
	MSG_WriteAngle (&host_client->message, sendangles[0]);
	MSG_WriteAngle (&host_client->message, sendangles[1]);
	MSG_WriteAngle (&host_client->message, 0);

	SV_WriteClientdataToMessage (sv_player, &host_client->message);

	MSG_WriteByte (&host_client->message, svc_signonnum);
	MSG_WriteByte (&host_client->message, 3);
	host_client->sendsignon = true;
}