2004-08-23 00:15:46 +00:00
/*
Copyright ( C ) 1996 - 1997 Id Software , Inc .
This program is free software ; you can redistribute it and / or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation ; either version 2
of the License , or ( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
2005-12-13 02:31:57 +00:00
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
2004-08-23 00:15:46 +00:00
See the GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program ; if not , write to the Free Software
Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
*/
# include "qwsvdef.h"
2009-11-04 21:16:50 +00:00
# include "pr_common.h"
2004-11-29 01:21:00 +00:00
# ifndef CLIENTONLY
2004-08-23 00:15:46 +00:00
void SV_CleanupEnts ( void ) ;
extern cvar_t sv_nailhack ;
2007-08-30 18:55:44 +00:00
extern cvar_t sv_cullentities_trace ;
extern cvar_t sv_cullplayers_trace ;
2004-08-23 00:15:46 +00:00
/*
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
The PVS must include a small area around the client to allow head bobbing
or other small motion on the client side . Otherwise , a bob might cause an
entity that should be visible to not show up , especially when the bob
crosses a waterline .
= = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
*/
int needcleanup ;
2009-06-21 17:45:33 +00:00
//int fatbytes;
2006-01-27 08:06:48 +00:00
int glowsize , glowcolor ; // made it a global variable, to suppress msvc warning.
2004-08-23 00:15:46 +00:00
# ifdef Q2BSPS
2009-06-28 19:57:09 +00:00
unsigned int SV_Q2BSP_FatPVS ( model_t * mod , vec3_t org , qbyte * resultbuf , unsigned int buffersize , qboolean add )
2004-08-23 00:15:46 +00:00
{
int leafs [ 64 ] ;
int i , j , count ;
2009-06-21 17:45:33 +00:00
unsigned int longs ;
2004-08-23 00:15:46 +00:00
qbyte * src ;
vec3_t mins , maxs ;
for ( i = 0 ; i < 3 ; i + + )
{
mins [ i ] = org [ i ] - 8 ;
maxs [ i ] = org [ i ] + 8 ;
}
2005-08-26 22:56:51 +00:00
count = CM_BoxLeafnums ( mod , mins , maxs , leafs , 64 , NULL ) ;
2004-08-23 00:15:46 +00:00
if ( count < 1 )
Sys_Error ( " SV_Q2FatPVS: count < 1 " ) ;
2009-11-04 21:16:50 +00:00
if ( sv . world . worldmodel - > fromgame = = fg_quake3 )
2005-08-26 22:56:51 +00:00
longs = CM_ClusterSize ( mod ) ;
2004-08-23 00:15:46 +00:00
else
2009-06-21 17:45:33 +00:00
longs = ( CM_NumClusters ( mod ) + 7 ) / 8 ;
longs = ( longs + ( sizeof ( long ) - 1 ) ) / sizeof ( long ) ;
2004-08-23 00:15:46 +00:00
// convert leafs to clusters
for ( i = 0 ; i < count ; i + + )
2005-08-26 22:56:51 +00:00
leafs [ i ] = CM_LeafCluster ( mod , leafs [ i ] ) ;
2004-08-23 00:15:46 +00:00
2009-06-21 17:45:33 +00:00
CM_ClusterPVS ( mod , leafs [ 0 ] , resultbuf , buffersize ) ;
2004-08-23 00:15:46 +00:00
2009-06-28 19:57:09 +00:00
if ( ! add )
{
memcpy ( resultbuf , CM_ClusterPVS ( mod , leafs [ 0 ] , NULL , 0 ) , longs < < 2 ) ;
i = 1 ;
}
else
i = 0 ;
2004-08-23 00:15:46 +00:00
// or in all the other leaf bits
2009-06-28 19:57:09 +00:00
for ( ; i < count ; i + + )
2004-08-23 00:15:46 +00:00
{
for ( j = 0 ; j < i ; j + + )
if ( leafs [ i ] = = leafs [ j ] )
break ;
if ( j ! = i )
continue ; // already have the cluster we want
2009-06-21 17:45:33 +00:00
src = CM_ClusterPVS ( mod , leafs [ i ] , NULL , 0 ) ;
2004-08-23 00:15:46 +00:00
for ( j = 0 ; j < longs ; j + + )
2009-06-21 17:45:33 +00:00
( ( long * ) resultbuf ) [ j ] | = ( ( long * ) src ) [ j ] ;
2004-08-23 00:15:46 +00:00
}
2009-06-21 17:45:33 +00:00
return longs * sizeof ( long ) ;
2004-08-23 00:15:46 +00:00
}
# endif
//=============================================================================
// because there can be a lot of nails, there is a special
// network protocol for them
# define MAX_NAILS 32
edict_t * nails [ MAX_NAILS ] ;
int numnails ;
int nailcount = 0 ;
extern int sv_nailmodel , sv_supernailmodel , sv_playermodel ;
qboolean demonails ;
2005-04-26 16:04:12 +00:00
static edict_t * csqcent [ MAX_EDICTS ] ;
static int csqcnuments ;
2005-02-12 18:56:04 +00:00
2004-08-23 00:15:46 +00:00
qboolean SV_AddNailUpdate ( edict_t * ent )
{
2005-03-28 00:11:59 +00:00
if ( ent - > v - > modelindex ! = sv_nailmodel
& & ent - > v - > modelindex ! = sv_supernailmodel )
2004-08-23 00:15:46 +00:00
return false ;
if ( sv_nailhack . value )
return false ;
2005-05-20 03:32:53 +00:00
demonails = false ;
2004-08-23 00:15:46 +00:00
if ( numnails = = MAX_NAILS )
return true ;
nails [ numnails ] = ent ;
numnails + + ;
return true ;
}
qboolean SV_DemoNailUpdate ( int i )
{
demonails = true ;
if ( numnails = = MAX_NAILS )
return true ;
nails [ numnails ] = ( edict_t * ) i ;
numnails + + ;
return true ;
}
void SV_EmitNailUpdate ( sizebuf_t * msg , qboolean recorder )
{
2005-12-13 02:31:57 +00:00
qbyte bits [ 6 ] ; // [48 bits] xyzpy 12 12 12 4 8
2004-08-23 00:15:46 +00:00
int n , i ;
edict_t * ent ;
int x , y , z , p , yaw ;
if ( ! numnails )
return ;
if ( recorder )
MSG_WriteByte ( msg , svc_nails2 ) ;
else
MSG_WriteByte ( msg , svc_nails ) ;
MSG_WriteByte ( msg , numnails ) ;
2009-11-07 13:29:15 +00:00
# ifdef SERVER_DEMO_PLAYBACK
2004-08-23 00:15:46 +00:00
if ( demonails )
{
for ( n = 0 ; n < numnails ; n + + )
{
i = ( int ) ( nails [ n ] ) ;
if ( recorder ) {
if ( ! sv . demospikes [ i ] . id ) {
if ( ! ( ( + + nailcount ) & 255 ) ) nailcount + + ;
sv . demospikes [ i ] . id = nailcount & 255 ;
}
MSG_WriteByte ( msg , ( qbyte ) sv . demospikes [ i ] . id ) ;
}
x = ( int ) ( sv . demospikes [ i ] . org [ 0 ] + 4096 ) > > 1 ;
y = ( int ) ( sv . demospikes [ i ] . org [ 1 ] + 4096 ) > > 1 ;
z = ( int ) ( sv . demospikes [ i ] . org [ 2 ] + 4096 ) > > 1 ;
p = ( int ) ( sv . demospikes [ i ] . pitch ) & 15 ;
yaw = ( int ) ( sv . demospikes [ i ] . yaw ) & 255 ;
bits [ 0 ] = x ;
bits [ 1 ] = ( x > > 8 ) | ( y < < 4 ) ;
bits [ 2 ] = ( y > > 4 ) ;
bits [ 3 ] = z ;
bits [ 4 ] = ( z > > 8 ) | ( p < < 4 ) ;
bits [ 5 ] = yaw ;
for ( i = 0 ; i < 6 ; i + + )
MSG_WriteByte ( msg , bits [ i ] ) ;
}
return ;
}
2009-11-07 13:29:15 +00:00
# endif
2004-08-23 00:15:46 +00:00
for ( n = 0 ; n < numnails ; n + + )
{
ent = nails [ n ] ;
if ( recorder ) {
2005-03-28 00:11:59 +00:00
if ( ! ent - > v - > colormap ) {
2004-08-23 00:15:46 +00:00
if ( ! ( ( + + nailcount ) & 255 ) ) nailcount + + ;
2005-03-28 00:11:59 +00:00
ent - > v - > colormap = nailcount & 255 ;
2004-08-23 00:15:46 +00:00
}
2005-03-28 00:11:59 +00:00
MSG_WriteByte ( msg , ( qbyte ) ent - > v - > colormap ) ;
2004-08-23 00:15:46 +00:00
}
2005-03-28 00:11:59 +00:00
x = ( int ) ( ent - > v - > origin [ 0 ] + 4096 ) > > 1 ;
y = ( int ) ( ent - > v - > origin [ 1 ] + 4096 ) > > 1 ;
z = ( int ) ( ent - > v - > origin [ 2 ] + 4096 ) > > 1 ;
p = ( int ) ( 16 * ent - > v - > angles [ 0 ] / 360 ) & 15 ;
yaw = ( int ) ( 256 * ent - > v - > angles [ 1 ] / 360 ) & 255 ;
2004-08-23 00:15:46 +00:00
2011-06-29 18:39:11 +00:00
bits [ 0 ] = x & 0xff ;
bits [ 1 ] = ( ( x > > 8 ) | ( y < < 4 ) ) & 0xff ;
bits [ 2 ] = ( y > > 4 ) & 0xff ;
bits [ 3 ] = z & 0xff ;
bits [ 4 ] = ( ( z > > 8 ) | ( p < < 4 ) ) & 0xff ;
bits [ 5 ] = yaw & 0xff ;
2004-08-23 00:15:46 +00:00
for ( i = 0 ; i < 6 ; i + + )
MSG_WriteByte ( msg , bits [ i ] ) ;
}
}
2005-02-28 07:16:19 +00:00
//=============================================================================
//this is the bit of the code that sends the csqc entity deltas out.
//whenever the entity in question has a newer version than we sent to the client, we need to resend.
//So, we track the outgoing sequence that an entity was sent in, and the version.
//Upon detection of a dropped packet, we resend all entities who were last sent in that packet.
//When an entities' last sent version doesn't match the current version, we send.
static qboolean SV_AddCSQCUpdate ( client_t * client , edict_t * ent )
{
# ifndef PEXT_CSQC
return false ;
# else
2005-03-10 03:55:18 +00:00
if ( ! ( client - > csqcactive ) )
2005-02-28 07:16:19 +00:00
return false ;
2007-09-02 19:55:17 +00:00
if ( ! ent - > xv - > SendEntity )
2005-02-28 07:16:19 +00:00
return false ;
csqcent [ csqcnuments + + ] = ent ;
return true ;
# endif
}
sizebuf_t csqcmsgbuffer ;
2005-02-12 18:56:04 +00:00
void SV_EmitCSQCUpdate ( client_t * client , sizebuf_t * msg )
{
2005-02-28 07:16:19 +00:00
# ifdef PEXT_CSQC
qbyte messagebuffer [ 1024 ] ;
int en ;
int currentsequence = client - > netchan . outgoing_sequence ;
unsigned short mask ;
2009-03-03 01:52:30 +00:00
globalvars_t * pr_globals ;
2005-02-28 07:16:19 +00:00
edict_t * ent ;
qboolean writtenheader = false ;
2008-11-09 22:29:28 +00:00
//we don't check that we got some already - because this is delta compressed!
2005-02-28 07:16:19 +00:00
2009-03-03 01:52:30 +00:00
if ( ! ( client - > csqcactive ) | | ! svprogfuncs )
2005-02-28 07:16:19 +00:00
return ;
2009-03-03 01:52:30 +00:00
pr_globals = PR_globals ( svprogfuncs , PR_CURRENT ) ;
2005-02-28 07:16:19 +00:00
//FIXME: prioritise the list of csqc ents somehow
csqcmsgbuffer . data = messagebuffer ;
csqcmsgbuffer . maxsize = sizeof ( messagebuffer ) ;
csqcmsgbuffer . packing = msg - > packing ;
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
csqcmsgbuffer . prim = msg - > prim ;
2005-02-28 07:16:19 +00:00
for ( en = 0 ; en < csqcnuments ; en + + )
{
ent = csqcent [ en ] ;
2008-11-09 22:29:28 +00:00
if ( ent - > xv - > SendFlags )
{
ent - > xv - > SendFlags = 0 ;
ent - > xv - > Version + = 1 ;
}
2005-02-28 07:16:19 +00:00
//prevent mishaps with entities being respawned and things.
2007-09-02 19:55:17 +00:00
if ( ( int ) ent - > xv - > Version < sv . csqcentversion [ ent - > entnum ] )
ent - > xv - > Version = sv . csqcentversion [ ent - > entnum ] ;
2005-02-28 07:16:19 +00:00
else
2007-09-02 19:55:17 +00:00
sv . csqcentversion [ ent - > entnum ] = ( int ) ent - > xv - > Version ;
2005-02-28 07:16:19 +00:00
//If it's not changed, don't send
if ( client - > csqcentversions [ ent - > entnum ] = = sv . csqcentversion [ ent - > entnum ] )
continue ;
csqcmsgbuffer . cursize = 0 ;
csqcmsgbuffer . currentbit = 0 ;
//Ask CSQC to write a buffer for it.
G_INT ( OFS_PARM0 ) = EDICT_TO_PROG ( svprogfuncs , client - > edict ) ;
2010-02-06 01:25:04 +00:00
G_FLOAT ( OFS_PARM1 ) = 0xffffff ; //psudo compatibility with SendFlags (fte doesn't support properly)
2005-02-28 07:16:19 +00:00
pr_global_struct - > self = EDICT_TO_PROG ( svprogfuncs , ent ) ;
2007-09-02 19:55:17 +00:00
PR_ExecuteProgram ( svprogfuncs , ent - > xv - > SendEntity ) ;
2005-02-28 07:16:19 +00:00
if ( G_INT ( OFS_RETURN ) ) //0 means not to tell the client about it.
{
if ( msg - > cursize + csqcmsgbuffer . cursize + 5 > = msg - > maxsize )
{
if ( csqcmsgbuffer . cursize < 32 )
break ;
continue ;
}
if ( ! writtenheader )
{
writtenheader = true ;
2007-06-10 05:14:38 +00:00
if ( client - > protocol ! = SCP_QUAKEWORLD )
MSG_WriteByte ( msg , svcdp_csqcentities ) ;
else
2008-05-25 22:23:43 +00:00
MSG_WriteByte ( msg , svcfte_csqcentities ) ;
2005-02-28 07:16:19 +00:00
}
MSG_WriteShort ( msg , ent - > entnum ) ;
2005-03-20 02:57:11 +00:00
if ( sv . csqcdebug ) //optional extra.
{
if ( ! csqcmsgbuffer . cursize )
2005-03-28 00:11:59 +00:00
Con_Printf ( " Warning: empty csqc packet on %s \n " , svprogfuncs - > stringtable + ent - > v - > classname ) ;
2005-03-20 02:57:11 +00:00
MSG_WriteShort ( msg , csqcmsgbuffer . cursize ) ;
}
2005-02-28 07:16:19 +00:00
//FIXME: Add a developer mode to write the length of each entity.
SZ_Write ( msg , csqcmsgbuffer . data , csqcmsgbuffer . cursize ) ;
2005-04-16 16:21:27 +00:00
// Con_Printf("Sending update packet %i\n", ent->entnum);
2005-02-28 07:16:19 +00:00
}
2008-05-25 22:23:43 +00:00
else if ( sv . csqcentversion [ ent - > entnum ] & & ! ( ( int ) ent - > xv - > pvsflags & PVSF_NOREMOVE ) )
2008-11-09 22:29:28 +00:00
{ //Don't want to send, but they have it already
2005-02-28 07:16:19 +00:00
if ( ! writtenheader )
{
writtenheader = true ;
2008-05-25 22:23:43 +00:00
MSG_WriteByte ( msg , svcfte_csqcentities ) ;
2005-02-28 07:16:19 +00:00
}
2005-02-12 18:56:04 +00:00
2005-02-28 07:16:19 +00:00
mask = ( unsigned ) ent - > entnum | 0x8000 ;
MSG_WriteShort ( msg , mask ) ;
2005-04-16 16:21:27 +00:00
// Con_Printf("Sending remove 2 packet\n");
2005-02-28 07:16:19 +00:00
}
client - > csqcentversions [ ent - > entnum ] = sv . csqcentversion [ ent - > entnum ] ;
client - > csqcentsequence [ ent - > entnum ] = currentsequence ;
}
2008-11-09 22:29:28 +00:00
//now remove any out dated ones
2009-11-04 21:16:50 +00:00
for ( en = 1 ; en < sv . world . num_edicts ; en + + )
2005-02-28 07:16:19 +00:00
{
2008-05-25 22:23:43 +00:00
ent = EDICT_NUM ( svprogfuncs , en ) ;
if ( client - > csqcentversions [ en ] > 0 & & ( client - > csqcentversions [ en ] ! = sv . csqcentversion [ en ] ) & & ! ( ( int ) ent - > xv - > pvsflags & PVSF_NOREMOVE ) )
2005-02-28 07:16:19 +00:00
{
// if (!ent->isfree)
// continue;
if ( msg - > cursize + 5 > = msg - > maxsize ) //try removing next frame instead.
{
}
else
{
if ( ! writtenheader )
{
writtenheader = true ;
2008-05-25 22:23:43 +00:00
MSG_WriteByte ( msg , svcfte_csqcentities ) ;
2005-02-28 07:16:19 +00:00
}
2005-04-16 16:21:27 +00:00
// Con_Printf("Sending remove packet %i\n", en);
2005-02-28 07:16:19 +00:00
mask = ( unsigned ) en | 0x8000 ;
MSG_WriteShort ( msg , mask ) ;
client - > csqcentversions [ en ] = 0 ;
client - > csqcentsequence [ en ] = currentsequence ;
}
}
}
if ( writtenheader )
MSG_WriteShort ( msg , 0 ) ; //a 0 means no more.
csqcnuments = 0 ;
//prevent the qc from trying to use it at inopertune times.
csqcmsgbuffer . maxsize = 0 ;
csqcmsgbuffer . data = NULL ;
# endif
}
2005-03-10 03:55:18 +00:00
# ifdef PEXT_CSQC
2005-02-28 07:16:19 +00:00
void SV_CSQC_DroppedPacket ( client_t * client , int sequence )
{
int i ;
2005-03-10 03:55:18 +00:00
if ( ! ( client - > csqcactive ) ) //we don't need this, but it might be a little faster.
return ;
2009-11-04 21:16:50 +00:00
for ( i = 0 ; i < sv . world . num_edicts ; i + + )
2005-02-28 07:16:19 +00:00
if ( client - > csqcentsequence [ i ] = = sequence )
client - > csqcentversions [ i ] - - ; //do that update thang (but later).
2005-02-12 18:56:04 +00:00
}
2005-12-06 02:17:55 +00:00
void SV_CSQC_DropAll ( client_t * client )
{
int i ;
if ( ! ( client - > csqcactive ) ) //we don't need this, but it might be a little faster.
return ;
2009-11-04 21:16:50 +00:00
for ( i = 0 ; i < sv . world . num_edicts ; i + + )
2005-12-06 02:17:55 +00:00
client - > csqcentversions [ i ] - - ; //do that update thang (but later).
}
2005-03-10 03:55:18 +00:00
# endif
2005-02-12 18:56:04 +00:00
2004-08-23 00:15:46 +00:00
//=============================================================================
/*
= = = = = = = = = = = = = = = = = =
SV_WriteDelta
Writes part of a packetentities message .
Can delta from either a baseline or a previous packet_entity
= = = = = = = = = = = = = = = = = =
*/
void SV_WriteDelta ( entity_state_t * from , entity_state_t * to , sizebuf_t * msg , qboolean force , unsigned int protext )
{
# ifdef PROTOCOLEXTENSIONS
int evenmorebits = 0 ;
# endif
int bits ;
int i ;
2006-06-04 18:57:00 +00:00
int fromeffects ;
2009-11-15 03:20:17 +00:00
coorddata coordd [ 3 ] ;
coorddata angled [ 3 ] ;
2004-08-23 00:15:46 +00:00
2004-12-08 04:14:52 +00:00
static entity_state_t defaultbaseline ;
if ( from = = & ( ( edict_t * ) NULL ) - > baseline )
from = & defaultbaseline ;
2004-08-23 00:15:46 +00:00
// send an update
bits = 0 ;
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
if ( msg - > prim . coordsize = = 2 )
2004-08-23 00:15:46 +00:00
{
2009-07-18 20:14:10 +00:00
for ( i = 0 ; i < 3 ; i + + )
{
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
coordd [ i ] = MSG_ToCoord ( to - > origin [ i ] , msg - > prim . coordsize ) ;
if ( MSG_ToCoord ( from - > origin [ i ] , msg - > prim . coordsize ) . b4 ! = coordd [ i ] . b4 )
2009-07-18 20:14:10 +00:00
bits | = U_ORIGIN1 < < i ;
else
to - > origin [ i ] = from - > origin [ i ] ;
}
}
else
{
for ( i = 0 ; i < 3 ; i + + )
2004-08-23 00:15:46 +00:00
{
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
coordd [ i ] = MSG_ToCoord ( to - > origin [ i ] , msg - > prim . coordsize ) ;
2009-07-18 20:14:10 +00:00
if ( to - > origin [ i ] ! = from - > origin [ i ] )
bits | = U_ORIGIN1 < < i ;
2004-08-23 00:15:46 +00:00
}
}
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
angled [ 0 ] = MSG_ToAngle ( to - > angles [ 0 ] , msg - > prim . anglesize ) ;
if ( MSG_ToAngle ( from - > angles [ 0 ] , msg - > prim . anglesize ) . b4 ! = angled [ 0 ] . b4 )
2004-08-23 00:15:46 +00:00
bits | = U_ANGLE1 ;
2009-11-15 03:20:17 +00:00
else
to - > angles [ 0 ] = from - > angles [ 0 ] ;
2004-08-23 00:15:46 +00:00
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
angled [ 1 ] = MSG_ToAngle ( to - > angles [ 1 ] , msg - > prim . anglesize ) ;
if ( MSG_ToAngle ( from - > angles [ 1 ] , msg - > prim . anglesize ) . b4 ! = angled [ 1 ] . b4 )
2004-08-23 00:15:46 +00:00
bits | = U_ANGLE2 ;
2009-11-15 03:20:17 +00:00
else
to - > angles [ 1 ] = from - > angles [ 1 ] ;
2004-08-23 00:15:46 +00:00
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
angled [ 2 ] = MSG_ToAngle ( to - > angles [ 2 ] , msg - > prim . anglesize ) ;
if ( MSG_ToAngle ( from - > angles [ 2 ] , msg - > prim . anglesize ) . b4 ! = angled [ 2 ] . b4 )
2004-08-23 00:15:46 +00:00
bits | = U_ANGLE3 ;
2009-11-15 03:20:17 +00:00
else
to - > angles [ 2 ] = from - > angles [ 2 ] ;
2004-08-23 00:15:46 +00:00
if ( to - > colormap ! = from - > colormap )
bits | = U_COLORMAP ;
if ( to - > skinnum ! = from - > skinnum )
bits | = U_SKIN ;
if ( to - > frame ! = from - > frame )
bits | = U_FRAME ;
2006-06-04 18:57:00 +00:00
if ( force & & ! ( protext & PEXT_SPAWNSTATIC2 ) )
fromeffects = 0 ; //force is true if we're going from baseline
else //old quakeworld protocols do not include effects in the baseline
fromeffects = from - > effects ; //so old clients will see the effects baseline as 0
2008-11-09 22:29:28 +00:00
if ( ( to - > effects & 0x00ff ) ! = ( fromeffects & 0x00ff ) )
2004-08-23 00:15:46 +00:00
bits | = U_EFFECTS ;
2008-11-09 22:29:28 +00:00
if ( ( to - > effects & 0xff00 ) ! = ( fromeffects & 0xff00 ) & & protext & PEXT_DPFLAGS )
2005-08-26 22:56:51 +00:00
evenmorebits | = U_EFFECTS16 ;
2004-08-23 00:15:46 +00:00
2008-11-09 22:29:28 +00:00
if ( to - > modelindex ! = from - > modelindex )
2004-08-23 00:15:46 +00:00
{
bits | = U_MODEL ;
if ( to - > modelindex > 255 )
2008-11-09 22:29:28 +00:00
{
2008-12-02 23:05:14 +00:00
if ( protext & PEXT_MODELDBL )
2008-11-09 22:29:28 +00:00
evenmorebits | = U_MODELDBL ;
else
return ;
}
2004-08-23 00:15:46 +00:00
}
# ifdef PROTOCOLEXTENSIONS
# ifdef U_SCALE
if ( to - > scale ! = from - > scale & & protext & PEXT_SCALE )
evenmorebits | = U_SCALE ;
# endif
# ifdef U_TRANS
if ( to - > trans ! = from - > trans & & protext & PEXT_TRANS )
evenmorebits | = U_TRANS ;
# endif
# ifdef U_FATNESS
if ( to - > fatness ! = from - > fatness & & protext & PEXT_FATNESS )
evenmorebits | = U_FATNESS ;
# endif
2005-05-15 18:49:04 +00:00
if ( to - > hexen2flags ! = from - > hexen2flags & & protext & PEXT_HEXEN2 )
2004-08-23 00:15:46 +00:00
evenmorebits | = U_DRAWFLAGS ;
if ( to - > abslight ! = from - > abslight & & protext & PEXT_HEXEN2 )
evenmorebits | = U_ABSLIGHT ;
2006-03-12 06:23:52 +00:00
if ( ( to - > colormod [ 0 ] ! = from - > colormod [ 0 ] | | to - > colormod [ 1 ] ! = from - > colormod [ 1 ] | | to - > colormod [ 2 ] ! = from - > colormod [ 2 ] ) & & protext & PEXT_COLOURMOD )
2006-02-27 00:42:25 +00:00
evenmorebits | = U_COLOURMOD ;
2005-07-01 19:23:00 +00:00
if ( to - > glowsize ! = from - > glowsize )
2006-07-24 04:24:41 +00:00
to - > dpflags | = 2 ; // RENDER_GLOWTRAIL
2005-05-17 02:36:54 +00:00
2005-08-07 18:08:13 +00:00
if ( to - > dpflags ! = from - > dpflags & & protext & PEXT_DPFLAGS )
2005-05-15 18:49:04 +00:00
evenmorebits | = U_DPFLAGS ;
2005-08-07 18:08:13 +00:00
if ( ( to - > tagentity ! = from - > tagentity | | to - > tagindex ! = from - > tagindex ) & & protext & PEXT_DPFLAGS )
2005-07-01 19:23:00 +00:00
evenmorebits | = U_TAGINFO ;
2005-08-07 18:08:13 +00:00
if ( ( to - > light [ 0 ] ! = from - > light [ 0 ] | | to - > light [ 1 ] ! = from - > light [ 1 ] | | to - > light [ 2 ] ! = from - > light [ 2 ] | | to - > light [ 3 ] ! = from - > light [ 3 ] | | to - > lightstyle ! = from - > lightstyle | | to - > lightpflags ! = from - > lightstyle ) & & protext & PEXT_DPFLAGS )
evenmorebits | = U_LIGHT ;
2004-08-23 00:15:46 +00:00
# endif
if ( to - > flags & U_SOLID )
bits | = U_SOLID ;
if ( msg - > cursize + 40 > msg - > maxsize )
{ //not enough space in the buffer, don't send the entity this frame. (not sending means nothing changes, and it takes no bytes!!)
* to = * from ;
return ;
}
//
// write the message
//
if ( ! to - > number )
SV_Error ( " Unset entity number " ) ;
2009-01-30 06:46:21 +00:00
if ( ! bits & & ! evenmorebits & & ! force )
2004-08-23 00:15:46 +00:00
return ; // nothing to send!
2009-01-30 06:46:21 +00:00
# ifdef PROTOCOLEXTENSIONS
if ( to - > number > = 512 )
{
if ( to - > number > = 1024 )
{
if ( to - > number > = 1024 + 512 )
evenmorebits | = U_ENTITYDBL ;
evenmorebits | = U_ENTITYDBL2 ;
if ( to - > number > = 2048 )
SV_Error ( " Entity number >= 2048 " ) ;
}
else
evenmorebits | = U_ENTITYDBL ;
}
if ( evenmorebits & 0xff00 )
evenmorebits | = U_YETMORE ;
if ( evenmorebits & 0x00ff )
bits | = U_EVENMORE ;
if ( bits & 511 )
bits | = U_MOREBITS ;
# endif
2004-08-23 00:15:46 +00:00
i = ( to - > number & 511 ) | ( bits & ~ 511 ) ;
if ( i & U_REMOVE )
Sys_Error ( " U_REMOVE " ) ;
MSG_WriteShort ( msg , i ) ;
if ( bits & U_MOREBITS )
MSG_WriteByte ( msg , bits & 255 ) ;
# ifdef PROTOCOLEXTENSIONS
if ( bits & U_EVENMORE )
MSG_WriteByte ( msg , evenmorebits & 255 ) ;
if ( evenmorebits & U_YETMORE )
MSG_WriteByte ( msg , ( evenmorebits > > 8 ) & 255 ) ;
# endif
if ( bits & U_MODEL )
MSG_WriteByte ( msg , to - > modelindex & 255 ) ;
if ( bits & U_FRAME )
MSG_WriteByte ( msg , to - > frame ) ;
if ( bits & U_COLORMAP )
MSG_WriteByte ( msg , to - > colormap ) ;
if ( bits & U_SKIN )
MSG_WriteByte ( msg , to - > skinnum ) ;
if ( bits & U_EFFECTS )
2005-08-26 22:56:51 +00:00
MSG_WriteByte ( msg , to - > effects & 0x00ff ) ;
2004-08-23 00:15:46 +00:00
if ( bits & U_ORIGIN1 )
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
SZ_Write ( msg , & coordd [ 0 ] , msg - > prim . coordsize ) ;
2004-08-23 00:15:46 +00:00
if ( bits & U_ANGLE1 )
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
SZ_Write ( msg , & angled [ 0 ] , msg - > prim . anglesize ) ;
2004-08-23 00:15:46 +00:00
if ( bits & U_ORIGIN2 )
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
SZ_Write ( msg , & coordd [ 1 ] , msg - > prim . coordsize ) ;
2004-08-23 00:15:46 +00:00
if ( bits & U_ANGLE2 )
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
SZ_Write ( msg , & angled [ 1 ] , msg - > prim . anglesize ) ;
2004-08-23 00:15:46 +00:00
if ( bits & U_ORIGIN3 )
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
SZ_Write ( msg , & coordd [ 2 ] , msg - > prim . coordsize ) ;
2004-08-23 00:15:46 +00:00
if ( bits & U_ANGLE3 )
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
SZ_Write ( msg , & angled [ 2 ] , msg - > prim . anglesize ) ;
2004-08-23 00:15:46 +00:00
# ifdef U_SCALE
if ( evenmorebits & U_SCALE )
2005-07-01 19:23:00 +00:00
MSG_WriteByte ( msg , ( qbyte ) ( to - > scale ) ) ;
2004-08-23 00:15:46 +00:00
# endif
# ifdef U_TRANS
if ( evenmorebits & U_TRANS )
2005-07-01 19:23:00 +00:00
MSG_WriteByte ( msg , ( qbyte ) ( to - > trans ) ) ;
2004-08-23 00:15:46 +00:00
# endif
# ifdef U_FATNESS
if ( evenmorebits & U_FATNESS )
2005-07-01 19:23:00 +00:00
MSG_WriteChar ( msg , to - > fatness ) ;
2004-08-23 00:15:46 +00:00
# endif
if ( evenmorebits & U_DRAWFLAGS )
2005-05-15 18:49:04 +00:00
MSG_WriteByte ( msg , to - > hexen2flags ) ;
2004-08-23 00:15:46 +00:00
if ( evenmorebits & U_ABSLIGHT )
MSG_WriteByte ( msg , to - > abslight ) ;
2005-05-15 18:49:04 +00:00
2006-02-27 00:42:25 +00:00
if ( evenmorebits & U_COLOURMOD )
{
MSG_WriteByte ( msg , to - > colormod [ 0 ] ) ;
MSG_WriteByte ( msg , to - > colormod [ 1 ] ) ;
MSG_WriteByte ( msg , to - > colormod [ 2 ] ) ;
}
2005-05-15 18:49:04 +00:00
if ( evenmorebits & U_DPFLAGS )
MSG_WriteByte ( msg , to - > dpflags ) ;
2005-07-01 19:23:00 +00:00
if ( evenmorebits & U_TAGINFO )
{
MSG_WriteShort ( msg , to - > tagentity ) ;
MSG_WriteShort ( msg , to - > tagindex ) ;
}
2005-08-07 18:08:13 +00:00
if ( evenmorebits & U_LIGHT )
{
MSG_WriteShort ( msg , to - > light [ 0 ] ) ;
MSG_WriteShort ( msg , to - > light [ 1 ] ) ;
MSG_WriteShort ( msg , to - > light [ 2 ] ) ;
MSG_WriteShort ( msg , to - > light [ 3 ] ) ;
MSG_WriteByte ( msg , to - > lightstyle ) ;
MSG_WriteByte ( msg , to - > lightpflags ) ;
}
2005-08-26 22:56:51 +00:00
if ( evenmorebits & U_EFFECTS16 )
MSG_WriteByte ( msg , ( to - > effects & 0xff00 ) > > 8 ) ;
2004-08-23 00:15:46 +00:00
}
/*
= = = = = = = = = = = = =
SV_EmitPacketEntities
Writes a delta update of a packet_entities_t to the message .
= = = = = = = = = = = = =
*/
void SV_EmitPacketEntities ( client_t * client , packet_entities_t * to , sizebuf_t * msg )
{
edict_t * ent ;
client_frame_t * fromframe ;
packet_entities_t * from ;
int oldindex , newindex ;
int oldnum , newnum ;
int oldmax ;
// this is the frame that we are going to delta update from
if ( client - > delta_sequence ! = - 1 )
{
2006-02-17 02:51:59 +00:00
fromframe = & client - > frameunion . frames [ client - > delta_sequence & UPDATE_MASK ] ;
2004-08-23 00:15:46 +00:00
from = & fromframe - > entities ;
oldmax = from - > num_entities ;
MSG_WriteByte ( msg , svc_deltapacketentities ) ;
MSG_WriteByte ( msg , client - > delta_sequence ) ;
}
else
{
oldmax = 0 ; // no delta update
from = NULL ;
MSG_WriteByte ( msg , svc_packetentities ) ;
}
newindex = 0 ;
oldindex = 0 ;
//Con_Printf ("---%i to %i ----\n", client->delta_sequence & UPDATE_MASK
// , client->netchan.outgoing_sequence & UPDATE_MASK);
while ( newindex < to - > num_entities | | oldindex < oldmax )
{
newnum = newindex > = to - > num_entities ? 9999 : to - > entities [ newindex ] . number ;
oldnum = oldindex > = oldmax ? 9999 : from - > entities [ oldindex ] . number ;
if ( newnum = = oldnum )
{ // delta update from old position
//Con_Printf ("delta %i\n", newnum);
# ifdef PROTOCOLEXTENSIONS
SV_WriteDelta ( & from - > entities [ oldindex ] , & to - > entities [ newindex ] , msg , false , client - > fteprotocolextensions ) ;
# else
2005-12-13 02:31:57 +00:00
SV_WriteDelta ( & from - > entities [ oldindex ] , & to - > entities [ newindex ] , msg , false ) ;
2004-08-23 00:15:46 +00:00
# endif
oldindex + + ;
newindex + + ;
continue ;
}
if ( newnum < oldnum )
{ // this is a new entity, send it from the baseline
2009-03-03 01:52:30 +00:00
if ( svprogfuncs )
ent = EDICT_NUM ( svprogfuncs , newnum ) ;
else
ent = NULL ;
2004-08-23 00:15:46 +00:00
//Con_Printf ("baseline %i\n", newnum);
# ifdef PROTOCOLEXTENSIONS
SV_WriteDelta ( & ent - > baseline , & to - > entities [ newindex ] , msg , true , client - > fteprotocolextensions ) ;
# else
2005-12-13 02:31:57 +00:00
SV_WriteDelta ( & ent - > baseline , & to - > entities [ newindex ] , msg , true ) ;
2004-08-23 00:15:46 +00:00
# endif
newindex + + ;
continue ;
}
if ( newnum > oldnum )
{ // the old entity isn't present in the new message
//Con_Printf ("remove %i\n", oldnum);
2009-01-30 06:46:21 +00:00
if ( oldnum > = 512 )
2005-10-19 21:12:49 +00:00
{
//yup, this is expensive.
MSG_WriteShort ( msg , oldnum | U_REMOVE | U_MOREBITS ) ;
MSG_WriteByte ( msg , U_EVENMORE ) ;
if ( oldnum > = 1024 )
{
if ( oldnum > = 1024 + 512 )
MSG_WriteByte ( msg , U_ENTITYDBL | U_ENTITYDBL2 ) ;
2009-01-30 06:46:21 +00:00
else
MSG_WriteByte ( msg , U_ENTITYDBL2 ) ;
2005-10-19 21:12:49 +00:00
}
else
MSG_WriteByte ( msg , U_ENTITYDBL ) ;
}
else
MSG_WriteShort ( msg , oldnum | U_REMOVE ) ;
2004-08-23 00:15:46 +00:00
oldindex + + ;
continue ;
}
}
2005-10-19 21:12:49 +00:00
if ( newindex > to - > max_entities )
Con_Printf ( " Exceeded max entities \n " ) ;
2004-08-23 00:15:46 +00:00
MSG_WriteShort ( msg , 0 ) ; // end of packetentities
}
2005-06-14 04:52:10 +00:00
# ifdef NQPROT
// reset all entity fields (typically used if status changed)
# define E5_FULLUPDATE (1<<0)
// E5_ORIGIN32=0: short[3] = s->origin[0] * 8, s->origin[1] * 8, s->origin[2] * 8
// E5_ORIGIN32=1: float[3] = s->origin[0], s->origin[1], s->origin[2]
# define E5_ORIGIN (1<<1)
// E5_ANGLES16=0: byte[3] = s->angle[0] * 256 / 360, s->angle[1] * 256 / 360, s->angle[2] * 256 / 360
// E5_ANGLES16=1: short[3] = s->angle[0] * 65536 / 360, s->angle[1] * 65536 / 360, s->angle[2] * 65536 / 360
# define E5_ANGLES (1<<2)
// E5_MODEL16=0: byte = s->modelindex
// E5_MODEL16=1: short = s->modelindex
# define E5_MODEL (1<<3)
// E5_FRAME16=0: byte = s->frame
// E5_FRAME16=1: short = s->frame
# define E5_FRAME (1<<4)
// byte = s->skin
# define E5_SKIN (1<<5)
// E5_EFFECTS16=0 && E5_EFFECTS32=0: byte = s->effects
// E5_EFFECTS16=1 && E5_EFFECTS32=0: short = s->effects
// E5_EFFECTS16=0 && E5_EFFECTS32=1: int = s->effects
// E5_EFFECTS16=1 && E5_EFFECTS32=1: int = s->effects
# define E5_EFFECTS (1<<6)
// bits >= (1<<8)
# define E5_EXTEND1 (1<<7)
// byte = s->renderflags
# define E5_FLAGS (1<<8)
// byte = bound(0, s->alpha * 255, 255)
# define E5_ALPHA (1<<9)
// byte = bound(0, s->scale * 16, 255)
# define E5_SCALE (1<<10)
// flag
# define E5_ORIGIN32 (1<<11)
// flag
# define E5_ANGLES16 (1<<12)
// flag
# define E5_MODEL16 (1<<13)
// byte = s->colormap
# define E5_COLORMAP (1<<14)
// bits >= (1<<16)
# define E5_EXTEND2 (1<<15)
// short = s->tagentity
// byte = s->tagindex
# define E5_ATTACHMENT (1<<16)
// short[4] = s->light[0], s->light[1], s->light[2], s->light[3]
// byte = s->lightstyle
// byte = s->lightpflags
# define E5_LIGHT (1<<17)
// byte = s->glowsize
// byte = s->glowcolor
# define E5_GLOW (1<<18)
// short = s->effects
# define E5_EFFECTS16 (1<<19)
// int = s->effects
# define E5_EFFECTS32 (1<<20)
// flag
# define E5_FRAME16 (1<<21)
// unused
2005-10-01 03:09:17 +00:00
# define E5_COLORMOD (1<<22)
2005-06-14 04:52:10 +00:00
// bits >= (1<<24)
# define E5_EXTEND3 (1<<23)
// unused
# define E5_UNUSED24 (1<<24)
// unused
# define E5_UNUSED25 (1<<25)
// unused
# define E5_UNUSED26 (1<<26)
// unused
# define E5_UNUSED27 (1<<27)
// unused
# define E5_UNUSED28 (1<<28)
// unused
# define E5_UNUSED29 (1<<29)
// unused
# define E5_UNUSED30 (1<<30)
// bits2 > 0
# define E5_EXTEND4 (1<<31)
2008-11-09 22:29:28 +00:00
void SVDP_EmitEntityDelta ( entity_state_t * from , entity_state_t * to , sizebuf_t * msg , qboolean isnew )
2005-06-14 04:52:10 +00:00
{
int bits ;
2005-07-01 19:23:00 +00:00
if ( ! isnew & & ! memcmp ( from , to , sizeof ( entity_state_t ) ) )
{
2005-06-14 04:52:10 +00:00
return ; //didn't change
2005-07-01 19:23:00 +00:00
}
2005-06-14 04:52:10 +00:00
bits = 0 ;
if ( isnew )
2005-07-01 19:23:00 +00:00
{
2005-06-14 04:52:10 +00:00
bits | = E5_FULLUPDATE ;
2005-07-01 19:23:00 +00:00
}
2005-06-14 04:52:10 +00:00
2009-07-18 20:14:10 +00:00
if ( ! VectorEquals ( from - > origin , to - > origin ) )
2005-06-14 04:52:10 +00:00
bits | = E5_ORIGIN ;
2009-07-18 20:14:10 +00:00
if ( ! VectorEquals ( from - > angles , to - > angles ) )
2005-06-14 04:52:10 +00:00
bits | = E5_ANGLES ;
if ( from - > modelindex ! = to - > modelindex )
bits | = E5_MODEL ;
if ( from - > frame ! = to - > frame )
bits | = E5_FRAME ;
if ( from - > skinnum ! = to - > skinnum )
bits | = E5_SKIN ;
if ( from - > effects ! = to - > effects )
bits | = E5_EFFECTS ;
2005-07-01 19:23:00 +00:00
if ( from - > dpflags ! = to - > dpflags )
2005-06-14 04:52:10 +00:00
bits | = E5_FLAGS ;
if ( from - > trans ! = to - > trans )
bits | = E5_ALPHA ;
2005-07-01 19:23:00 +00:00
if ( from - > scale ! = to - > scale )
bits | = E5_SCALE ;
2005-06-14 04:52:10 +00:00
if ( from - > colormap ! = to - > colormap )
bits | = E5_COLORMAP ;
2005-07-01 19:23:00 +00:00
if ( from - > tagentity ! = to - > tagentity | | from - > tagindex ! = to - > tagindex )
bits | = E5_ATTACHMENT ;
2005-08-07 18:08:13 +00:00
if ( from - > light [ 0 ] ! = to - > light [ 0 ] | | from - > light [ 1 ] ! = to - > light [ 1 ] | | from - > light [ 2 ] ! = to - > light [ 2 ] | | from - > light [ 3 ] ! = to - > light [ 3 ] | | from - > lightstyle ! = to - > lightstyle | | from - > lightpflags ! = to - > lightpflags )
bits | = E5_LIGHT ;
2005-07-01 19:23:00 +00:00
if ( from - > glowsize ! = to - > glowsize | | from - > glowcolour ! = to - > glowcolour )
bits | = E5_GLOW ;
2005-10-01 03:09:17 +00:00
if ( from - > colormod [ 0 ] ! = to - > colormod [ 0 ] | | from - > colormod [ 1 ] ! = to - > colormod [ 1 ] | | from - > colormod [ 2 ] ! = to - > colormod [ 2 ] )
bits | = E5_COLORMOD ;
2005-06-14 04:52:10 +00:00
if ( ( bits & E5_ORIGIN ) & & ( /*!(to->flags & RENDER_LOWPRECISION) ||*/ to - > origin [ 0 ] < - 4096 | | to - > origin [ 0 ] > = 4096 | | to - > origin [ 1 ] < - 4096 | | to - > origin [ 1 ] > = 4096 | | to - > origin [ 2 ] < - 4096 | | to - > origin [ 2 ] > = 4096 ) )
bits | = E5_ORIGIN32 ;
if ( ( bits & E5_ANGLES ) /* && !(to->flags & RENDER_LOWPRECISION)*/ )
bits | = E5_ANGLES16 ;
if ( ( bits & E5_MODEL ) & & to - > modelindex > = 256 )
bits | = E5_MODEL16 ;
if ( ( bits & E5_FRAME ) & & to - > frame > = 256 )
bits | = E5_FRAME16 ;
if ( bits & E5_EFFECTS )
{
if ( to - > effects > = 65536 )
bits | = E5_EFFECTS32 ;
else if ( to - > effects > = 256 )
bits | = E5_EFFECTS16 ;
}
2008-11-09 22:29:28 +00:00
2005-06-14 04:52:10 +00:00
if ( bits > = 256 )
bits | = E5_EXTEND1 ;
if ( bits > = 65536 )
bits | = E5_EXTEND2 ;
if ( bits > = 16777216 )
bits | = E5_EXTEND3 ;
if ( ! bits )
return ;
MSG_WriteShort ( msg , to - > number ) ;
MSG_WriteByte ( msg , bits & 0xFF ) ;
if ( bits & E5_EXTEND1 )
MSG_WriteByte ( msg , ( bits > > 8 ) & 0xFF ) ;
if ( bits & E5_EXTEND2 )
MSG_WriteByte ( msg , ( bits > > 16 ) & 0xFF ) ;
if ( bits & E5_EXTEND3 )
MSG_WriteByte ( msg , ( bits > > 24 ) & 0xFF ) ;
if ( bits & E5_FLAGS )
2005-07-01 19:23:00 +00:00
MSG_WriteByte ( msg , to - > dpflags ) ;
2005-06-14 04:52:10 +00:00
if ( bits & E5_ORIGIN )
{
if ( bits & E5_ORIGIN32 )
{
MSG_WriteFloat ( msg , to - > origin [ 0 ] ) ;
MSG_WriteFloat ( msg , to - > origin [ 1 ] ) ;
MSG_WriteFloat ( msg , to - > origin [ 2 ] ) ;
}
else
{
MSG_WriteShort ( msg , to - > origin [ 0 ] * 8 ) ;
MSG_WriteShort ( msg , to - > origin [ 1 ] * 8 ) ;
MSG_WriteShort ( msg , to - > origin [ 2 ] * 8 ) ;
}
}
if ( bits & E5_ANGLES )
{
if ( bits & E5_ANGLES16 )
{
MSG_WriteAngle16 ( msg , to - > angles [ 0 ] ) ;
MSG_WriteAngle16 ( msg , to - > angles [ 1 ] ) ;
MSG_WriteAngle16 ( msg , to - > angles [ 2 ] ) ;
}
else
{
MSG_WriteAngle8 ( msg , to - > angles [ 0 ] ) ;
MSG_WriteAngle8 ( msg , to - > angles [ 1 ] ) ;
MSG_WriteAngle8 ( msg , to - > angles [ 2 ] ) ;
}
}
if ( bits & E5_MODEL )
{
if ( bits & E5_MODEL16 )
MSG_WriteShort ( msg , to - > modelindex ) ;
else
MSG_WriteByte ( msg , to - > modelindex ) ;
}
if ( bits & E5_FRAME )
{
if ( bits & E5_FRAME16 )
MSG_WriteShort ( msg , to - > frame ) ;
else
MSG_WriteByte ( msg , to - > frame ) ;
}
if ( bits & E5_SKIN )
MSG_WriteByte ( msg , to - > skinnum ) ;
if ( bits & E5_EFFECTS )
{
if ( bits & E5_EFFECTS32 )
MSG_WriteLong ( msg , to - > effects ) ;
else if ( bits & E5_EFFECTS16 )
MSG_WriteShort ( msg , to - > effects ) ;
else
MSG_WriteByte ( msg , to - > effects ) ;
}
if ( bits & E5_ALPHA )
2005-07-01 19:23:00 +00:00
MSG_WriteByte ( msg , to - > trans ) ;
2005-06-14 04:52:10 +00:00
if ( bits & E5_SCALE )
MSG_WriteByte ( msg , to - > scale ) ;
if ( bits & E5_COLORMAP )
MSG_WriteByte ( msg , to - > colormap ) ;
2005-07-01 19:23:00 +00:00
if ( bits & E5_ATTACHMENT )
{
MSG_WriteShort ( msg , to - > tagentity ) ;
MSG_WriteByte ( msg , to - > tagindex ) ;
}
2005-08-07 18:08:13 +00:00
if ( bits & E5_LIGHT )
{
MSG_WriteShort ( msg , to - > light [ 0 ] ) ;
MSG_WriteShort ( msg , to - > light [ 1 ] ) ;
MSG_WriteShort ( msg , to - > light [ 2 ] ) ;
MSG_WriteShort ( msg , to - > light [ 3 ] ) ;
MSG_WriteByte ( msg , to - > lightstyle ) ;
MSG_WriteByte ( msg , to - > lightpflags ) ;
}
2005-07-01 19:23:00 +00:00
if ( bits & E5_GLOW )
{
MSG_WriteByte ( msg , to - > glowsize ) ;
MSG_WriteByte ( msg , to - > glowcolour ) ;
}
2005-10-01 03:09:17 +00:00
if ( bits & E5_COLORMOD )
{
MSG_WriteByte ( msg , to - > colormod [ 0 ] ) ;
MSG_WriteByte ( msg , to - > colormod [ 1 ] ) ;
MSG_WriteByte ( msg , to - > colormod [ 2 ] ) ;
}
2005-06-14 04:52:10 +00:00
}
2005-07-01 19:23:00 +00:00
entity_state_t defaultstate ;
2005-06-14 04:52:10 +00:00
void SVDP_EmitEntitiesUpdate ( client_t * client , packet_entities_t * to , sizebuf_t * msg )
{
edict_t * ent ;
client_frame_t * fromframe ;
packet_entities_t * from ;
int oldindex , newindex ;
int oldnum , newnum ;
int oldmax ;
2005-07-01 19:23:00 +00:00
client - > netchan . incoming_sequence + + ;
2005-06-14 04:52:10 +00:00
// this is the frame that we are going to delta update from
2006-02-17 02:51:59 +00:00
fromframe = & client - > frameunion . frames [ ( client - > netchan . incoming_sequence - 2 ) & UPDATE_MASK ] ;
2005-07-01 19:23:00 +00:00
from = & fromframe - > entities ;
oldmax = from - > num_entities ;
// Con_Printf ("frame %i\n", client->netchan.incoming_sequence);
2005-06-14 04:52:10 +00:00
MSG_WriteByte ( msg , svcdp_entities ) ;
MSG_WriteLong ( msg , 0 ) ;
if ( client - > protocol = = SCP_DARKPLACES7 )
2005-06-22 17:10:13 +00:00
MSG_WriteLong ( msg , client - > last_sequence ) ;
2005-06-14 04:52:10 +00:00
for ( newindex = 0 ; newindex < to - > num_entities ; newindex + + )
to - > entities [ newindex ] . bitmask = 0 ;
2005-07-01 19:23:00 +00:00
//add in the bitmasks of dropped packets.
2005-06-14 04:52:10 +00:00
newindex = 0 ;
oldindex = 0 ;
//Con_Printf ("---%i to %i ----\n", client->delta_sequence & UPDATE_MASK
// , client->netchan.outgoing_sequence & UPDATE_MASK);
while ( newindex < to - > num_entities | | oldindex < oldmax )
{
newnum = newindex > = to - > num_entities ? 0x7fff : to - > entities [ newindex ] . number ;
oldnum = oldindex > = oldmax ? 0x7fff : from - > entities [ oldindex ] . number ;
if ( newnum = = oldnum )
{ // delta update from old position
//Con_Printf ("delta %i\n", newnum);
2008-11-09 22:29:28 +00:00
SVDP_EmitEntityDelta ( & from - > entities [ oldindex ] , & to - > entities [ newindex ] , msg , false ) ;
2005-06-14 04:52:10 +00:00
oldindex + + ;
newindex + + ;
continue ;
}
if ( newnum < oldnum )
2005-07-01 19:23:00 +00:00
{ // this is a new entity, send it from the baseline... as far as dp understands it...
2005-06-14 04:52:10 +00:00
ent = EDICT_NUM ( svprogfuncs , newnum ) ;
//Con_Printf ("baseline %i\n", newnum);
2008-11-09 22:29:28 +00:00
SVDP_EmitEntityDelta ( & defaultstate , & to - > entities [ newindex ] , msg , true ) ;
2005-06-14 04:52:10 +00:00
newindex + + ;
continue ;
}
if ( newnum > oldnum )
{ // the old entity isn't present in the new message
MSG_WriteShort ( msg , oldnum | 0x8000 ) ;
oldindex + + ;
continue ;
}
}
MSG_WriteShort ( msg , 0x8000 ) ;
}
# endif
2004-08-23 00:15:46 +00:00
int SV_HullNumForPlayer ( int h2hull , float * mins , float * maxs )
{
int diff ;
int best ;
int hullnum , i ;
2009-11-04 21:16:50 +00:00
if ( sv . world . worldmodel - > fromgame ! = fg_quake )
2004-08-23 00:15:46 +00:00
{
2011-05-20 04:10:46 +00:00
return - mins [ 2 ] + 32 ; //clients are expected to decide themselves.
2004-08-23 00:15:46 +00:00
}
2004-08-31 23:58:18 +00:00
if ( h2hull )
2011-06-02 05:16:44 +00:00
return ( h2hull - 1 ) | ( mins [ 2 ] ? 0 : 128 ) ;
2004-08-23 00:15:46 +00:00
hullnum = 0 ;
best = 8192 ;
//x/y pos/neg are assumed to be the same magnitute.
//y pos/height are assumed to be different from all the others.
for ( i = 0 ; i < MAX_MAP_HULLSM ; i + + )
{
# define sq(x) ((x)*(x))
2009-11-04 21:16:50 +00:00
diff = sq ( sv . world . worldmodel - > hulls [ i ] . clip_maxs [ 2 ] - maxs [ 2 ] ) +
sq ( sv . world . worldmodel - > hulls [ i ] . clip_mins [ 2 ] - mins [ 2 ] ) +
sq ( sv . world . worldmodel - > hulls [ i ] . clip_maxs [ 0 ] - maxs [ 0 ] ) +
sq ( sv . world . worldmodel - > hulls [ i ] . clip_mins [ 0 ] - mins [ 0 ] ) ;
2004-08-23 00:15:46 +00:00
if ( diff < best )
{
best = diff ;
hullnum = i ;
}
}
return hullnum ;
}
# if 1
typedef struct {
int playernum ;
qboolean onladder ;
usercmd_t * lastcmd ;
int modelindex ;
int frame ;
int weaponframe ;
2009-06-21 17:45:33 +00:00
int vw_index ;
2004-08-23 00:15:46 +00:00
float * angles ;
float * origin ;
float * velocity ;
int effects ;
int skin ;
float * mins ;
float * maxs ;
float scale ;
float transparency ;
float fatness ;
float localtime ;
int health ;
int spectator ; //0=send to a player. 1=non-tracked player, to a spec. 2=tracked player, to a spec(or self)
qboolean isself ;
int fteext ;
int zext ;
int hull ;
client_t * cl ;
} clstate_t ;
void SV_WritePlayerToClient ( sizebuf_t * msg , clstate_t * ent )
{
usercmd_t cmd ;
int msec ;
int hullnumber ;
int i ;
int pflags ;
int pm_type , pm_code ;
int zext = ent - > zext ;
pflags = PF_MSEC | PF_COMMAND ;
2005-12-13 02:31:57 +00:00
2004-08-23 00:15:46 +00:00
if ( ent - > modelindex ! = sv_playermodel )
pflags | = PF_MODEL ;
if ( ent - > velocity )
for ( i = 0 ; i < 3 ; i + + )
if ( ent - > velocity [ i ] )
pflags | = PF_VELOCITY1 < < i ;
if ( ent - > effects )
pflags | = PF_EFFECTS ;
if ( ent - > skin | | ent - > modelindex > = 256 )
pflags | = PF_SKINNUM ;
if ( ent - > health < = 0 )
pflags | = PF_DEAD ;
if ( progstype = = PROG_QW )
{
if ( ent - > mins [ 2 ] ! = - 24 )
pflags | = PF_GIB ;
}
else if ( progstype = = PROG_H2 )
{
// if (ent->maxs[2] != 56)
// pflags |= PF_GIB;
}
else
{
if ( ent - > mins [ 2 ] ! = - 24 )
pflags | = PF_GIB ;
}
if ( ent - > isself )
{
if ( ent - > spectator )
pflags & = PF_VELOCITY1 | PF_VELOCITY2 | PF_VELOCITY3 | PF_DEAD | PF_GIB ;
else
{ // don't send a lot of data on personal entity
pflags & = ~ ( PF_MSEC | PF_COMMAND ) ;
if ( ent - > weaponframe )
pflags | = PF_WEAPONFRAME ;
}
}
2005-01-26 03:39:47 +00:00
if ( ent - > spectator = = 2 & & ent - > weaponframe ) //it's not us, but we are spectating, so we need the correct weaponframe
2004-08-23 00:15:46 +00:00
pflags | = PF_WEAPONFRAME ;
2004-10-10 06:32:29 +00:00
if ( ! ent - > isself | | ent - > fteext & PEXT_SPLITSCREEN )
2004-08-23 00:15:46 +00:00
{
# ifdef PEXT_SCALE //this is graphics, not physics
if ( ent - > fteext & PEXT_SCALE )
{
2010-08-12 09:04:05 +00:00
if ( ent - > scale & & ent - > scale ! = 1 ) pflags | = PF_SCALE_Z ;
2004-08-23 00:15:46 +00:00
}
# endif
# ifdef PEXT_TRANS
if ( ent - > fteext & PEXT_TRANS )
{
2005-07-01 19:23:00 +00:00
if ( ent - > transparency ) pflags | = PF_TRANS_Z ;
2004-08-23 00:15:46 +00:00
}
# endif
# ifdef PEXT_FATNESS
if ( ent - > fteext & PEXT_FATNESS )
{
2005-07-01 19:23:00 +00:00
if ( ent - > fatness ) pflags | = PF_FATNESS_Z ;
2004-08-23 00:15:46 +00:00
}
# endif
}
# ifdef PEXT_HULLSIZE
if ( ent - > fteext & PEXT_HULLSIZE )
{
hullnumber = SV_HullNumForPlayer ( ent - > hull , ent - > mins , ent - > maxs ) ;
if ( hullnumber ! = 1 )
2005-07-01 19:23:00 +00:00
pflags | = PF_HULLSIZE_Z ;
2004-08-23 00:15:46 +00:00
}
else
hullnumber = 1 ;
# endif
if ( zext & Z_EXT_PM_TYPE )
{
if ( ent - > cl )
{
2004-08-31 23:58:18 +00:00
if ( ent - > cl - > viewent )
pm_type = PMC_NONE ;
else
pm_type = SV_PMTypeForClient ( ent - > cl ) ;
2004-08-23 00:15:46 +00:00
switch ( pm_type )
{
case PM_NORMAL : // Z_EXT_PM_TYPE protocol extension
if ( ent - > cl - > jump_held )
pm_code = PMC_NORMAL_JUMP_HELD ; // encode pm_type and jump_held into pm_code
else
pm_code = PMC_NORMAL ;
break ;
case PM_OLD_SPECTATOR :
pm_code = PMC_OLD_SPECTATOR ;
break ;
case PM_SPECTATOR : // Z_EXT_PM_TYPE_NEW protocol extension
pm_code = PMC_SPECTATOR ;
break ;
case PM_FLY :
pm_code = PMC_FLY ;
break ;
case PM_DEAD :
pm_code = PMC_NORMAL ;
break ;
case PM_NONE :
pm_code = PMC_NONE ;
break ;
default :
Sys_Error ( " SV_WritePlayersToClient: unexpected pm_type " ) ;
pm_code = 0 ;
}
}
else
2004-12-06 00:58:19 +00:00
pm_code = ( ent - > zext & Z_EXT_PM_TYPE_NEW ) ? PMC_SPECTATOR : PMC_OLD_SPECTATOR ; //(ent->spectator && ent->isself) ? PMC_OLD_SPECTATOR : PMC_NORMAL;
2004-08-23 00:15:46 +00:00
pflags | = pm_code < < PF_PMC_SHIFT ;
}
if ( pflags & 0xff0000 )
pflags | = PF_EXTRA_PFS ;
MSG_WriteByte ( msg , svc_playerinfo ) ;
MSG_WriteByte ( msg , ent - > playernum ) ;
MSG_WriteShort ( msg , pflags & 0xffff ) ;
if ( pflags & PF_EXTRA_PFS )
{
MSG_WriteByte ( msg , ( pflags & 0xff0000 ) > > 16 ) ;
}
//we need to tell the client that it's moved, as it's own origin might not be natural
2004-11-13 17:36:42 +00:00
for ( i = 0 ; i < 3 ; i + + )
2009-11-07 13:29:15 +00:00
MSG_WriteCoord ( msg , ent - > origin [ i ] ) ;
2004-08-23 00:15:46 +00:00
MSG_WriteByte ( msg , ent - > frame ) ;
if ( pflags & PF_MSEC )
{
msec = 1000 * ( sv . time - ent - > localtime ) ;
if ( msec < 0 )
msec = 0 ;
if ( msec > 255 )
msec = 255 ;
MSG_WriteByte ( msg , msec ) ;
}
if ( pflags & PF_COMMAND )
{
if ( ent - > lastcmd )
cmd = * ent - > lastcmd ;
else
{
memset ( & cmd , 0 , sizeof ( cmd ) ) ;
2007-10-14 00:54:29 +00:00
cmd . angles [ 0 ] = ( int ) ( ent - > angles [ 0 ] * 65535 / 360.0f ) ;
cmd . angles [ 1 ] = ( int ) ( ent - > angles [ 1 ] * 65535 / 360.0f ) ;
cmd . angles [ 2 ] = ( int ) ( ent - > angles [ 2 ] * 65535 / 360.0f ) ;
2004-08-23 00:15:46 +00:00
}
if ( ent - > health < = 0 )
{ // don't show the corpse looking around...
cmd . angles [ 0 ] = 0 ;
2007-10-14 00:54:29 +00:00
cmd . angles [ 1 ] = ( int ) ( ent - > angles [ 1 ] * 65535 / 360 ) ;
2006-07-02 04:27:56 +00:00
cmd . angles [ 2 ] = 0 ;
2004-08-23 00:15:46 +00:00
}
cmd . buttons = 0 ; // never send buttons
2009-06-21 17:45:33 +00:00
if ( ent - > zext & Z_EXT_VWEP )
cmd . impulse = ent - > vw_index ; // never send impulses
else
cmd . impulse = 0 ;
2004-08-23 00:15:46 +00:00
MSG_WriteDeltaUsercmd ( msg , & nullcmd , & cmd ) ;
}
if ( ent - > velocity )
{
for ( i = 0 ; i < 3 ; i + + )
if ( pflags & ( PF_VELOCITY1 < < i ) )
MSG_WriteShort ( msg , ent - > velocity [ i ] ) ;
}
else
{
for ( i = 0 ; i < 3 ; i + + )
if ( pflags & ( PF_VELOCITY1 < < i ) )
MSG_WriteShort ( msg , 0 ) ;
}
2005-01-26 03:39:47 +00:00
2004-08-23 00:15:46 +00:00
if ( pflags & PF_MODEL )
{
MSG_WriteByte ( msg , ent - > modelindex ) ;
}
if ( pflags & PF_SKINNUM )
MSG_WriteByte ( msg , ent - > skin | ( ( ( pflags & PF_MODEL ) & & ( ent - > modelindex > = 256 ) ) < < 7 ) ) ;
if ( pflags & PF_EFFECTS )
MSG_WriteByte ( msg , ent - > effects ) ;
if ( pflags & PF_WEAPONFRAME )
MSG_WriteByte ( msg , ent - > weaponframe ) ;
# ifdef PEXT_SCALE
2005-07-01 19:23:00 +00:00
if ( pflags & PF_SCALE_Z )
MSG_WriteByte ( msg , ent - > scale * 50 ) ;
2004-08-23 00:15:46 +00:00
# endif
# ifdef PEXT_TRANS
2005-07-01 19:23:00 +00:00
if ( pflags & PF_TRANS_Z )
MSG_WriteByte ( msg , ( qbyte ) ( ent - > transparency * 255 ) ) ;
2004-08-23 00:15:46 +00:00
# endif
# ifdef PEXT_FATNESS
2005-07-01 19:23:00 +00:00
if ( pflags & PF_FATNESS_Z )
2009-07-05 18:45:53 +00:00
MSG_WriteChar ( msg , ent - > fatness * 10 ) ;
2004-08-23 00:15:46 +00:00
# endif
# ifdef PEXT_HULLSIZE //shrunken or crouching in halflife levels. (possibly enlarged)
2005-07-01 19:23:00 +00:00
if ( pflags & PF_HULLSIZE_Z )
MSG_WriteChar ( msg , hullnumber + ( ent - > onladder ? 128 : 0 ) ) ; //physics.
2004-08-23 00:15:46 +00:00
# endif
}
# endif
2007-08-30 18:55:44 +00:00
qboolean Cull_Traceline ( edict_t * viewer , edict_t * seen )
{
int i ;
trace_t tr ;
vec3_t start ;
vec3_t end ;
if ( seen - > v - > solid = = SOLID_BSP )
return false ; //bsp ents are never culled this way
//stage 1: check against their origin
VectorAdd ( viewer - > v - > origin , viewer - > v - > view_ofs , start ) ;
tr . fraction = 1 ;
2010-08-28 17:14:38 +00:00
if ( ! sv . world . worldmodel - > funcs . Trace ( sv . world . worldmodel , 1 , 0 , NULL , start , seen - > v - > origin , vec3_origin , vec3_origin , & tr ) )
2007-08-30 18:55:44 +00:00
return false ; //wasn't blocked
//stage 2: check against their bbox
for ( i = 0 ; i < 8 ; i + + )
{
end [ 0 ] = seen - > v - > origin [ 0 ] + ( ( i & 1 ) ? seen - > v - > mins [ 0 ] : seen - > v - > maxs [ 0 ] ) ;
end [ 1 ] = seen - > v - > origin [ 1 ] + ( ( i & 2 ) ? seen - > v - > mins [ 1 ] : seen - > v - > maxs [ 1 ] ) ;
end [ 2 ] = seen - > v - > origin [ 2 ] + ( ( i & 4 ) ? seen - > v - > mins [ 2 ] + 0.1 : seen - > v - > maxs [ 2 ] ) ;
tr . fraction = 1 ;
2010-08-28 17:14:38 +00:00
if ( ! sv . world . worldmodel - > funcs . Trace ( sv . world . worldmodel , 1 , 0 , NULL , start , end , vec3_origin , vec3_origin , & tr ) )
2007-08-30 18:55:44 +00:00
return false ; //this trace went through, so don't cull
}
return true ;
}
2004-08-23 00:15:46 +00:00
/*
= = = = = = = = = = = = =
SV_WritePlayersToClient
= = = = = = = = = = = = =
*/
2009-11-04 21:16:50 +00:00
void SV_WritePlayersToClient ( client_t * client , client_frame_t * frame , edict_t * clent , qbyte * pvs , sizebuf_t * msg )
2004-08-23 00:15:46 +00:00
{
qboolean isbot ;
2009-11-15 03:20:17 +00:00
int j ;
2004-08-23 00:15:46 +00:00
client_t * cl ;
edict_t * ent , * vent ;
int pflags ;
demo_frame_t * demo_frame ;
demo_client_t * dcl ;
# define DF_DEAD (1<<8)
# define DF_GIB (1<<9)
2005-01-26 03:39:47 +00:00
if ( clent = = NULL ) //write to demo file. (no PVS)
2004-08-23 00:15:46 +00:00
{
demo_frame = & demo . frames [ demo . parsecount & DEMO_FRAMES_MASK ] ;
for ( j = 0 , cl = svs . clients , dcl = demo_frame - > clients ; j < MAX_CLIENTS ; j + + , cl + + , dcl + + )
{
if ( cl - > state ! = cs_spawned )
continue ;
2009-11-07 13:29:15 +00:00
# ifdef SERVER_DEMO_PLAYBACK
2004-08-23 00:15:46 +00:00
if ( sv . demostatevalid )
{
if ( client ! = cl )
continue ;
}
2009-11-07 13:29:15 +00:00
# endif
2004-08-23 00:15:46 +00:00
ent = cl - > edict ;
if ( cl - > viewent & & ent = = clent )
vent = EDICT_NUM ( svprogfuncs , cl - > viewent ) ;
else
vent = ent ;
if ( progstype ! = PROG_QW )
{
2005-03-28 00:11:59 +00:00
if ( ( int ) ent - > v - > effects & EF_MUZZLEFLASH )
2004-08-23 00:15:46 +00:00
{
if ( needcleanup < ( j + 1 ) )
{
needcleanup = ( j + 1 ) ;
}
}
}
if ( cl - > spectator )
continue ;
dcl - > parsecount = demo . parsecount ;
2005-03-28 00:11:59 +00:00
VectorCopy ( vent - > v - > origin , dcl - > info . origin ) ;
VectorCopy ( vent - > v - > angles , dcl - > info . angles ) ;
2004-08-23 00:15:46 +00:00
dcl - > info . angles [ 0 ] * = - 3 ;
dcl - > info . angles [ 2 ] = 0 ; // no roll angle
2005-03-28 00:11:59 +00:00
if ( ent - > v - > health < = 0 )
2004-08-23 00:15:46 +00:00
{ // don't show the corpse looking around...
dcl - > info . angles [ 0 ] = 0 ;
2005-03-28 00:11:59 +00:00
dcl - > info . angles [ 1 ] = vent - > v - > angles [ 1 ] ;
2004-08-23 00:15:46 +00:00
dcl - > info . angles [ 2 ] = 0 ;
}
if ( ent ! = vent )
{
dcl - > info . model = 0 ; //invisible.
dcl - > info . effects = 0 ;
}
else
{
2005-03-28 00:11:59 +00:00
dcl - > info . skinnum = ent - > v - > skin ;
dcl - > info . effects = ent - > v - > effects ;
dcl - > info . weaponframe = ent - > v - > weaponframe ;
dcl - > info . model = ent - > v - > modelindex ;
2004-08-23 00:15:46 +00:00
}
dcl - > sec = sv . time - cl - > localtime ;
2005-03-28 00:11:59 +00:00
dcl - > frame = ent - > v - > frame ;
2004-08-23 00:15:46 +00:00
dcl - > flags = 0 ;
dcl - > cmdtime = cl - > localtime ;
dcl - > fixangle = demo . fixangle [ j ] ;
demo . fixangle [ j ] = 0 ;
2005-03-28 00:11:59 +00:00
if ( ent - > v - > health < = 0 )
2004-08-23 00:15:46 +00:00
dcl - > flags | = DF_DEAD ;
2005-03-28 00:11:59 +00:00
if ( ent - > v - > mins [ 2 ] ! = - 24 )
2004-08-23 00:15:46 +00:00
dcl - > flags | = DF_GIB ;
continue ;
}
return ;
}
# ifdef NQPROT
2005-05-26 12:55:34 +00:00
if ( ! ISQWCLIENT ( client ) )
2004-08-23 00:15:46 +00:00
return ;
# endif
2009-11-07 13:29:15 +00:00
# ifdef SERVER_DEMO_PLAYBACK
2005-01-26 03:39:47 +00:00
if ( sv . demostatevalid ) //this is a demo
2004-08-23 00:15:46 +00:00
{
2005-01-26 03:39:47 +00:00
usercmd_t cmd ;
vec3_t ang ;
vec3_t org ;
vec3_t vel ;
float lerp ;
2005-01-27 01:53:05 +00:00
float a1 , a2 ;
2009-11-15 03:20:17 +00:00
int i ;
2005-01-26 03:39:47 +00:00
extern vec3_t player_mins , player_maxs ;
clstate_t clst ;
extern float olddemotime , nextdemotime ;
2005-12-13 02:31:57 +00:00
2005-01-26 03:39:47 +00:00
for ( i = 0 ; i < MAX_CLIENTS ; i + + )
2004-08-23 00:15:46 +00:00
{
2005-01-26 03:39:47 +00:00
//FIXME: Add PVS stuff.
2004-08-23 00:15:46 +00:00
2005-01-26 03:39:47 +00:00
if ( * sv . recordedplayer [ i ] . userinfo ) //if the client was active
2004-08-23 00:15:46 +00:00
{
clst . playernum = i ;
clst . onladder = 0 ;
clst . lastcmd = & cmd ;
clst . modelindex = sv . demostate [ i + 1 ] . modelindex ;
2005-01-26 03:39:47 +00:00
if ( ! clst . modelindex )
continue ;
2004-08-23 00:15:46 +00:00
clst . frame = sv . demostate [ i + 1 ] . frame ;
clst . weaponframe = sv . recordedplayer [ i ] . weaponframe ;
clst . angles = ang ;
clst . origin = org ;
clst . hull = 1 ;
2005-01-26 03:39:47 +00:00
clst . velocity = vel ;
2004-08-23 00:15:46 +00:00
clst . effects = sv . demostate [ i + 1 ] . effects ;
clst . skin = sv . demostate [ i + 1 ] . skinnum ;
clst . mins = player_mins ;
clst . maxs = player_maxs ;
clst . scale = sv . demostate [ i + 1 ] . scale ;
clst . transparency = sv . demostate [ i + 1 ] . trans ;
clst . fatness = sv . demostate [ i + 1 ] . fatness ;
clst . localtime = sv . time ; //sv.recordedplayer[j].updatetime;
clst . health = sv . recordedplayer [ i ] . stats [ STAT_HEALTH ] ;
2005-01-26 03:39:47 +00:00
clst . spectator = 2 ; //so that weaponframes work properly.
2004-08-23 00:15:46 +00:00
clst . isself = false ;
2005-01-26 03:39:47 +00:00
clst . fteext = 0 ; //client->fteprotocolextensions;
clst . zext = 0 ; //client->zquake_extensions;
2004-08-23 00:15:46 +00:00
clst . cl = NULL ;
2009-06-21 17:45:33 +00:00
clst . vw_index = 0 ;
2004-08-23 00:15:46 +00:00
2005-01-26 03:39:47 +00:00
lerp = ( realtime - olddemotime ) / ( nextdemotime - olddemotime ) ;
if ( lerp < 0 )
lerp = 0 ;
if ( lerp > 1 )
lerp = 1 ;
for ( j = 0 ; j < 3 ; j + + )
{
2005-01-27 01:53:05 +00:00
a1 = ( 360.0f / 256 ) * sv . recordedplayer [ i ] . oldang [ j ] ;
a2 = ( 360.0f / 256 ) * sv . demostate [ i + 1 ] . angles [ j ] ;
a2 = a2 - a1 ;
if ( a2 > 180 )
a2 - = 360 ;
if ( a2 < - 180 )
a2 + = 360 ;
ang [ j ] = ( a1 + ( a2 ) * lerp ) ;
2005-01-26 03:39:47 +00:00
org [ j ] = sv . recordedplayer [ i ] . oldorg [ j ] + ( sv . demostate [ i + 1 ] . origin [ j ] - sv . recordedplayer [ i ] . oldorg [ j ] ) * lerp ;
2005-12-13 02:31:57 +00:00
2005-01-26 03:39:47 +00:00
vel [ j ] = ( - sv . recordedplayer [ i ] . oldorg [ j ] + sv . demostate [ i + 1 ] . origin [ j ] ) * ( nextdemotime - olddemotime ) ;
}
2004-12-08 04:14:52 +00:00
2004-08-23 00:15:46 +00:00
ang [ 0 ] * = - 3 ;
// ang[0] = ang[1] = ang[2] = 0;
memset ( & cmd , 0 , sizeof ( cmd ) ) ;
cmd . angles [ 0 ] = ang [ 0 ] * 65535 / 360.0f ;
cmd . angles [ 1 ] = ang [ 1 ] * 65535 / 360.0f ;
cmd . angles [ 2 ] = ang [ 2 ] * 65535 / 360.0f ;
cmd . msec = 50 ;
2005-01-26 03:39:47 +00:00
{ vec3_t f , r , u , v ;
2004-08-23 00:15:46 +00:00
AngleVectors ( ang , f , r , u ) ;
2005-01-26 03:39:47 +00:00
VectorCopy ( vel , v ) ;
2004-08-23 00:15:46 +00:00
cmd . forwardmove = DotProduct ( f , v ) ;
cmd . sidemove = DotProduct ( r , v ) ;
cmd . upmove = DotProduct ( u , v ) ;
2005-01-26 03:39:47 +00:00
}
2004-08-23 00:15:46 +00:00
clst . lastcmd = NULL ;
SV_WritePlayerToClient ( msg , & clst ) ;
}
2005-01-26 03:39:47 +00:00
}
//now build the spectator's thingie
memset ( & clst , 0 , sizeof ( clst ) ) ;
clst . fteext = 0 ; //client->fteprotocolextensions;
clst . zext = 0 ; //client->zquake_extensions;
2009-06-21 17:45:33 +00:00
clst . vw_index = 0 ;
2005-01-26 03:39:47 +00:00
clst . playernum = MAX_CLIENTS - 1 ;
clst . isself = true ;
clst . modelindex = 0 ;
clst . hull = 1 ;
clst . frame = 0 ;
clst . localtime = sv . time ;
clst . mins = player_mins ;
clst . maxs = player_maxs ;
clst . angles = vec3_origin ; //not needed, as the client knows better than us anyway.
clst . origin = client - > specorigin ;
clst . velocity = client - > specvelocity ;
for ( client = client ; client ; client = client - > controller )
{
clst . health = 100 ;
if ( client - > spec_track )
{
clst . weaponframe = sv . recordedplayer [ client - > spec_track - 1 ] . weaponframe ;
clst . spectator = 2 ;
2004-12-08 04:14:52 +00:00
}
2005-01-26 03:39:47 +00:00
else
{
clst . weaponframe = 0 ;
clst . spectator = 1 ;
}
SV_WritePlayerToClient ( msg , & clst ) ;
clst . playernum - - ;
2004-08-23 00:15:46 +00:00
}
2005-01-26 03:39:47 +00:00
return ;
}
2009-11-07 13:29:15 +00:00
# endif
2005-01-26 03:39:47 +00:00
for ( j = 0 , cl = svs . clients ; j < sv . allocated_client_slots ; j + + , cl + + )
{
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
if ( cl - > state ! = cs_spawned & & ! ( cl - > state = = cs_free & & cl - > name [ 0 ] ) ) //this includes bots, and nq bots
2006-07-02 04:27:56 +00:00
continue ;
2005-01-25 05:01:30 +00:00
2006-09-26 22:54:27 +00:00
isbot = ( ! cl - > name [ 0 ] | | cl - > protocol = = SCP_BAD ) ;
2005-01-25 05:01:30 +00:00
ent = cl - > edict ;
if ( cl - > viewent & & ent = = clent )
{
vent = EDICT_NUM ( svprogfuncs , cl - > viewent ) ;
if ( ! vent )
vent = ent ;
}
else
vent = ent ;
2005-12-13 02:31:57 +00:00
2004-08-23 00:15:46 +00:00
if ( progstype ! = PROG_QW )
{
2005-04-16 16:21:27 +00:00
if ( progstype = = PROG_H2 & & ( int ) ent - > v - > effects & H2EF_NODRAW & & ent ! = clent )
2004-08-23 00:15:46 +00:00
continue ;
2005-03-28 00:11:59 +00:00
if ( ( int ) ent - > v - > effects & EF_MUZZLEFLASH )
2004-08-23 00:15:46 +00:00
{
if ( needcleanup < ( j + 1 ) )
{
needcleanup = ( j + 1 ) ;
}
}
}
// ZOID visibility tracking
if ( ent ! = clent & &
2005-12-13 02:31:57 +00:00
! ( client - > spec_track & & client - > spec_track - 1 = = j ) )
2004-08-23 00:15:46 +00:00
{
if ( cl - > spectator )
continue ;
// ignore if not touching a PV leaf
2010-07-11 10:53:13 +00:00
if ( ! sv . world . worldmodel - > funcs . EdictInFatPVS ( sv . world . worldmodel , & ( ( wedict_t * ) ent ) - > pvsinfo , pvs ) )
2005-08-26 22:56:51 +00:00
continue ;
2004-08-31 23:58:18 +00:00
2007-09-02 19:55:17 +00:00
if ( ! ( ( int ) clent - > xv - > dimension_see & ( ( int ) ent - > xv - > dimension_seen | ( int ) ent - > xv - > dimension_ghost ) ) )
2004-08-31 23:58:18 +00:00
continue ; //not in this dimension - sorry...
2007-08-30 18:55:44 +00:00
if ( sv_cullplayers_trace . value | | sv_cullentities_trace . value )
if ( Cull_Traceline ( clent , ent ) )
continue ;
2004-08-23 00:15:46 +00:00
}
2005-02-28 07:16:19 +00:00
if ( SV_AddCSQCUpdate ( client , ent ) )
2005-02-12 18:56:04 +00:00
continue ;
2004-08-23 00:15:46 +00:00
{
clstate_t clst ;
clst . playernum = j ;
2009-04-19 00:50:42 +00:00
clst . onladder = ( int ) ent - > xv - > pmove_flags & PMF_LADDER ;
2004-08-23 00:15:46 +00:00
clst . lastcmd = & cl - > lastcmd ;
2005-03-28 00:11:59 +00:00
clst . modelindex = vent - > v - > modelindex ;
clst . frame = vent - > v - > frame ;
clst . weaponframe = ent - > v - > weaponframe ;
clst . angles = ent - > v - > angles ;
clst . origin = vent - > v - > origin ;
clst . velocity = vent - > v - > velocity ;
clst . effects = ent - > v - > effects ;
2009-06-21 17:45:33 +00:00
clst . vw_index = ent - > xv - > vw_index ;
2005-03-28 00:11:59 +00:00
2005-04-16 16:21:27 +00:00
if ( progstype = = PROG_H2 & & ( ( int ) vent - > v - > effects & H2EF_NODRAW ) )
2004-08-23 00:15:46 +00:00
{
clst . effects = 0 ;
clst . modelindex = 0 ;
}
2005-03-28 00:11:59 +00:00
clst . skin = vent - > v - > skin ;
clst . mins = vent - > v - > mins ;
2007-09-02 19:55:17 +00:00
clst . hull = vent - > xv - > hull ;
2005-03-28 00:11:59 +00:00
clst . maxs = vent - > v - > maxs ;
2007-09-02 19:55:17 +00:00
clst . scale = vent - > xv - > scale ;
clst . transparency = vent - > xv - > alpha ;
2004-08-31 23:58:18 +00:00
//QSG_DIMENSION_PLANES - if the only shared dimensions are ghost dimensions, Set half alpha.
2007-09-02 19:55:17 +00:00
if ( ( ( int ) clent - > xv - > dimension_see & ( int ) ent - > xv - > dimension_ghost ) )
if ( ! ( ( int ) clent - > xv - > dimension_see & ( ( int ) ent - > xv - > dimension_seen & ~ ( int ) ent - > xv - > dimension_ghost ) ) )
2004-09-04 17:55:12 +00:00
{
2007-09-02 19:55:17 +00:00
if ( ent - > xv - > dimension_ghost_alpha )
clst . transparency * = ent - > xv - > dimension_ghost_alpha ;
2004-09-04 17:55:12 +00:00
else
clst . transparency * = 0.5 ;
}
2004-08-31 23:58:18 +00:00
2007-09-02 19:55:17 +00:00
clst . fatness = vent - > xv - > fatness ;
2004-08-23 00:15:46 +00:00
clst . localtime = cl - > localtime ;
2005-03-28 00:11:59 +00:00
clst . health = ent - > v - > health ;
2004-08-23 00:15:46 +00:00
clst . spectator = 0 ;
clst . fteext = client - > fteprotocolextensions ;
clst . zext = client - > zquake_extensions ;
clst . cl = cl ;
2007-06-20 00:02:54 +00:00
if ( ent ! = vent | | host_client - > viewent = = j + 1 )
2004-08-23 00:15:46 +00:00
clst . modelindex = 0 ;
2009-11-07 13:29:15 +00:00
# ifdef SERVER_DEMO_PLAYBACK
2004-08-23 00:15:46 +00:00
if ( sv . demostatevalid )
clst . health = 100 ;
2009-11-07 13:29:15 +00:00
# endif
2004-08-23 00:15:46 +00:00
clst . isself = false ;
2005-01-26 03:39:47 +00:00
if ( ( cl = = client | | cl - > controller = = client ) )
2004-08-23 00:15:46 +00:00
{
clst . isself = true ;
clst . spectator = 0 ;
if ( client - > spectator )
{
if ( client - > spec_track )
{
2005-01-26 03:39:47 +00:00
clst . spectator = 2 ;
2005-03-28 00:11:59 +00:00
clst . mins = svs . clients [ client - > spec_track - 1 ] . edict - > v - > mins ;
clst . maxs = svs . clients [ client - > spec_track - 1 ] . edict - > v - > maxs ;
clst . health = svs . clients [ client - > spec_track - 1 ] . edict - > v - > health ;
clst . weaponframe = svs . clients [ client - > spec_track - 1 ] . edict - > v - > weaponframe ;
2004-08-23 00:15:46 +00:00
}
else
2005-01-26 03:39:47 +00:00
{
clst . spectator = 1 ;
2004-08-23 00:15:46 +00:00
clst . health = 1 ;
2005-01-26 03:39:47 +00:00
}
2004-08-23 00:15:46 +00:00
}
}
2005-01-26 03:39:47 +00:00
else if ( client - > spectator )
2004-08-23 00:15:46 +00:00
{
clst . health = 100 ;
2007-07-27 21:24:31 +00:00
if ( client - > spec_track = = j + 1 )
2004-08-23 00:15:46 +00:00
clst . spectator = 2 ;
else
clst . spectator = 1 ;
}
if ( isbot )
{
clst . lastcmd = NULL ;
clst . velocity = NULL ;
2009-11-04 21:16:50 +00:00
clst . localtime = sv . time ;
VectorCopy ( clst . origin , frame - > playerpositions [ j ] ) ;
2004-08-23 00:15:46 +00:00
}
2009-11-04 21:16:50 +00:00
else
{
VectorMA ( clst . origin , ( sv . time - clst . localtime ) , clst . velocity , frame - > playerpositions [ j ] ) ;
}
frame - > playerpresent [ j ] = true ;
2004-08-23 00:15:46 +00:00
SV_WritePlayerToClient ( msg , & clst ) ;
}
//FIXME: Name flags
//player is visible, now would be a good time to update what the player is like.
pflags = 0 ;
2008-11-29 16:15:04 +00:00
# ifdef PEXT_VWEAP
2007-09-02 19:55:17 +00:00
if ( client - > fteprotocolextensions & PEXT_VWEAP & & client - > otherclientsknown [ j ] . vweap ! = ent - > xv - > vweapmodelindex )
2004-08-23 00:15:46 +00:00
{
pflags | = 1 ;
2007-09-02 19:55:17 +00:00
client - > otherclientsknown [ j ] . vweap = ent - > xv - > vweapmodelindex ;
2004-08-23 00:15:46 +00:00
}
2008-11-29 16:15:04 +00:00
# endif
2004-08-23 00:15:46 +00:00
if ( pflags )
{
ClientReliableWrite_Begin ( client , svc_ftesetclientpersist , 10 ) ;
ClientReliableWrite_Short ( client , pflags ) ;
if ( pflags & 1 )
ClientReliableWrite_Short ( client , client - > otherclientsknown [ j ] . vweap ) ;
ClientReliable_FinishWrite ( client ) ;
}
}
}
2008-11-09 22:29:28 +00:00
void SVNQ_EmitEntityState ( sizebuf_t * msg , entity_state_t * ent )
2004-08-23 00:15:46 +00:00
{
2008-11-09 22:29:28 +00:00
entity_state_t * baseline = & EDICT_NUM ( svprogfuncs , ent - > number ) - > baseline ;
2004-11-20 00:54:23 +00:00
2005-12-13 02:31:57 +00:00
int i , eff ;
2004-08-23 00:15:46 +00:00
float miss ;
2004-11-20 00:54:23 +00:00
unsigned int bits = 0 ;
2006-02-27 00:42:25 +00:00
int glowsize = 0 , glowcolor = 0 , colourmod = 0 ;
2006-01-28 02:35:40 +00:00
2004-08-23 00:15:46 +00:00
for ( i = 0 ; i < 3 ; i + + )
2005-12-13 02:31:57 +00:00
{
2008-11-09 22:29:28 +00:00
miss = ent - > origin [ i ] - baseline - > origin [ i ] ;
2004-08-23 00:15:46 +00:00
if ( miss < - 0.1 | | miss > 0.1 )
bits | = NQU_ORIGIN1 < < i ;
}
2008-11-09 22:29:28 +00:00
if ( ent - > angles [ 0 ] ! = baseline - > angles [ 0 ] )
2004-08-23 00:15:46 +00:00
bits | = NQU_ANGLE1 ;
2005-12-13 02:31:57 +00:00
2008-11-09 22:29:28 +00:00
if ( ent - > angles [ 1 ] ! = baseline - > angles [ 1 ] )
2004-08-23 00:15:46 +00:00
bits | = NQU_ANGLE2 ;
2005-12-13 02:31:57 +00:00
2008-11-09 22:29:28 +00:00
if ( ent - > angles [ 2 ] ! = baseline - > angles [ 2 ] )
2004-08-23 00:15:46 +00:00
bits | = NQU_ANGLE3 ;
2005-12-13 02:31:57 +00:00
2009-07-18 20:14:10 +00:00
if ( ent - > dpflags & RENDER_STEP )
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
bits | = NQU_NOLERP ; // don't mess up the step animation
2004-08-23 00:15:46 +00:00
2008-11-09 22:29:28 +00:00
if ( baseline - > colormap ! = ent - > colormap & & ent - > colormap > = 0 )
2004-08-23 00:15:46 +00:00
bits | = NQU_COLORMAP ;
2008-11-09 22:29:28 +00:00
if ( baseline - > skinnum ! = ent - > skinnum )
2004-08-23 00:15:46 +00:00
bits | = NQU_SKIN ;
2008-11-09 22:29:28 +00:00
if ( baseline - > frame ! = ent - > frame )
2004-08-23 00:15:46 +00:00
bits | = NQU_FRAME ;
2008-11-09 22:29:28 +00:00
eff = ent - > effects ;
2004-08-23 00:15:46 +00:00
2008-11-09 22:29:28 +00:00
if ( ( baseline - > effects & 0x00ff ) ! = ( ( int ) eff & 0x00ff ) )
2005-12-13 02:31:57 +00:00
bits | = NQU_EFFECTS ;
2004-11-20 00:54:23 +00:00
2008-11-09 22:29:28 +00:00
if ( baseline - > modelindex ! = ent - > modelindex )
2004-08-23 00:15:46 +00:00
bits | = NQU_MODEL ;
2008-11-09 22:29:28 +00:00
if ( ent - > number > = 256 )
2004-08-23 00:15:46 +00:00
bits | = NQU_LONGENTITY ;
2004-11-20 00:54:23 +00:00
2005-12-13 02:31:57 +00:00
if ( 0 )
2004-11-20 00:54:23 +00:00
{
2008-11-09 22:29:28 +00:00
#if 0
if ( baseline . trans ! = ent - > xv - > alpha )
if ( ! ( baseline . trans = = 1 & & ! ent - > xv - > alpha ) )
2004-11-20 00:54:23 +00:00
bits | = DPU_ALPHA ;
2008-11-09 22:29:28 +00:00
if ( baseline . scale ! = ent - > xv - > scale )
2005-05-17 02:36:54 +00:00
{
2007-09-02 19:55:17 +00:00
if ( ent - > xv - > scale ! = 0 | | ent - > baseline . scale ! = 1 )
2005-05-17 02:36:54 +00:00
bits | = DPU_SCALE ;
}
2004-11-20 00:54:23 +00:00
2005-05-26 12:55:34 +00:00
if ( ent - > v - > modelindex > = 256 ) //as much as protocols can handle
bits | = DPU_MODEL2 ;
2008-11-09 22:29:28 +00:00
if ( ( baseline . effects & 0xff00 ) ! = ( ( int ) eff & 0xff00 ) )
2004-11-20 00:54:23 +00:00
bits | = DPU_EFFECTS2 ;
2007-09-02 19:55:17 +00:00
if ( ent - > xv - > exteriormodeltoclient = = EDICT_TO_PROG ( svprogfuncs , host_client - > edict ) )
2005-05-26 12:55:34 +00:00
bits | = DPU_EXTERIORMODEL ;
2007-09-02 19:55:17 +00:00
if ( ent - > xv - > viewmodelforclient = = EDICT_TO_PROG ( svprogfuncs , host_client - > edict ) )
2005-05-26 12:55:34 +00:00
bits | = DPU_VIEWMODEL ;
2004-11-20 00:54:23 +00:00
2007-09-02 19:55:17 +00:00
glowsize = ent - > xv - > glow_size * 0.25f ;
glowcolor = ent - > xv - > glow_color ;
2005-05-19 02:53:03 +00:00
2007-09-02 19:55:17 +00:00
colourmod = ( ( int ) bound ( 0 , ent - > xv - > colormod [ 0 ] * ( 7.0f / 32.0f ) , 7 ) < < 5 ) | ( ( int ) bound ( 0 , ent - > xv - > colormod [ 1 ] * ( 7.0f / 32.0f ) , 7 ) < < 2 ) | ( ( int ) bound ( 0 , ent - > xv - > colormod [ 2 ] * ( 3.0f / 32.0f ) , 3 ) < < 0 ) ;
2006-02-27 00:42:25 +00:00
2004-11-20 00:54:23 +00:00
if ( 0 ! = glowsize )
bits | = DPU_GLOWSIZE ;
if ( 0 ! = glowcolor )
bits | = DPU_GLOWCOLOR ;
2006-02-27 00:42:25 +00:00
if ( 0 ! = colourmod )
bits | = DPU_COLORMOD ;
2008-11-09 22:29:28 +00:00
# endif
2004-11-20 00:54:23 +00:00
}
2005-05-26 12:55:34 +00:00
else
{
2008-11-09 22:29:28 +00:00
if ( ent - > modelindex > = 256 ) //as much as protocols can handle
2005-05-26 12:55:34 +00:00
return ;
2008-11-09 22:29:28 +00:00
if ( ent - > number > = 600 ) //too many for a conventional nq client.
2005-05-26 12:55:34 +00:00
return ;
}
2004-11-20 00:54:23 +00:00
if ( bits & 0xFF000000 )
bits | = DPU_EXTEND2 ;
2005-05-26 12:55:34 +00:00
if ( bits & 0xFF0000 )
bits | = DPU_EXTEND1 ;
if ( bits & 0xFF00 )
bits | = NQU_MOREBITS ;
2004-11-20 00:54:23 +00:00
2004-08-23 00:15:46 +00:00
//
// write the message
//
# ifdef PARANOID
MSG_WriteByte ( msg , ( bits | NQU_SIGNAL ) & 0xFF ) ; //gets caught on 'range error'
# else
MSG_WriteByte ( msg , bits | NQU_SIGNAL ) ;
# endif
2004-11-20 00:54:23 +00:00
if ( bits & NQU_MOREBITS ) MSG_WriteByte ( msg , bits > > 8 ) ;
if ( bits & DPU_EXTEND1 ) MSG_WriteByte ( msg , bits > > 16 ) ;
if ( bits & DPU_EXTEND2 ) MSG_WriteByte ( msg , bits > > 24 ) ;
2004-08-23 00:15:46 +00:00
if ( bits & NQU_LONGENTITY )
2008-11-09 22:29:28 +00:00
MSG_WriteShort ( msg , ent - > number ) ;
2004-08-23 00:15:46 +00:00
else
2008-11-09 22:29:28 +00:00
MSG_WriteByte ( msg , ent - > number ) ;
2004-08-23 00:15:46 +00:00
2008-11-09 22:29:28 +00:00
if ( bits & NQU_MODEL ) MSG_WriteByte ( msg , ent - > modelindex ) ;
if ( bits & NQU_FRAME ) MSG_WriteByte ( msg , ent - > frame ) ;
if ( bits & NQU_COLORMAP ) MSG_WriteByte ( msg , ent - > colormap ) ;
if ( bits & NQU_SKIN ) MSG_WriteByte ( msg , ent - > skinnum ) ;
2005-12-13 02:31:57 +00:00
if ( bits & NQU_EFFECTS ) MSG_WriteByte ( msg , eff & 0x00ff ) ;
2008-11-09 22:29:28 +00:00
if ( bits & NQU_ORIGIN1 ) MSG_WriteCoord ( msg , ent - > origin [ 0 ] ) ;
if ( bits & NQU_ANGLE1 ) MSG_WriteAngle ( msg , ent - > angles [ 0 ] ) ;
if ( bits & NQU_ORIGIN2 ) MSG_WriteCoord ( msg , ent - > origin [ 1 ] ) ;
if ( bits & NQU_ANGLE2 ) MSG_WriteAngle ( msg , ent - > angles [ 1 ] ) ;
if ( bits & NQU_ORIGIN3 ) MSG_WriteCoord ( msg , ent - > origin [ 2 ] ) ;
if ( bits & NQU_ANGLE3 ) MSG_WriteAngle ( msg , ent - > angles [ 2 ] ) ;
if ( bits & DPU_ALPHA ) MSG_WriteByte ( msg , ent - > trans * 255 ) ;
if ( bits & DPU_SCALE ) MSG_WriteByte ( msg , ent - > scale * 16 ) ;
2004-11-20 00:54:23 +00:00
if ( bits & DPU_EFFECTS2 ) MSG_WriteByte ( msg , eff > > 8 ) ;
if ( bits & DPU_GLOWSIZE ) MSG_WriteByte ( msg , glowsize ) ;
if ( bits & DPU_GLOWCOLOR ) MSG_WriteByte ( msg , glowcolor ) ;
2006-02-27 00:42:25 +00:00
if ( bits & DPU_COLORMOD ) MSG_WriteByte ( msg , colourmod ) ;
2008-11-09 22:29:28 +00:00
if ( bits & DPU_FRAME2 ) MSG_WriteByte ( msg , ( int ) ent - > frame > > 8 ) ;
if ( bits & DPU_MODEL2 ) MSG_WriteByte ( msg , ( int ) ent - > modelindex > > 8 ) ;
2004-08-23 00:15:46 +00:00
}
typedef struct gibfilter_s {
struct gibfilter_s * next ;
int modelindex ;
int minframe ;
int maxframe ;
} gibfilter_t ;
gibfilter_t * gibfilter ;
2008-06-01 22:06:22 +00:00
void SV_GibFilterAdd ( char * modelname , int min , int max , qboolean allowwarn )
2004-08-23 00:15:46 +00:00
{
int i ;
2005-12-13 02:31:57 +00:00
gibfilter_t * gf ;
2004-08-23 00:15:46 +00:00
2006-02-17 02:51:59 +00:00
for ( i = 1 ; sv . strings . model_precache [ i ] ; i + + )
if ( ! strcmp ( sv . strings . model_precache [ i ] , modelname ) )
2004-08-23 00:15:46 +00:00
break ;
2006-02-17 02:51:59 +00:00
if ( ! sv . strings . model_precache [ i ] )
2004-08-23 00:15:46 +00:00
{
2008-06-01 22:06:22 +00:00
if ( allowwarn )
Con_Printf ( " Filtered model \" %s \" was not precached \n " , modelname ) ;
2004-08-23 00:15:46 +00:00
return ; //model not in use.
}
gf = Z_Malloc ( sizeof ( gibfilter_t ) ) ;
gf - > modelindex = i ;
gf - > minframe = ( ( min = = - 1 ) ? 0 : min ) ;
2005-11-26 21:16:48 +00:00
gf - > maxframe = ( ( max = = - 1 ) ? 0x80000000 : max ) ;
2004-08-23 00:15:46 +00:00
gf - > next = gibfilter ;
gibfilter = gf ;
}
void SV_GibFilterInit ( void )
{
char buffer [ 2048 ] ;
char * file ;
int min , max ;
gibfilter_t * gf ;
while ( gibfilter )
{
gf = gibfilter ;
gibfilter = gibfilter - > next ;
Z_Free ( gf ) ;
}
2007-09-02 19:55:17 +00:00
if ( svs . gametype ! = GT_PROGS & & svs . gametype ! = GT_Q1QVM )
2006-01-01 04:14:41 +00:00
return ;
2004-08-23 00:15:46 +00:00
file = COM_LoadStackFile ( " gibfiltr.cfg " , buffer , sizeof ( buffer ) ) ;
if ( ! file )
{
2005-12-21 07:00:33 +00:00
Con_DPrintf ( " gibfiltr.cfg file was not found. Using defaults \n " ) ;
2008-06-01 22:06:22 +00:00
SV_GibFilterAdd ( " progs/gib1.mdl " , - 1 , - 1 , false ) ;
SV_GibFilterAdd ( " progs/gib2.mdl " , - 1 , - 1 , false ) ;
SV_GibFilterAdd ( " progs/gib3.mdl " , - 1 , - 1 , false ) ;
SV_GibFilterAdd ( " progs/h_player.mdl " , - 1 , - 1 , false ) ;
2004-08-23 00:15:46 +00:00
return ;
}
while ( file )
{
file = COM_Parse ( file ) ;
if ( ! file )
2005-12-13 02:31:57 +00:00
{
2004-08-23 00:15:46 +00:00
return ;
}
min = atoi ( com_token ) ;
file = COM_Parse ( file ) ; //handles nulls nicly
max = atoi ( com_token ) ;
file = COM_Parse ( file ) ;
if ( ! file )
{
Con_Printf ( " Sudden ending to gibfiltr.cfg \n " ) ;
return ;
}
2008-06-01 22:06:22 +00:00
SV_GibFilterAdd ( com_token , min , max , true ) ;
2004-08-23 00:15:46 +00:00
}
}
qboolean SV_GibFilter ( edict_t * ent )
{
2005-03-28 00:11:59 +00:00
int indx = ent - > v - > modelindex ;
int frame = ent - > v - > frame ;
2004-08-23 00:15:46 +00:00
gibfilter_t * gf ;
for ( gf = gibfilter ; gf ; gf = gf - > next )
{
if ( gf - > modelindex = = indx )
if ( frame > = gf - > minframe & & frame < = gf - > maxframe )
return true ;
}
return false ;
}
# ifdef Q2BSPS
static int clientarea ;
2009-06-21 17:45:33 +00:00
unsigned int Q2BSP_FatPVS ( model_t * mod , vec3_t org , qbyte * buffer , unsigned int buffersize , qboolean add )
2005-08-26 22:56:51 +00:00
{ //fixme: this doesn't add
2004-08-23 00:15:46 +00:00
int leafnum ;
2005-08-26 22:56:51 +00:00
leafnum = CM_PointLeafnum ( mod , org ) ;
clientarea = CM_LeafArea ( mod , leafnum ) ;
2004-08-23 00:15:46 +00:00
2009-06-28 19:57:09 +00:00
return SV_Q2BSP_FatPVS ( mod , org , buffer , buffersize , add ) ;
2004-08-23 00:15:46 +00:00
}
2010-07-11 02:22:39 +00:00
qboolean Q2BSP_EdictInFatPVS ( model_t * mod , pvscache_t * ent , qbyte * pvs )
2004-08-23 00:15:46 +00:00
{
int i , l ;
2005-08-26 22:56:51 +00:00
if ( ! CM_AreasConnected ( mod , clientarea , ent - > areanum ) )
2004-08-23 00:15:46 +00:00
{ // doors can legally straddle two areas, so
// we may need to check another one
if ( ! ent - > areanum2
2005-08-26 22:56:51 +00:00
| | ! CM_AreasConnected ( mod , clientarea , ent - > areanum2 ) )
2004-08-23 00:15:46 +00:00
return false ; // blocked by a door
}
if ( ent - > num_leafs = = - 1 )
{ // too many leafs for individual check, go by headnode
2009-06-21 17:45:33 +00:00
if ( ! CM_HeadnodeVisible ( mod , ent - > headnode , pvs ) )
2004-08-23 00:15:46 +00:00
return false ;
}
else
{ // check individual leafs
for ( i = 0 ; i < ent - > num_leafs ; i + + )
{
l = ent - > leafnums [ i ] ;
2009-06-21 17:45:33 +00:00
if ( pvs [ l > > 3 ] & ( 1 < < ( l & 7 ) ) )
2004-08-23 00:15:46 +00:00
break ;
}
if ( i = = ent - > num_leafs )
return false ; // not visible
}
return true ;
}
# endif
2005-02-12 18:56:04 +00:00
2009-11-07 13:29:15 +00:00
# ifdef SERVER_DEMO_PLAYBACK
static void SV_Snapshot_Build_Playback ( client_t * client , packet_entities_t * pack )
2004-08-23 00:15:46 +00:00
{
2008-11-09 22:29:28 +00:00
int e ;
2004-08-23 00:15:46 +00:00
entity_state_t * state ;
2008-11-09 22:29:28 +00:00
mvdentity_state_t * dement ;
2004-12-08 04:14:52 +00:00
for ( e = 1 , dement = & sv . demostate [ e ] ; e < = sv . demomaxents ; e + + , dement + + )
2004-08-23 00:15:46 +00:00
{
if ( ! dement - > modelindex )
continue ;
if ( e > = 1 & & e < = MAX_CLIENTS )
continue ;
if ( pack - > num_entities = = pack - > max_entities )
continue ; // all full
//the entity would mess up the client and possibly disconnect them.
//FIXME: add an option to drop clients... entity fog could be killed in this way.
if ( e > = 512 & & ! ( client - > fteprotocolextensions & PEXT_ENTITYDBL ) )
continue ;
if ( e > = 1024 & & ! ( client - > fteprotocolextensions & PEXT_ENTITYDBL2 ) )
continue ;
2005-06-22 17:10:13 +00:00
// if (dement->modelindex >= 256 && !(client->fteprotocolextensions & PEXT_MODELDBL))
// continue;
2004-08-23 00:15:46 +00:00
state = & pack - > entities [ pack - > num_entities ] ;
pack - > num_entities + + ;
state - > number = e ;
2004-12-06 00:58:19 +00:00
state - > flags = EF_DIMLIGHT ;
2004-08-23 00:15:46 +00:00
VectorCopy ( dement - > origin , state - > origin ) ;
2004-12-08 04:14:52 +00:00
state - > angles [ 0 ] = dement - > angles [ 0 ] * 360.0f / 256 ;
state - > angles [ 1 ] = dement - > angles [ 1 ] * 360.0f / 256 ;
state - > angles [ 2 ] = dement - > angles [ 2 ] * 360.0f / 256 ;
2004-08-23 00:15:46 +00:00
state - > modelindex = dement - > modelindex ;
state - > frame = dement - > frame ;
state - > colormap = dement - > colormap ;
state - > skinnum = dement - > skinnum ;
state - > effects = dement - > effects ;
# ifdef PEXT_SCALE
state - > scale = dement - > scale ;
# endif
# ifdef PEXT_TRANS
state - > trans = dement - > trans ;
# endif
# ifdef PEXT_FATNESS
state - > fatness = dement - > fatness ;
# endif
}
for ( e = 0 ; e < sv . numdemospikes ; e + + )
{
if ( SV_DemoNailUpdate ( e ) )
continue ;
}
2008-11-09 22:29:28 +00:00
}
2009-11-07 13:29:15 +00:00
# endif
2004-08-23 00:15:46 +00:00
2008-11-09 22:29:28 +00:00
void SV_Snapshot_BuildStateQ1 ( entity_state_t * state , edict_t * ent , client_t * client )
{
//builds an entity_state from an entity
//note that client can be null, for building baselines.
2004-08-23 00:15:46 +00:00
2008-11-09 22:29:28 +00:00
int i ;
2004-08-23 00:15:46 +00:00
2008-11-09 22:29:28 +00:00
# ifdef Q2SERVER
state - > modelindex2 = 0 ;
state - > modelindex3 = 0 ;
state - > modelindex4 = 0 ;
state - > event = 0 ;
state - > solid = 0 ;
state - > sound = 0 ;
state - > renderfx = 0 ;
state - > old_origin [ 0 ] = 0 ;
state - > old_origin [ 1 ] = 0 ;
state - > old_origin [ 2 ] = 0 ;
# endif
state - > dpflags = 0 ;
if ( ent - > xv - > viewmodelforclient )
{ //this ent would have been filtered out by now if its not ours
//if ent->viewmodelforclient == client then:
state - > dpflags | = RENDER_VIEWMODEL ;
}
if ( ent - > xv - > exteriormodeltoclient & & client )
{
if ( ent - > xv - > exteriormodeltoclient = = EDICT_TO_PROG ( svprogfuncs , client - > edict ) )
state - > dpflags | = RENDER_EXTERIORMODEL ;
//everyone else sees it normally.
}
2009-07-18 20:14:10 +00:00
if ( ent - > v - > movetype = = MOVETYPE_STEP )
state - > dpflags | = RENDER_STEP ;
2008-11-09 22:29:28 +00:00
state - > number = NUM_FOR_EDICT ( svprogfuncs , ent ) ;
state - > flags = 0 ;
VectorCopy ( ent - > v - > origin , state - > origin ) ;
VectorCopy ( ent - > v - > angles , state - > angles ) ;
state - > modelindex = ent - > v - > modelindex ;
state - > frame = ent - > v - > frame ;
state - > colormap = ent - > v - > colormap ;
state - > skinnum = ent - > v - > skin ;
state - > effects = ent - > v - > effects ;
state - > hexen2flags = ent - > xv - > drawflags ;
state - > abslight = ( int ) ( ent - > xv - > abslight * 255 ) & 255 ;
state - > tagentity = ent - > xv - > tag_entity ;
state - > tagindex = ent - > xv - > tag_index ;
state - > light [ 0 ] = ent - > xv - > color [ 0 ] * 255 ;
state - > light [ 1 ] = ent - > xv - > color [ 1 ] * 255 ;
state - > light [ 2 ] = ent - > xv - > color [ 2 ] * 255 ;
state - > light [ 3 ] = ent - > xv - > light_lev ;
state - > lightstyle = ent - > xv - > style ;
2010-08-28 17:14:38 +00:00
state - > lightstyle = ent - > xv - > style ;
2008-11-09 22:29:28 +00:00
state - > lightpflags = ent - > xv - > pflags ;
if ( ( int ) ent - > v - > flags & FL_CLASS_DEPENDENT & & client - > playerclass ) //hexen2 wierdness.
{
char modname [ MAX_QPATH ] ;
Q_strncpyz ( modname , sv . strings . model_precache [ state - > modelindex ] , sizeof ( modname ) ) ;
if ( strlen ( modname ) > 5 )
{
modname [ strlen ( modname ) - 5 ] = client - > playerclass + ' 0 ' ;
state - > modelindex = SV_ModelIndex ( modname ) ;
}
}
if ( state - > effects & 0x00400000 ) //DP's EF_LOWPRECISION
state - > effects & = ~ 0x00400000 ; //we don't support it, nor does dp any more. strip it.
if ( state - > effects & EF_FULLBRIGHT ) //wrap the field for fte clients (this is horrible)
{
state - > hexen2flags | = MLS_FULLBRIGHT ;
}
if ( progstype ! = PROG_QW & & state - > effects & & client & & ISQWCLIENT ( client ) ) //don't send extra nq effects to a qw client.
{
//EF_NODRAW doesn't draw the model.
//The client still needs to know about it though, as it might have other effects on it.
if ( progstype = = PROG_H2 )
{
if ( state - > effects = = H2EF_NODRAW )
{
//actually, H2 is pretty lame about this
state - > effects = 0 ;
state - > modelindex = 0 ;
state - > frame = 0 ;
state - > colormap = 0 ;
state - > abslight = 0 ;
state - > skinnum = 0 ;
state - > hexen2flags = 0 ;
}
}
else
{
if ( state - > effects & NQEF_NODRAW )
state - > modelindex = 0 ;
}
if ( state - > number < = sv . allocated_client_slots ) // clear only client ents
state - > effects & = ~ ( QWEF_FLAG1 | QWEF_FLAG2 ) ;
2004-08-23 00:15:46 +00:00
}
2008-11-09 22:29:28 +00:00
if ( ! ent - > xv - > colormod [ 0 ] & & ! ent - > xv - > colormod [ 1 ] & & ! ent - > xv - > colormod [ 2 ] )
{
state - > colormod [ 0 ] = ( 256 ) / 8 ;
state - > colormod [ 1 ] = ( 256 ) / 8 ;
state - > colormod [ 2 ] = ( 256 ) / 8 ;
}
else
{
i = ent - > xv - > colormod [ 0 ] * ( 256 / 8 ) ; state - > colormod [ 0 ] = bound ( 0 , i , 255 ) ;
i = ent - > xv - > colormod [ 1 ] * ( 256 / 8 ) ; state - > colormod [ 1 ] = bound ( 0 , i , 255 ) ;
i = ent - > xv - > colormod [ 2 ] * ( 256 / 8 ) ; state - > colormod [ 2 ] = bound ( 0 , i , 255 ) ;
}
state - > glowsize = ent - > xv - > glow_size * 0.25 ;
state - > glowcolour = ent - > xv - > glow_color ;
if ( ent - > xv - > glow_trail )
state - > dpflags | = RENDER_GLOWTRAIL ;
# ifdef PEXT_SCALE
state - > scale = ent - > xv - > scale * 16 ;
if ( ! ent - > xv - > scale )
state - > scale = 1 * 16 ;
# endif
# ifdef PEXT_TRANS
state - > trans = ent - > xv - > alpha * 255 ;
if ( ! ent - > xv - > alpha )
state - > trans = 255 ;
//QSG_DIMENSION_PLANES - if the only shared dimensions are ghost dimensions, Set half alpha.
if ( client & & client - > edict )
{
if ( ( ( int ) client - > edict - > xv - > dimension_see & ( int ) ent - > xv - > dimension_ghost ) )
if ( ! ( ( int ) client - > edict - > xv - > dimension_see & ( ( int ) ent - > xv - > dimension_seen & ~ ( int ) ent - > xv - > dimension_ghost ) ) )
{
if ( ent - > xv - > dimension_ghost_alpha )
state - > trans * = ent - > xv - > dimension_ghost_alpha ;
else
state - > trans * = 0.5 ;
}
}
# endif
# ifdef PEXT_FATNESS
2009-07-05 18:45:53 +00:00
state - > fatness = ent - > xv - > fatness * 16 ;
2008-11-09 22:29:28 +00:00
# endif
}
void SV_Snapshot_BuildQ1 ( client_t * client , packet_entities_t * pack , qbyte * pvs , edict_t * clent , qboolean ignorepvs )
{
//pvs and clent can be null, but only if the other is also null
int e , i ;
edict_t * ent ;
entity_state_t * state ;
# define DEPTHOPTIMISE
# ifdef DEPTHOPTIMISE
vec3_t org ;
float distances [ MAX_EXTENDED_PACKET_ENTITIES ] ;
float dist ;
# endif
globalvars_t * pr_globals = PR_globals ( svprogfuncs , PR_CURRENT ) ;
int pvsflags ;
2004-08-23 00:15:46 +00:00
if ( client - > viewent
# ifdef NQPROT
2005-06-14 04:52:10 +00:00
& & ISQWCLIENT ( client )
2004-08-23 00:15:46 +00:00
# endif
2008-11-09 22:29:28 +00:00
) //this entity is watching from outside themselves. The client is tricked into thinking that they themselves are in the view ent, and a new dummy ent (the old them) must be spawned.
2009-11-04 21:16:50 +00:00
2004-08-23 00:15:46 +00:00
{
2008-11-09 22:29:28 +00:00
//FIXME: this hack needs cleaning up
# ifdef DEPTHOPTIMISE
2004-08-23 00:15:46 +00:00
distances [ 0 ] = 0 ;
2008-11-09 22:29:28 +00:00
# endif
2004-08-23 00:15:46 +00:00
state = & pack - > entities [ pack - > num_entities ] ;
pack - > num_entities + + ;
2008-11-09 22:29:28 +00:00
SV_Snapshot_BuildStateQ1 ( state , clent , client ) ;
2004-08-23 00:15:46 +00:00
2008-11-09 22:29:28 +00:00
state - > number = client - svs . clients + 1 ;
2004-08-23 00:15:46 +00:00
2008-11-09 22:29:28 +00:00
//yeah, I doubt anyone will need this
2007-06-20 00:02:54 +00:00
if ( progstype = = PROG_QW )
2004-08-23 00:15:46 +00:00
{
2008-11-09 22:29:28 +00:00
if ( ( int ) clent - > v - > effects & QWEF_FLAG1 )
2007-06-20 00:02:54 +00:00
{
memcpy ( & pack - > entities [ pack - > num_entities ] , state , sizeof ( * state ) ) ;
state = & pack - > entities [ pack - > num_entities ] ;
pack - > num_entities + + ;
state - > modelindex = SV_ModelIndex ( " progs/flag.mdl " ) ;
state - > frame = 0 ;
2008-11-09 22:29:28 +00:00
state - > number + + ; //yeek
2007-06-20 00:02:54 +00:00
state - > skinnum = 0 ;
}
2008-11-09 22:29:28 +00:00
else if ( ( int ) clent - > v - > effects & QWEF_FLAG2 )
2007-06-20 00:02:54 +00:00
{
memcpy ( & pack - > entities [ pack - > num_entities ] , state , sizeof ( * state ) ) ;
state = & pack - > entities [ pack - > num_entities ] ;
pack - > num_entities + + ;
state - > modelindex = SV_ModelIndex ( " progs/flag.mdl " ) ;
state - > frame = 0 ;
2008-11-09 22:29:28 +00:00
state - > number + + ; //yeek
2007-06-20 00:02:54 +00:00
state - > skinnum = 1 ;
}
2004-08-23 00:15:46 +00:00
}
}
2008-11-09 22:29:28 +00:00
2004-08-23 00:15:46 +00:00
# ifdef NQPROT
2009-11-04 21:16:50 +00:00
for ( e = ( ISQWCLIENT ( client ) ? sv . allocated_client_slots + 1 : 1 ) ; e < sv . world . num_edicts ; e + + )
2004-08-23 00:15:46 +00:00
# else
for ( e = sv . allocated_client_slots + 1 ; e < sv . num_edicts ; e + + )
# endif
{
ent = EDICT_NUM ( svprogfuncs , e ) ;
2008-11-09 22:29:28 +00:00
if ( ent - > xv - > customizeentityforclient )
{
pr_global_struct - > self = EDICT_TO_PROG ( svprogfuncs , ent ) ;
2010-07-18 08:42:59 +00:00
pr_global_struct - > other = ( clent ? EDICT_TO_PROG ( svprogfuncs , clent ) : 0 ) ;
2008-11-09 22:29:28 +00:00
PR_ExecuteProgram ( svprogfuncs , ent - > xv - > customizeentityforclient ) ;
if ( ! G_FLOAT ( OFS_RETURN ) )
continue ;
}
2004-08-23 00:15:46 +00:00
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
if ( progstype ! = PROG_QW )
{
// if (progstype == PROG_H2)
// if (ent->v->effects == H2EF_NODRAW)
// continue;
if ( ( int ) ent - > v - > effects & EF_MUZZLEFLASH )
{
if ( needcleanup < e )
{
needcleanup = e ;
}
}
}
2010-07-11 02:22:39 +00:00
if ( ent - > xv - > viewmodelforclient )
{
2010-07-18 08:42:59 +00:00
if ( ent - > xv - > viewmodelforclient ! = ( clent ? EDICT_TO_PROG ( svprogfuncs , clent ) : 0 ) )
2010-07-11 02:22:39 +00:00
continue ;
pvsflags = PVSF_IGNOREPVS ;
}
else if ( ent = = clent )
2004-08-23 00:15:46 +00:00
{
2008-11-09 22:29:28 +00:00
pvsflags = PVSF_IGNOREPVS ;
}
else
{
// ignore ents without visible models
if ( ! ent - > xv - > SendEntity & & ( ! ent - > v - > modelindex | | ! * PR_GetString ( svprogfuncs , ent - > v - > model ) ) & & ! ( ( int ) ent - > xv - > pflags & PFLAGS_FULLDYNAMIC ) )
continue ;
pvsflags = ent - > xv - > pvsflags ;
if ( pvs & & ent ! = clent ) //self doesn't get a pvs test, to cover teleporters
2004-10-10 06:32:29 +00:00
{
2008-11-09 22:29:28 +00:00
if ( ( int ) ent - > v - > effects & EF_NODEPTHTEST )
2004-10-10 06:32:29 +00:00
{
2008-05-25 22:23:43 +00:00
}
2008-11-09 22:29:28 +00:00
else if ( ( pvsflags & PVSF_MODE_MASK ) < PVSF_USEPHS )
2008-05-25 22:23:43 +00:00
{
2008-11-09 22:29:28 +00:00
//branch out to the pvs testing.
2010-07-11 02:22:39 +00:00
if ( ent - > xv - > tag_entity )
2008-11-09 22:29:28 +00:00
{
edict_t * p = ent ;
int c = 10 ;
while ( p - > xv - > tag_entity & & c - - > 0 )
{
p = EDICT_NUM ( svprogfuncs , p - > xv - > tag_entity ) ;
}
2010-07-11 02:22:39 +00:00
if ( ! sv . world . worldmodel - > funcs . EdictInFatPVS ( sv . world . worldmodel , & ( ( wedict_t * ) p ) - > pvsinfo , pvs ) )
2008-11-09 22:29:28 +00:00
continue ;
}
else
{
2010-07-11 02:22:39 +00:00
if ( ! sv . world . worldmodel - > funcs . EdictInFatPVS ( sv . world . worldmodel , & ( ( wedict_t * ) ent ) - > pvsinfo , pvs ) )
2008-11-09 22:29:28 +00:00
continue ;
2008-05-25 22:23:43 +00:00
}
}
2009-11-04 21:16:50 +00:00
else if ( ( pvsflags & PVSF_MODE_MASK ) = = PVSF_USEPHS & & sv . world . worldmodel - > fromgame = = fg_quake )
2008-05-25 22:23:43 +00:00
{
2008-11-09 22:29:28 +00:00
int leafnum ;
unsigned char * mask ;
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
if ( sv . phs )
2008-11-09 22:29:28 +00:00
{
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
leafnum = sv . world . worldmodel - > funcs . LeafnumForPoint ( sv . world . worldmodel , host_client - > edict - > v - > origin ) ;
mask = sv . phs + leafnum * 4 * ( ( sv . world . worldmodel - > numleafs + 31 ) > > 5 ) ;
leafnum = sv . world . worldmodel - > funcs . LeafnumForPoint ( sv . world . worldmodel , ent - > v - > origin ) - 1 ;
if ( ! ( mask [ leafnum > > 3 ] & ( 1 < < ( leafnum & 7 ) ) ) )
{
continue ;
}
2008-11-09 22:29:28 +00:00
}
2004-10-10 06:32:29 +00:00
}
2008-05-25 22:23:43 +00:00
2008-11-09 22:29:28 +00:00
if ( client - > gibfilter & & SV_GibFilter ( ent ) )
2004-10-10 06:32:29 +00:00
continue ;
}
2004-08-23 00:15:46 +00:00
}
2005-05-26 12:55:34 +00:00
2008-11-09 22:29:28 +00:00
//DP_SV_NODRAWONLYTOCLIENT
2007-09-02 19:55:17 +00:00
if ( ent - > xv - > nodrawtoclient ) //DP extension.
if ( ent - > xv - > nodrawtoclient = = EDICT_TO_PROG ( svprogfuncs , client - > edict ) )
2004-08-23 00:15:46 +00:00
continue ;
2008-11-09 22:29:28 +00:00
//DP_SV_DRAWONLYTOCLIENT
2007-09-02 19:55:17 +00:00
if ( ent - > xv - > drawonlytoclient )
if ( ent - > xv - > drawonlytoclient ! = EDICT_TO_PROG ( svprogfuncs , client - > edict ) )
2004-11-13 17:36:42 +00:00
{
client_t * split ;
for ( split = client - > controlled ; split ; split = split - > controlled )
{
2007-09-02 19:55:17 +00:00
if ( split - > edict - > xv - > view2 = = EDICT_TO_PROG ( svprogfuncs , ent ) )
2004-11-13 17:36:42 +00:00
break ;
}
if ( ! split )
continue ;
}
2004-08-31 23:58:18 +00:00
2004-09-04 17:55:12 +00:00
//QSG_DIMENSION_PLANES
2004-11-20 00:54:23 +00:00
if ( client - > edict )
2007-09-02 19:55:17 +00:00
if ( ! ( ( int ) client - > edict - > xv - > dimension_see & ( ( int ) ent - > xv - > dimension_seen | ( int ) ent - > xv - > dimension_ghost ) ) )
2004-11-20 00:54:23 +00:00
continue ; //not in this dimension - sorry...
2004-09-04 17:55:12 +00:00
2007-08-30 18:55:44 +00:00
2008-11-09 22:29:28 +00:00
if ( ! ignorepvs & & ent ! = clent & & ( pvsflags & PVSF_MODE_MASK ) = = PVSF_NORMALPVS & & ! ( ( unsigned int ) ent - > v - > effects & ( EF_DIMLIGHT | EF_BLUE | EF_RED | EF_BRIGHTLIGHT | EF_BRIGHTFIELD | EF_NODEPTHTEST ) ) )
2007-08-30 18:55:44 +00:00
{ //more expensive culling
if ( ( e < = sv . allocated_client_slots & & sv_cullplayers_trace . value ) | | sv_cullentities_trace . value )
if ( Cull_Traceline ( clent , ent ) )
continue ;
}
2008-11-09 22:29:28 +00:00
//EXT_CSQC
2005-02-28 07:16:19 +00:00
if ( SV_AddCSQCUpdate ( client , ent ) ) //csqc took it.
2005-02-12 18:56:04 +00:00
continue ;
2005-06-14 04:52:10 +00:00
if ( ISQWCLIENT ( client ) )
2008-11-09 22:29:28 +00:00
{
2005-06-14 04:52:10 +00:00
if ( SV_AddNailUpdate ( ent ) )
continue ; // added to the special update list
2008-11-09 22:29:28 +00:00
}
2004-08-23 00:15:46 +00:00
//the entity would mess up the client and possibly disconnect them.
//FIXME: add an option to drop clients... entity fog could be killed in this way.
2008-11-09 22:29:28 +00:00
if ( ! ISDPCLIENT ( client ) )
2005-10-19 21:12:49 +00:00
{
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
if ( e > = client - > max_net_ents )
continue ;
2008-12-02 23:05:14 +00:00
# ifdef PEXT_MODELDBL
2008-11-09 22:29:28 +00:00
if ( ent - > v - > modelindex > = 256 & & ! ( client - > fteprotocolextensions & PEXT_MODELDBL ) )
continue ;
2008-12-02 23:05:14 +00:00
# endif
2005-10-19 21:12:49 +00:00
}
2004-08-23 00:15:46 +00:00
# ifdef DEPTHOPTIMISE
if ( clent )
{
//find distance based upon absolute mins/maxs so bsps are treated fairly.
2008-11-09 22:29:28 +00:00
//org = clentorg + -0.5*(max+min)
2005-03-28 00:11:59 +00:00
VectorAdd ( ent - > v - > absmin , ent - > v - > absmax , org ) ;
VectorMA ( clent - > v - > origin , - 0.5 , org , org ) ;
2008-11-09 22:29:28 +00:00
dist = DotProduct ( org , org ) ; //Length
2004-08-23 00:15:46 +00:00
// add to the packetentities
if ( pack - > num_entities = = pack - > max_entities )
{
float furthestdist = - 1 ;
int best = - 1 ;
for ( i = 0 ; i < pack - > max_entities ; i + + )
if ( furthestdist < distances [ i ] )
{
furthestdist = distances [ i ] ;
best = i ;
}
if ( furthestdist > dist & & best ! = - 1 )
{
state = & pack - > entities [ best ] ;
// Con_Printf("Dropping ent %s\n", sv.model_precache[state->modelindex]);
memmove ( & distances [ best ] , & distances [ best + 1 ] , sizeof ( * distances ) * ( pack - > num_entities - best - 1 ) ) ;
memmove ( state , state + 1 , sizeof ( * state ) * ( pack - > num_entities - best - 1 ) ) ;
best = pack - > num_entities - 1 ;
distances [ best ] = dist ;
state = & pack - > entities [ best ] ;
}
else
continue ; // all full
}
else
{
state = & pack - > entities [ pack - > num_entities ] ;
distances [ pack - > num_entities ] = dist ;
pack - > num_entities + + ;
}
}
else
# endif
{
// add to the packetentities
if ( pack - > num_entities = = pack - > max_entities )
continue ; // all full
else
{
state = & pack - > entities [ pack - > num_entities ] ;
pack - > num_entities + + ;
}
}
2008-11-09 22:29:28 +00:00
//its not a nail or anything, pack it up and ship it on
SV_Snapshot_BuildStateQ1 ( state , ent , client ) ;
}
}
2005-05-15 18:49:04 +00:00
2009-06-21 17:45:33 +00:00
qbyte * SV_Snapshot_SetupPVS ( client_t * client , qbyte * pvs , unsigned int pvsbufsize )
2008-11-09 22:29:28 +00:00
{
vec3_t org ;
int leavepvs = false ;
for ( ; client ; client = client - > controlled )
{
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
if ( client - > viewent )
{
edict_t * e = PROG_TO_EDICT ( svprogfuncs , client - > viewent ) ;
VectorAdd ( e - > v - > origin , client - > edict - > v - > view_ofs , org ) ;
}
else
VectorAdd ( client - > edict - > v - > origin , client - > edict - > v - > view_ofs , org ) ;
2009-11-04 21:16:50 +00:00
sv . world . worldmodel - > funcs . FatPVS ( sv . world . worldmodel , org , pvs , pvsbufsize , leavepvs ) ;
2008-11-09 22:29:28 +00:00
leavepvs = true ;
# ifdef PEXT_VIEW2
if ( client - > edict - > xv - > view2 ) //add a second view point to the pvs
2009-11-04 21:16:50 +00:00
sv . world . worldmodel - > funcs . FatPVS ( sv . world . worldmodel , PROG_TO_EDICT ( svprogfuncs , client - > edict - > xv - > view2 ) - > v - > origin , pvs , pvsbufsize , leavepvs ) ;
2008-11-09 22:29:28 +00:00
# endif
}
2009-06-21 17:45:33 +00:00
return pvs ;
2008-11-09 22:29:28 +00:00
}
void SV_Snapshot_Clear ( packet_entities_t * pack )
{
pack - > num_entities = 0 ;
csqcnuments = 0 ;
numnails = 0 ;
}
2010-01-21 03:28:52 +00:00
2008-11-09 22:29:28 +00:00
/*
= = = = = = = = = = = = =
SVQ3Q1_BuildEntityPacket
2004-08-23 00:15:46 +00:00
2008-11-09 22:29:28 +00:00
Builds a temporary q1 style entity packet for a q3 client
= = = = = = = = = = = = =
*/
void SVQ3Q1_BuildEntityPacket ( client_t * client , packet_entities_t * pack )
{
2009-06-21 17:45:33 +00:00
qbyte pvsbuf [ ( MAX_MAP_LEAFS + 7 ) > > 3 ] ;
2008-11-09 22:29:28 +00:00
qbyte * pvs ;
SV_Snapshot_Clear ( pack ) ;
2009-06-21 17:45:33 +00:00
pvs = SV_Snapshot_SetupPVS ( client , pvsbuf , sizeof ( pvsbuf ) ) ;
2008-11-09 22:29:28 +00:00
SV_Snapshot_BuildQ1 ( client , pack , pvs , client - > edict , false ) ;
}
2006-06-19 21:56:42 +00:00
2008-11-09 22:29:28 +00:00
/*
= = = = = = = = = = = = =
SV_WriteEntitiesToClient
2007-06-20 00:02:54 +00:00
2008-11-09 22:29:28 +00:00
Encodes the current state of the world as
a svc_packetentities messages and possibly
a svc_nails message and
svc_playerinfo messages
= = = = = = = = = = = = =
*/
void SV_WriteEntitiesToClient ( client_t * client , sizebuf_t * msg , qboolean ignorepvs )
{
int e ;
qbyte * pvs ;
packet_entities_t * pack ;
edict_t * clent ;
client_frame_t * frame ;
2009-06-21 17:45:33 +00:00
qbyte pvsbuffer [ ( MAX_MAP_LEAFS + 7 ) / 8 ] ;
2005-05-15 18:49:04 +00:00
2004-08-23 00:15:46 +00:00
2008-11-09 22:29:28 +00:00
// this is the frame we are creating
frame = & client - > frameunion . frames [ client - > netchan . incoming_sequence & UPDATE_MASK ] ;
2009-11-04 21:16:50 +00:00
if ( ! sv . paused )
memset ( frame - > playerpresent , 0 , sizeof ( frame - > playerpresent ) ) ;
2005-07-01 19:23:00 +00:00
2008-11-09 22:29:28 +00:00
// find the client's PVS
if ( ignorepvs )
{
clent = NULL ;
pvs = NULL ;
}
else
{
clent = client - > edict ;
2009-03-03 01:52:30 +00:00
# ifdef HLSERVER
if ( svs . gametype = = GT_HALFLIFE )
2009-06-21 17:45:33 +00:00
pvs = SVHL_Snapshot_SetupPVS ( client , pvsbuffer , sizeof ( pvsbuffer ) ) ;
2009-03-03 01:52:30 +00:00
else
# endif
2009-06-21 17:45:33 +00:00
pvs = SV_Snapshot_SetupPVS ( client , pvsbuffer , sizeof ( pvsbuffer ) ) ;
2008-11-09 22:29:28 +00:00
}
2005-07-01 19:23:00 +00:00
2008-11-09 22:29:28 +00:00
host_client = client ;
pack = & frame - > entities ;
SV_Snapshot_Clear ( pack ) ;
2005-05-17 02:36:54 +00:00
2008-11-09 22:29:28 +00:00
// send over the players in the PVS
2009-03-03 01:52:30 +00:00
if ( svs . gametype ! = GT_HALFLIFE )
2009-11-04 21:16:50 +00:00
SV_WritePlayersToClient ( client , frame , clent , pvs , msg ) ;
2008-11-09 22:29:28 +00:00
// put other visible entities into either a packet_entities or a nails message
2009-11-07 13:29:15 +00:00
# ifdef SERVER_DEMO_PLAYBACK
2008-11-09 22:29:28 +00:00
if ( sv . demostatevalid ) //generate info from demo stats
{
SV_Snapshot_Build_Playback ( client , pack ) ;
}
else
2009-11-07 13:29:15 +00:00
# endif
2008-11-09 22:29:28 +00:00
{
2009-03-03 01:52:30 +00:00
# ifdef HLSERVER
if ( svs . gametype = = GT_HALFLIFE )
SVHL_Snapshot_Build ( client , pack , pvs , clent , ignorepvs ) ;
else
# endif
SV_Snapshot_BuildQ1 ( client , pack , pvs , clent , ignorepvs ) ;
2004-08-23 00:15:46 +00:00
}
2008-11-09 22:29:28 +00:00
2004-08-23 00:15:46 +00:00
# ifdef NQPROT
2005-07-01 19:23:00 +00:00
if ( ISNQCLIENT ( client ) )
2005-06-14 04:52:10 +00:00
{
2005-07-01 19:23:00 +00:00
if ( client - > protocol = = SCP_DARKPLACES6 | | client - > protocol = = SCP_DARKPLACES7 )
{
SVDP_EmitEntitiesUpdate ( client , pack , msg ) ;
SV_EmitCSQCUpdate ( client , msg ) ;
return ;
}
else
{
2008-11-09 22:29:28 +00:00
for ( e = 0 ; e < pack - > num_entities ; e + + )
{
if ( msg - > cursize + 32 > msg - > maxsize )
break ;
SVNQ_EmitEntityState ( msg , & pack - > entities [ e ] ) ;
}
2005-07-01 19:23:00 +00:00
client - > netchan . incoming_sequence + + ;
return ;
}
2005-06-14 04:52:10 +00:00
}
2004-08-23 00:15:46 +00:00
# endif
// encode the packet entities as a delta from the
// last packetentities acknowledged by the client
SV_EmitPacketEntities ( client , pack , msg ) ;
2005-02-28 07:16:19 +00:00
SV_EmitCSQCUpdate ( client , msg ) ;
2004-08-23 00:15:46 +00:00
// now add the specialized nail update
SV_EmitNailUpdate ( msg , ignorepvs ) ;
}
void SV_CleanupEnts ( void )
{
int e ;
edict_t * ent ;
2010-08-14 00:15:07 +00:00
vec3_t org ;
2004-08-23 00:15:46 +00:00
if ( ! needcleanup )
return ;
for ( e = 1 ; e < = needcleanup ; e + + )
{
ent = EDICT_NUM ( svprogfuncs , e ) ;
2005-03-28 00:11:59 +00:00
if ( ( int ) ent - > v - > effects & EF_MUZZLEFLASH )
2010-08-14 00:15:07 +00:00
{
2005-03-28 00:11:59 +00:00
ent - > v - > effects = ( int ) ent - > v - > effects & ~ EF_MUZZLEFLASH ;
2010-08-14 00:15:07 +00:00
MSG_WriteByte ( & sv . multicast , svc_muzzleflash ) ;
MSG_WriteShort ( & sv . multicast , e ) ;
VectorCopy ( ent - > v - > origin , org ) ;
if ( progstype = = PROG_H2 )
org [ 2 ] + = 24 ;
SV_Multicast ( org , MULTICAST_PVS ) ;
}
2004-08-23 00:15:46 +00:00
}
needcleanup = 0 ;
}
2004-11-29 01:21:00 +00:00
# endif
2010-02-06 01:25:04 +00:00