03 Jul 2010

This commit is contained in:
g-cont 2010-07-03 00:00:00 +04:00 committed by Alibek Omarov
parent 303191f982
commit 34ac272674
31 changed files with 165 additions and 212 deletions

View File

@ -1227,12 +1227,12 @@ addEntity:
if( pEntity->pev->groundentity ) if( pEntity->pev->groundentity )
state->groundent = ENTINDEX( pEntity->pev->groundentity ); state->groundent = ENTINDEX( pEntity->pev->groundentity );
else state->groundent = NULLENT_INDEX; else state->groundent = -1;
// translate attached entity // translate attached entity
if( pEntity->pev->aiment ) if( pEntity->pev->aiment )
state->aiment = ENTINDEX( pEntity->pev->aiment ); state->aiment = ENTINDEX( pEntity->pev->aiment );
else state->aiment = NULLENT_INDEX; else state->aiment = -1;
// studio model sequence // studio model sequence
if( pEntity->pev->sequence != -1 ) if( pEntity->pev->sequence != -1 )
@ -1260,7 +1260,7 @@ addEntity:
if( pEntity->pev->aiment ) if( pEntity->pev->aiment )
state->aiment = ENTINDEX( pEntity->pev->aiment ); state->aiment = ENTINDEX( pEntity->pev->aiment );
else state->aiment = NULLENT_INDEX; else state->aiment = -1;
state->viewoffset = pEntity->pev->view_ofs; state->viewoffset = pEntity->pev->view_ofs;
state->viewangles = pEntity->pev->v_angle; state->viewangles = pEntity->pev->v_angle;
@ -1304,7 +1304,7 @@ addEntity:
// translate StartBeamEntity // translate StartBeamEntity
if( pEntity->pev->owner ) if( pEntity->pev->owner )
state->owner = ENTINDEX( pEntity->pev->owner ); state->owner = ENTINDEX( pEntity->pev->owner );
else state->owner = NULLENT_INDEX; else state->owner = -1;
} }
return 1; return 1;

View File

@ -153,7 +153,7 @@ void CDecal :: TriggerDecal ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE
WRITE_SHORT( (int)pev->skin ); WRITE_SHORT( (int)pev->skin );
entityIndex = (short)ENTINDEX(trace.pHit); entityIndex = (short)ENTINDEX(trace.pHit);
WRITE_SHORT( entityIndex ); WRITE_SHORT( entityIndex );
if ( entityIndex != NULLENT_INDEX ) if ( entityIndex > 0 )
WRITE_SHORT( (int)VARS(trace.pHit)->modelindex ); WRITE_SHORT( (int)VARS(trace.pHit)->modelindex );
MESSAGE_END(); MESSAGE_END();
@ -170,7 +170,7 @@ void CDecal :: StaticDecal( void )
UTIL_TraceLine( pev->origin - Vector(5,5,5), pev->origin + Vector(5,5,5), ignore_monsters, ENT(pev), &trace ); UTIL_TraceLine( pev->origin - Vector(5,5,5), pev->origin + Vector(5,5,5), ignore_monsters, ENT(pev), &trace );
entityIndex = (short)ENTINDEX(trace.pHit); entityIndex = (short)ENTINDEX(trace.pHit);
if ( entityIndex != NULLENT_INDEX ) if ( entityIndex > 0 )
modelIndex = (int)VARS(trace.pHit)->modelindex; modelIndex = (int)VARS(trace.pHit)->modelindex;
else else
modelIndex = 0; modelIndex = 0;

View File

@ -418,7 +418,7 @@ void TE_ParseBSPDecal( void )
decalIndex = READ_SHORT(); decalIndex = READ_SHORT();
entityIndex = READ_SHORT(); entityIndex = READ_SHORT();
if( entityIndex != NULLENT_INDEX ) if( entityIndex > 0 )
modelIndex = READ_SHORT(); modelIndex = READ_SHORT();
else modelIndex = 0; else modelIndex = 0;

View File

@ -66,12 +66,13 @@ float EV_HLDM_PlayTextureSound( int idx, TraceResult *ptr, float *vecSrc, float
char *rgsz[4]; char *rgsz[4];
int cnt; int cnt;
float fattn = ATTN_NORM; float fattn = ATTN_NORM;
int entity = NULLENT_INDEX; int entity = 0;
char *pTextureName; char *pTextureName;
char texname[64]; char texname[64];
char szbuffer[64]; char szbuffer[64];
if( ptr->pHit ) entity = ptr->pHit->serialnumber; if( ptr->pHit )
entity = ptr->pHit->serialnumber;
// check if playtexture sounds movevar is set // check if playtexture sounds movevar is set
if( gpGlobals->maxClients != 1 && gpMovevars->footsteps == 0 ) if( gpGlobals->maxClients != 1 && gpMovevars->footsteps == 0 )

View File

@ -63,7 +63,7 @@ void CTempEnts::TE_Prepare( TEMPENTITY *pTemp, model_t modelIndex )
pTemp->skin = 0; pTemp->skin = 0;
pTemp->fadeSpeed = 0.5f; pTemp->fadeSpeed = 0.5f;
pTemp->hitSound = 0; pTemp->hitSound = 0;
pTemp->clientIndex = NULLENT_INDEX; pTemp->clientIndex = 0;
pTemp->bounceFactor = 1; pTemp->bounceFactor = 1;
pTemp->m_flSpriteScale = 1.0f; pTemp->m_flSpriteScale = 1.0f;
} }

View File

