2013-03-31 04:21:08 +00:00
# include "quakedef.h"
2004-08-23 00:15:46 +00:00
2004-11-29 01:21:00 +00:00
# ifndef CLIENTONLY
2004-08-23 00:15:46 +00:00
# define Q2EDICT_NUM(i) (q2edict_t*)((char *)ge->edicts+i*ge->edict_size)
# ifndef Q2SERVER
void SV_WriteFrameToClient ( client_t * client , sizebuf_t * msg )
{
}
void SV_BuildClientFrame ( client_t * client )
{
}
# else
q2entity_state_t * svs_client_entities ; //[Q2UPDATE_BACKUP*MAX_PACKET_ENTITIES];
int svs_num_client_entities ;
int svs_next_client_entities ;
q2entity_state_t sv_baselines [ Q2MAX_EDICTS ] ;
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Encode a client frame onto the network channel
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
2023-09-11 09:31:09 +00:00
static void MSG_WriteSizeQ2E ( sizebuf_t * sb , int solid )
{ //urgh...
if ( solid ! = ES_SOLID_BSP & & solid ! = ES_SOLID_NOT )
solid = ( ( solid & 255 ) < < 0 ) //recode fte's sizes to q2ex's...
| ( ( solid & 255 ) < < 8 )
| ( ( ( solid > > 8 ) & 255 ) < < 16 )
| ( ( ( ( solid > > 16 ) & 65535 ) - 32768 + 32 ) < < 24 ) ;
MSG_WriteLong ( sb , solid ) ;
}
2004-08-23 00:15:46 +00:00
/*
= = = = = = = = = = = = = = = = = =
MSG_WriteDeltaEntity
Writes part of a packetentities message .
Can delta from either a baseline or a previous packet_entity
= = = = = = = = = = = = = = = = = =
*/
2023-09-11 09:31:09 +00:00
void MSGQ2_WriteDeltaEntity ( q2entity_state_t * from , q2entity_state_t * to , sizebuf_t * msg , qboolean force , qboolean newentity , qboolean q2ex )
2004-08-23 00:15:46 +00:00
{
2023-09-11 09:31:09 +00:00
quint64_t bits ;
2004-08-23 00:15:46 +00:00
if ( ! to - > number )
Sys_Error ( " Unset entity number " ) ;
if ( to - > number > = Q2MAX_EDICTS )
Sys_Error ( " Entity number >= MAX_EDICTS " ) ;
// send an update
bits = 0 ;
if ( to - > number > = 256 )
bits | = Q2U_NUMBER16 ; // number8 is implicit otherwise
if ( to - > origin [ 0 ] ! = from - > origin [ 0 ] )
bits | = Q2U_ORIGIN1 ;
if ( to - > origin [ 1 ] ! = from - > origin [ 1 ] )
bits | = Q2U_ORIGIN2 ;
if ( to - > origin [ 2 ] ! = from - > origin [ 2 ] )
bits | = Q2U_ORIGIN3 ;
if ( to - > angles [ 0 ] ! = from - > angles [ 0 ] )
bits | = Q2U_ANGLE1 ;
if ( to - > angles [ 1 ] ! = from - > angles [ 1 ] )
bits | = Q2U_ANGLE2 ;
if ( to - > angles [ 2 ] ! = from - > angles [ 2 ] )
bits | = Q2U_ANGLE3 ;
if ( to - > skinnum ! = from - > skinnum )
{
if ( ( unsigned ) to - > skinnum < 256 )
bits | = Q2U_SKIN8 ;
else if ( ( unsigned ) to - > skinnum < 0x10000 )
bits | = Q2U_SKIN16 ;
else
bits | = ( Q2U_SKIN8 | Q2U_SKIN16 ) ;
}
if ( to - > frame ! = from - > frame )
{
if ( to - > frame < 256 )
bits | = Q2U_FRAME8 ;
else
bits | = Q2U_FRAME16 ;
}
if ( to - > effects ! = from - > effects )
{
2023-09-11 09:31:09 +00:00
if ( ( uint64_t ) to - > effects > 0xffffffffu )
{ //this encoding is weird, Q2UEX_EFFECTS64 without any of the other flags is equivelent to the 8|16==32bit flags, so is pointless without the extra ones.
if ( to - > effects < ( uint64_t ) 256 < < 32 )
bits | = Q2U_EFFECTS8 | Q2UEX_EFFECTS64 ;
else if ( to - > effects < ( uint64_t ) 0x8000 < < 32 )
bits | = Q2U_EFFECTS16 | Q2UEX_EFFECTS64 ;
else
bits | = Q2U_EFFECTS8 | Q2U_EFFECTS16 | Q2UEX_EFFECTS64 ;
}
else if ( to - > effects < 256 )
2004-08-23 00:15:46 +00:00
bits | = Q2U_EFFECTS8 ;
else if ( to - > effects < 0x8000 )
bits | = Q2U_EFFECTS16 ;
else
bits | = Q2U_EFFECTS8 | Q2U_EFFECTS16 ;
}
if ( to - > renderfx ! = from - > renderfx )
{
if ( to - > renderfx < 256 )
bits | = Q2U_RENDERFX8 ;
else if ( to - > renderfx < 0x8000 )
bits | = Q2U_RENDERFX16 ;
else
bits | = Q2U_RENDERFX8 | Q2U_RENDERFX16 ;
}
if ( to - > solid ! = from - > solid )
bits | = Q2U_SOLID ;
// event is not delta compressed, just 0 compressed
if ( to - > event )
bits | = Q2U_EVENT ;
if ( to - > modelindex ! = from - > modelindex )
2016-01-18 05:22:07 +00:00
{
2004-08-23 00:15:46 +00:00
bits | = Q2U_MODEL ;
2016-01-18 05:22:07 +00:00
if ( to - > modelindex > 0xff )
bits | = Q2UX_INDEX16 ;
}
2004-08-23 00:15:46 +00:00
if ( to - > modelindex2 ! = from - > modelindex2 )
2016-01-18 05:22:07 +00:00
{
2004-08-23 00:15:46 +00:00
bits | = Q2U_MODEL2 ;
2016-01-18 05:22:07 +00:00
if ( to - > modelindex2 > 0xff )
bits | = Q2UX_INDEX16 ;
}
2004-08-23 00:15:46 +00:00
if ( to - > modelindex3 ! = from - > modelindex3 )
2016-01-18 05:22:07 +00:00
{
2004-08-23 00:15:46 +00:00
bits | = Q2U_MODEL3 ;
2016-01-18 05:22:07 +00:00
if ( to - > modelindex3 > 0xff )
bits | = Q2UX_INDEX16 ;
}
2004-08-23 00:15:46 +00:00
if ( to - > modelindex4 ! = from - > modelindex4 )
2016-01-18 05:22:07 +00:00
{
2004-08-23 00:15:46 +00:00
bits | = Q2U_MODEL4 ;
2016-01-18 05:22:07 +00:00
if ( to - > modelindex4 > 0xff )
bits | = Q2UX_INDEX16 ;
}
2004-08-23 00:15:46 +00:00
2023-09-11 09:31:09 +00:00
if ( to - > sound ! = from - > sound /*||vol or attn*/ )
2016-01-18 05:22:07 +00:00
{
2004-08-23 00:15:46 +00:00
bits | = Q2U_SOUND ;
2023-09-11 09:31:09 +00:00
if ( to - > sound > 0xff & & ! q2ex )
2016-01-18 05:22:07 +00:00
bits | = Q2UX_INDEX16 ;
}
2004-08-23 00:15:46 +00:00
2023-09-11 09:31:09 +00:00
// if (to->alpha != from->alpha) bits |= Q2UEX_ALPHA;
// if (to->scale != from->scale)bits |= Q2UEX_SCALE;
// if (to->instance != from->instance) bits |= Q2UEX_INSTANCE;
// if (to->owner != from->owner) bits |= Q2UEX_OWNER;
// if (to->oldframe != from->oldframe) bits |= Q2UEX_OLDFRAME;
2004-08-23 00:15:46 +00:00
if ( newentity | | ( to - > renderfx & Q2RF_BEAM ) )
bits | = Q2U_OLDORIGIN ;
//
// write the message
//
if ( ! bits & & ! force )
return ; // nothing to send!
//----------
2023-09-11 09:31:09 +00:00
if ( bits & 0xff00000000 )
bits | = Q2UEX_MOREBITS4 | Q2U_MOREBITS3 | Q2U_MOREBITS2 | Q2U_MOREBITS1 ;
else if ( bits & 0xff000000 )
2004-08-23 00:15:46 +00:00
bits | = Q2U_MOREBITS3 | Q2U_MOREBITS2 | Q2U_MOREBITS1 ;
else if ( bits & 0x00ff0000 )
bits | = Q2U_MOREBITS2 | Q2U_MOREBITS1 ;
else if ( bits & 0x0000ff00 )
bits | = Q2U_MOREBITS1 ;
MSG_WriteByte ( msg , bits & 255 ) ;
2023-09-11 09:31:09 +00:00
if ( bits & 0xff00000000 )
{
MSG_WriteByte ( msg , ( bits > > 8 ) & 255 ) ;
MSG_WriteByte ( msg , ( bits > > 16 ) & 255 ) ;
MSG_WriteByte ( msg , ( bits > > 24 ) & 255 ) ;
MSG_WriteByte ( msg , ( bits > > 32 ) & 255 ) ;
}
else if ( bits & 0xff000000 )
2004-08-23 00:15:46 +00:00
{
MSG_WriteByte ( msg , ( bits > > 8 ) & 255 ) ;
MSG_WriteByte ( msg , ( bits > > 16 ) & 255 ) ;
MSG_WriteByte ( msg , ( bits > > 24 ) & 255 ) ;
}
else if ( bits & 0x00ff0000 )
{
MSG_WriteByte ( msg , ( bits > > 8 ) & 255 ) ;
MSG_WriteByte ( msg , ( bits > > 16 ) & 255 ) ;
}
else if ( bits & 0x0000ff00 )
{
MSG_WriteByte ( msg , ( bits > > 8 ) & 255 ) ;
}
//----------
if ( bits & Q2U_NUMBER16 )
MSG_WriteShort ( msg , to - > number ) ;
else
MSG_WriteByte ( msg , to - > number ) ;
if ( bits & Q2U_MODEL )
2016-01-18 05:22:07 +00:00
{
if ( bits & Q2UX_INDEX16 )
MSG_WriteShort ( msg , to - > modelindex ) ;
else
MSG_WriteByte ( msg , to - > modelindex ) ;
}
2004-08-23 00:15:46 +00:00
if ( bits & Q2U_MODEL2 )
2016-01-18 05:22:07 +00:00
{
if ( bits & Q2UX_INDEX16 )
MSG_WriteShort ( msg , to - > modelindex2 ) ;
else
MSG_WriteByte ( msg , to - > modelindex2 ) ;
}
2004-08-23 00:15:46 +00:00
if ( bits & Q2U_MODEL3 )
2016-01-18 05:22:07 +00:00
{
if ( bits & Q2UX_INDEX16 )
MSG_WriteShort ( msg , to - > modelindex3 ) ;
else
MSG_WriteByte ( msg , to - > modelindex3 ) ;
}
2004-08-23 00:15:46 +00:00
if ( bits & Q2U_MODEL4 )
2016-01-18 05:22:07 +00:00
{
if ( bits & Q2UX_INDEX16 )
MSG_WriteShort ( msg , to - > modelindex4 ) ;
else
MSG_WriteByte ( msg , to - > modelindex4 ) ;
}
2004-08-23 00:15:46 +00:00
if ( bits & Q2U_FRAME8 )
MSG_WriteByte ( msg , to - > frame ) ;
if ( bits & Q2U_FRAME16 )
MSG_WriteShort ( msg , to - > frame ) ;
if ( ( bits & Q2U_SKIN8 ) & & ( bits & Q2U_SKIN16 ) ) //used for laser colors
MSG_WriteLong ( msg , to - > skinnum ) ;
else if ( bits & Q2U_SKIN8 )
MSG_WriteByte ( msg , to - > skinnum ) ;
else if ( bits & Q2U_SKIN16 )
MSG_WriteShort ( msg , to - > skinnum ) ;
2023-09-11 09:31:09 +00:00
if ( bits & Q2UEX_EFFECTS64 )
{
2004-08-23 00:15:46 +00:00
MSG_WriteLong ( msg , to - > effects ) ;
2023-09-11 09:31:09 +00:00
if ( ( bits & ( Q2U_EFFECTS8 | Q2U_EFFECTS16 ) ) = = ( Q2U_EFFECTS8 | Q2U_EFFECTS16 ) )
MSG_WriteLong ( msg , ( quint64_t ) to - > effects > > 32 ) ;
else if ( bits & Q2U_EFFECTS8 )
MSG_WriteByte ( msg , ( quint64_t ) to - > effects > > 32 ) ;
else if ( bits & Q2U_EFFECTS16 )
MSG_WriteShort ( msg , ( quint64_t ) to - > effects > > 32 ) ;
}
else
{
if ( ( bits & ( Q2U_EFFECTS8 | Q2U_EFFECTS16 ) ) = = ( Q2U_EFFECTS8 | Q2U_EFFECTS16 ) )
MSG_WriteLong ( msg , to - > effects ) ;
else if ( bits & Q2U_EFFECTS8 )
MSG_WriteByte ( msg , to - > effects ) ;
else if ( bits & Q2U_EFFECTS16 )
MSG_WriteShort ( msg , to - > effects ) ;
}
2004-08-23 00:15:46 +00:00
if ( ( bits & ( Q2U_RENDERFX8 | Q2U_RENDERFX16 ) ) = = ( Q2U_RENDERFX8 | Q2U_RENDERFX16 ) )
MSG_WriteLong ( msg , to - > renderfx ) ;
else if ( bits & Q2U_RENDERFX8 )
MSG_WriteByte ( msg , to - > renderfx ) ;
else if ( bits & Q2U_RENDERFX16 )
MSG_WriteShort ( msg , to - > renderfx ) ;
2023-09-11 09:31:09 +00:00
if ( q2ex )
{
if ( bits & Q2U_SOLID )
MSG_WriteSizeQ2E ( msg , to - > solid ) ;
if ( ! to - > solid )
{ //demos reportedly compress these... not that it makes a difference.
if ( bits & Q2U_ORIGIN1 )
MSG_WriteCoord ( msg , to - > origin [ 0 ] ) ;
if ( bits & Q2U_ORIGIN2 )
MSG_WriteCoord ( msg , to - > origin [ 1 ] ) ;
if ( bits & Q2U_ORIGIN3 )
MSG_WriteCoord ( msg , to - > origin [ 2 ] ) ;
if ( bits & Q2U_OLDORIGIN )
{
MSG_WriteCoord ( msg , to - > old_origin [ 0 ] ) ;
MSG_WriteCoord ( msg , to - > old_origin [ 1 ] ) ;
MSG_WriteCoord ( msg , to - > old_origin [ 2 ] ) ;
}
}
else
{
if ( bits & Q2U_ORIGIN1 )
MSG_WriteFloat ( msg , to - > origin [ 0 ] ) ;
if ( bits & Q2U_ORIGIN2 )
MSG_WriteFloat ( msg , to - > origin [ 1 ] ) ;
if ( bits & Q2U_ORIGIN3 )
MSG_WriteFloat ( msg , to - > origin [ 2 ] ) ;
if ( bits & Q2U_OLDORIGIN )
{
MSG_WriteFloat ( msg , to - > old_origin [ 0 ] ) ;
MSG_WriteFloat ( msg , to - > old_origin [ 1 ] ) ;
MSG_WriteFloat ( msg , to - > old_origin [ 2 ] ) ;
}
}
2004-08-23 00:15:46 +00:00
2023-09-11 09:31:09 +00:00
if ( bits & Q2U_ANGLE1 )
MSG_WriteFloat ( msg , to - > angles [ 0 ] ) ; //blatent overkill.
if ( bits & Q2U_ANGLE2 )
MSG_WriteFloat ( msg , to - > angles [ 1 ] ) ;
if ( bits & Q2U_ANGLE3 )
MSG_WriteFloat ( msg , to - > angles [ 2 ] ) ;
}
else
2004-08-23 00:15:46 +00:00
{
2023-09-11 09:31:09 +00:00
if ( bits & Q2U_ORIGIN1 )
MSG_WriteCoord ( msg , to - > origin [ 0 ] ) ;
if ( bits & Q2U_ORIGIN2 )
MSG_WriteCoord ( msg , to - > origin [ 1 ] ) ;
if ( bits & Q2U_ORIGIN3 )
MSG_WriteCoord ( msg , to - > origin [ 2 ] ) ;
if ( bits & Q2U_ANGLE1 )
MSG_WriteAngle ( msg , to - > angles [ 0 ] ) ;
if ( bits & Q2U_ANGLE2 )
MSG_WriteAngle ( msg , to - > angles [ 1 ] ) ;
if ( bits & Q2U_ANGLE3 )
MSG_WriteAngle ( msg , to - > angles [ 2 ] ) ;
if ( bits & Q2U_OLDORIGIN )
{
MSG_WriteCoord ( msg , to - > old_origin [ 0 ] ) ;
MSG_WriteCoord ( msg , to - > old_origin [ 1 ] ) ;
MSG_WriteCoord ( msg , to - > old_origin [ 2 ] ) ;
}
2004-08-23 00:15:46 +00:00
}
if ( bits & Q2U_SOUND )
2016-01-18 05:22:07 +00:00
{
2023-09-11 09:31:09 +00:00
if ( q2ex )
{
# if 1
MSG_WriteShort ( msg , to - > sound & 0x3fff ) ;
# else
MSG_WriteShort ( msg , to - > sound & 0x3fff | ( ( to - > soundvol ! = 1 ) ? 0x4000 : 0 ) ) | ( ( to - > soundattn ! = 3 ) ? 0x8000 : 0 ) ) ;
MSG_WriteByte ( msg , to - > soundvol * 255 ) ;
MSG_WriteByte ( msg , to - > soundattn ) ; //this is normally a /64, but oh well...
# endif
}
2016-01-18 05:22:07 +00:00
else
2023-09-11 09:31:09 +00:00
{
if ( bits & Q2UX_INDEX16 )
MSG_WriteShort ( msg , to - > sound ) ;
else
MSG_WriteByte ( msg , to - > sound ) ;
}
2016-01-18 05:22:07 +00:00
}
2004-08-23 00:15:46 +00:00
if ( bits & Q2U_EVENT )
MSG_WriteByte ( msg , to - > event ) ;
2023-09-11 09:31:09 +00:00
if ( ! q2ex )
if ( bits & Q2U_SOLID )
{
if ( msg - > prim . flags & NPQ2_SOLID32 )
MSG_WriteLong ( msg , to - > solid ) ;
else
MSG_WriteSize16 ( msg , to - > solid ) ;
}
if ( bits & Q2UEX_ALPHA ) MSG_WriteByte ( msg , 0 ) ;
if ( bits & Q2UEX_SCALE ) MSG_WriteByte ( msg , 0 ) ;
if ( bits & Q2UEX_INSTANCE ) MSG_WriteByte ( msg , 0 ) ;
if ( bits & Q2UEX_OWNER ) MSG_WriteShort ( msg , 0 ) ;
if ( bits & Q2UEX_OLDFRAME ) MSG_WriteShort ( msg , 0 ) ;
2004-08-23 00:15:46 +00:00
}
/*
= = = = = = = = = = = = =
SV_EmitPacketEntities
Writes a delta update of an entity_state_t list to the message .
= = = = = = = = = = = = =
*/
2023-09-11 09:31:09 +00:00
void SVQ2_EmitPacketEntities ( q2client_frame_t * from , q2client_frame_t * to , sizebuf_t * msg , qboolean q2ex )
2004-08-23 00:15:46 +00:00
{
q2entity_state_t * oldent , * newent ;
int oldindex , newindex ;
int oldnum , newnum ;
int from_num_entities ;
int bits ;
MSG_WriteByte ( msg , svcq2_packetentities ) ;
if ( ! from )
from_num_entities = 0 ;
else
from_num_entities = from - > num_entities ;
newindex = 0 ;
oldindex = 0 ;
while ( newindex < to - > num_entities | | oldindex < from_num_entities )
{
if ( newindex > = to - > num_entities )
{
newent = NULL ; //shh compiler, shh...
newnum = 9999 ;
}
else
{
newent = & svs_client_entities [ ( to - > first_entity + newindex ) % svs_num_client_entities ] ;
newnum = newent - > number ;
}
if ( oldindex > = from_num_entities )
{
oldent = NULL ; //shh compiler, shh...
oldnum = 9999 ;
}
else
{
oldent = & svs_client_entities [ ( from - > first_entity + oldindex ) % svs_num_client_entities ] ;
oldnum = oldent - > number ;
}
if ( newnum = = oldnum )
{ // delta update from old position
// because the force parm is false, this will not result
// in any bytes being emited if the entity has not changed at all
// note that players are always 'newentities', this updates their oldorigin always
// and prevents warping
2006-04-09 02:04:40 +00:00
if ( msg - > cursize + 128 > msg - > maxsize )
memcpy ( newent , oldent , sizeof ( * newent ) ) ; //too much data, so set the ent up as the same as the old, so it's sent next frame
else
2023-09-11 09:31:09 +00:00
MSGQ2_WriteDeltaEntity ( oldent , newent , msg , false , newent - > number < = svs . allocated_client_slots , q2ex ) ;
2004-08-23 00:15:46 +00:00
oldindex + + ;
newindex + + ;
continue ;
}
if ( newnum < oldnum )
{ // this is a new entity, send it from the baseline
2006-04-09 02:04:40 +00:00
if ( msg - > cursize + 128 > msg - > maxsize )
{ //might cause the packet to overflow
//so strip out this ent, we can add it next frame if it's still relevent
to - > num_entities - - ;
memmove ( newent , newent + 1 , sizeof ( * newent ) * ( to - > num_entities - newindex ) ) ;
}
else
{
2023-09-11 09:31:09 +00:00
MSGQ2_WriteDeltaEntity ( & sv_baselines [ newnum ] , newent , msg , true , true , q2ex ) ;
2006-04-09 02:04:40 +00:00
newindex + + ;
}
2004-08-23 00:15:46 +00:00
continue ;
}
if ( newnum > oldnum )
{ // the old entity isn't present in the new message
bits = Q2U_REMOVE ;
if ( oldnum > = 256 )
bits | = Q2U_NUMBER16 | Q2U_MOREBITS1 ;
MSG_WriteByte ( msg , bits & 255 ) ;
if ( bits & 0x0000ff00 )
MSG_WriteByte ( msg , ( bits > > 8 ) & 255 ) ;
if ( bits & Q2U_NUMBER16 )
MSG_WriteShort ( msg , oldnum ) ;
else
MSG_WriteByte ( msg , oldnum ) ;
oldindex + + ;
continue ;
}
}
MSG_WriteShort ( msg , 0 ) ; // end of packetentities
#if 0
if ( numprojs )
SV_EmitProjectileUpdate ( msg ) ;
# endif
}
/*
= = = = = = = = = = = = =
SV_WritePlayerstateToClient
= = = = = = = = = = = = =
*/
2023-09-11 09:31:09 +00:00
void SVQ2_WritePlayerstateToClient ( client_t * client , int seat , int extflags , q2client_frame_t * from , q2client_frame_t * to , sizebuf_t * msg )
2004-08-23 00:15:46 +00:00
{
int i ;
int pflags ;
q2player_state_t * ps , * ops ;
q2player_state_t dummy ;
int statbits ;
2023-09-11 09:31:09 +00:00
unsigned int pext = client - > fteprotocolextensions ;
unsigned int q2e = client - > protocol = = SCP_QUAKE2EX ;
2004-08-23 00:15:46 +00:00
2016-01-18 05:22:07 +00:00
ps = & to - > ps [ seat ] ;
2004-08-23 00:15:46 +00:00
if ( ! from )
{
memset ( & dummy , 0 , sizeof ( dummy ) ) ;
ops = & dummy ;
}
else
2016-01-18 05:22:07 +00:00
ops = & from - > ps [ seat ] ;
2004-08-23 00:15:46 +00:00
//
// determine what needs to be sent
//
pflags = 0 ;
2016-01-18 05:22:07 +00:00
if ( pext & PEXT_SPLITSCREEN )
if ( ! from | | from - > clientnum [ seat ] ! = to - > clientnum [ seat ] )
2023-09-11 09:31:09 +00:00
pflags | = Q2FTEPS_CLIENTNUM ;
2016-01-18 05:22:07 +00:00
2004-08-23 00:15:46 +00:00
if ( ps - > pmove . pm_type ! = ops - > pmove . pm_type )
pflags | = Q2PS_M_TYPE ;
if ( ps - > pmove . origin [ 0 ] ! = ops - > pmove . origin [ 0 ]
| | ps - > pmove . origin [ 1 ] ! = ops - > pmove . origin [ 1 ]
| | ps - > pmove . origin [ 2 ] ! = ops - > pmove . origin [ 2 ] )
pflags | = Q2PS_M_ORIGIN ;
if ( ps - > pmove . velocity [ 0 ] ! = ops - > pmove . velocity [ 0 ]
| | ps - > pmove . velocity [ 1 ] ! = ops - > pmove . velocity [ 1 ]
| | ps - > pmove . velocity [ 2 ] ! = ops - > pmove . velocity [ 2 ] )
pflags | = Q2PS_M_VELOCITY ;
if ( ps - > pmove . pm_time ! = ops - > pmove . pm_time )
pflags | = Q2PS_M_TIME ;
if ( ps - > pmove . pm_flags ! = ops - > pmove . pm_flags )
pflags | = Q2PS_M_FLAGS ;
if ( ps - > pmove . gravity ! = ops - > pmove . gravity )
pflags | = Q2PS_M_GRAVITY ;
if ( ps - > pmove . delta_angles [ 0 ] ! = ops - > pmove . delta_angles [ 0 ]
| | ps - > pmove . delta_angles [ 1 ] ! = ops - > pmove . delta_angles [ 1 ]
| | ps - > pmove . delta_angles [ 2 ] ! = ops - > pmove . delta_angles [ 2 ] )
pflags | = Q2PS_M_DELTA_ANGLES ;
if ( ps - > viewoffset [ 0 ] ! = ops - > viewoffset [ 0 ]
| | ps - > viewoffset [ 1 ] ! = ops - > viewoffset [ 1 ]
| | ps - > viewoffset [ 2 ] ! = ops - > viewoffset [ 2 ] )
pflags | = Q2PS_VIEWOFFSET ;
if ( ps - > viewangles [ 0 ] ! = ops - > viewangles [ 0 ]
| | ps - > viewangles [ 1 ] ! = ops - > viewangles [ 1 ]
| | ps - > viewangles [ 2 ] ! = ops - > viewangles [ 2 ] )
pflags | = Q2PS_VIEWANGLES ;
if ( ps - > kick_angles [ 0 ] ! = ops - > kick_angles [ 0 ]
| | ps - > kick_angles [ 1 ] ! = ops - > kick_angles [ 1 ]
| | ps - > kick_angles [ 2 ] ! = ops - > kick_angles [ 2 ] )
pflags | = Q2PS_KICKANGLES ;
if ( ps - > blend [ 0 ] ! = ops - > blend [ 0 ]
| | ps - > blend [ 1 ] ! = ops - > blend [ 1 ]
| | ps - > blend [ 2 ] ! = ops - > blend [ 2 ]
| | ps - > blend [ 3 ] ! = ops - > blend [ 3 ] )
pflags | = Q2PS_BLEND ;
if ( ps - > fov ! = ops - > fov )
pflags | = Q2PS_FOV ;
if ( ps - > rdflags ! = ops - > rdflags )
pflags | = Q2PS_RDFLAGS ;
if ( ps - > gunframe ! = ops - > gunframe )
pflags | = Q2PS_WEAPONFRAME ;
2016-01-18 05:22:07 +00:00
if ( ps - > gunindex ! = ops - > gunindex )
pflags | = Q2PS_WEAPONINDEX ;
if ( pext & PEXT_MODELDBL )
{
if ( ( pflags & Q2PS_WEAPONINDEX ) & & ps - > gunindex > 0xff )
2023-09-11 09:31:09 +00:00
pflags | = Q2FTEPS_INDEX16 ;
2016-01-18 05:22:07 +00:00
if ( ( pflags & Q2PS_WEAPONFRAME ) & & ps - > gunframe > 0xff )
2023-09-11 09:31:09 +00:00
pflags | = Q2FTEPS_INDEX16 ;
2016-01-18 05:22:07 +00:00
}
if ( pflags > 0xffff )
pflags | = Q2PS_EXTRABITS ;
2004-08-23 00:15:46 +00:00
//
// write it
//
MSG_WriteByte ( msg , svcq2_playerinfo ) ;
2016-01-18 05:22:07 +00:00
MSG_WriteShort ( msg , pflags & 0xffff ) ;
if ( pflags & Q2PS_EXTRABITS )
2023-09-11 09:31:09 +00:00
{
if ( q2e )
MSG_WriteShort ( msg , pflags > > 16 ) ;
else
MSG_WriteByte ( msg , pflags > > 16 ) ;
}
2004-08-23 00:15:46 +00:00
//
// write the pmove_state_t
//
if ( pflags & Q2PS_M_TYPE )
{
2023-09-11 09:31:09 +00:00
i = ps - > pmove . pm_type ;
if ( q2e )
{ //sigh... q2e added some extra pmove types that we don't support, and not on the end. :(
switch ( ( q2pmtype_t ) i )
{
case Q2PM_NORMAL : i = Q2EPM_NORMAL ; break ;
//case Q2PM_GRAPPLE: i = Q2EPM_GRAPPLE; break;
case Q2PM_SPECTATOR : i = Q2EPM_SPECTATOR ; break ;
//case Q2PM_SPECTATOR2: i = Q2EPM_SPECTATOR2; break;
case Q2PM_DEAD : i = Q2EPM_DEAD ; break ;
case Q2PM_GIB : i = Q2EPM_GIB ; break ;
case Q2PM_FREEZE : i = Q2EPM_FREEZE ; break ;
}
}
MSG_WriteByte ( msg , i ) ;
2004-08-23 00:15:46 +00:00
}
2023-09-11 09:31:09 +00:00
if ( q2e )
2004-08-23 00:15:46 +00:00
{
2023-09-11 09:31:09 +00:00
if ( pflags & Q2PS_M_ORIGIN )
{
MSG_WriteFloat ( msg , ps - > pmove . origin [ 0 ] / 8.0 ) ;
MSG_WriteFloat ( msg , ps - > pmove . origin [ 1 ] / 8.0 ) ;
MSG_WriteFloat ( msg , ps - > pmove . origin [ 2 ] / 8.0 ) ;
}
if ( pflags & Q2PS_M_VELOCITY )
{
MSG_WriteFloat ( msg , ps - > pmove . velocity [ 0 ] / 8.0 ) ;
MSG_WriteFloat ( msg , ps - > pmove . velocity [ 1 ] / 8.0 ) ;
MSG_WriteFloat ( msg , ps - > pmove . velocity [ 2 ] / 8.0 ) ;
}
}
else
{
if ( pflags & Q2PS_M_ORIGIN )
{
MSG_WriteShort ( msg , ps - > pmove . origin [ 0 ] ) ;
MSG_WriteShort ( msg , ps - > pmove . origin [ 1 ] ) ;
MSG_WriteShort ( msg , ps - > pmove . origin [ 2 ] ) ;
}
if ( pflags & Q2PS_M_VELOCITY )
{
MSG_WriteShort ( msg , ps - > pmove . velocity [ 0 ] ) ;
MSG_WriteShort ( msg , ps - > pmove . velocity [ 1 ] ) ;
MSG_WriteShort ( msg , ps - > pmove . velocity [ 2 ] ) ;
}
2004-08-23 00:15:46 +00:00
}
if ( pflags & Q2PS_M_TIME )
2023-09-11 09:31:09 +00:00
{
if ( q2e )
MSG_WriteShort ( msg , ps - > pmove . pm_time ) ;
else
MSG_WriteByte ( msg , ps - > pmove . pm_time ) ;
}
2004-08-23 00:15:46 +00:00
if ( pflags & Q2PS_M_FLAGS )
2023-09-11 09:31:09 +00:00
{
if ( q2e )
MSG_WriteShort ( msg , ps - > pmove . pm_flags ) ;
else
MSG_WriteByte ( msg , ps - > pmove . pm_flags ) ;
}
2004-08-23 00:15:46 +00:00
if ( pflags & Q2PS_M_GRAVITY )
MSG_WriteShort ( msg , ps - > pmove . gravity ) ;
if ( pflags & Q2PS_M_DELTA_ANGLES )
{
2023-09-11 09:31:09 +00:00
if ( q2e )
{
MSG_WriteFloat ( msg , SHORT2ANGLE ( ps - > pmove . delta_angles [ 0 ] ) ) ;
MSG_WriteFloat ( msg , SHORT2ANGLE ( ps - > pmove . delta_angles [ 1 ] ) ) ;
MSG_WriteFloat ( msg , SHORT2ANGLE ( ps - > pmove . delta_angles [ 2 ] ) ) ;
}
else
{
MSG_WriteShort ( msg , ps - > pmove . delta_angles [ 0 ] ) ;
MSG_WriteShort ( msg , ps - > pmove . delta_angles [ 1 ] ) ;
MSG_WriteShort ( msg , ps - > pmove . delta_angles [ 2 ] ) ;
}
2004-08-23 00:15:46 +00:00
}
//
// write the rest of the player_state_t
//
if ( pflags & Q2PS_VIEWOFFSET )
{
2023-09-11 09:31:09 +00:00
if ( q2e )
{
MSG_WriteShort ( msg , ps - > viewoffset [ 0 ] * 16 ) ;
MSG_WriteShort ( msg , ps - > viewoffset [ 1 ] * 16 ) ;
MSG_WriteShort ( msg , ( ps - > viewoffset [ 2 ] - DEFAULT_VIEWHEIGHT ) * 16 ) ;
MSG_WriteChar ( msg , DEFAULT_VIEWHEIGHT /*ps->pmove.viewheight*/ ) ;
}
else
{
MSG_WriteChar ( msg , ps - > viewoffset [ 0 ] * 4 ) ;
MSG_WriteChar ( msg , ps - > viewoffset [ 1 ] * 4 ) ;
MSG_WriteChar ( msg , ps - > viewoffset [ 2 ] * 4 ) ;
}
2004-08-23 00:15:46 +00:00
}
if ( pflags & Q2PS_VIEWANGLES )
{
2023-09-11 09:31:09 +00:00
if ( q2e )
{
MSG_WriteFloat ( msg , ps - > viewangles [ 0 ] ) ;
MSG_WriteFloat ( msg , ps - > viewangles [ 1 ] ) ;
MSG_WriteFloat ( msg , ps - > viewangles [ 2 ] ) ;
}
else
{
MSG_WriteAngle16 ( msg , ps - > viewangles [ 0 ] ) ;
MSG_WriteAngle16 ( msg , ps - > viewangles [ 1 ] ) ;
MSG_WriteAngle16 ( msg , ps - > viewangles [ 2 ] ) ;
}
2004-08-23 00:15:46 +00:00
}
if ( pflags & Q2PS_KICKANGLES )
{
2023-09-11 09:31:09 +00:00
if ( q2e )
{
MSG_WriteShort ( msg , ps - > kick_angles [ 0 ] * 1024 ) ;
MSG_WriteShort ( msg , ps - > kick_angles [ 1 ] * 1024 ) ;
MSG_WriteShort ( msg , ps - > kick_angles [ 2 ] * 1024 ) ;
}
else
{
MSG_WriteChar ( msg , ps - > kick_angles [ 0 ] * 4 ) ;
MSG_WriteChar ( msg , ps - > kick_angles [ 1 ] * 4 ) ;
MSG_WriteChar ( msg , ps - > kick_angles [ 2 ] * 4 ) ;
}
2004-08-23 00:15:46 +00:00
}
if ( pflags & Q2PS_WEAPONINDEX )
{
2023-09-11 09:31:09 +00:00
if ( q2e )
MSG_WriteShort ( msg , ( 0 /*gunskin*/ < < 13 ) | ps - > gunindex ) ;
2016-01-18 05:22:07 +00:00
else
2023-09-11 09:31:09 +00:00
{
if ( pflags & Q2FTEPS_INDEX16 )
MSG_WriteShort ( msg , ps - > gunindex ) ;
else
MSG_WriteByte ( msg , ps - > gunindex ) ;
}
2004-08-23 00:15:46 +00:00
}
if ( pflags & Q2PS_WEAPONFRAME )
{
2023-09-11 09:31:09 +00:00
if ( q2e )
{
unsigned short fl = ps - > gunframe & 0x1ff ;
if ( ps - > gunoffset [ 0 ] ) fl | = 1 < < 9 ;
if ( ps - > gunoffset [ 1 ] ) fl | = 1 < < 10 ;
if ( ps - > gunoffset [ 2 ] ) fl | = 1 < < 11 ;
if ( ps - > gunangles [ 0 ] ) fl | = 1 < < 12 ;
if ( ps - > gunangles [ 1 ] ) fl | = 1 < < 13 ;
if ( ps - > gunangles [ 2 ] ) fl | = 1 < < 14 ;
//if (ps->gunrate[2]) fl |= 1<<15;
MSG_WriteShort ( msg , fl ) ;
if ( fl & ( 1 < < 9 ) ) MSG_WriteFloat ( msg , ps - > gunoffset [ 0 ] ) ;
if ( fl & ( 1 < < 10 ) ) MSG_WriteFloat ( msg , ps - > gunoffset [ 1 ] ) ;
if ( fl & ( 1 < < 11 ) ) MSG_WriteFloat ( msg , ps - > gunoffset [ 2 ] ) ;
if ( fl & ( 1 < < 12 ) ) MSG_WriteFloat ( msg , ps - > gunangles [ 0 ] ) ;
if ( fl & ( 1 < < 13 ) ) MSG_WriteFloat ( msg , ps - > gunangles [ 1 ] ) ;
if ( fl & ( 1 < < 14 ) ) MSG_WriteFloat ( msg , ps - > gunangles [ 2 ] ) ;
//if (fl & (1<<15)) MSG_WriteByte(msg, ps->gunrate);
}
2016-01-18 05:22:07 +00:00
else
2023-09-11 09:31:09 +00:00
{
if ( pflags & Q2FTEPS_INDEX16 )
MSG_WriteShort ( msg , ps - > gunframe ) ;
else
MSG_WriteByte ( msg , ps - > gunframe ) ;
MSG_WriteChar ( msg , ps - > gunoffset [ 0 ] * 4 ) ;
MSG_WriteChar ( msg , ps - > gunoffset [ 1 ] * 4 ) ;
MSG_WriteChar ( msg , ps - > gunoffset [ 2 ] * 4 ) ;
MSG_WriteChar ( msg , ps - > gunangles [ 0 ] * 4 ) ;
MSG_WriteChar ( msg , ps - > gunangles [ 1 ] * 4 ) ;
MSG_WriteChar ( msg , ps - > gunangles [ 2 ] * 4 ) ;
}
2004-08-23 00:15:46 +00:00
}
if ( pflags & Q2PS_BLEND )
{
MSG_WriteByte ( msg , ps - > blend [ 0 ] * 255 ) ;
MSG_WriteByte ( msg , ps - > blend [ 1 ] * 255 ) ;
MSG_WriteByte ( msg , ps - > blend [ 2 ] * 255 ) ;
MSG_WriteByte ( msg , ps - > blend [ 3 ] * 255 ) ;
}
if ( pflags & Q2PS_FOV )
MSG_WriteByte ( msg , ps - > fov ) ;
if ( pflags & Q2PS_RDFLAGS )
MSG_WriteByte ( msg , ps - > rdflags ) ;
// send stats
statbits = 0 ;
2023-09-11 09:31:09 +00:00
for ( i = 0 ; i < min ( 32 , Q2MAX_STATS ) ; i + + )
2004-08-23 00:15:46 +00:00
if ( ps - > stats [ i ] ! = ops - > stats [ i ] )
statbits | = 1 < < i ;
MSG_WriteLong ( msg , statbits ) ;
2023-09-11 09:31:09 +00:00
for ( i = 0 ; i < min ( 32 , Q2MAX_STATS ) ; i + + )
2004-08-23 00:15:46 +00:00
if ( statbits & ( 1 < < i ) )
MSG_WriteShort ( msg , ps - > stats [ i ] ) ;
2016-01-18 05:22:07 +00:00
2023-09-11 09:31:09 +00:00
if ( q2e )
{
statbits = 0 ;
for ( i = 0 ; i < Q2MAX_STATS - 32 ; i + + )
if ( ps - > stats [ 32 + i ] ! = ops - > stats [ 32 + i ] )
statbits | = 1 < < i ;
MSG_WriteLong ( msg , statbits ) ;
for ( i = 0 ; i < Q2MAX_STATS - 32 ; i + + )
if ( statbits & ( 1 < < i ) )
MSG_WriteShort ( msg , ps - > stats [ 32 + i ] ) ;
if ( pflags & Q2EXPS_DAMAGEBLEND )
{
MSG_WriteByte ( msg , 0 * 255 ) ;
MSG_WriteByte ( msg , 0 * 255 ) ;
MSG_WriteByte ( msg , 0 * 255 ) ;
MSG_WriteByte ( msg , 0 * 255 ) ;
}
if ( pflags & Q2EXPS_TEAMID )
MSG_WriteByte ( msg , 0 ) ;
}
else
{
if ( ( extflags & Q2PSX_CLIENTNUM ) | | ( pflags & Q2FTEPS_CLIENTNUM ) )
MSG_WriteByte ( msg , to - > clientnum [ seat ] ) ;
}
2004-08-23 00:15:46 +00:00
}
/*
= = = = = = = = = = = = = = = = = =
SV_WriteFrameToClient
= = = = = = = = = = = = = = = = = =
*/
2012-02-12 05:18:31 +00:00
void SVQ2_WriteFrameToClient ( client_t * client , sizebuf_t * msg )
2004-08-23 00:15:46 +00:00
{
q2client_frame_t * frame , * oldframe ;
int lastframe ;
2016-01-18 05:22:07 +00:00
client_t * split ;
int seat ;
int extflags = 0 ;
2004-08-23 00:15:46 +00:00
//Com_Printf ("%i -> %i\n", client->lastframe, sv.framenum);
// this is the frame we are creating
2006-02-17 02:51:59 +00:00
frame = & client - > frameunion . q2frames [ sv . framenum & Q2UPDATE_MASK ] ;
2004-08-23 00:15:46 +00:00
if ( client - > delta_sequence < = 0 )
{ // client is asking for a retransmit
oldframe = NULL ;
lastframe = - 1 ;
}
else if ( sv . framenum - client - > delta_sequence > = ( Q2UPDATE_BACKUP - 3 ) )
{ // client hasn't gotten a good message through in a long time
// Com_Printf ("%s: Delta request from out-of-date packet.\n", client->name);
oldframe = NULL ;
lastframe = - 1 ;
}
else
{ // we have a valid message to delta from
2006-02-17 02:51:59 +00:00
oldframe = & client - > frameunion . q2frames [ client - > delta_sequence & Q2UPDATE_MASK ] ;
2004-08-23 00:15:46 +00:00
lastframe = client - > delta_sequence ;
}
MSG_WriteByte ( msg , svcq2_frame ) ;
MSG_WriteLong ( msg , sv . framenum ) ;
MSG_WriteLong ( msg , lastframe ) ; // what we are delta'ing from
2014-02-11 17:51:29 +00:00
MSG_WriteByte ( msg , client - > chokecount & 0xff ) ; // rate dropped packets
2016-01-18 05:22:07 +00:00
extflags | = Q2PSX_OLD ;
2011-04-20 03:34:32 +00:00
client - > chokecount = 0 ;
2004-08-23 00:15:46 +00:00
2023-09-11 09:31:09 +00:00
if ( client - > protocol = = SCP_QUAKE2EX )
{
for ( split = client , seat = 0 ; split ; split = split - > controlled , seat + + )
{
// send over the areabits, private per-seat
MSG_WriteByte ( msg , frame - > areabytes ) ;
SZ_Write ( msg , frame - > areabits , frame - > areabytes ) ;
// delta encode the playerstate
SVQ2_WritePlayerstateToClient ( client , seat , extflags , oldframe , frame , msg ) ;
}
}
else
{
// send over the areabits, shared between all seats
MSG_WriteByte ( msg , frame - > areabytes ) ;
SZ_Write ( msg , frame - > areabits , frame - > areabytes ) ;
2004-08-23 00:15:46 +00:00
2023-09-11 09:31:09 +00:00
// delta encode the playerstate
for ( split = client , seat = 0 ; split ; split = split - > controlled , seat + + )
SVQ2_WritePlayerstateToClient ( client , seat , extflags , oldframe , frame , msg ) ;
}
2004-08-23 00:15:46 +00:00
// delta encode the entities
2023-09-11 09:31:09 +00:00
SVQ2_EmitPacketEntities ( oldframe , frame , msg , client - > protocol = = SCP_QUAKE2EX ) ;
2004-08-23 00:15:46 +00:00
}
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
Build a client frame structure
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
/*
= = = = = = = = = = = = =
SV_BuildClientFrame
Decides which entities are going to be visible to the client , and
copies off the playerstat and areabits .
= = = = = = = = = = = = =
*/
void SVQ2_Ents_Init ( void ) ;
2012-02-12 05:18:31 +00:00
void SVQ2_BuildClientFrame ( client_t * client )
2004-08-23 00:15:46 +00:00
{
int e , i ;
2016-01-18 05:22:07 +00:00
vec3_t org [ MAX_SPLITS ] ;
int clientarea [ MAX_SPLITS ] ;
q2edict_t * clent [ MAX_SPLITS ] ;
client_t * split ;
2004-08-23 00:15:46 +00:00
q2edict_t * ent ;
q2client_frame_t * frame ;
q2entity_state_t * state ;
int l ;
2016-01-18 05:22:07 +00:00
int seat ;
2004-08-23 00:15:46 +00:00
int c_fullsend ;
2017-06-21 01:24:25 +00:00
pvsbuffer_t clientpvs ;
2016-01-18 05:22:07 +00:00
qbyte * clientphs = NULL ;
int seats ;
2004-08-23 00:15:46 +00:00
if ( client - > state < cs_spawned )
return ;
SVQ2_Ents_Init ( ) ;
2017-06-21 01:24:25 +00:00
clientpvs . buffer = alloca ( clientpvs . buffersize = sv . world . worldmodel - > pvsbytes ) ;
2004-08-23 00:15:46 +00:00
#if 0
numprojs = 0 ; // no projectiles yet
# endif
2015-05-14 03:06:58 +00:00
// this is the frame the client will be acking (EVIL HACKS!)
frame = & client - > frameunion . q2frames [ client - > netchan . outgoing_sequence & Q2UPDATE_MASK ] ;
2004-08-23 00:15:46 +00:00
2013-03-12 22:53:23 +00:00
frame - > senttime = realtime * 1000 ; // save it for ping calc later
2004-08-23 00:15:46 +00:00
2015-05-14 03:06:58 +00:00
// this is the frame we are creating
frame = & client - > frameunion . q2frames [ sv . framenum & Q2UPDATE_MASK ] ;
2016-01-18 05:22:07 +00:00
// grab the current player_state_t
for ( seat = 0 , split = client ; split ; split = split - > controlled , seat + + )
{
int clientcluster ;
clent [ seat ] = split - > q2edict ;
frame - > clientnum [ seat ] = split - svs . clients ;
if ( ! split - > q2edict - > client )
{ //shouldn't happen
VectorClear ( org [ seat ] ) ;
clientarea [ seat ] = 0 ;
memset ( & frame - > ps [ seat ] , 0 , sizeof ( frame - > ps [ seat ] ) ) ;
frame - > ps [ seat ] . pmove . pm_type = Q2PM_FREEZE ;
continue ;
}
2004-08-23 00:15:46 +00:00
2016-01-18 05:22:07 +00:00
// find the client's PVS
for ( i = 0 ; i < 3 ; i + + )
org [ seat ] [ i ] = clent [ seat ] - > client - > ps . pmove . origin [ i ] * 0.125 + clent [ seat ] - > client - > ps . viewoffset [ i ] ;
2004-08-23 00:15:46 +00:00
2021-11-03 20:30:40 +00:00
clientcluster = sv . world . worldmodel - > funcs . ClusterForPoint ( sv . world . worldmodel , org [ seat ] , & clientarea [ seat ] ) ;
2004-08-23 00:15:46 +00:00
2016-01-18 05:22:07 +00:00
// calculate the visible areas
2021-11-03 20:30:40 +00:00
frame - > areabytes = sv . world . worldmodel - > funcs . WriteAreaBits ( sv . world . worldmodel , frame - > areabits , sizeof ( frame - > areabits ) , clientarea [ seat ] , seat ! = 0 ) ;
2004-08-23 00:15:46 +00:00
2017-06-21 01:24:25 +00:00
sv . world . worldmodel - > funcs . FatPVS ( sv . world . worldmodel , org [ seat ] , & clientpvs , seat ! = 0 ) ;
if ( seat = = 0 ) //FIXME
2021-11-03 20:30:40 +00:00
clientphs = sv . world . worldmodel - > funcs . ClusterPHS ( sv . world . worldmodel , clientcluster , NULL ) ;
2011-04-20 03:34:32 +00:00
2016-01-18 05:22:07 +00:00
frame - > ps [ seat ] = clent [ seat ] - > client - > ps ;
if ( sv . paused )
frame - > ps [ seat ] . pmove . pm_type = Q2PM_FREEZE ;
}
seats = seat ;
for ( ; seat < MAX_SPLITS ; seat + + )
{
memset ( & frame - > ps [ seat ] , 0 , sizeof ( frame - > ps [ seat ] ) ) ;
frame - > clientnum [ seat ] = 0xff ; //invalid
}
2004-08-23 00:15:46 +00:00
// build up the list of visible entities
frame - > num_entities = 0 ;
frame - > first_entity = svs_next_client_entities ;
c_fullsend = 0 ;
for ( e = 1 ; e < ge - > num_edicts ; e + + )
{
ent = Q2EDICT_NUM ( e ) ;
// ignore ents without visible models
if ( ent - > svflags & SVF_NOCLIENT )
continue ;
// ignore ents without visible models unless they have an effect
if ( ! ent - > s . modelindex & & ! ent - > s . effects & & ! ent - > s . sound
& & ! ent - > s . event )
continue ;
2016-01-18 05:22:07 +00:00
for ( seat = 0 ; seat < seats ; seat + + )
2004-08-23 00:15:46 +00:00
{
2016-01-18 05:22:07 +00:00
// ignore if not touching a PV leaf
if ( ent ! = clent [ seat ] )
2004-08-23 00:15:46 +00:00
{
2016-01-18 05:22:07 +00:00
// check area
2021-11-03 20:30:40 +00:00
if ( ! sv . world . worldmodel - > funcs . AreasConnected ( sv . world . worldmodel , clientarea [ seat ] , ent - > areanum ) )
2016-01-18 05:22:07 +00:00
{ // doors can legally straddle two areas, so
// we may need to check another one
if ( ! ent - > areanum2
2021-11-03 20:30:40 +00:00
| | ! sv . world . worldmodel - > funcs . AreasConnected ( sv . world . worldmodel , clientarea [ seat ] , ent - > areanum2 ) )
2016-01-18 05:22:07 +00:00
continue ; // blocked by a door
}
2004-08-23 00:15:46 +00:00
2016-01-18 05:22:07 +00:00
// beams just check one point for PHS
if ( ent - > s . renderfx & Q2RF_BEAM )
{
l = ent - > clusternums [ 0 ] ;
if ( ! ( clientphs [ l > > 3 ] & ( 1 < < ( l & 7 ) ) ) )
2004-08-23 00:15:46 +00:00
continue ;
}
else
2016-01-18 05:22:07 +00:00
{
// FIXME: if an ent has a model and a sound, but isn't
// in the PVS, only the PHS, clear the model
if ( ent - > num_clusters = = - 1 )
{ // too many leafs for individual check, go by headnode
2021-11-03 20:30:40 +00:00
pvscache_t cache ;
cache . num_leafs = - 1 ;
cache . headnode = ent - > headnode ;
if ( ! sv . world . worldmodel - > funcs . EdictInFatPVS ( sv . world . worldmodel , & cache , clientpvs . buffer , NULL ) )
2016-01-18 05:22:07 +00:00
continue ;
c_fullsend + + ;
}
else
{ // check individual leafs
for ( i = 0 ; i < ent - > num_clusters ; i + + )
{
l = ent - > clusternums [ i ] ;
2017-06-21 01:24:25 +00:00
if ( clientpvs . buffer [ l > > 3 ] & ( 1 < < ( l & 7 ) ) )
2016-01-18 05:22:07 +00:00
break ;
}
if ( i = = ent - > num_clusters )
continue ; // not visible
2004-08-23 00:15:46 +00:00
}
2016-01-18 05:22:07 +00:00
if ( ! ent - > s . modelindex )
{ // don't send sounds if they will be attenuated away
vec3_t delta ;
float len ;
2004-08-23 00:15:46 +00:00
2016-01-18 05:22:07 +00:00
VectorSubtract ( org [ seat ] , ent - > s . origin , delta ) ;
len = Length ( delta ) ;
if ( len > 400 )
continue ;
}
2004-08-23 00:15:46 +00:00
}
}
2016-01-18 05:22:07 +00:00
break ;
2004-08-23 00:15:46 +00:00
}
2016-01-18 05:22:07 +00:00
if ( seat = = seats )
continue ; //not visible to any seat
seat = 0 ; //FIXME
2004-08-23 00:15:46 +00:00
// add it to the circular client_entities array
state = & svs_client_entities [ svs_next_client_entities % svs_num_client_entities ] ;
if ( ent - > s . number ! = e )
{
Con_DPrintf ( " FIXING ENT->S.NUMBER!!! \n " ) ;
ent - > s . number = e ;
}
* state = ent - > s ;
// don't mark players missiles as solid
2016-01-18 05:22:07 +00:00
if ( ent - > owner = = clent [ seat ] )
2004-08-23 00:15:46 +00:00
state - > solid = 0 ;
svs_next_client_entities + + ;
frame - > num_entities + + ;
}
}
Fixes, workarounds, and breakages. Hexen2 should work much better (-hexen2 says no mission pack, -portals says h2mp). Started working on splitting bigcoords per client, far too much work still to go on that. Removed gl_ztrick entirely. Enabled csprogs download by default. Added client support for fitzquake's 666 protocol, needs testing, some cleanup for dp protocols too, no server support, couldn't selectively enable it anyway. Now attempting to cache shadow meshes for explosions and stuff. Played with lightmaps a little, should potentially run a little faster on certain (intel?) cards. Tweeked npfte a little to try to avoid deadlocks and crashes. Fixed sky worldspawn parsing. Added h2mp's model format. Fixed baseline issue in q2 client, made servers generate q2 baselines. MOVETYPE_PUSH will not rotate extra if rotation is forced. Made status command show allowed client types. Changed lighting on weapons - should now be shaded.
git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3572 fc73d0e0-1445-4013-8a0c-d673dee63da5
2010-08-11 03:36:31 +00:00
void SVQ2_BuildBaselines ( void )
{
unsigned int e ;
q2edict_t * ent ;
q2entity_state_t * base ;
if ( ! ge )
return ;
for ( e = 1 ; e < ge - > num_edicts ; e + + )
{
ent = Q2EDICT_NUM ( e ) ;
base = & ent - > s ;
if ( base - > modelindex | | base - > sound | | base - > effects )
sv_baselines [ e ] = * base ;
}
}
2004-08-23 00:15:46 +00:00
void SVQ2_Ents_Init ( void )
{
extern cvar_t maxclients ;
if ( ! svs_client_entities )
{
svs_num_client_entities = maxclients . value * Q2UPDATE_BACKUP * 64 ;
svs_client_entities = Z_Malloc ( sizeof ( entity_state_t ) * svs_num_client_entities ) ;
}
}
2015-05-03 19:57:46 +00:00
void SVQ2_Ents_Shutdown ( void )
{
if ( svs_client_entities )
{
Z_Free ( svs_client_entities ) ;
svs_client_entities = NULL ;
svs_num_client_entities = 0 ;
}
}
2004-08-23 00:15:46 +00:00
# endif
2004-11-29 01:21:00 +00:00
# endif