@ -66,8 +66,6 @@ void CL_DeltaEntity( sizebuf_t *msg, frame_t *frame, int newnum, entity_state_t
if( ent->free ) CL_InitEdict( ent ); if( ent->free ) CL_InitEdict( ent );
if( ent->free ) CL_InitEdict( ent );
// some data changes will force no lerping // some data changes will force no lerping
if( state->ed_flags & ESF_NODELTA ) ent->pvClientData->serverframe = -99; if( state->ed_flags & ESF_NODELTA ) ent->pvClientData->serverframe = -99;
if( newent ) state->ed_flags |= ESF_LINKEDICT; // need to relink if( newent ) state->ed_flags |= ESF_LINKEDICT; // need to relink
@ -86,6 +84,14 @@ void CL_DeltaEntity( sizebuf_t *msg, frame_t *frame, int newnum, entity_state_t
ent->pvClientData->current = *state; ent->pvClientData->current = *state;
} }
/*
==================
CL_ParsePacketEntities
An svc_packetentities has just been parsed, deal with the
rest of the data stream.
==================
*/
void CL_ParsePacketEntities( sizebuf_t *msg, frame_t *oldframe, frame_t *newframe ) void CL_ParsePacketEntities( sizebuf_t *msg, frame_t *oldframe, frame_t *newframe )
{ {
int newnum; int newnum;

View File

@ -2612,7 +2612,7 @@ bool CL_LoadProgs( const char *name )
CL_InitEdict( &clgame.playermodel ); CL_InitEdict( &clgame.playermodel );
clgame.playermodel.serialnumber = MAX_EDICTS - 1; clgame.playermodel.serialnumber = MAX_EDICTS - 1;
CL_InitTitles( "scripts/titles.txt" ); CL_InitTitles( "titles.txt" );
// initialize game // initialize game
clgame.dllFuncs.pfnInit(); clgame.dllFuncs.pfnInit();

View File

@ -1204,6 +1204,9 @@ void Host_ClientFrame( void )
cl.oldtime = cl.time; cl.oldtime = cl.time;
cl.time += host.frametime; cl.time += host.frametime;
// if in the debugger last frame, don't timeout
if( host.frametime > 5.0 ) cls.netchan.last_received = Sys_DoubleTime();
// fetch results from server // fetch results from server
CL_ReadPackets(); CL_ReadPackets();

View File

@ -37,6 +37,7 @@ CL_CreateCmd
usercmd_t CL_CreateCmd( void ) usercmd_t CL_CreateCmd( void )
{ {
usercmd_t cmd; usercmd_t cmd;
static double extramsec = 0;
int ms; int ms;
// catch windowState for client.dll // catch windowState for client.dll
@ -56,7 +57,9 @@ usercmd_t CL_CreateCmd( void )
} }
// send milliseconds of time to apply the move // send milliseconds of time to apply the move
ms = host.frametime * 1000; extramsec += ( cl.time - cl.oldtime ) * 1000;
ms = extramsec;
extramsec -= ms; // fractional part is left for next frame
if( ms > 250 ) ms = 100; // time was unreasonable if( ms > 250 ) ms = 100; // time was unreasonable
Mem_Set( &cmd, 0, sizeof( cmd )); Mem_Set( &cmd, 0, sizeof( cmd ));
@ -109,7 +112,7 @@ void CL_WritePacket( void )
if( cls.state == ca_connected ) if( cls.state == ca_connected )
{ {
// just update reliable // just update reliable
if( cls.netchan.message.cursize ) if( cls.netchan.message.cursize || host.realtime - cls.netchan.last_sent > 1.0 )
Netchan_Transmit( &cls.netchan, 0, NULL ); Netchan_Transmit( &cls.netchan, 0, NULL );
return; return;
} }
@ -167,8 +170,6 @@ Called every frame to builds and sends a command packet to the server.
*/ */
void CL_SendCmd( void ) void CL_SendCmd( void )
{ {
if( host.type == HOST_DEDICATED ) return;
// we create commands even if a demo is playing, // we create commands even if a demo is playing,
cl.refdef.cmd = &cl.cmds[cls.netchan.outgoing_sequence & CMD_MASK]; cl.refdef.cmd = &cl.cmds[cls.netchan.outgoing_sequence & CMD_MASK];
*cl.refdef.cmd = CL_CreateCmd(); *cl.refdef.cmd = CL_CreateCmd();
@ -279,7 +280,6 @@ static edict_t *PM_GetEntityByIndex( int index )
if( index < 0 || index > clgame.globals->numEntities ) if( index < 0 || index > clgame.globals->numEntities )
{ {
if( index == VIEWENT_INDEX ) return clgame.pmove->player->v.aiment; // current weapon if( index == VIEWENT_INDEX ) return clgame.pmove->player->v.aiment; // current weapon
if( index == NULLENT_INDEX ) return NULL;
MsgDev( D_ERROR, "PM_GetEntityByIndex: invalid entindex %i\n", index ); MsgDev( D_ERROR, "PM_GetEntityByIndex: invalid entindex %i\n", index );
return NULL; return NULL;
} }

View File

@ -432,7 +432,7 @@ void CL_ParseStaticDecal( sizebuf_t *msg )
decalIndex = MSG_ReadWord( msg ); decalIndex = MSG_ReadWord( msg );
entityIndex = MSG_ReadShort( msg ); entityIndex = MSG_ReadShort( msg );
if( entityIndex != NULLENT_INDEX ) if( entityIndex > 0 )
modelIndex = MSG_ReadWord( msg ); modelIndex = MSG_ReadWord( msg );
else modelIndex = 0; else modelIndex = 0;
flags = MSG_ReadByte( msg ); flags = MSG_ReadByte( msg );

View File

@ -565,8 +565,8 @@ void Key_Console( int key )
// backslash text are commands, else chat // backslash text are commands, else chat
if( g_consoleField.buffer[0] == '\\' || g_consoleField.buffer[0] == '/' ) if( g_consoleField.buffer[0] == '\\' || g_consoleField.buffer[0] == '/' )
Cbuf_AddText( g_consoleField.buffer + 1 ); // skip backslash Cbuf_AddText( g_consoleField.buffer + 1 ); // skip backslash
else Cbuf_AddText (g_consoleField.buffer); // valid command else Cbuf_AddText( g_consoleField.buffer ); // valid command
Cbuf_AddText ("\n"); Cbuf_AddText( "\n" );
Msg( ">%s\n", g_consoleField.buffer ); // echo to console Msg( ">%s\n", g_consoleField.buffer ); // echo to console
// copy line to history buffer // copy line to history buffer
@ -602,7 +602,7 @@ void Key_Console( int key )
g_consoleField = historyEditLines[ historyLine % COMMAND_HISTORY ]; g_consoleField = historyEditLines[ historyLine % COMMAND_HISTORY ];
return; return;
} }
if ( (key == K_MWHEELDOWN && keys[K_SHIFT].down) || ( key == K_DOWNARROW ) || ( key == K_KP_DOWNARROW ) || (( com.tolower(key) == 'n' ) && keys[K_CTRL].down )) if( (key == K_MWHEELDOWN && keys[K_SHIFT].down) || ( key == K_DOWNARROW ) || ( key == K_KP_DOWNARROW ) || (( com.tolower(key) == 'n' ) && keys[K_CTRL].down ))
{ {
if (historyLine == nextHistoryLine) return; if (historyLine == nextHistoryLine) return;
historyLine++; historyLine++;
@ -611,7 +611,7 @@ void Key_Console( int key )
} }
// console scrolling // console scrolling
if ( key == K_PGUP ) if( key == K_PGUP )
{ {
Con_PageUp(); Con_PageUp();
return; return;

View File

@ -97,11 +97,10 @@ void Netchan_Setup( netsrc_t sock, netchan_t *chan, netadr_t adr, int qport )
chan->sock = sock; chan->sock = sock;
chan->remote_address = adr; chan->remote_address = adr;
chan->qport = qport; chan->qport = qport;
chan->last_received = host.realtime; chan->last_received = Sys_DoubleTime();
chan->incoming_sequence = 0; chan->incoming_sequence = 0;
chan->outgoing_sequence = 1; chan->outgoing_sequence = 1;
chan->compress = true; chan->compress = true;
chan->rate = 1.0f / 2500;
MSG_Init( &chan->message, chan->message_buf, sizeof( chan->message_buf )); MSG_Init( &chan->message, chan->message_buf, sizeof( chan->message_buf ));
} }
@ -147,38 +146,6 @@ void Netchan_OutOfBandPrint( int net_socket, netadr_t adr, char *format, ... )
Netchan_OutOfBand( net_socket, adr, com.strlen( string ), string ); Netchan_OutOfBand( net_socket, adr, com.strlen( string ), string );
} }
/*
===============
Netchan_CanPacket
Returns true if the bandwidth choke isn't active
================
*/
bool Netchan_CanPacket( netchan_t *chan )
{
// never drop over the loopback
if( NET_IsLocalAddress( chan->remote_address ))
return true;
if( chan->cleartime < host.realtime + MAX_BACKUP * chan->rate )
return true;
return false;
}
/*
===============
Netchan_CanReliable
Returns true if the bandwidth choke isn't
================
*/
bool Netchan_CanReliable( netchan_t *chan )
{
if( chan->reliable_length )
return false; // waiting for ack
return Netchan_CanPacket( chan );
}
bool Netchan_NeedReliable( netchan_t *chan ) bool Netchan_NeedReliable( netchan_t *chan )
{ {
bool send_reliable = false; bool send_reliable = false;
@ -221,7 +188,7 @@ void Netchan_Transmit( netchan_t *chan, int length, byte *data )
byte send_buf[MAX_MSGLEN]; byte send_buf[MAX_MSGLEN];
bool send_reliable; bool send_reliable;
size_t size1, size2; size_t size1, size2;
uint i, w1, w2; uint w1, w2;
// check for message overflow // check for message overflow
if( chan->message.overflowed ) if( chan->message.overflowed )
@ -240,6 +207,7 @@ void Netchan_Transmit( netchan_t *chan, int length, byte *data )
w2 = (chan->incoming_sequence & ~(1<<31)) | (chan->incoming_reliable_sequence<<31); w2 = (chan->incoming_sequence & ~(1<<31)) | (chan->incoming_reliable_sequence<<31);
chan->outgoing_sequence++; chan->outgoing_sequence++;
chan->last_sent = Sys_DoubleTime();
MSG_WriteLong( &send, w1 ); MSG_WriteLong( &send, w1 );
MSG_WriteLong( &send, w2 ); MSG_WriteLong( &send, w2 );
@ -271,18 +239,9 @@ void Netchan_Transmit( netchan_t *chan, int length, byte *data )
if( chan->compress ) Huff_CompressPacket( &send, (chan->sock == NS_CLIENT) ? 10 : 8 ); if( chan->compress ) Huff_CompressPacket( &send, (chan->sock == NS_CLIENT) ? 10 : 8 );
size2 = send.cursize; size2 = send.cursize;
// record the size for rate estimation
i = chan->outgoing_sequence & (MAX_LATENT - 1);
chan->outgoing_size[i] = send.cursize;
chan->outgoing_time[i] = host.realtime;
// send the datagram // send the datagram
NET_SendPacket( chan->sock, send.cursize, send.data, chan->remote_address ); NET_SendPacket( chan->sock, send.cursize, send.data, chan->remote_address );
if( chan->cleartime < host.realtime )
chan->cleartime = host.realtime + send.cursize * chan->rate;
else chan->cleartime += send.cursize * chan->rate;
if( net_showpackets->integer ) if( net_showpackets->integer )
{ {
const char *s1, *s2; const char *s1, *s2;
@ -327,41 +286,6 @@ bool Netchan_Process( netchan_t *chan, sizebuf_t *msg )
sequence &= ~(1<<31); sequence &= ~(1<<31);
sequence_ack &= ~(1<<31); sequence_ack &= ~(1<<31);
#if 0
// get a rate estimation
if( chan->outgoing_sequence - sequence_ack < MAX_LATENT )
{
int i;
double time, rate;
i = sequence_ack & (MAX_LATENT - 1);
time = host.realtime - chan->outgoing_time[i];
time -= 0.1f; // subtract 100 ms
if( time <= 0 )
{
// gotta be a digital link for <100 ms ping
if( chan->rate > 1.0f / 5000 )
chan->rate = 1.0f / 5000;
}
else
{
if( chan->outgoing_size[i] < 512 )
{
// only deal with small messages
rate = chan->outgoing_size[i] / time;
if( rate > 5000 ) rate = 5000;
rate = 1.0f / rate;
if( chan->rate > rate )
chan->rate = rate;
}
}
if( chan->sock == NS_SERVER )
Msg( "Adjust rate: %g\n", chan->rate );
}
#endif
// discard stale or duplicated packets // discard stale or duplicated packets
if( sequence <= chan->incoming_sequence ) if( sequence <= chan->incoming_sequence )
{ {
@ -405,15 +329,10 @@ bool Netchan_Process( netchan_t *chan, sizebuf_t *msg )
MsgDev( D_INFO, "Netchan_Process: %s[%s] : %sreliable\n", s1, s2, recv_reliable ? "" : "un" ); MsgDev( D_INFO, "Netchan_Process: %s[%s] : %sreliable\n", s1, s2, recv_reliable ? "" : "un" );
} }
// the message can now be read from the current message pointer
// update statistics counters
chan->frame_latency = chan->frame_latency * OLD_AVG + (chan->outgoing_sequence-sequence_ack) * (1.0f - OLD_AVG);
chan->frame_rate = chan->frame_rate * OLD_AVG + (host.realtime - chan->last_received) * (1.0f - OLD_AVG);
chan->good_count += 1; chan->good_count += 1;
// the message can now be read from the current message pointer // the message can now be read from the current message pointer
chan->last_received = host.realtime; chan->last_received = Sys_DoubleTime();
return true; return true;
} }

View File

@ -254,9 +254,6 @@ NET
============================================================== ==============================================================
*/ */
#define MAX_LATENT 32
#define OLD_AVG 0.99 // total = oldtotal * OLD_AVG + new * ( 1 - OLD_AVG )
#define MAX_BACKUP 200
typedef struct netchan_s typedef struct netchan_s
{ {
@ -267,11 +264,7 @@ typedef struct netchan_s
bool compress; // enable huffman compression bool compress; // enable huffman compression
float last_received; // for timeouts float last_received; // for timeouts
float last_sent; // for retransmits
// the statistics are cleared at each client begin, because
// the server connecting process gives a bogus picture of the data
float frame_latency; // rolling average
float frame_rate;
int drop_count; // dropped packets, cleared each level int drop_count; // dropped packets, cleared each level
int good_count; // cleared each level int good_count; // cleared each level
@ -279,10 +272,6 @@ typedef struct netchan_s
netadr_t remote_address; netadr_t remote_address;
int qport; // qport value to write when transmitting int qport; // qport value to write when transmitting
// bandwidth estimator
double cleartime; // if host.realtime > nc->cleartime, free to go
double rate; // seconds / byte
// sequencing variables // sequencing variables
int incoming_sequence; int incoming_sequence;
int incoming_acknowledged; int incoming_acknowledged;
@ -301,11 +290,6 @@ typedef struct netchan_s
// message is copied to this buffer when it is first transfered // message is copied to this buffer when it is first transfered
int reliable_length; int reliable_length;
byte reliable_buf[MAX_MSGLEN-16]; // unacked reliable message byte reliable_buf[MAX_MSGLEN-16]; // unacked reliable message
// time and size data to calculate bandwidth
int outgoing_size[MAX_LATENT];
double outgoing_time[MAX_LATENT];
} netchan_t; } netchan_t;
extern netadr_t net_from; extern netadr_t net_from;
@ -329,9 +313,6 @@ void Netchan_OutOfBand( int net_socket, netadr_t adr, int length, byte *data );
void Netchan_OutOfBandPrint( int net_socket, netadr_t adr, char *format, ... ); void Netchan_OutOfBandPrint( int net_socket, netadr_t adr, char *format, ... );
bool Netchan_Process( netchan_t *chan, sizebuf_t *msg ); bool Netchan_Process( netchan_t *chan, sizebuf_t *msg );
bool Netchan_CanPacket( netchan_t *chan );
bool Netchan_CanReliable( netchan_t *chan );
// //
// net_encode.c // net_encode.c
// //

View File

@ -13,6 +13,7 @@
//============================================================================= //=============================================================================
#define MAX_MASTERS 8 // max recipients for heartbeat packets #define MAX_MASTERS 8 // max recipients for heartbeat packets
#define MAX_ENT_LEAFS 48 #define MAX_ENT_LEAFS 48
#define RATE_MESSAGES 10
#define SV_UPDATE_MASK (SV_UPDATE_BACKUP - 1) #define SV_UPDATE_MASK (SV_UPDATE_BACKUP - 1)
extern int SV_UPDATE_BACKUP; extern int SV_UPDATE_BACKUP;
@ -101,13 +102,16 @@ typedef struct sv_client_s
bool sendmovevars; bool sendmovevars;
bool sendinfo; bool sendinfo;
int lastframe; // for delta compression
usercmd_t lastcmd; // for filling in big drops usercmd_t lastcmd; // for filling in big drops
int lastframe;
int modelindex; // custom playermodel index int modelindex; // custom playermodel index
int packet_loss; int packet_loss;
int ping; int ping;
int message_size[RATE_MESSAGES]; // used to rate drop packets
int rate;
int surpressCount; // number of messages rate supressed int surpressCount; // number of messages rate supressed
float addangle; // add angles to client position float addangle; // add angles to client position

View File

@ -1034,7 +1034,7 @@ Dumps the serverinfo info string
*/ */
void SV_ShowServerinfo_f( sv_client_t *cl ) void SV_ShowServerinfo_f( sv_client_t *cl )
{ {
Info_Print( Cvar_Serverinfo()); Info_Print( Cvar_Serverinfo( ));
} }
/* /*
@ -1077,7 +1077,6 @@ void SV_UserinfoChanged( sv_client_t *cl, const char *userinfo )
{ {
edict_t *ent = cl->edict; edict_t *ent = cl->edict;
char *val; char *val;
int i;
if( !userinfo || !userinfo[0] ) return; // ignored if( !userinfo || !userinfo[0] ) return; // ignored
@ -1089,11 +1088,9 @@ void SV_UserinfoChanged( sv_client_t *cl, const char *userinfo )
// rate command // rate command
val = Info_ValueForKey( cl->userinfo, "rate" ); val = Info_ValueForKey( cl->userinfo, "rate" );
if( com.strlen( val )) if( com.strlen( val ))
{ cl->rate = bound ( 100, com.atoi( val ), 15000 );
i = com.atoi( val ); else cl->rate = 5000;
cl->netchan.rate = 1.0f / (bound( 500, i, 10000 ));
}
// msg command // msg command
val = Info_ValueForKey( cl->userinfo, "msg" ); val = Info_ValueForKey( cl->userinfo, "msg" );
if( com.strlen( val )) if( com.strlen( val ))
@ -1101,24 +1098,32 @@ void SV_UserinfoChanged( sv_client_t *cl, const char *userinfo )
if( SV_IsValidEdict( ent )) if( SV_IsValidEdict( ent ))
{ {
const char *model = Info_ValueForKey( cl->userinfo, "model" ); if( sv_maxclients->integer > 1 )
// apply custom playermodel
if( com.strlen( model ) && com.stricmp( model, "player" ))
{ {
string path; const char *model = Info_ValueForKey( cl->userinfo, "model" );
com.snprintf( path, sizeof( path ), "models/player/%s/%s.mdl", model, model ); // apply custom playermodel
cl->modelindex = SV_ModelIndex( path ); if( com.strlen( model ) && com.stricmp( model, "player" ))
CM_RegisterModel( path, cl->modelindex ); // upload model {
const char *path = va( "models/player/%s/%s.mdl", model, model );
CM_RegisterModel( path, SV_ModelIndex( path )); // register model
SV_SetModel( ent, path );
cl->modelindex = ent->v.modelindex;
}
else cl->modelindex = 0;
} }
else cl->modelindex = 0; // reset to default else cl->modelindex = 0;
ent->v.netname = MAKE_STRING( Info_ValueForKey( cl->userinfo, "name" ));
} }
// call prog code to allow overrides // call prog code to allow overrides
svgame.dllFuncs.pfnClientUserInfoChanged( cl->edict, cl->userinfo ); svgame.dllFuncs.pfnClientUserInfoChanged( cl->edict, cl->userinfo );
if( SV_IsValidEdict( ent ))
{
if( sv_maxclients->integer > 1 )
ent->v.netname = MAKE_STRING(Info_ValueForKey( cl->userinfo, "name" ));
else ent->v.netname = 0;
}
if( cl->state >= cs_connected ) cl->sendinfo = true; // needs for update client info if( cl->state >= cs_connected ) cl->sendinfo = true; // needs for update client info
} }
@ -1426,10 +1431,18 @@ static void SV_ReadClientMove( sv_client_t *cl, sizebuf_t *msg )
key = msg->readcount; key = msg->readcount;
checksum1 = MSG_ReadByte( msg ); checksum1 = MSG_ReadByte( msg );
lastframe = MSG_ReadLong( msg ); lastframe = MSG_ReadLong( msg );
cl->packet_loss = SV_CalcPacketLoss( cl );
if( lastframe != cl->lastframe ) if( lastframe != cl->lastframe )
{
cl->lastframe = lastframe; cl->lastframe = lastframe;
if( cl->lastframe > 0 )
{
client_frame_t *frame = &cl->frames[cl->lastframe & SV_UPDATE_MASK];
frame->latency = host.realtime - frame->senttime;
}
}
cl->packet_loss = SV_CalcPacketLoss( cl );
Mem_Set( &nulcmd, 0, sizeof( nulcmd )); Mem_Set( &nulcmd, 0, sizeof( nulcmd ));
MSG_ReadDeltaUsercmd( msg, &nulcmd, &oldest ); MSG_ReadDeltaUsercmd( msg, &nulcmd, &oldest );
@ -1455,6 +1468,7 @@ static void SV_ReadClientMove( sv_client_t *cl, sizebuf_t *msg )
SV_PreRunCmd( cl, &newcmd ); // get random_seed from newcmd SV_PreRunCmd( cl, &newcmd ); // get random_seed from newcmd
net_drop = cl->netchan.dropped; net_drop = cl->netchan.dropped;
cl->netchan.dropped = 0; // reset counter
if( net_drop < 20 ) if( net_drop < 20 )
{ {
@ -1468,7 +1482,6 @@ static void SV_ReadClientMove( sv_client_t *cl, sizebuf_t *msg )
if( net_drop > 0 ) SV_RunCmd( cl, &oldcmd ); if( net_drop > 0 ) SV_RunCmd( cl, &oldcmd );
} }
cl->netchan.dropped = 0;
SV_RunCmd( cl, &newcmd ); SV_RunCmd( cl, &newcmd );
SV_PostRunCmd( cl ); SV_PostRunCmd( cl );
} }
@ -1486,14 +1499,9 @@ Parse a client packet
*/ */
void SV_ExecuteClientMessage( sv_client_t *cl, sizebuf_t *msg ) void SV_ExecuteClientMessage( sv_client_t *cl, sizebuf_t *msg )
{ {
int c, stringCmdCount = 0; int c, stringCmdCount = 0;
bool move_issued = false; bool move_issued = false;
client_frame_t *frame; char *s;
char *s;
// calc ping time
frame = &cl->frames[cl->netchan.incoming_acknowledged & SV_UPDATE_MASK];
frame->latency = host.realtime - frame->senttime;
// make sure the reply sequence number matches the incoming sequence number // make sure the reply sequence number matches the incoming sequence number
if( cl->netchan.incoming_sequence >= cl->netchan.outgoing_sequence ) if( cl->netchan.incoming_sequence >= cl->netchan.outgoing_sequence )

View File

@ -462,9 +462,40 @@ bool SV_SendClientDatagram( sv_client_t *cl )
// send the datagram // send the datagram
Netchan_Transmit( &cl->netchan, msg.cursize, msg.data ); Netchan_Transmit( &cl->netchan, msg.cursize, msg.data );
// record the size for rate estimation
cl->message_size[sv.framenum % RATE_MESSAGES] = msg.cursize;
return true; return true;
} }
/*
=======================
SV_RateDrop
Returns true if the client is over its current
bandwidth estimation and should not be sent another packet
=======================
*/
bool SV_RateDrop( sv_client_t *cl )
{
int i, total = 0;
// never drop over the loopback
if( NET_IsLocalAddress( cl->netchan.remote_address ))
return false;
for( i = 0; i < RATE_MESSAGES; i++ )
total += cl->message_size[i];
if( total > cl->rate )
{
cl->surpressCount++;
cl->message_size[sv.framenum % RATE_MESSAGES] = 0;
return true;
}
return false;
}
/* /*
======================= =======================
SV_SendClientMessages SV_SendClientMessages
@ -518,26 +549,20 @@ void SV_SendClientMessages( void )
SV_BroadcastPrintf( PRINT_HIGH, "%s overflowed\n", cl->name ); SV_BroadcastPrintf( PRINT_HIGH, "%s overflowed\n", cl->name );
SV_DropClient( cl ); SV_DropClient( cl );
cl->send_message = true; cl->send_message = true;
cl->netchan.cleartime = 0; // don't choke this message
} }
// only send messages if the client has sent one // only send messages if the client has sent one
if( !cl->send_message ) continue; if( !cl->send_message ) continue;
/*
if( !sv.paused && !Netchan_CanPacket( &cl->netchan ))
{
cl->surpressCount++;
continue; // bandwidth choke
}
*/
if( cl->state == cs_spawned ) if( cl->state == cs_spawned )
{ {
// don't overrun bandwidth
if( SV_RateDrop( cl )) continue;
SV_SendClientDatagram( cl ); SV_SendClientDatagram( cl );
} }
else else
{ {
if( cl->netchan.message.cursize ) if( cl->netchan.message.cursize || host.realtime - cl->netchan.last_sent > 1.0 )
Netchan_Transmit( &cl->netchan, 0, NULL ); Netchan_Transmit( &cl->netchan, 0, NULL );
} }
// yes, message really sended // yes, message really sended

View File

@ -170,7 +170,7 @@ void SV_CreateDecal( const float *origin, int decalIndex, int entityIndex, int m
MSG_WritePos( &sv.multicast, origin ); MSG_WritePos( &sv.multicast, origin );
MSG_WriteWord( &sv.multicast, decalIndex ); MSG_WriteWord( &sv.multicast, decalIndex );
MSG_WriteShort( &sv.multicast, entityIndex ); MSG_WriteShort( &sv.multicast, entityIndex );
if( entityIndex != NULLENT_INDEX ) if( entityIndex > 0 )
MSG_WriteWord( &sv.multicast, modelIndex ); MSG_WriteWord( &sv.multicast, modelIndex );
MSG_WriteByte( &sv.multicast, flags ); MSG_WriteByte( &sv.multicast, flags );
MSG_Send( MSG_INIT, NULL, NULL ); MSG_Send( MSG_INIT, NULL, NULL );
@ -2103,7 +2103,7 @@ pfnWriteEntity
*/ */
void pfnWriteEntity( int iValue ) void pfnWriteEntity( int iValue )
{ {
if( iValue <= NULLENT_INDEX || iValue >= svgame.globals->numEntities ) if( iValue < 0 || iValue >= svgame.globals->numEntities )
Host_Error( "MSG_WriteEntity: invalid entnumber %i\n", iValue ); Host_Error( "MSG_WriteEntity: invalid entnumber %i\n", iValue );
MSG_WriteShort( &sv.multicast, iValue ); MSG_WriteShort( &sv.multicast, iValue );
svgame.msg_realsize += 2; svgame.msg_realsize += 2;
@ -2228,7 +2228,7 @@ pfnIndexOfEdict
int pfnIndexOfEdict( const edict_t *pEdict ) int pfnIndexOfEdict( const edict_t *pEdict )
{ {
if( !SV_IsValidEdict( pEdict )) if( !SV_IsValidEdict( pEdict ))
return NULLENT_INDEX; return 0;
return NUM_FOR_EDICT( pEdict ); return NUM_FOR_EDICT( pEdict );
} }

View File

@ -413,7 +413,6 @@ static edict_t *PM_GetEntityByIndex( int index )
if( index < 0 || index > svgame.globals->numEntities ) if( index < 0 || index > svgame.globals->numEntities )
{ {
if( index == VIEWENT_INDEX ) return svgame.pmove->player->v.aiment; // current weapon if( index == VIEWENT_INDEX ) return svgame.pmove->player->v.aiment; // current weapon
if( index == NULLENT_INDEX ) return NULL;
MsgDev( D_ERROR, "PM_GetEntityByIndex: invalid entindex %i\n", index ); MsgDev( D_ERROR, "PM_GetEntityByIndex: invalid entindex %i\n", index );
return NULL; return NULL;
} }

View File

@ -792,6 +792,10 @@ static edict_t *SV_PushMove( edict_t *pusher, float movetime )
continue; continue;
} }
// remove the onground flag for non-players
if( check->v.movetype != MOVETYPE_WALK )
check->v.flags &= ~FL_ONGROUND;
VectorCopy( check->v.origin, entorg ); VectorCopy( check->v.origin, entorg );
VectorCopy( check->v.origin, check->pvServerData->moved_origin ); VectorCopy( check->v.origin, check->pvServerData->moved_origin );
moved_edict[num_moved] = check; moved_edict[num_moved] = check;
@ -828,13 +832,8 @@ static edict_t *SV_PushMove( edict_t *pusher, float movetime )
} }
else else
{ {
// if leaving it where it was, allow it to drop to the floor again if( check->v.movetype == MOVETYPE_WALK && lmove[2] < 0.0f )
// (useful for plats that move downward)
if( check->v.flags & ( FL_CLIENT|FL_FAKECLIENT ))
check->v.groundentity = NULL; check->v.groundentity = NULL;
else if( check->v.flags & FL_MONSTER )
check->v.flags &= ~FL_ONGROUND;
num_moved--; num_moved--;
continue; continue;
} }
@ -929,7 +928,7 @@ static edict_t *SV_PushRotate( edict_t *pusher, float movetime )
pusher->v.solid = oldsolid; pusher->v.solid = oldsolid;
#endif #endif
// if it is still inside the pusher, block // if it is still inside the pusher, block
if( block || SV_TestEntityPosition( check )) if( block )//|| SV_TestEntityPosition( check ))
{ {
if( !SV_CanBlock( check )) if( !SV_CanBlock( check ))
continue; continue;
@ -1561,13 +1560,13 @@ void SV_Physics_Step( edict_t *ent )
if( ent->v.waterlevel > 1 ) if( ent->v.waterlevel > 1 )
{ {
VectorScale( ent->v.velocity, 0.9f, ent->v.velocity ); VectorScale( ent->v.velocity, 0.9f, ent->v.velocity );
ent->v.velocity[2] += ( ent->v.skin * sv.frametime ); ent->v.velocity[2] += (ent->v.skin * svgame.globals->frametime);
} }
else if( ent->v.waterlevel == 1 ) else if( ent->v.waterlevel == 1 )
{ {
if( ent->v.velocity[2] > 0.0f ) if( ent->v.velocity[2] > 0.0f )
ent->v.velocity[2] = sv.frametime; ent->v.velocity[2] = svgame.globals->frametime;
ent->v.velocity[2] -= ( ent->v.skin * sv.frametime ); ent->v.velocity[2] -= (ent->v.skin * svgame.globals->frametime);
} }
} }
} }

View File

@ -16,7 +16,7 @@ half-life implementation of saverestore system
*/ */
#define SAVEFILE_HEADER (('V'<<24)+('L'<<16)+('A'<<8)+'V') // little-endian "VALV" #define SAVEFILE_HEADER (('V'<<24)+('L'<<16)+('A'<<8)+'V') // little-endian "VALV"
#define SAVEGAME_HEADER (('V'<<24)+('A'<<16)+('S'<<8)+'J') // little-endian "JSAV" #define SAVEGAME_HEADER (('V'<<24)+('A'<<16)+('S'<<8)+'J') // little-endian "JSAV"
#define SAVEGAME_VERSION 0x0071 // Version 0.71 #define SAVEGAME_VERSION 0x0065 // Version 0.65
#define SAVE_AGED_COUNT 1 #define SAVE_AGED_COUNT 1
@ -413,7 +413,7 @@ void ReapplyDecal( SAVERESTOREDATA *pSaveData, decallist_t *entry, bool adjacent
if( dot >= 0.95f ) if( dot >= 0.95f )
{ {
entityIndex = pfnIndexOfEdict( tr.pHit ); entityIndex = pfnIndexOfEdict( tr.pHit );
if( entityIndex != NULLENT_INDEX ) if( entityIndex > 0 )
modelIndex = tr.pHit->v.modelindex; modelIndex = tr.pHit->v.modelindex;
// FIXME: probably some rotating or moving objects can't receive decal properly // FIXME: probably some rotating or moving objects can't receive decal properly
@ -1810,6 +1810,12 @@ bool SV_GetComment( const char *savename, char *comment )
FS_Read( f, &tag, sizeof( int )); FS_Read( f, &tag, sizeof( int ));
if( tag == 0x0071 )
{
com.strncpy( comment, "Gold Source <unsupported>", MAX_STRING );
FS_Close( f );
return 0;
}
if( tag < SAVEGAME_VERSION ) if( tag < SAVEGAME_VERSION )
{ {
com.strncpy( comment, "<old version>", MAX_STRING ); com.strncpy( comment, "<old version>", MAX_STRING );

View File

@ -77,7 +77,7 @@ static void UI_GameOptions_UpdateConfig( void )
Cvar_SetValue( "hand", uiGameOptions.hand.enabled ); Cvar_SetValue( "hand", uiGameOptions.hand.enabled );
Cvar_SetValue( "allow_download", uiGameOptions.allowDownload.enabled ); Cvar_SetValue( "allow_download", uiGameOptions.allowDownload.enabled );
Cvar_SetValue( "host_maxfps", uiGameOptions.maxFPS.curValue ); Cvar_SetValue( "fps_max", uiGameOptions.maxFPS.curValue );
Cvar_SetValue( "cl_run", uiGameOptions.alwaysRun.enabled ); Cvar_SetValue( "cl_run", uiGameOptions.alwaysRun.enabled );
} }
@ -90,7 +90,7 @@ static void UI_GameOptions_DiscardChanges( void )
{ {
Cvar_SetValue( "hand", uiGameInitial.hand ); Cvar_SetValue( "hand", uiGameInitial.hand );
Cvar_SetValue( "allow_download", uiGameInitial.allowDownload ); Cvar_SetValue( "allow_download", uiGameInitial.allowDownload );
Cvar_SetValue( "host_maxfps", uiGameInitial.maxFPS ); Cvar_SetValue( "fps_max", uiGameInitial.maxFPS );
Cvar_SetValue( "cl_run", uiGameInitial.alwaysRun ); Cvar_SetValue( "cl_run", uiGameInitial.alwaysRun );
} }
@ -113,7 +113,7 @@ UI_GameOptions_GetConfig
*/ */
static void UI_GameOptions_GetConfig( void ) static void UI_GameOptions_GetConfig( void )
{ {
uiGameInitial.maxFPS = uiGameOptions.maxFPS.curValue = Cvar_VariableValue( "host_maxfps" ); uiGameInitial.maxFPS = uiGameOptions.maxFPS.curValue = Cvar_VariableValue( "fps_max" );
if( Cvar_VariableInteger( "hand" )) if( Cvar_VariableInteger( "hand" ))
uiGameInitial.hand = uiGameOptions.hand.enabled = 1; uiGameInitial.hand = uiGameOptions.hand.enabled = 1;

View File

@ -32,18 +32,18 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define UI_CURSOR_DISABLED "gfx/shell/denied" #define UI_CURSOR_DISABLED "gfx/shell/denied"
#define UI_CURSOR_TYPING "gfx/shell/typing" #define UI_CURSOR_TYPING "gfx/shell/typing"
#define UI_SLIDER_MAIN "gfx/shell/slider" #define UI_SLIDER_MAIN "gfx/shell/slider"
#define UI_LEFTARROW "gfx/shell/larrow_d" #define UI_LEFTARROW "gfx/shell/larrowdefault"
#define UI_LEFTARROWFOCUS "gfx/shell/larrow_f" #define UI_LEFTARROWFOCUS "gfx/shell/larrowflyover"
#define UI_LEFTARROWPRESSED "gfx/shell/larrow_n" #define UI_LEFTARROWPRESSED "gfx/shell/larrowpressed"
#define UI_RIGHTARROW "gfx/shell/rarrow_d" #define UI_RIGHTARROW "gfx/shell/rarrowdefault"
#define UI_RIGHTARROWFOCUS "gfx/shell/rarrow_f" #define UI_RIGHTARROWFOCUS "gfx/shell/rarrowflyover"
#define UI_RIGHTARROWPRESSED "gfx/shell/rarrow_n" #define UI_RIGHTARROWPRESSED "gfx/shell/rarrowpressed"
#define UI_UPARROW "gfx/shell/uparrow_d" #define UI_UPARROW "gfx/shell/uparrowd"
#define UI_UPARROWFOCUS "gfx/shell/uparrow_f" #define UI_UPARROWFOCUS "gfx/shell/uparrowf"
#define UI_UPARROWPRESSED "gfx/shell/uparrow_n" #define UI_UPARROWPRESSED "gfx/shell/uparrowp"
#define UI_DOWNARROW "gfx/shell/dnarrow_d" #define UI_DOWNARROW "gfx/shell/dnarrowd"
#define UI_DOWNARROWFOCUS "gfx/shell/dnarrow_f" #define UI_DOWNARROWFOCUS "gfx/shell/dnarrowf"
#define UI_DOWNARROWPRESSED "gfx/shell/dnarrow_n" #define UI_DOWNARROWPRESSED "gfx/shell/dnarrowp"
#define UI_CHECKBOX_EMPTY "gfx/shell/cb_empty" #define UI_CHECKBOX_EMPTY "gfx/shell/cb_empty"
#define UI_CHECKBOX_GRAYED "gfx/shell/cb_disabled" #define UI_CHECKBOX_GRAYED "gfx/shell/cb_disabled"
#define UI_CHECKBOX_FOCUS "gfx/shell/cb_over" #define UI_CHECKBOX_FOCUS "gfx/shell/cb_over"

View File

@ -1217,11 +1217,11 @@ void UI_ApplyCustomColors( void )
script_t *script = NULL; script_t *script = NULL;
token_t token; token_t token;
script = Com_OpenScript( "scripts/colors.lst", NULL, 0 ); script = Com_OpenScript( "gfx/shell/colors.lst", NULL, 0 );
if( !script ) if( !script )
{ {
// not error, not warning, just notify // not error, not warning, just notify
MsgDev( D_NOTE, "UI_SetColors: scripts/colors.lst not found\n" ); MsgDev( D_NOTE, "UI_SetColors: colors.lst not found\n" );
return; return;
} }

View File

@ -1,3 +1,4 @@
//======================================================================= //=======================================================================
// Copyright XashXT Group 2007 © // Copyright XashXT Group 2007 ©
// utils.c - shared launcher utils // utils.c - shared launcher utils

View File

@ -122,7 +122,7 @@ chull_t *CM_HullForBsp( edict_t *ent, const vec3_t mins, const vec3_t maxs, floa
} }
else if( size[0] <= 36 ) else if( size[0] <= 36 )
{ {
if( size[2] < 36 ) if( size[2] <= 36 )
{ {
// head hull (ducked) // head hull (ducked)
hull = &model->hulls[3]; hull = &model->hulls[3];

View File

@ -94,7 +94,7 @@ public:
int entityIndex, modelIndex; int entityIndex, modelIndex;
UTIL_TraceLine( pev->origin - Vector(5,5,5), pev->origin + Vector(5,5,5), ignore_monsters, ENT(pev), &trace ); UTIL_TraceLine( pev->origin - Vector(5,5,5), pev->origin + Vector(5,5,5), ignore_monsters, ENT(pev), &trace );
entityIndex = (short)ENTINDEX(trace.pHit); entityIndex = (short)ENTINDEX(trace.pHit);
if ( entityIndex != NULLENT_INDEX ) if ( entityIndex > 0 )
modelIndex = (int)VARS(trace.pHit)->modelindex; modelIndex = (int)VARS(trace.pHit)->modelindex;
else modelIndex = 0; else modelIndex = 0;
g_engfuncs.pfnStaticDecal( pev->origin, (int)pev->skin, entityIndex, modelIndex ); g_engfuncs.pfnStaticDecal( pev->origin, (int)pev->skin, entityIndex, modelIndex );

View File

@ -1552,12 +1552,12 @@ addEntity:
if( pEntity->pev->groundentity ) if( pEntity->pev->groundentity )
state->groundent = ENTINDEX( pEntity->pev->groundentity ); state->groundent = ENTINDEX( pEntity->pev->groundentity );
else state->groundent = NULLENT_INDEX; else state->groundent = -1;
// translate attached entity // translate attached entity
if( pEntity->pev->aiment ) if( pEntity->pev->aiment )
state->aiment = ENTINDEX( pEntity->pev->aiment ); state->aiment = ENTINDEX( pEntity->pev->aiment );
else state->aiment = NULLENT_INDEX; else state->aiment = -1;
// studio model sequence // studio model sequence
if( pEntity->pev->sequence != -1 ) if( pEntity->pev->sequence != -1 )
@ -1585,7 +1585,7 @@ addEntity:
if( pEntity->pev->aiment ) if( pEntity->pev->aiment )
state->aiment = ENTINDEX( pEntity->pev->aiment ); state->aiment = ENTINDEX( pEntity->pev->aiment );
else state->aiment = NULLENT_INDEX; else state->aiment = -1;
state->viewoffset = pEntity->pev->view_ofs; state->viewoffset = pEntity->pev->view_ofs;
state->viewangles = pEntity->pev->v_angle; state->viewangles = pEntity->pev->v_angle;
@ -1629,7 +1629,7 @@ addEntity:
// translate StartBeamEntity // translate StartBeamEntity
if( pEntity->pev->owner ) if( pEntity->pev->owner )
state->owner = ENTINDEX( pEntity->pev->owner ); state->owner = ENTINDEX( pEntity->pev->owner );
else state->owner = NULLENT_INDEX; else state->owner = -1;
} }
return 1; return 1;

View File

@ -1353,12 +1353,12 @@ addEntity:
if( pEntity->pev->groundentity ) if( pEntity->pev->groundentity )
state->groundent = ENTINDEX( pEntity->pev->groundentity ); state->groundent = ENTINDEX( pEntity->pev->groundentity );
else state->groundent = NULLENT_INDEX; else state->groundent = -1;
// translate attached entity // translate attached entity
if( pEntity->pev->aiment ) if( pEntity->pev->aiment )
state->aiment = ENTINDEX( pEntity->pev->aiment ); state->aiment = ENTINDEX( pEntity->pev->aiment );
else state->aiment = NULLENT_INDEX; else state->aiment = -1;
// studio model sequence // studio model sequence
if( pEntity->pev->sequence != -1 ) if( pEntity->pev->sequence != -1 )
@ -1386,7 +1386,7 @@ addEntity:
if( pEntity->pev->aiment ) if( pEntity->pev->aiment )
state->aiment = ENTINDEX( pEntity->pev->aiment ); state->aiment = ENTINDEX( pEntity->pev->aiment );
else state->aiment = NULLENT_INDEX; else state->aiment = -1;
state->viewoffset = pEntity->pev->view_ofs; state->viewoffset = pEntity->pev->view_ofs;
state->viewangles = pEntity->pev->v_angle; state->viewangles = pEntity->pev->v_angle;
@ -1430,7 +1430,7 @@ addEntity:
// translate StartBeamEntity // translate StartBeamEntity
if( pEntity->pev->owner ) if( pEntity->pev->owner )
state->owner = ENTINDEX( pEntity->pev->owner ); state->owner = ENTINDEX( pEntity->pev->owner );
else state->owner = NULLENT_INDEX; else state->owner = -1;
} }
return 1; return 1;

View File

@ -154,7 +154,7 @@ void CDecal :: TriggerDecal ( CBaseEntity *pActivator, CBaseEntity *pCaller, USE
WRITE_SHORT( (int)pev->skin ); WRITE_SHORT( (int)pev->skin );
entityIndex = (short)ENTINDEX(trace.pHit); entityIndex = (short)ENTINDEX(trace.pHit);
WRITE_SHORT( entityIndex ); WRITE_SHORT( entityIndex );
if( entityIndex != NULLENT_INDEX ) if( entityIndex > 0 )
WRITE_SHORT( (int)VARS(trace.pHit)->modelindex ); WRITE_SHORT( (int)VARS(trace.pHit)->modelindex );
MESSAGE_END(); MESSAGE_END();
@ -171,7 +171,7 @@ void CDecal :: StaticDecal( void )
UTIL_TraceLine( pev->origin - Vector(5,5,5), pev->origin + Vector(5,5,5), ignore_monsters, ENT(pev), &trace ); UTIL_TraceLine( pev->origin - Vector(5,5,5), pev->origin + Vector(5,5,5), ignore_monsters, ENT(pev), &trace );
entityIndex = (short)ENTINDEX(trace.pHit); entityIndex = (short)ENTINDEX(trace.pHit);
if ( entityIndex != NULLENT_INDEX ) if ( entityIndex > 0 )
modelIndex = (int)VARS(trace.pHit)->modelindex; modelIndex = (int)VARS(trace.pHit)->modelindex;
else else
modelIndex = 0; modelIndex = 0;

View File

@ -34,4 +34,4 @@ Xash 0.72 Beta 5.07.10
10.create animated decals OK 10.create animated decals OK
11.fix external shader lighting bug OK 11.fix external shader lighting bug OK
12.revision resources 12.revision resources
13.implement the sv_lightpoint 13.implement the sv_lightpoint OK

View File

@ -2540,6 +2540,7 @@ bool R_AddTeEntToScene( TEMPENTITY *pTempEntity, int ed_type, shader_t customSha
if( pTempEntity->clientIndex != 0 ) if( pTempEntity->clientIndex != 0 )
refent->index = pTempEntity->clientIndex; refent->index = pTempEntity->clientIndex;
else refent->index = NULLENT_INDEX; else refent->index = NULLENT_INDEX;
refent->ent_type = ed_type; refent->ent_type = ed_type;
refent->rendermode = pTempEntity->renderMode; refent->rendermode = pTempEntity->renderMode;
refent->body = pTempEntity->body; refent->body = pTempEntity->body;