21 May 2008

This commit is contained in:
g-cont 2008-05-21 00:00:00 +04:00 committed by Alibek Omarov
parent 1fe636b994
commit e1ff227045
28 changed files with 983 additions and 955 deletions

View File

@ -536,13 +536,13 @@ bool CG_GetInteger( const char *name, int *value )
CG_ParseInventory
================
*/
void CG_ParseInventory (void)
void CG_ParseInventory( sizebuf_t *msg )
{
int i;
for (i = 0; i < MAX_ITEMS; i++)
{
cl.inventory[i] = MSG_ReadShort (&net_message);
cl.inventory[i] = MSG_ReadShort( msg );
}
}

328
engine/client/cl_demo.c Normal file
View File

@ -0,0 +1,328 @@
//=======================================================================
// Copyright XashXT Group 2007 ©
// cl_demo.c - demo record & playback
//=======================================================================
#include "client.h"
/*
====================
CL_WriteDemoMessage
Dumps the current net message, prefixed by the length
====================
*/
void CL_WriteDemoMessage( void )
{
int len, swlen;
if( !cls.demofile ) return;
if( cl_paused->value ) return;
// the first eight bytes are just packet sequencing stuff
len = net_message.cursize - 8;
swlen = LittleLong(len);
FS_Write( cls.demofile, &swlen, 4);
FS_Write( cls.demofile, net_message.data + 8, len );
}
void CL_WriteDemoHeader( const char *name )
{
char buf_data[MAX_MSGLEN];
entity_state_t *ent, nullstate;
int i, len;
sizebuf_t buf;
MsgDev(D_INFO, "recording to %s.\n", name );
cls.demofile = FS_Open( name, "wb" );
if( !cls.demofile )
{
MsgDev(D_ERROR, "CL_Record: unable to create %s\n", name );
return;
}
cls.demorecording = true;
// don't start saving messages until a non-delta compressed message is received
cls.demowaiting = true;
// write out messages to hold the startup information
SZ_Init( &buf, buf_data, sizeof(buf_data));
// send the serverdata
MSG_WriteByte( &buf, svc_serverdata );
MSG_WriteLong( &buf, PROTOCOL_VERSION );
MSG_WriteLong( &buf, 0x10000 + cl.servercount );
MSG_WriteShort( &buf, cl.playernum );
MSG_WriteString( &buf, cl.configstrings[CS_NAME] );
// configstrings
for( i = 0; i < MAX_CONFIGSTRINGS; i++ )
{
if( cl.configstrings[i][0] )
{
if( buf.cursize + com.strlen(cl.configstrings[i]) + 32 > buf.maxsize )
{
// write it out
len = LittleLong (buf.cursize);
FS_Write( cls.demofile, &len, 4 );
FS_Write( cls.demofile, buf.data, buf.cursize );
buf.cursize = 0;
}
MSG_WriteByte( &buf, svc_configstring );
MSG_WriteShort( &buf, i);
MSG_WriteString( &buf, cl.configstrings[i] );
}
}
// baselines
memset(&nullstate, 0, sizeof(nullstate));
for( i = 0; i < MAX_EDICTS; i++ )
{
ent = &cl_entities[i].baseline;
if(!ent->modelindex) continue;
if( buf.cursize + 64 > buf.maxsize )
{
// write it out
len = LittleLong (buf.cursize);
FS_Write( cls.demofile, &len, 4 );
FS_Write( cls.demofile, buf.data, buf.cursize );
buf.cursize = 0;
}
MSG_WriteByte (&buf, svc_spawnbaseline);
MSG_WriteDeltaEntity (&nullstate, &cl_entities[i].baseline, &buf, true, true);
}
MSG_WriteByte( &buf, svc_stufftext );
MSG_WriteString( &buf, "precache\n");
// write it to the demo file
len = LittleLong( buf.cursize );
FS_Write( cls.demofile, &len, 4 );
FS_Write( cls.demofile, buf.data, buf.cursize );
}
/*
=======================================================================
CLIENT SIDE DEMO PLAYBACK
=======================================================================
*/
/*
==================
CL_NextDemo
Called when a demo or cinematic finishes
If the "nextdemo" cvar is set, that command will be issued
==================
*/
void CL_NextDemo( void )
{
string v;
com.strncpy( v, Cvar_VariableString( "playdemo" ), sizeof(v));
MsgDev(D_INFO, "CL_NextDemo: %s\n", v );
if(!v[0]) return;
Cvar_Set( "nextdemo","" );
Cbuf_AddText(va("%s\n", v));
Cbuf_Execute();
}
/*
=================
CL_DemoCompleted
=================
*/
void CL_DemoCompleted( void )
{
CL_StopPlayback();
CL_NextDemo();
}
/*
=================
CL_ReadDemoMessage
reads demo data and write it to client
=================
*/
void CL_ReadDemoMessage( void )
{
sizebuf_t buf;
char bufData[MAX_MSGLEN];
int r;
if( !cls.demofile )
{
CL_DemoCompleted();
return;
}
if( cl_paused->value ) return;
// init the message
SZ_Init( &buf, bufData, sizeof( bufData ));
// get the length
r = FS_Read( cls.demofile, &buf.cursize, 4 );
if( r != 4 )
{
CL_DemoCompleted();
return;
}
buf.cursize = LittleLong( buf.cursize );
if( buf.cursize == -1 )
{
CL_DemoCompleted();
return;
}
if( buf.cursize > buf.maxsize )
{
Host_Error( "CL_ReadDemoMessage: demoMsglen > MAX_MSGLEN\n" );
}
r = FS_Read( cls.demofile, buf.data, buf.cursize );
if( r != buf.cursize )
{
MsgDev( D_ERROR, "CL_ReadDemoMessage: demo file was truncated\n");
CL_DemoCompleted();
return;
}
cl.time = cls.realtime;
buf.readcount = 0;
CL_ParseServerMessage( &buf );
}
/*
==============
CL_StopPlayback
Called when a demo file runs out, or the user starts a game
==============
*/
void CL_StopPlayback( void )
{
if( !cls.demoplayback ) return;
// release demofile
FS_Close( cls.demofile );
cls.demoplayback = false;
cls.demofile = NULL;
// let game known about movie state
cls.state = ca_disconnected;
}
void CL_StopRecord( void )
{
int len = -1;
if (!cls.demorecording) return;
// finish up
FS_Write( cls.demofile, &len, 4 );
FS_Close( cls.demofile );
cls.demofile = NULL;
cls.demorecording = false;
}
/*
====================
CL_Record_f
record <demoname>
Begins recording a demo from the current position
====================
*/
void CL_Record_f( void )
{
string name;
if( Cmd_Argc() != 2 )
{
Msg ("record <demoname>\n");
return;
}
if( cls.demorecording )
{
Msg("CL_Record: already recording.\n");
return;
}
if( cls.state != ca_active )
{
Msg ("You must be in a level to record.\n");
return;
}
// open the demo file
com.sprintf (name, "demos/%s.dem", Cmd_Argv(1));
CL_WriteDemoHeader( name );
}
/*
====================
CL_PlayDemo_f
playdemo <demoname>
====================
*/
void CL_PlayDemo_f( void )
{
string filename;
if(Cmd_Argc() != 2)
{
Msg( "playdemo <demoname>\n" );
return;
}
// shutdown any game or cinematic server
CL_Disconnect();
Cbuf_ExecuteText(EXEC_APPEND, "killserver\n");
com.snprintf( filename, MAX_STRING, "demos/%s.dem", Cmd_Argv(1));
if(!FS_FileExists( filename ))
{
Msg("Can't loading %s\n", filename );
return;
}
cls.demofile = FS_Open( filename, "rb" );
com.strncpy( cls.demoname, Cmd_Argv(1), sizeof(cls.demoname));
Con_Close();
cls.state = ca_connected;
cls.demoplayback = true;
com.strncpy( cls.servername, Cmd_Argv(1), sizeof(cls.servername));
// begin a playback demo
}
/*
====================
CL_Stop_f
stop recording a demo
====================
*/
void CL_Stop_f( void )
{
// stop all
CL_StopRecord();
CL_StopPlayback();
}

View File

@ -51,26 +51,26 @@ Returns the entity number and the header bits
=================
*/
int bitcounts[32]; /// just for protocol profiling
int CL_ParseEntityBits (uint *bits)
int CL_ParseEntityBits( sizebuf_t *msg, uint *bits )
{
unsigned b, total;
int i;
int number;
total = MSG_ReadByte (&net_message);
total = MSG_ReadByte (msg);
if (total & U_MOREBITS1)
{
b = MSG_ReadByte (&net_message);
b = MSG_ReadByte (msg);
total |= b<<8;
}
if (total & U_MOREBITS2)
{
b = MSG_ReadByte (&net_message);
b = MSG_ReadByte (msg);
total |= b<<16;
}
if (total & U_MOREBITS3)
{
b = MSG_ReadByte (&net_message);
b = MSG_ReadByte (msg);
total |= b<<24;
}
@ -78,8 +78,8 @@ int CL_ParseEntityBits (uint *bits)
for (i = 0; i < 32; i++)
if (total&(1<<i)) bitcounts[i]++;
if (total & U_NUMBER16) number = MSG_ReadShort (&net_message);
else number = MSG_ReadByte (&net_message);
if (total & U_NUMBER16) number = MSG_ReadShort (msg);
else number = MSG_ReadByte (msg);
*bits = total;
@ -94,7 +94,7 @@ Parses deltas from the given base and adds the resulting entity
to the current frame
==================
*/
void CL_DeltaEntity (frame_t *frame, int newnum, entity_state_t *old, int bits)
void CL_DeltaEntity( sizebuf_t *msg, frame_t *frame, int newnum, entity_state_t *old, int bits )
{
centity_t *ent;
entity_state_t *state;
@ -105,19 +105,13 @@ void CL_DeltaEntity (frame_t *frame, int newnum, entity_state_t *old, int bits)
cl.parse_entities++;
frame->num_entities++;
MSG_ReadDeltaEntity(old, state, newnum, bits);
MSG_ReadDeltaEntity( msg, old, state, newnum, bits );
// some data changes will force no lerping
if (state->modelindex != ent->current.modelindex
|| state->weaponmodel != ent->current.weaponmodel
|| state->body != ent->current.body
|| state->sequence != ent->current.sequence
|| abs(state->origin[0] - ent->current.origin[0]) > 512
|| abs(state->origin[1] - ent->current.origin[1]) > 512
|| abs(state->origin[2] - ent->current.origin[2]) > 512
|| state->event == EV_PLAYER_TELEPORT
|| state->event == EV_OTHER_TELEPORT
)
if (state->modelindex != ent->current.modelindex || state->weaponmodel != ent->current.weaponmodel || state->body != ent->current.body
|| state->sequence != ent->current.sequence || abs(state->origin[0] - ent->current.origin[0]) > 512
|| abs(state->origin[1] - ent->current.origin[1]) > 512 || abs(state->origin[2] - ent->current.origin[2]) > 512
|| state->event == EV_PLAYER_TELEPORT || state->event == EV_OTHER_TELEPORT )
{
ent->serverframe = -99;
}
@ -155,12 +149,12 @@ An svc_packetentities has just been parsed, deal with the
rest of the data stream.
==================
*/
void CL_ParsePacketEntities (frame_t *oldframe, frame_t *newframe)
void CL_ParsePacketEntities( sizebuf_t *msg, frame_t *oldframe, frame_t *newframe )
{
int newnum;
int bits;
int newnum;
int bits;
entity_state_t *oldstate;
int oldindex, oldnum;
int oldindex, oldnum;
newframe->parse_entities = cl.parse_entities;
newframe->num_entities = 0;
@ -182,11 +176,11 @@ void CL_ParsePacketEntities (frame_t *oldframe, frame_t *newframe)
while (1)
{
newnum = CL_ParseEntityBits (&bits);
newnum = CL_ParseEntityBits( msg, &bits );
if (newnum >= MAX_EDICTS)
Host_Error("CL_ParsePacketEntities: bad number:%i\n", newnum);
if (net_message.readcount > net_message.cursize)
if (msg->readcount > msg->cursize)
Host_Error("CL_ParsePacketEntities: end of message\n");
if (!newnum) break;
@ -195,7 +189,7 @@ void CL_ParsePacketEntities (frame_t *oldframe, frame_t *newframe)
{
// one or more entities from the old packet are unchanged
if (cl_shownet->value == 3) Msg (" unchanged: %i\n", oldnum);
CL_DeltaEntity (newframe, oldnum, oldstate, 0);
CL_DeltaEntity( msg, newframe, oldnum, oldstate, 0);
oldindex++;
@ -231,7 +225,7 @@ void CL_ParsePacketEntities (frame_t *oldframe, frame_t *newframe)
{ // delta from previous state
if (cl_shownet->value == 3)
Msg (" delta: %i\n", newnum);
CL_DeltaEntity (newframe, newnum, oldstate, bits);
CL_DeltaEntity( msg, newframe, newnum, oldstate, bits );
oldindex++;
@ -246,10 +240,11 @@ void CL_ParsePacketEntities (frame_t *oldframe, frame_t *newframe)
}
if (oldnum > newnum)
{ // delta from baseline
{
// delta from baseline
if (cl_shownet->value == 3)
Msg (" baseline: %i\n", newnum);
CL_DeltaEntity (newframe, newnum, &cl_entities[newnum].baseline, bits);
CL_DeltaEntity( msg, newframe, newnum, &cl_entities[newnum].baseline, bits );
continue;
}
@ -260,7 +255,7 @@ void CL_ParsePacketEntities (frame_t *oldframe, frame_t *newframe)
{ // one or more entities from the old packet are unchanged
if (cl_shownet->value == 3)
Msg (" unchanged: %i\n", oldnum);
CL_DeltaEntity (newframe, oldnum, oldstate, 0);
CL_DeltaEntity( msg, newframe, oldnum, oldstate, 0 );
oldindex++;
@ -281,12 +276,12 @@ void CL_ParsePacketEntities (frame_t *oldframe, frame_t *newframe)
CL_ParsePlayerstate
===================
*/
void CL_ParsePlayerstate (frame_t *oldframe, frame_t *newframe)
void CL_ParsePlayerstate( sizebuf_t *msg, frame_t *oldframe, frame_t *newframe )
{
int flags;
int flags;
player_state_t *state;
int i;
int statbits;
int i;
int statbits;
state = &newframe->playerstate;
@ -294,16 +289,16 @@ void CL_ParsePlayerstate (frame_t *oldframe, frame_t *newframe)
if (oldframe) *state = oldframe->playerstate;
else memset (state, 0, sizeof(*state));
flags = MSG_ReadLong(&net_message);//four bytes
flags = MSG_ReadLong(msg);//four bytes
// parse the pmove_state_t
if (flags & PS_M_TYPE) state->pm_type = MSG_ReadByte (&net_message);
if (flags & PS_M_ORIGIN) MSG_ReadPos32(&net_message, state->origin );
if (flags & PS_M_VELOCITY) MSG_ReadPos32(&net_message, state->velocity );
if (flags & PS_M_TIME) state->pm_time = MSG_ReadByte (&net_message);
if (flags & PS_M_FLAGS) state->pm_flags = MSG_ReadByte (&net_message);
if (flags & PS_M_GRAVITY) state->gravity = MSG_ReadShort (&net_message);
if (flags & PS_M_DELTA_ANGLES) MSG_ReadPos32(&net_message, state->delta_angles );
if (flags & PS_M_TYPE) state->pm_type = MSG_ReadByte (msg);
if (flags & PS_M_ORIGIN) MSG_ReadPos32(msg, state->origin );
if (flags & PS_M_VELOCITY) MSG_ReadPos32(msg, state->velocity );
if (flags & PS_M_TIME) state->pm_time = MSG_ReadByte (msg);
if (flags & PS_M_FLAGS) state->pm_flags = MSG_ReadByte (msg);
if (flags & PS_M_GRAVITY) state->gravity = MSG_ReadShort (msg);
if (flags & PS_M_DELTA_ANGLES) MSG_ReadPos32(msg, state->delta_angles );
if(cls.state == ca_cinematic || cl.servercount > 0x10000)
state->pm_type = PM_FREEZE; // demo or movie playback
@ -311,74 +306,74 @@ void CL_ParsePlayerstate (frame_t *oldframe, frame_t *newframe)
// parse the rest of the player_state_t
if (flags & PS_VIEWOFFSET)
{
state->viewoffset[0] = MSG_ReadChar (&net_message) * 0.25;
state->viewoffset[1] = MSG_ReadChar (&net_message) * 0.25;
state->viewoffset[2] = MSG_ReadChar (&net_message) * 0.25;
state->viewoffset[0] = MSG_ReadChar (msg) * 0.25;
state->viewoffset[1] = MSG_ReadChar (msg) * 0.25;
state->viewoffset[2] = MSG_ReadChar (msg) * 0.25;
}
if (flags & PS_VIEWANGLES)
{
state->viewangles[0] = MSG_ReadAngle32 (&net_message);
state->viewangles[1] = MSG_ReadAngle32 (&net_message);
state->viewangles[2] = MSG_ReadAngle32 (&net_message);
state->viewangles[0] = MSG_ReadAngle32 (msg);
state->viewangles[1] = MSG_ReadAngle32 (msg);
state->viewangles[2] = MSG_ReadAngle32 (msg);
}
if (flags & PS_KICKANGLES)
{
state->kick_angles[0] = MSG_ReadChar (&net_message) * 0.25;
state->kick_angles[1] = MSG_ReadChar (&net_message) * 0.25;
state->kick_angles[2] = MSG_ReadChar (&net_message) * 0.25;
state->kick_angles[0] = MSG_ReadChar (msg) * 0.25;
state->kick_angles[1] = MSG_ReadChar (msg) * 0.25;
state->kick_angles[2] = MSG_ReadChar (msg) * 0.25;
}
if (flags & PS_WEAPONINDEX)
{
state->vmodel.index = MSG_ReadByte (&net_message);
state->vmodel.index = MSG_ReadByte (msg);
}
if (flags & PS_WEAPONFRAME)
{
state->vmodel.frame = MSG_ReadByte (&net_message);
state->vmodel.offset[0] = MSG_ReadChar (&net_message)*0.25;
state->vmodel.offset[1] = MSG_ReadChar (&net_message)*0.25;
state->vmodel.offset[2] = MSG_ReadChar (&net_message)*0.25;
state->vmodel.angles[0] = MSG_ReadChar (&net_message)*0.25;
state->vmodel.angles[1] = MSG_ReadChar (&net_message)*0.25;
state->vmodel.angles[2] = MSG_ReadChar (&net_message)*0.25;
state->vmodel.frame = MSG_ReadByte (msg);
state->vmodel.offset[0] = MSG_ReadChar (msg)*0.25;
state->vmodel.offset[1] = MSG_ReadChar (msg)*0.25;
state->vmodel.offset[2] = MSG_ReadChar (msg)*0.25;
state->vmodel.angles[0] = MSG_ReadChar (msg)*0.25;
state->vmodel.angles[1] = MSG_ReadChar (msg)*0.25;
state->vmodel.angles[2] = MSG_ReadChar (msg)*0.25;
}
if (flags & PS_WEAPONSEQUENCE)
{
state->vmodel.sequence = MSG_ReadByte (&net_message);
state->vmodel.sequence = MSG_ReadByte (msg);
}
if (flags & PS_WEAPONBODY)
{
state->vmodel.body = MSG_ReadByte (&net_message);
state->vmodel.body = MSG_ReadByte (msg);
}
if (flags & PS_WEAPONSKIN)
{
state->vmodel.skin = MSG_ReadByte (&net_message);
state->vmodel.skin = MSG_ReadByte (msg);
}
if (flags & PS_BLEND)
{
state->blend[0] = MSG_ReadByte (&net_message) / 255.0;
state->blend[1] = MSG_ReadByte (&net_message) / 255.0;
state->blend[2] = MSG_ReadByte (&net_message) / 255.0;
state->blend[3] = MSG_ReadByte (&net_message) / 255.0;
state->blend[0] = MSG_ReadByte (msg) / 255.0;
state->blend[1] = MSG_ReadByte (msg) / 255.0;
state->blend[2] = MSG_ReadByte (msg) / 255.0;
state->blend[3] = MSG_ReadByte (msg) / 255.0;
}
if (flags & PS_FOV)
state->fov = MSG_ReadByte (&net_message);
state->fov = MSG_ReadByte (msg);
if (flags & PS_RDFLAGS)
state->effects = MSG_ReadByte (&net_message);
state->effects = MSG_ReadByte (msg);
// parse stats
statbits = MSG_ReadLong (&net_message);
statbits = MSG_ReadLong (msg);
for (i = 0; i < MAX_STATS; i++)
if (statbits & (1<<i) ) state->stats[i] = MSG_ReadShort(&net_message);
if (statbits & (1<<i) ) state->stats[i] = MSG_ReadShort(msg);
}
@ -412,11 +407,11 @@ void CL_FireEntityEvents (frame_t *frame)
CL_ParseFrame
================
*/
void CL_ParseFrame (void)
void CL_ParseFrame( sizebuf_t *msg )
{
int cmd;
int len;
frame_t *old;
int cmd;
int len;
frame_t *old;
memset (&cl.frame, 0, sizeof(cl.frame));
@ -424,12 +419,12 @@ void CL_ParseFrame (void)
CL_ClearProjectiles(); // clear projectiles for new frame
#endif
cl.frame.serverframe = MSG_ReadLong (&net_message);
cl.frame.deltaframe = MSG_ReadLong (&net_message);
cl.frame.serverframe = MSG_ReadLong (msg);
cl.frame.deltaframe = MSG_ReadLong (msg);
cl.frame.servertime = cl.frame.serverframe * host_frametime->value;
// BIG HACK to let old demos continue to work
if (cls.serverProtocol != 26) cl.surpressCount = MSG_ReadByte (&net_message);
if (cls.serverProtocol != 26) cl.surpressCount = MSG_ReadByte (msg);
if (cl_shownet->value == 3) Msg (" frame:%i delta:%i\n", cl.frame.serverframe, cl.frame.deltaframe);
// If the frame is delta compressed from data that we
@ -468,20 +463,20 @@ void CL_ParseFrame (void)
else if (cl.time < cl.frame.servertime - host_frametime->value) cl.time = cl.frame.servertime - host_frametime->value;
// read areabits
len = MSG_ReadByte (&net_message);
MSG_ReadData (&net_message, &cl.frame.areabits, len);
len = MSG_ReadByte (msg);
MSG_ReadData (msg, &cl.frame.areabits, len);
// read playerinfo
cmd = MSG_ReadByte (&net_message);
SHOWNET(svc_strings[cmd]);
cmd = MSG_ReadByte (msg);
SHOWNET( msg, svc_strings[cmd] );
if (cmd != svc_playerinfo) Host_Error("CL_ParseFrame: not playerinfo\n");
CL_ParsePlayerstate (old, &cl.frame);
CL_ParsePlayerstate( msg, old, &cl.frame );
// read packet entities
cmd = MSG_ReadByte (&net_message);
SHOWNET(svc_strings[cmd]);
cmd = MSG_ReadByte (msg);
SHOWNET( msg, svc_strings[cmd] );
if (cmd != svc_packetentities) Host_Error("CL_ParseFrame: not packetentities\n");
CL_ParsePacketEntities (old, &cl.frame);
CL_ParsePacketEntities( msg, old, &cl.frame );
// save the frame off in the backup array for later delta comparisons
@ -831,17 +826,18 @@ void CL_CalcViewValues (void)
}
// if not running a demo or on a locked frame, add the local angle movement
if ( cl.frame.playerstate.pm_type < PM_DEAD )
if( cls.demoplayback )
{
for (i = 0; i < 3; i++)
cl.refdef.viewangles[i] = LerpAngle (ops->viewangles[i], ps->viewangles[i], lerp);
}
else //if ( cl.frame.playerstate.pm_type < PM_DEAD )
{
// use predicted values
// in-game use predicted values
for (i = 0; i < 3; i++) cl.refdef.viewangles[i] = cl.predicted_angles[i];
}
else
{ // just use interpolated values
for (i = 0; i < 3; i++) cl.refdef.viewangles[i] = LerpAngle (ops->viewangles[i], ps->viewangles[i], lerp);
}
for (i=0 ; i<3 ; i++)
for( i = 0; i < 3; i++ )
cl.refdef.viewangles[i] += LerpAngle (ops->kick_angles[i], ps->kick_angles[i], lerp);
// sound engine requiried left-side hand
@ -887,9 +883,7 @@ void CL_AddEntities (void)
}
else cl.lerpfrac = 1.0 - (cl.frame.servertime - cl.time) * host_frametime->value;
if (cl_timedemo->value) cl.lerpfrac = 1.0;
CL_CalcViewValues ();
CL_CalcViewValues();
// PMM - moved this here so the heat beam has the right values for the vieworg, and can lock the beam to the gun
CL_AddPacketEntities (&cl.frame);
CL_AddTEnts ();

View File

@ -767,6 +767,8 @@ void CL_SendCmd (void)
if(cls.state == ca_cinematic || cl.servercount > 0x10000)
return;
if( cls.demoplayback ) return;
if( cls.state == ca_connected)
{
if (cls.netchan.message.cursize || host.realtime - cls.netchan.last_sent > 1.0f )

View File

@ -152,7 +152,6 @@ static void FindMatches( const char *s, const char *unused1, const char *unused2
/*
===============
PrintMatches
===============
*/
static void PrintMatches( const char *s, const char *unused1, const char *m, void *unused2 )
@ -241,7 +240,7 @@ void Field_CompleteCommand( field_t *field )
{
result = Cmd_GetMapList(Cmd_Argv(1), filename, MAX_STRING );
}
else if(!stricmp(Cmd_Argv(0), "demo" ) || !stricmp(Cmd_Argv(0), "\\demo" ))
else if(!stricmp(Cmd_Argv(0), "playdemo" ) || !stricmp(Cmd_Argv(0), "\\playdemo" ))
{
result = Cmd_GetDemoList(Cmd_Argv(1), filename, MAX_STRING );
}

View File

@ -56,7 +56,6 @@ cvar_t *cl_showmiss;
cvar_t *cl_showclamp;
cvar_t *cl_paused;
cvar_t *cl_timedemo;
cvar_t *lookspring;
cvar_t *lookstrafe;
@ -99,168 +98,6 @@ extern cvar_t *allow_download_sounds;
extern cvar_t *allow_download_maps;
//======================================================================
/*
====================
CL_WriteDemoMessage
Dumps the current net message, prefixed by the length
====================
*/
void CL_WriteDemoMessage (void)
{
int len, swlen;
// the first eight bytes are just packet sequencing stuff
len = net_message.cursize-8;
swlen = LittleLong(len);
FS_Write (cls.demofile, &swlen, 4);
FS_Write (cls.demofile, net_message.data + 8, len );
}
/*
====================
CL_Stop_f
stop recording a demo
====================
*/
void CL_Stop_f (void)
{
int len;
if (!cls.demorecording)
{
Msg ("Not recording a demo.\n");
return;
}
// finish up
len = -1;
FS_Write (cls.demofile, &len, 4 );
FS_Close (cls.demofile);
cls.demofile = NULL;
cls.demorecording = false;
Msg ("Stopped demo.\n");
}
/*
====================
CL_Record_f
record <demoname>
Begins recording a demo from the current position
====================
*/
void CL_Record_f (void)
{
char name[MAX_OSPATH];
char buf_data[MAX_MSGLEN];
sizebuf_t buf;
int i;
int len;
entity_state_t *ent;
entity_state_t nullstate;
if (Cmd_Argc() != 2)
{
Msg ("record <demoname>\n");
return;
}
if (cls.demorecording)
{
Msg ("Already recording.\n");
return;
}
if (cls.state != ca_active)
{
Msg ("You must be in a level to record.\n");
return;
}
// open the demo file
sprintf (name, "demos/%s.dem", Cmd_Argv(1));
Msg ("recording to %s.\n", name);
cls.demofile = FS_Open (name, "wb");
if (!cls.demofile)
{
Msg ("ERROR: couldn't open.\n");
return;
}
cls.demorecording = true;
// don't start saving messages until a non-delta compressed message is received
cls.demowaiting = true;
//
// write out messages to hold the startup information
//
SZ_Init (&buf, buf_data, sizeof(buf_data));
// send the serverdata
MSG_WriteByte (&buf, svc_serverdata);
MSG_WriteLong (&buf, PROTOCOL_VERSION);
MSG_WriteLong (&buf, 0x10000 + cl.servercount);
MSG_WriteShort (&buf, cl.playernum);
MSG_WriteString (&buf, cl.configstrings[CS_NAME]);
// configstrings
for (i=0 ; i<MAX_CONFIGSTRINGS ; i++)
{
if (cl.configstrings[i][0])
{
if (buf.cursize + strlen (cl.configstrings[i]) + 32 > buf.maxsize)
{ // write it out
len = LittleLong (buf.cursize);
FS_Write (cls.demofile, &len, 4 );
FS_Write (cls.demofile, buf.data, buf.cursize );
buf.cursize = 0;
}
MSG_WriteByte (&buf, svc_configstring);
MSG_WriteShort (&buf, i);
MSG_WriteString (&buf, cl.configstrings[i]);
}
}
// baselines
memset (&nullstate, 0, sizeof(nullstate));
for (i=0; i<MAX_EDICTS ; i++)
{
ent = &cl_entities[i].baseline;
if (!ent->modelindex)
continue;
if (buf.cursize + 64 > buf.maxsize)
{ // write it out
len = LittleLong (buf.cursize);
FS_Write(cls.demofile, &len, 4 );
FS_Write(cls.demofile, buf.data, buf.cursize );
buf.cursize = 0;
}
MSG_WriteByte (&buf, svc_spawnbaseline);
MSG_WriteDeltaEntity (&nullstate, &cl_entities[i].baseline, &buf, true, true);
}
MSG_WriteByte (&buf, svc_stufftext);
MSG_WriteString (&buf, "precache\n");
// write it to the demo file
len = LittleLong (buf.cursize);
FS_Write (cls.demofile, &len, 4 );
FS_Write (cls.demofile, buf.data, buf.cursize );
// the rest of the demo file will be individual frames
}
//======================================================================
/*
@ -276,6 +113,8 @@ void Cmd_ForwardToServer (void)
{
char *cmd;
if( cls.demoplayback ) return; // not really connected
cmd = Cmd_Argv(0);
if (cls.state <= ca_connected || *cmd == '-' || *cmd == '+')
{
@ -299,6 +138,7 @@ CL_ForwardToServer_f
*/
void CL_ForwardToServer_f (void)
{
if( cls.demoplayback ) return; // not really connected
if (cls.state != ca_connected && cls.state != ca_active)
{
Msg("Can't \"%s\", not connected\n", Cmd_Argv(0));
@ -373,7 +213,7 @@ void CL_SendConnectPacket (void)
if(!NET_StringToAdr (cls.servername, &adr))
{
Msg ("Bad server address\n");
MsgDev( D_INFO, "CL_SendConnectPacket: bad server address\n");
cls.connect_time = 0;
return;
}
@ -407,12 +247,13 @@ void CL_CheckForResend (void)
}
// resend if we haven't gotten a reply yet
if(cls.state != ca_connecting) return;
if(cls.demoplayback || cls.state != ca_connecting)
return;
if(cls.realtime - cls.connect_time < 3.0f) return;
if(!NET_StringToAdr (cls.servername, &adr))
{
Msg ("Bad server address\n");
MsgDev(D_INFO, "CL_CheckForResend: bad server address\n");
cls.state = ca_disconnected;
return;
}
@ -555,29 +396,21 @@ void CL_Disconnect (void)
if (cls.state == ca_disconnected)
return;
if (cl_timedemo && cl_timedemo->value)
{
float time;
time = Sys_DoubleTime() - cl.timedemo_start;
if (time > 0) Msg ("%i frames, %3.1f seconds: %3.1f fps\n", cl.timedemo_frames, time, cl.timedemo_frames / time);
}
VectorClear (cl.refdef.blend);
M_ForceMenuOff ();
cls.connect_time = 0;
SCR_StopCinematic ();
SCR_StopCinematic();
if(cls.demorecording) CL_Stop_f ();
CL_Stop_f();
// send a disconnect message to the server
final[0] = clc_stringcmd;
strcpy ((char *)final+1, "disconnect");
Netchan_Transmit (&cls.netchan, strlen(final), final);
Netchan_Transmit (&cls.netchan, strlen(final), final);
Netchan_Transmit (&cls.netchan, strlen(final), final);
com.strcpy ((char *)final+1, "disconnect");
Netchan_Transmit(&cls.netchan, strlen(final), final);
Netchan_Transmit(&cls.netchan, strlen(final), final);
Netchan_Transmit(&cls.netchan, strlen(final), final);
CL_ClearState ();
@ -889,6 +722,38 @@ void CL_DumpPackets (void)
}
}
void CL_ReadNetMessage( void )
{
while (NET_GetPacket (NS_CLIENT, &net_from, &net_message))
{
// remote command packet
if(*(int *)net_message.data == -1)
{
CL_ConnectionlessPacket();
continue;
}
if( cls.state == ca_disconnected || cls.state == ca_connecting )
continue; // dump it if not connected
if( net_message.cursize < 8 )
{
Msg( "%s: Runt packet\n", NET_AdrToString(net_from));
continue;
}
// packet from server
if (!NET_CompareAdr (net_from, cls.netchan.remote_address))
{
MsgWarn("CL_ReadPackets: %s:sequenced packet without connection\n",NET_AdrToString(net_from));
continue;
}
if(!Netchan_Process(&cls.netchan, &net_message))
continue; // wasn't accepted for some reason
CL_ParseServerMessage( &net_message );
}
}
/*
=================
CL_ReadPackets
@ -896,40 +761,10 @@ CL_ReadPackets
*/
void CL_ReadPackets (void)
{
while (NET_GetPacket (NS_CLIENT, &net_from, &net_message))
{
//Msg ("packet\n");
//
// remote command packet
//
if (*(int *)net_message.data == -1)
{
CL_ConnectionlessPacket ();
continue;
}
if (cls.state == ca_disconnected || cls.state == ca_connecting)
continue; // dump it if not connected
if (net_message.cursize < 8)
{
Msg ("%s: Runt packet\n",NET_AdrToString(net_from));
continue;
}
//
// packet from server
//
if (!NET_CompareAdr (net_from, cls.netchan.remote_address))
{
MsgWarn("CL_ReadPackets: %s:sequenced packet without connection\n",NET_AdrToString(net_from));
continue;
}
if (!Netchan_Process(&cls.netchan, &net_message))
continue; // wasn't accepted for some reason
CL_ParseServerMessage ();
}
if( cls.demoplayback )
CL_ReadDemoMessage();
else CL_ReadNetMessage();
//
// check timeout
//
@ -1027,9 +862,16 @@ void CL_RequestNextDownload (void)
char fn[MAX_OSPATH];
studiohdr_t *pheader;
if (cls.state != ca_connected)
if(cls.state != ca_connected)
return;
if( cls.demoplayback )
{
CL_RegisterSounds();
CL_PrepRefresh();
return;
}
if (!allow_download->value && precache_check < ENV_CNT)
precache_check = ENV_CNT;
@ -1245,8 +1087,8 @@ void CL_RequestNextDownload (void)
//ZOID
CL_RegisterSounds();
CL_PrepRefresh();
MSG_WriteByte (&cls.netchan.message, clc_stringcmd);
MSG_WriteString (&cls.netchan.message, va("begin %i\n", precache_spawncount) );
MSG_WriteByte( &cls.netchan.message, clc_stringcmd );
MSG_WriteString( &cls.netchan.message, va("begin %i\n", precache_spawncount));
}
/*
@ -1336,7 +1178,6 @@ void CL_InitLocal (void)
cl_showclamp = Cvar_Get ("showclamp", "0", 0);
cl_timeout = Cvar_Get ("cl_timeout", "120", 0);
cl_paused = Cvar_Get ("paused", "0", 0);
cl_timedemo = Cvar_Get ("timedemo", "0", 0);
rcon_client_password = Cvar_Get ("rcon_password", "", 0);
rcon_address = Cvar_Get ("rcon_address", "", 0);
@ -1371,7 +1212,8 @@ void CL_InitLocal (void)
Cmd_AddCommand ("changing", CL_Changing_f, "sent by server to tell client to wait for level change" );
Cmd_AddCommand ("disconnect", CL_Disconnect_f, "disconnect from server" );
Cmd_AddCommand ("record", CL_Record_f, "record a demo" );
Cmd_AddCommand ("stop", CL_Stop_f, "stop recording a demo" );
Cmd_AddCommand ("playdemo", CL_PlayDemo_f, "playing a demo" );
Cmd_AddCommand ("stop", CL_Stop_f, "stop playing or recording a demo" );
Cmd_AddCommand ("quit", CL_Quit_f, "quit from game" );
Cmd_AddCommand ("exit", CL_Quit_f, "quit from game" );
@ -1474,7 +1316,6 @@ typedef struct
cheatvar_t cheatvars[] = {
{"timescale", "1"},
{"timedemo", "0"},
{"r_drawworld", "1"},
{"cl_testlights", "0"},
{"r_fullbright", "0"},
@ -1556,18 +1397,14 @@ void CL_Frame( float time )
static float extratime;
static float lasttimecalled;
if (dedicated->value)
return;
if( dedicated->integer ) return;
extratime += time;
if (!cl_timedemo->value)
{
if (cls.state == ca_connected && extratime < 0.01f)
return; // don't flood packets out while connecting
if (extratime < 1.0f / cl_maxfps->value)
return; // framerate is too high
}
if (cls.state == ca_connected && extratime < 0.01f)
return; // don't flood packets out while connecting
if (extratime < 1.0f / cl_maxfps->value)
return; // framerate is too high
// let the mouse activate or deactivate
CL_UpdateMouse();

View File

@ -204,22 +204,22 @@ CL_ParseDownload
A download message has been received from the server
=====================
*/
void CL_ParseDownload (void)
void CL_ParseDownload( sizebuf_t *msg )
{
int size, percent;
char name[MAX_OSPATH];
string name;
int r;
// read the data
size = MSG_ReadShort (&net_message);
percent = MSG_ReadByte (&net_message);
size = MSG_ReadShort( msg );
percent = MSG_ReadByte( msg );
if (size == -1)
{
Msg ("Server does not have this file.\n");
Msg("Server does not have this file.\n");
if (cls.download)
{
// if here, we tried to resume a file but the server said no
FS_Close (cls.download);
FS_Close(cls.download);
cls.download = NULL;
}
CL_RequestNextDownload ();
@ -234,15 +234,15 @@ void CL_ParseDownload (void)
cls.download = FS_Open (name, "wb");
if (!cls.download)
{
net_message.readcount += size;
msg->readcount += size;
Msg ("Failed to open %s\n", cls.downloadtempname);
CL_RequestNextDownload ();
return;
}
}
FS_Write (cls.download, net_message.data + net_message.readcount, size );
net_message.readcount += size;
FS_Write (cls.download, msg->data + msg->readcount, size );
msg->readcount += size;
if (percent != 100)
{
@ -289,7 +289,7 @@ void CL_ParseDownload (void)
CL_ParseServerData
==================
*/
void CL_ParseServerData (void)
void CL_ParseServerData( sizebuf_t *msg )
{
char *str;
int i;
@ -301,18 +301,18 @@ void CL_ParseServerData (void)
cls.state = ca_connected;
// parse protocol version number
i = MSG_ReadLong (&net_message);
i = MSG_ReadLong( msg );
cls.serverProtocol = i;
if (i != PROTOCOL_VERSION) Host_Error("Server returned version %i, not %i", i, PROTOCOL_VERSION);
cl.servercount = MSG_ReadLong (&net_message);
cl.servercount = MSG_ReadLong( msg );
// parse player entity number
cl.playernum = MSG_ReadShort (&net_message);
cl.playernum = MSG_ReadShort( msg );
// get the full level name
str = MSG_ReadString (&net_message);
str = MSG_ReadString( msg );
if (cl.playernum == -1)
{
@ -333,7 +333,7 @@ void CL_ParseServerData (void)
CL_ParseBaseline
==================
*/
void CL_ParseBaseline (void)
void CL_ParseBaseline( sizebuf_t *msg )
{
entity_state_t *es;
int bits;
@ -342,9 +342,9 @@ void CL_ParseBaseline (void)
memset (&nullstate, 0, sizeof(nullstate));
newnum = CL_ParseEntityBits (&bits);
newnum = CL_ParseEntityBits( msg, &bits );
es = &cl_entities[newnum].baseline;
MSG_ReadDeltaEntity(&nullstate, es, newnum, bits);
MSG_ReadDeltaEntity( msg, &nullstate, es, newnum, bits);
}
@ -467,15 +467,15 @@ void CL_ParseClientinfo (int player)
CL_ParseConfigString
================
*/
void CL_ParseConfigString (void)
void CL_ParseConfigString( sizebuf_t *msg )
{
int i;
char *s;
char olds[MAX_QPATH];
char *s;
string olds;
i = MSG_ReadShort (&net_message);
i = MSG_ReadShort( msg );
if (i < 0 || i >= MAX_CONFIGSTRINGS) Host_Error("configstring > MAX_CONFIGSTRINGS\n");
s = MSG_ReadString(&net_message);
s = MSG_ReadString( msg );
strncpy (olds, cl.configstrings[i], sizeof(olds));
olds[sizeof(olds) - 1] = 0;
@ -529,9 +529,9 @@ ACTION MESSAGES
CL_ParseStartSoundPacket
==================
*/
void CL_ParseStartSoundPacket(void)
void CL_ParseStartSoundPacket( sizebuf_t *msg )
{
vec3_t pos_v;
vec3_t pos_v;
float *pos;
int channel, ent;
int sound_num;
@ -540,22 +540,22 @@ void CL_ParseStartSoundPacket(void)
int flags;
float ofs;
flags = MSG_ReadByte (&net_message);
sound_num = MSG_ReadByte (&net_message);
flags = MSG_ReadByte( msg );
sound_num = MSG_ReadByte( msg );
if (flags & SND_VOLUME) volume = MSG_ReadByte (&net_message) / 255.0;
if (flags & SND_VOLUME) volume = MSG_ReadByte( msg ) / 255.0;
else volume = DEFAULT_SOUND_PACKET_VOL;
if (flags & SND_ATTENUATION) attenuation = MSG_ReadByte (&net_message) / 64.0;
if (flags & SND_ATTENUATION) attenuation = MSG_ReadByte( msg ) / 64.0;
else attenuation = DEFAULT_SOUND_PACKET_ATTN;
if (flags & SND_OFFSET) ofs = MSG_ReadByte (&net_message) / 1000.0;
if (flags & SND_OFFSET) ofs = MSG_ReadByte( msg ) / 1000.0;
else ofs = 0;
if (flags & SND_ENT)
{
// entity reletive
channel = MSG_ReadShort(&net_message);
channel = MSG_ReadShort( msg );
ent = channel>>3;
if (ent > MAX_EDICTS) Host_Error("CL_ParseStartSoundPacket: ent out of range\n" );
channel &= 7;
@ -569,7 +569,7 @@ void CL_ParseStartSoundPacket(void)
if (flags & SND_POS)
{
// positioned in space
MSG_ReadPos32(&net_message, pos_v);
MSG_ReadPos32( msg, pos_v);
pos = pos_v;
}
else pos = NULL; // use entity number
@ -578,24 +578,24 @@ void CL_ParseStartSoundPacket(void)
S_StartSound (pos, ent, channel, cl.sound_precache[sound_num]);
}
void CL_ParseAmbientSound( void )
void CL_ParseAmbientSound( sizebuf_t *msg )
{
sound_t loopSoundHandle;
int entityNum, soundNum;
vec3_t ambient_org;
entityNum = MSG_ReadShort (&net_message);
soundNum = MSG_ReadShort (&net_message);
MSG_ReadPos32 (&net_message, ambient_org);
entityNum = MSG_ReadShort( msg );
soundNum = MSG_ReadShort( msg );
MSG_ReadPos32( msg, ambient_org);
loopSoundHandle = S_RegisterSound( cl.configstrings[CS_SOUNDS + soundNum] );
// add ambient looping sound
S_AddRealLoopingSound( entityNum, ambient_org, vec3_origin, loopSoundHandle );
}
void SHOWNET(char *s)
void SHOWNET( sizebuf_t *msg, char *s )
{
if (cl_shownet->value >= 2) Msg ("%3i:%s\n", net_message.readcount-1, s);
if (cl_shownet->value >= 2) Msg ("%3i:%s\n", msg->readcount-1, s);
}
/*
@ -603,36 +603,36 @@ void SHOWNET(char *s)
CL_ParseServerMessage
=====================
*/
void CL_ParseServerMessage (void)
void CL_ParseServerMessage( sizebuf_t *msg )
{
int i, cmd;
char *s;
// if recording demos, copy the message out
if (cl_shownet->value == 1) Msg ("%i ",net_message.cursize);
if (cl_shownet->value == 1) Msg ("%i ",msg->cursize);
else if (cl_shownet->value >= 2) Msg ("------------------\n");
// parse the message
while (1)
while( 1 )
{
if (net_message.readcount > net_message.cursize)
if (msg->readcount > msg->cursize)
{
Host_Error("CL_ParseServerMessage: Bad server message\n");
break;
}
cmd = MSG_ReadByte (&net_message);
cmd = MSG_ReadByte( msg );
if (cmd == -1)
{
SHOWNET("END OF MESSAGE");
SHOWNET( msg, "END OF MESSAGE" );
break;
}
if (cl_shownet->value >= 2)
{
if (!svc_strings[cmd]) Msg ("%3i:BAD CMD %i\n", net_message.readcount - 1, cmd);
else SHOWNET(svc_strings[cmd]);
if (!svc_strings[cmd]) Msg ("%3i:BAD CMD %i\n", msg->readcount - 1, cmd);
else SHOWNET( msg, svc_strings[cmd] );
}
// other commands
@ -660,60 +660,60 @@ void CL_ParseServerMessage (void)
break;
case svc_print:
i = MSG_ReadByte (&net_message);
i = MSG_ReadByte( msg );
if (i == 3) S_StartLocalSound ("misc/talk.wav"); // chat
Msg ("^6%s", MSG_ReadString (&net_message));
Msg ("^6%s", MSG_ReadString( msg ));
break;
case svc_centerprint:
CG_CenterPrint(MSG_ReadString (&net_message), SCREEN_HEIGHT/2, BIGCHAR_WIDTH );
CG_CenterPrint(MSG_ReadString( msg ), SCREEN_HEIGHT/2, BIGCHAR_WIDTH );
break;
case svc_stufftext:
s = MSG_ReadString (&net_message);
s = MSG_ReadString( msg );
Cbuf_AddText (s);
break;
case svc_serverdata:
Cbuf_Execute (); // make sure any stuffed commands are done
CL_ParseServerData ();
CL_ParseServerData( msg );
break;
case svc_configstring:
CL_ParseConfigString ();
CL_ParseConfigString( msg );
break;
case svc_sound:
CL_ParseStartSoundPacket();
CL_ParseStartSoundPacket( msg );
break;
case svc_ambientsound:
CL_ParseAmbientSound();
CL_ParseAmbientSound( msg );
break;
case svc_spawnbaseline:
CL_ParseBaseline ();
CL_ParseBaseline( msg );
break;
case svc_temp_entity:
CL_ParseTEnt ();
CL_ParseTEnt( msg );
break;
case svc_download:
CL_ParseDownload ();
CL_ParseDownload( msg );
break;
case svc_frame:
CL_ParseFrame ();
CL_ParseFrame( msg );
break;
case svc_inventory:
CG_ParseInventory();
CG_ParseInventory( msg );
break;
case svc_layout:
s = MSG_ReadString (&net_message);
strncpy(cl.layout, s, sizeof(cl.layout)-1);
s = MSG_ReadString( msg );
com.strncpy(cl.layout, s, sizeof(cl.layout)-1);
break;
case svc_playerinfo:
@ -730,7 +730,7 @@ void CL_ParseServerMessage (void)
// we don't know if it is ok to save a demo message until
// after we have parsed the frame
if (cls.demorecording && !cls.demowaiting)
CL_WriteDemoMessage ();
CL_WriteDemoMessage();
}

View File

@ -268,16 +268,16 @@ void CL_SmokeAndFlash(vec3_t origin)
CL_ParseParticles
=================
*/
void CL_ParseParticles (void)
void CL_ParseParticles( sizebuf_t *msg )
{
int color, count;
vec3_t pos, dir;
MSG_ReadPos32(&net_message, pos);
MSG_ReadPos32(&net_message, dir);
MSG_ReadPos32(msg, pos);
MSG_ReadPos32(msg, dir);
color = MSG_ReadByte(&net_message);
count = MSG_ReadByte(&net_message);
color = MSG_ReadByte(msg);
count = MSG_ReadByte(msg);
CL_ParticleEffect(pos, dir, color, count);
}
@ -287,17 +287,17 @@ void CL_ParseParticles (void)
CL_ParseBeam
=================
*/
int CL_ParseBeam (model_t *model)
int CL_ParseBeam( sizebuf_t *msg, model_t *model )
{
int ent;
vec3_t start, end;
beam_t *b;
int i;
ent = MSG_ReadShort (&net_message);
ent = MSG_ReadShort (msg);
MSG_ReadPos32(&net_message, start);
MSG_ReadPos32(&net_message, end);
MSG_ReadPos32(msg, start);
MSG_ReadPos32(msg, end);
// override any beam with the same entity
for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
@ -335,18 +335,18 @@ int CL_ParseBeam (model_t *model)
CL_ParseBeam2
=================
*/
int CL_ParseBeam2 (model_t *model)
int CL_ParseBeam2( sizebuf_t *msg, model_t *model )
{
int ent;
vec3_t start, end, offset;
beam_t *b;
int i;
ent = MSG_ReadShort (&net_message);
ent = MSG_ReadShort (msg);
MSG_ReadPos32(&net_message, start);
MSG_ReadPos32(&net_message, end);
MSG_ReadPos32(&net_message, offset);
MSG_ReadPos32(msg, start);
MSG_ReadPos32(msg, end);
MSG_ReadPos32(msg, offset);
// Msg ("end- %f %f %f\n", end[0], end[1], end[2]);
@ -387,18 +387,18 @@ int CL_ParseBeam2 (model_t *model)
CL_ParseLightning
=================
*/
int CL_ParseLightning (model_t *model)
int CL_ParseLightning( sizebuf_t *msg, model_t *model )
{
int srcEnt, destEnt;
vec3_t start, end;
beam_t *b;
int i;
srcEnt = MSG_ReadShort (&net_message);
destEnt = MSG_ReadShort (&net_message);
srcEnt = MSG_ReadShort (msg);
destEnt = MSG_ReadShort (msg);
MSG_ReadPos32(&net_message, start);
MSG_ReadPos32(&net_message, end);
MSG_ReadPos32(msg, start);
MSG_ReadPos32(msg, end);
// override any beam with the same source AND destination entities
for (i=0, b=cl_beams ; i< MAX_BEAMS ; i++, b++)
@ -440,15 +440,15 @@ int CL_ParseLightning (model_t *model)
CL_ParseLaser
=================
*/
void CL_ParseLaser (int colors)
void CL_ParseLaser( sizebuf_t *msg, int colors )
{
vec3_t start;
vec3_t end;
laser_t *l;
int i;
MSG_ReadPos32(&net_message, start);
MSG_ReadPos32(&net_message, end);
MSG_ReadPos32(msg, start);
MSG_ReadPos32(msg, end);
for (i=0, l=cl_lasers ; i< MAX_LASERS ; i++, l++)
{
@ -474,7 +474,7 @@ CL_ParseTEnt
*/
static byte splash_color[] = {0x00, 0xe0, 0xb0, 0x50, 0xd0, 0xe0, 0xe8};
void CL_ParseTEnt (void)
void CL_ParseTEnt( sizebuf_t *msg )
{
int type;
vec3_t pos, pos2, dir;
@ -484,21 +484,21 @@ void CL_ParseTEnt (void)
int r;
int ent;
type = MSG_ReadByte (&net_message);
type = MSG_ReadByte (msg);
switch (type)
{
case TE_BLOOD: // bullet hitting flesh
MSG_ReadPos32(&net_message, pos);
MSG_ReadPos32(&net_message, dir);
MSG_ReadPos32(msg, pos);
MSG_ReadPos32(msg, dir);
CL_ParticleEffect (pos, dir, 0xe8, 60);
break;
case TE_GUNSHOT: // bullet hitting wall
case TE_SPARKS:
case TE_BULLET_SPARKS:
MSG_ReadPos32(&net_message, pos);
MSG_ReadPos32(&net_message, dir);
MSG_ReadPos32(msg, pos);
MSG_ReadPos32(msg, dir);
if (type == TE_GUNSHOT)
CL_ParticleEffect (pos, dir, 0, 40);
else
@ -522,8 +522,8 @@ void CL_ParseTEnt (void)
case TE_SCREEN_SPARKS:
case TE_SHIELD_SPARKS:
MSG_ReadPos32(&net_message, pos);
MSG_ReadPos32(&net_message, dir);
MSG_ReadPos32(msg, pos);
MSG_ReadPos32(msg, dir);
if (type == TE_SCREEN_SPARKS)
CL_ParticleEffect (pos, dir, 0xd0, 40);
else
@ -533,17 +533,17 @@ void CL_ParseTEnt (void)
break;
case TE_SHOTGUN: // bullet hitting wall
MSG_ReadPos32 (&net_message, pos);
MSG_ReadPos32 (&net_message, dir);
MSG_ReadPos32 (msg, pos);
MSG_ReadPos32 (msg, dir);
CL_ParticleEffect (pos, dir, 0, 20);
CL_SmokeAndFlash(pos);
break;
case TE_SPLASH: // bullet hitting water
cnt = MSG_ReadByte (&net_message);
MSG_ReadPos32 (&net_message, pos);
MSG_ReadPos32 (&net_message, dir);
r = MSG_ReadByte (&net_message);
cnt = MSG_ReadByte (msg);
MSG_ReadPos32 (msg, pos);
MSG_ReadPos32 (msg, dir);
r = MSG_ReadByte (msg);
if (r > 6)
color = 0x00;
else
@ -552,23 +552,23 @@ void CL_ParseTEnt (void)
break;
case TE_LASER_SPARKS:
cnt = MSG_ReadByte (&net_message);
MSG_ReadPos32 (&net_message, pos);
MSG_ReadPos32 (&net_message, dir);
color = MSG_ReadByte (&net_message);
cnt = MSG_ReadByte (msg);
MSG_ReadPos32 (msg, pos);
MSG_ReadPos32 (msg, dir);
color = MSG_ReadByte (msg);
CL_ParticleEffect2 (pos, dir, color, cnt);
break;
// RAFAEL
case TE_BLUEHYPERBLASTER:
MSG_ReadPos32 (&net_message, pos);
MSG_ReadPos32 (&net_message, dir);
MSG_ReadPos32 (msg, pos);
MSG_ReadPos32 (msg, dir);
CL_BlasterParticles (pos, dir);
break;
case TE_BLASTER: // blaster hitting wall
MSG_ReadPos32 (&net_message, pos);
MSG_ReadPos32 (&net_message, dir);
MSG_ReadPos32 (msg, pos);
MSG_ReadPos32 (msg, dir);
CL_BlasterParticles (pos, dir);
ex = CL_AllocExplosion ();
@ -596,8 +596,8 @@ void CL_ParseTEnt (void)
break;
case TE_RAILTRAIL: // railgun effect
MSG_ReadPos32 (&net_message, pos);
MSG_ReadPos32 (&net_message, pos2);
MSG_ReadPos32 (msg, pos);
MSG_ReadPos32 (msg, pos2);
CL_RailTrail (pos, pos2);
S_StartSound (pos2, 0, 0, cl_sfx_railg);
break;
@ -605,7 +605,7 @@ void CL_ParseTEnt (void)
case TE_EXPLOSION2:
case TE_GRENADE_EXPLOSION:
case TE_GRENADE_EXPLOSION_WATER:
MSG_ReadPos32 (&net_message, pos);
MSG_ReadPos32 (msg, pos);
ex = CL_AllocExplosion ();
VectorCopy (pos, ex->ent.origin);
@ -629,7 +629,7 @@ void CL_ParseTEnt (void)
// RAFAEL
case TE_PLASMA_EXPLOSION:
MSG_ReadPos32 (&net_message, pos);
MSG_ReadPos32 (msg, pos);
ex = CL_AllocExplosion ();
VectorCopy (pos, ex->ent.origin);
ex->type = ex_poly;
@ -650,7 +650,7 @@ void CL_ParseTEnt (void)
case TE_EXPLOSION1:
case TE_ROCKET_EXPLOSION:
case TE_ROCKET_EXPLOSION_WATER:
MSG_ReadPos32 (&net_message, pos);
MSG_ReadPos32 (msg, pos);
ex = CL_AllocExplosion ();
VectorCopy (pos, ex->ent.origin);
@ -673,7 +673,7 @@ void CL_ParseTEnt (void)
break;
case TE_BFG_EXPLOSION:
MSG_ReadPos32 (&net_message, pos);
MSG_ReadPos32 (msg, pos);
ex = CL_AllocExplosion ();
VectorCopy (pos, ex->ent.origin);
ex->type = ex_poly;
@ -690,27 +690,27 @@ void CL_ParseTEnt (void)
break;
case TE_BFG_BIGEXPLOSION:
MSG_ReadPos32 (&net_message, pos);
MSG_ReadPos32 (msg, pos);
CL_BFGExplosionParticles (pos);
break;
case TE_BFG_LASER:
CL_ParseLaser (0xd0d1d2d3);
CL_ParseLaser( msg, 0xd0d1d2d3 );
break;
case TE_BUBBLETRAIL:
MSG_ReadPos32 (&net_message, pos);
MSG_ReadPos32 (&net_message, pos2);
MSG_ReadPos32 (msg, pos);
MSG_ReadPos32 (msg, pos2);
CL_BubbleTrail (pos, pos2);
break;
case TE_PARASITE_ATTACK:
case TE_MEDIC_CABLE_ATTACK:
ent = CL_ParseBeam (cl_mod_laser);
ent = CL_ParseBeam( msg, cl_mod_laser );
break;
case TE_BOSSTPORT: // boss teleporting to station
MSG_ReadPos32 (&net_message, pos);
MSG_ReadPos32 (msg, pos);
CL_BigTeleportParticles (pos);
S_StartSound (pos, 0, 0, S_RegisterSound ("misc/bigtele.wav"));
break;
@ -720,10 +720,10 @@ void CL_ParseTEnt (void)
// RAFAEL
case TE_WELDING_SPARKS:
cnt = MSG_ReadByte (&net_message);
MSG_ReadPos32 (&net_message, pos);
MSG_ReadPos32 (&net_message, dir);
color = MSG_ReadByte (&net_message);
cnt = MSG_ReadByte (msg);
MSG_ReadPos32 (msg, pos);
MSG_ReadPos32 (msg, dir);
color = MSG_ReadByte (msg);
CL_ParticleEffect2 (pos, dir, color, cnt);
ex = CL_AllocExplosion ();
@ -742,29 +742,29 @@ void CL_ParseTEnt (void)
break;
case TE_GREENBLOOD:
MSG_ReadPos32 (&net_message, pos);
MSG_ReadPos32 (&net_message, dir);
MSG_ReadPos32 (msg, pos);
MSG_ReadPos32 (msg, dir);
CL_ParticleEffect2 (pos, dir, 0xdf, 30);
break;
case TE_FLASHLIGHT:
MSG_ReadPos32(&net_message, pos);
ent = MSG_ReadShort(&net_message);
MSG_ReadPos32(msg, pos);
ent = MSG_ReadShort(msg);
CL_Flashlight(ent, pos);
break;
case TE_DEBUGTRAIL:
MSG_ReadPos32 (&net_message, pos);
MSG_ReadPos32 (&net_message, pos2);
MSG_ReadPos32 (msg, pos);
MSG_ReadPos32 (msg, pos2);
CL_DebugTrail (pos, pos2);
break;
// RAFAEL
case TE_TUNNEL_SPARKS:
cnt = MSG_ReadByte (&net_message);
MSG_ReadPos32 (&net_message, pos);
MSG_ReadPos32 (&net_message, dir);
color = MSG_ReadByte (&net_message);
cnt = MSG_ReadByte (msg);
MSG_ReadPos32 (msg, pos);
MSG_ReadPos32 (msg, dir);
color = MSG_ReadByte (msg);
CL_ParticleEffect3 (pos, dir, color, cnt);
break;
default:

View File

@ -433,13 +433,6 @@ void V_RenderView( void )
if (cls.state != ca_active) return;
if (!cl.refresh_prepped) return; // still loading
if (cl_timedemo->value)
{
if (!cl.timedemo_start)
cl.timedemo_start = Sys_DoubleTime();
cl.timedemo_frames++;
}
// an invalid frame will just use the exact previous refdef
// we can't use the old frame if the video mode has changed, though...
if ( cl.frame.valid && (cl.force_refdef || !cl_paused->value) )

View File

@ -127,13 +127,10 @@ extern int num_cl_weaponmodels;
//
typedef struct
{
int timeoutcount;
int timeoutcount;
int timedemo_frames;
float timedemo_start;
bool refresh_prepped; // false if on new level or new ref dll
bool force_refdef; // vid has changed, so we can't use a paused refdef
bool refresh_prepped; // false if on new level or new ref dll
bool force_refdef; // vid has changed, so we can't use a paused refdef
int parse_entities; // index (not anded off) into cl_parse_entities[]
@ -244,7 +241,7 @@ typedef struct
float frametime; // seconds since last frame
// connection information
char servername[MAX_OSPATH]; // name of server from original connect
string servername; // name of server from original connect
float connect_time; // for connection retransmits
int quakePort; // a 16 bit value that allows quake servers
@ -257,18 +254,22 @@ typedef struct
file_t *download; // file transfer from server
char downloadtempname[MAX_OSPATH];
char downloadname[MAX_OSPATH];
int downloadnumber;
dltype_t downloadtype;
int downloadpercent;
int downloadnumber;
dltype_t downloadtype;
int downloadpercent;
// demo recording info must be here, so it isn't cleared on level change
bool demorecording;
bool demowaiting; // don't record until a non-delta message is received
bool demorecording;
bool demoplayback;
bool demowaiting; // don't record until a non-delta message is received
string demoname; // for demo looping
file_t *demofile;
// hudprogram stack
byte *hud_program;
uint hud_program_size;
// hudprogram stack
bool cg_init;
char cg_function[MAX_QPATH];
char cg_builtin[MAX_QPATH];
@ -345,7 +346,6 @@ extern cvar_t *freelook;
extern cvar_t *cl_lightlevel; // FIXME HACK
extern cvar_t *cl_paused;
extern cvar_t *cl_timedemo;
extern cvar_t *cl_levelshot_name;
extern cvar_t *cl_vwep;
@ -450,11 +450,11 @@ void CL_WidowSplash (vec3_t org);
// PGM
// ========
int CL_ParseEntityBits (unsigned *bits);
void CL_ParseFrame (void);
int CL_ParseEntityBits( sizebuf_t *msg, uint *bits );
void CL_ParseFrame( sizebuf_t *msg );
void CL_ParseTEnt (void);
void CL_ParseConfigString (void);
void CL_ParseTEnt( sizebuf_t *msg );
void CL_ParseConfigString( sizebuf_t *msg );
void SmokeAndFlash(vec3_t origin);
void CL_SetLightstyle (int i);
@ -478,8 +478,6 @@ void CL_ScreenShot_f( void );
void CL_LevelShot_f( void );
void CL_SetSky_f( void );
void CL_SetFont_f( void );
void CL_ParseLayout (void);
//
// cl_main
@ -534,9 +532,13 @@ char *Key_KeynumToString (int keynum);
//
// cl_demo.c
//
void CL_WriteDemoMessage (void);
void CL_Stop_f (void);
void CL_Record_f (void);
void CL_WriteDemoMessage( void );
void CL_ReadDemoMessage( void );
void CL_StopPlayback( void );
void CL_StopRecord( void );
void CL_PlayDemo_f( void );
void CL_Record_f( void );
void CL_Stop_f( void );
//
// cl_sound.c
@ -597,10 +599,10 @@ extern cvar_t *s_separation;
//
extern char *svc_strings[256];
void CL_ParseServerMessage (void);
void CL_ParseServerMessage( sizebuf_t *msg );
void CL_LoadClientinfo (clientinfo_t *ci, char *s);
void SHOWNET(char *s);
void CL_ParseClientinfo (int player);
void SHOWNET( sizebuf_t *msg, char *s );
void CL_ParseClientinfo( int player );
void CL_Download_f (void);
//

View File

@ -422,7 +422,7 @@ bool Cmd_GetFontList (const char *s, char *completedname, int length )
{
for( i = 0; matchbuf[i]; i++ )
{
if(tolower(completedname[i]) != tolower(matchbuf[i]))
if(com.tolower(completedname[i]) != tolower(matchbuf[i]))
completedname[i] = 0;
}
}
@ -467,7 +467,7 @@ bool Cmd_GetDemoList (const char *s, char *completedname, int length )
{
for( i = 0; matchbuf[i]; i++ )
{
if(tolower(completedname[i]) != tolower(matchbuf[i]))
if(com.tolower(completedname[i]) != tolower(matchbuf[i]))
completedname[i] = 0;
}
}
@ -512,7 +512,7 @@ bool Cmd_GetMovieList (const char *s, char *completedname, int length )
{
for( i = 0; matchbuf[i]; i++ )
{
if(tolower(completedname[i]) != tolower(matchbuf[i]))
if(com.tolower(completedname[i]) != tolower(matchbuf[i]))
completedname[i] = 0;
}
}

View File

@ -57,8 +57,8 @@ LINK32=link.exe
# ADD LINK32 winmm.lib user32.lib msvcrt.lib ole32.lib /nologo /subsystem:windows /dll /pdb:none /machine:I386 /nodefaultlib:"libc.lib" /opt:nowin98
# SUBTRACT LINK32 /debug /nodefaultlib
# Begin Custom Build
TargetDir=\XASH3D\src_main\temp\engine\!release
InputPath=\XASH3D\src_main\temp\engine\!release\engine.dll
TargetDir=\Xash3D\src_main\temp\engine\!release
InputPath=\Xash3D\src_main\temp\engine\!release\engine.dll
SOURCE="$(InputPath)"
"D:\Xash3D\bin\engine.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
@ -94,8 +94,8 @@ LINK32=link.exe
# ADD LINK32 winmm.lib user32.lib msvcrt.lib ole32.lib /nologo /subsystem:windows /dll /debug /machine:I386 /nodefaultlib:"msvcrtd.lib" /pdbtype:sept
# SUBTRACT LINK32 /incremental:no /map /nodefaultlib
# Begin Custom Build
TargetDir=\XASH3D\src_main\temp\engine\!debug
InputPath=\XASH3D\src_main\temp\engine\!debug\engine.dll
TargetDir=\Xash3D\src_main\temp\engine\!debug
InputPath=\Xash3D\src_main\temp\engine\!debug\engine.dll
SOURCE="$(InputPath)"
"D:\Xash3D\bin\engine.dll" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
@ -130,6 +130,10 @@ SOURCE=.\client\cl_console.c
# End Source File
# Begin Source File
SOURCE=.\client\cl_demo.c
# End Source File
# Begin Source File
SOURCE=.\client\cl_ents.c
# End Source File
# Begin Source File
@ -218,6 +222,10 @@ SOURCE=.\server\sv_ents.c
# End Source File
# Begin Source File
SOURCE=.\server\sv_game.c
# End Source File
# Begin Source File
SOURCE=.\server\sv_init.c
# End Source File
# Begin Source File

View File

@ -497,7 +497,7 @@ void MSG_ReadDeltaUsercmd (sizebuf_t *msg_read, usercmd_t *from, usercmd_t *move
move->lightlevel = MSG_ReadByte (msg_read); // read the light level
}
void MSG_ReadDeltaEntity(entity_state_t *from, entity_state_t *to, int number, int bits)
void MSG_ReadDeltaEntity( sizebuf_t *msg_read, entity_state_t *from, entity_state_t *to, int number, int bits )
{
// set everything to the state we are delta'ing from
*to = *from;
@ -505,41 +505,41 @@ void MSG_ReadDeltaEntity(entity_state_t *from, entity_state_t *to, int number, i
VectorCopy (from->origin, to->old_origin);
to->number = number;
if (bits & U_MODEL) to->modelindex = MSG_ReadShort (&net_message);
if (bits & U_WEAPONMODEL) to->weaponmodel = MSG_ReadShort (&net_message);
if (bits & U_MODEL) to->modelindex = MSG_ReadShort (msg_read);
if (bits & U_WEAPONMODEL) to->weaponmodel = MSG_ReadShort (msg_read);
if (bits & U_FRAME ) to->frame = MSG_ReadFloat (&net_message);
if (bits & U_SKIN8 ) to->skin = MSG_ReadByte(&net_message);
if (bits & U_SKIN16) to->skin = MSG_ReadShort(&net_message);
if (bits & U_FRAME ) to->frame = MSG_ReadFloat (msg_read);
if (bits & U_SKIN8 ) to->skin = MSG_ReadByte(msg_read);
if (bits & U_SKIN16) to->skin = MSG_ReadShort(msg_read);
if ( (bits & (U_EFFECTS8|U_EFFECTS16)) == (U_EFFECTS8|U_EFFECTS16) )
to->effects = MSG_ReadLong(&net_message);
else if (bits & U_EFFECTS8 ) to->effects = MSG_ReadByte(&net_message);
else if (bits & U_EFFECTS16) to->effects = MSG_ReadShort(&net_message);
to->effects = MSG_ReadLong(msg_read);
else if (bits & U_EFFECTS8 ) to->effects = MSG_ReadByte(msg_read);
else if (bits & U_EFFECTS16) to->effects = MSG_ReadShort(msg_read);
if ( (bits & (U_RENDERFX8|U_RENDERFX16)) == (U_RENDERFX8|U_RENDERFX16) )
to->renderfx = MSG_ReadLong(&net_message);
else if (bits & U_RENDERFX8 ) to->renderfx = MSG_ReadByte(&net_message);
else if (bits & U_RENDERFX16) to->renderfx = MSG_ReadShort(&net_message);
to->renderfx = MSG_ReadLong(msg_read);
else if (bits & U_RENDERFX8 ) to->renderfx = MSG_ReadByte(msg_read);
else if (bits & U_RENDERFX16) to->renderfx = MSG_ReadShort(msg_read);
if (bits & U_ORIGIN1) to->origin[0] = MSG_ReadCoord32(&net_message);
if (bits & U_ORIGIN2) to->origin[1] = MSG_ReadCoord32(&net_message);
if (bits & U_ORIGIN3) to->origin[2] = MSG_ReadCoord32(&net_message);
if (bits & U_ORIGIN1) to->origin[0] = MSG_ReadCoord32(msg_read);
if (bits & U_ORIGIN2) to->origin[1] = MSG_ReadCoord32(msg_read);
if (bits & U_ORIGIN3) to->origin[2] = MSG_ReadCoord32(msg_read);
if (bits & U_ANGLE1) to->angles[0] = MSG_ReadAngle32(&net_message);
if (bits & U_ANGLE2) to->angles[1] = MSG_ReadAngle32(&net_message);
if (bits & U_ANGLE3) to->angles[2] = MSG_ReadAngle32(&net_message);
if (bits & U_OLDORIGIN) MSG_ReadPos32(&net_message, to->old_origin);
if (bits & U_ANGLE1) to->angles[0] = MSG_ReadAngle32(msg_read);
if (bits & U_ANGLE2) to->angles[1] = MSG_ReadAngle32(msg_read);
if (bits & U_ANGLE3) to->angles[2] = MSG_ReadAngle32(msg_read);
if (bits & U_OLDORIGIN) MSG_ReadPos32(msg_read, to->old_origin);
if (bits & U_SEQUENCE) to->sequence = MSG_ReadByte(&net_message);
if (bits & U_SOLID) to->solid = MSG_ReadLong(&net_message);
if (bits & U_ALPHA) to->alpha = MSG_ReadFloat(&net_message);
if (bits & U_EVENT) to->event = MSG_ReadByte (&net_message);
if (bits & U_SOUNDIDX) to->soundindex = MSG_ReadByte (&net_message);
if (bits & U_SEQUENCE) to->sequence = MSG_ReadByte(msg_read);
if (bits & U_SOLID) to->solid = MSG_ReadLong(msg_read);
if (bits & U_ALPHA) to->alpha = MSG_ReadFloat(msg_read);
if (bits & U_EVENT) to->event = MSG_ReadByte (msg_read);
if (bits & U_SOUNDIDX) to->soundindex = MSG_ReadByte (msg_read);
else to->event = 0;
if (bits & U_BODY) to->body = MSG_ReadByte (&net_message);
if (bits & U_ANIMTIME) to->animtime = MSG_ReadFloat (&net_message);
if (bits & U_BODY) to->body = MSG_ReadByte (msg_read);
if (bits & U_ANIMTIME) to->animtime = MSG_ReadFloat (msg_read);
}
void MSG_ReadData (sizebuf_t *msg_read, void *data, int len)
@ -579,7 +579,7 @@ void *_SZ_GetSpace (sizebuf_t *buf, int length, const char *filename, int fileli
if (buf->cursize + length > buf->maxsize)
{
if (length > buf->maxsize)
Host_Error("SZ_GetSpace: length[%i] > buffer maxsize [%i]\n", length, buf->maxsize );
Host_Error("SZ_GetSpace: length[%i] > buffer maxsize [%i], called at %s:%i\n", length, buf->maxsize, filename, fileline );
MsgWarn("SZ_GetSpace: overflow [cursize %d maxsize %d], called at %s:%i\n", buf->cursize + length, buf->maxsize, filename, fileline );
SZ_Clear (buf);

View File

@ -358,9 +358,9 @@ float MSG_ReadAngle16(sizebuf_t *sb);
float MSG_ReadAngle32(sizebuf_t *sb);
void MSG_ReadPos16(sizebuf_t *sb, vec3_t pos);
void MSG_ReadPos32(sizebuf_t *sb, vec3_t pos);
void MSG_ReadDeltaUsercmd (sizebuf_t *sb, struct usercmd_s *from, struct usercmd_s *cmd);
void MSG_ReadDeltaEntity(entity_state_t *from, entity_state_t *to, int number, int bits);
void MSG_ReadData (sizebuf_t *sb, void *buffer, int size);
void MSG_ReadDeltaUsercmd (sizebuf_t *sb, struct usercmd_s *from, struct usercmd_s *cmd);
void MSG_ReadDeltaEntity(sizebuf_t *sb, entity_state_t *from, entity_state_t *to, int number, int bits);
/*
==============================================================

View File

@ -249,9 +249,9 @@ extern const int vm_sv_numbuiltins;
extern const int vm_cl_numbuiltins;
extern const int vm_m_numbuiltins;
extern char * vm_sv_extensions;
extern char * vm_cl_extensions;
extern char * vm_m_extensions;
extern char *vm_sv_extensions;
extern char *vm_cl_extensions;
extern char *vm_m_extensions;
void VM_SV_Cmd_Init(void);
void VM_SV_Cmd_Reset(void);

View File

@ -101,7 +101,7 @@ bool CG_ExecBuiltins( void );
void CG_MakeLevelShot( void );
void CG_DrawPause( void );
void CG_Init( void );
void CG_ParseInventory( void );
void CG_ParseInventory( sizebuf_t *msg );
void CG_DrawInventory( void );
void CG_DrawLayout( void );

View File

@ -39,10 +39,10 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define SPAWNFLAG_NOT_DEATHMATCH 0x00000800
// client printf level
#define PRINT_LOW 0 // pickup messages
#define PRINT_MEDIUM 1 // death messages
#define PRINT_HIGH 2 // critical messages
#define PRINT_CHAT 3 // chat messages
#define PRINT_LOW 0 // pickup messages
#define PRINT_MEDIUM 1 // death messages
#define PRINT_HIGH 2 // critical messages
#define PRINT_CHAT 3 // chat messages
#define FL_CLIENT (1<<0) // this is client
#define FL_MONSTER (1<<1) // this is npc
@ -59,9 +59,7 @@ typedef enum
ss_dead, // no map loaded
ss_loading, // spawning level edicts
ss_game, // actively running
ss_cinematic,
ss_demo,
ss_cinematic
} sv_state_t;
typedef enum
@ -95,10 +93,6 @@ typedef struct
sizebuf_t multicast;
byte multicast_buf[MAX_MSGLEN];
// demo server information
file_t *demofile;
bool timedemo; // don't time sync
float lastchecktime;
int lastcheck;
@ -253,7 +247,6 @@ void SV_InitGame (void);
void SV_Map(char *levelstring, char *savename );
void SV_SpawnServer (char *server, char *savename, sv_state_t serverstate );
int SV_FindIndex (const char *name, int start, int end, bool create);
void SV_VM_Setup(void);
void SV_VM_Begin(void);
void SV_VM_End(void);
@ -278,7 +271,6 @@ extern char sv_outputbuf[SV_OUTPUTBUF_LENGTH];
void SV_FlushRedirect (int sv_redirected, char *outputbuf);
void SV_DemoCompleted (void);
void SV_SendClientMessages (void);
void SV_AmbientSound( edict_t *entity, int soundindex, float volume, float attenuation );
void SV_StartSound (vec3_t origin, edict_t *entity, int channel, int index, float vol, float attn, float timeofs);
@ -303,7 +295,6 @@ void SV_SectorList_f( void );
// sv_ents.c
//
void SV_WriteFrameToClient (client_state_t *client, sizebuf_t *msg);
void SV_RecordDemoMessage (void);
void SV_BuildClientFrame (client_state_t *client);
void SV_UpdateEntityState( edict_t *ent);
void SV_FatPVS ( vec3_t org );
@ -313,8 +304,9 @@ void SV_Error (char *error, ...);
//
// sv_game.c
//
void SV_InitGameProgs (void);
void SV_ShutdownGameProgs (void);
void SV_InitServerProgs( void );
void SV_FreeServerProgs( void );
void SV_InitEdict (edict_t *e);
void SV_ConfigString (int index, const char *val);
void SV_SetModel (edict_t *ent, const char *name);

View File

@ -0,0 +1,8 @@
//=======================================================================
// Copyright XashXT Group 2008 ©
// sv_client.c - client interactions
//=======================================================================
#include "engine.h"
#include "server.h"

View File

@ -138,38 +138,6 @@ void SV_Map_f( void )
com.strncpy (svs.mapcmd, filename, sizeof(svs.mapcmd) - 1);
}
/*
==================
SV_Demo_f
Playing a demo with specified name
==================
*/
void SV_Demo_f( void )
{
char filename[MAX_QPATH];
if(Cmd_Argc() != 2)
{
Msg("Usage: demo <filename>\n");
return;
}
com.snprintf( filename, MAX_QPATH, "%s.dem", Cmd_Argv(1));
if(!FS_FileExists(va("demos/%s", filename )))
{
Msg("Can't loading %s\n", filename );
return;
}
// the game is just starting
if(sv.state == ss_dead) SV_InitGame();
SV_BroadcastCommand( "changing\n" );
SV_SpawnServer(filename, NULL, ss_demo );
SV_BroadcastCommand( "reconnect\n" );
}
/*
==================
SV_Movie_f
@ -203,6 +171,7 @@ void SV_Movie_f( void )
void SV_Newgame_f( void )
{
// FIXME: do some clear operations
// FIXME: parse newgame script
Cbuf_ExecuteText(EXEC_APPEND, va("map %s\n", GI->startmap ));
}
@ -517,7 +486,6 @@ void SV_InitOperatorCommands( void )
Cmd_AddCommand ("clientinfo", SV_ClientInfo_f, "print user infostring (player num required)" );
Cmd_AddCommand("map", SV_Map_f, "start new level" );
Cmd_AddCommand("demo", SV_Demo_f, "playing a demo file" );
Cmd_AddCommand("newgame", SV_Newgame_f, "begin new game" );
Cmd_AddCommand("movie", SV_Movie_f, "playing video file" );
Cmd_AddCommand("changelevel", SV_ChangeLevel_f, "changing level" );
@ -544,21 +512,18 @@ void SV_KillOperatorCommands( void )
Cmd_RemoveCommand("clientinfo");
Cmd_RemoveCommand("map");
Cmd_RemoveCommand("demo");
Cmd_RemoveCommand("movie");
Cmd_RemoveCommand("newgame");
Cmd_RemoveCommand("changelevel");
Cmd_RemoveCommand("restart");
Cmd_RemoveCommand("sectorlist");
if( dedicated->value )
if( dedicated->integer )
{
Cmd_RemoveCommand("say");
Cmd_RemoveCommand("setmaster");
}
Cmd_RemoveCommand("serverrecord");
Cmd_RemoveCommand("serverstop");
Cmd_RemoveCommand("save");
Cmd_RemoveCommand("load");
Cmd_RemoveCommand("killserver");

248
engine/server/sv_game.c Normal file
View File

@ -0,0 +1,248 @@
//=======================================================================
// Copyright XashXT Group 2008 ©
// sv_game.c - server.dat interface
//=======================================================================
#include "engine.h"
#include "server.h"
void SV_BeginIncreaseEdicts(void)
{
int i;
edict_t *ent;
PRVM_Free( sv.moved_edicts );
sv.moved_edicts = (edict_t **)PRVM_Alloc(prog->max_edicts * sizeof(edict_t *));
// links don't survive the transition, so unlink everything
for (i = 0, ent = prog->edicts; i < prog->max_edicts; i++, ent++)
{
if (!ent->priv.sv->free) SV_UnlinkEdict(prog->edicts + i); //free old entity
memset(&ent->priv.sv->clusternums, 0, sizeof(ent->priv.sv->clusternums));
}
SV_ClearWorld();
}
void SV_EndIncreaseEdicts(void)
{
int i;
edict_t *ent;
for (i = 0, ent = prog->edicts; i < prog->max_edicts; i++, ent++)
{
// link every entity except world
if (!ent->priv.sv->free) SV_LinkEdict(ent);
}
}
/*
=================
SV_InitEdict
Alloc new edict from list
=================
*/
void SV_InitEdict (edict_t *e)
{
e->priv.sv->serialnumber = PRVM_NUM_FOR_EDICT(e);
}
/*
=================
SV_FreeEdict
Marks the edict as free
=================
*/
void SV_FreeEdict( edict_t *ed )
{
// unlink from world
SV_UnlinkEdict( ed );
ed->priv.sv->freetime = sv.time;
ed->priv.sv->free = true;
ed->progs.sv->model = 0;
ed->progs.sv->takedamage = 0;
ed->progs.sv->modelindex = 0;
ed->progs.sv->skin = 0;
ed->progs.sv->frame = 0;
ed->progs.sv->solid = 0;
pe->RemoveBody( ed->priv.sv->physbody );
VectorClear(ed->progs.sv->origin);
VectorClear(ed->progs.sv->angles);
ed->progs.sv->nextthink = -1;
ed->priv.sv->physbody = NULL;
}
void SV_CountEdicts( void )
{
edict_t *ent;
int i, active = 0, models = 0, solid = 0, step = 0;
for (i = 0; i < prog->num_edicts; i++)
{
ent = PRVM_EDICT_NUM(i);
if (ent->priv.sv->free) continue;
active++;
if (ent->progs.sv->solid) solid++;
if (ent->progs.sv->model) models++;
if (ent->progs.sv->movetype == MOVETYPE_STEP) step++;
}
Msg("num_edicts:%3i\n", prog->num_edicts);
Msg("active :%3i\n", active);
Msg("view :%3i\n", models);
Msg("touch :%3i\n", solid);
Msg("step :%3i\n", step);
}
bool SV_LoadEdict( edict_t *ent )
{
int current_skill = (int)Cvar_VariableValue("skill");
// remove things from different skill levels or deathmatch
if(Cvar_VariableValue ("deathmatch"))
{
if( (int)ent->progs.sv->spawnflags & SPAWNFLAG_NOT_DEATHMATCH )
return false;
}
else if(current_skill <= 0 && (int)ent->progs.sv->spawnflags & SPAWNFLAG_NOT_EASY )
return false;
else if(current_skill == 1 && (int)ent->progs.sv->spawnflags & SPAWNFLAG_NOT_MEDIUM)
return false;
else if(current_skill >= 2 && (int)ent->progs.sv->spawnflags & SPAWNFLAG_NOT_HARD )
return false;
return true;
}
void SV_VM_Begin( void )
{
PRVM_Begin;
PRVM_SetProg( PRVM_SERVERPROG );
if( prog ) *prog->time = sv.time;
}
void SV_VM_End( void )
{
PRVM_End;
}
/*
==============
SpawnEntities
Creates a server's entity / program execution context by
parsing textual entity definitions out of an ent file.
==============
*/
void SV_SpawnEntities( const char *mapname, const char *entities )
{
edict_t *ent;
int i;
MsgDev( D_NOTE, "SV_SpawnEntities()\n" );
// used by PushMove to move back pushed entities
sv.moved_edicts = (edict_t **)PRVM_Alloc(prog->max_edicts * sizeof(edict_t *));
prog->protect_world = false; // allow to change world parms
ent = PRVM_EDICT_NUM( 0 );
memset (ent->progs.sv, 0, prog->progs->entityfields * 4);
ent->priv.sv->free = false;
ent->progs.sv->model = PRVM_SetEngineString( sv.configstrings[CS_MODELS] );
ent->progs.sv->modelindex = 1; // world model
ent->progs.sv->solid = SOLID_BSP;
ent->progs.sv->movetype = MOVETYPE_PUSH;
SV_ConfigString (CS_MAXCLIENTS, va("%i", maxclients->integer ));
prog->globals.sv->mapname = PRVM_SetEngineString( sv.name );
// spawn the rest of the entities on the map
*prog->time = sv.time;
// set client fields on player ents
for (i = 1; i < maxclients->value; i++)
{
// setup all clients
ent = PRVM_EDICT_NUM( i );
ent->priv.sv->client = svs.gclients + i - 1;
}
PRVM_ED_LoadFromFile( entities );
prog->protect_world = true; // make world read-only
}
/*
===============
SV_InitGameProgs
Init the game subsystem for a new map
===============
*/
void SV_InitServerProgs( void )
{
Msg("\n");
PRVM_Begin;
PRVM_InitProg( PRVM_SERVERPROG );
prog->reserved_edicts = maxclients->integer;
prog->loadintoworld = true;
if( !prog->loaded )
{
prog->progs_mempool = Mem_AllocPool("Server Progs" );
prog->name = "server";
prog->builtins = vm_sv_builtins;
prog->numbuiltins = vm_sv_numbuiltins;
prog->max_edicts = MAX_EDICTS<<2;
prog->limit_edicts = MAX_EDICTS;
prog->edictprivate_size = sizeof(sv_edict_t);
prog->begin_increase_edicts = SV_BeginIncreaseEdicts;
prog->end_increase_edicts = SV_EndIncreaseEdicts;
prog->init_edict = SV_InitEdict;
prog->free_edict = SV_FreeEdict;
prog->count_edicts = SV_CountEdicts;
prog->load_edict = SV_LoadEdict;
prog->extensionstring = "";
// using default builtins
prog->init_cmd = VM_Cmd_Init;
prog->reset_cmd = VM_Cmd_Reset;
prog->error_cmd = VM_Error;
prog->flag |= PRVM_OP_STATE; // enable op_state feature
PRVM_LoadProgs( "server.dat", 0, NULL, SV_NUM_REQFIELDS, sv_reqfields );
}
PRVM_End;
}
/*
===============
SV_ShutdownGameProgs
Called when either the entire server is being killed, or
it is changing to a different game directory.
===============
*/
void SV_FreeServerProgs( void )
{
edict_t *ent;
int i;
SV_VM_Begin();
for (i = 1; prog && i < prog->num_edicts; i++)
{
ent = PRVM_EDICT_NUM(i);
SV_FreeEdict( ent );// release physic
}
SV_VM_End();
if(!svs.gclients) return;
Mem_Free( svs.gclients );
svs.gclients = NULL;
}

View File

@ -146,11 +146,9 @@ void SV_SpawnServer (char *server, char *savename, sv_state_t serverstate )
{
uint i, checksum;
if(serverstate == ss_demo || serverstate == ss_cinematic)
Cvar_Set ("paused", "0");
if( serverstate == ss_cinematic ) Cvar_Set ("paused", "0");
Msg("SpawnServer [%s]\n", server );
if (sv.demofile) FS_Close (sv.demofile);
svs.spawncount++; // any partially connected client will be restarted
sv.state = ss_dead;
@ -226,7 +224,7 @@ void SV_SpawnServer (char *server, char *savename, sv_state_t serverstate )
if( serverstate == ss_game )
{
// ignore ents for demo or cinematic servers
// ignore ents for cinematic servers
if(sv.loadgame) SV_ReadLevelFile( savename );
else SV_SpawnEntities ( sv.name, pe->GetEntityString());
}
@ -321,7 +319,7 @@ void SV_InitGame (void)
NET_StringToAdr (idmaster, &master_adr[0]);
// init game
SV_InitGameProgs();
SV_InitServerProgs();
SV_VM_Begin();
@ -334,132 +332,4 @@ void SV_InitGame (void)
}
SV_VM_End();
}
void SV_VM_BeginIncreaseEdicts(void)
{
int i;
edict_t *ent;
PRVM_Free( sv.moved_edicts );
sv.moved_edicts = (edict_t **)PRVM_Alloc(prog->max_edicts * sizeof(edict_t *));
// links don't survive the transition, so unlink everything
for (i = 0, ent = prog->edicts; i < prog->max_edicts; i++, ent++)
{
if (!ent->priv.sv->free) SV_UnlinkEdict(prog->edicts + i); //free old entity
memset(&ent->priv.sv->clusternums, 0, sizeof(ent->priv.sv->clusternums));
}
SV_ClearWorld();
}
void SV_VM_EndIncreaseEdicts(void)
{
int i;
edict_t *ent;
for (i = 0, ent = prog->edicts; i < prog->max_edicts; i++, ent++)
{
// link every entity except world
if (!ent->priv.sv->free) SV_LinkEdict(ent);
}
}
void SV_VM_InitEdict(edict_t *e)
{
SV_InitEdict( e );
}
void SV_VM_FreeEdict(edict_t *e)
{
SV_UnlinkEdict(e); // unlink from world bsp
SV_FreeEdict( e );
}
void SV_VM_CountEdicts( void )
{
int i;
edict_t *ent;
int active = 0, models = 0, solid = 0, step = 0;
for (i = 0; i < prog->num_edicts; i++)
{
ent = PRVM_EDICT_NUM(i);
if (ent->priv.sv->free)
continue;
active++;
if (ent->progs.sv->solid) solid++;
if (ent->progs.sv->model) models++;
if (ent->progs.sv->movetype == MOVETYPE_STEP) step++;
}
Msg("num_edicts:%3i\n", prog->num_edicts);
Msg("active :%3i\n", active);
Msg("view :%3i\n", models);
Msg("touch :%3i\n", solid);
Msg("step :%3i\n", step);
}
bool SV_VM_LoadEdict(edict_t *ent)
{
int current_skill = (int)Cvar_VariableValue ("skill");
// remove things from different skill levels or deathmatch
if(Cvar_VariableValue ("deathmatch"))
{
if (((int)ent->progs.sv->spawnflags & SPAWNFLAG_NOT_DEATHMATCH))
{
return false;
}
}
else if ((current_skill <= 0 && ((int)ent->progs.sv->spawnflags & SPAWNFLAG_NOT_EASY )) || (current_skill == 1 && ((int)ent->progs.sv->spawnflags & SPAWNFLAG_NOT_MEDIUM)) || (current_skill >= 2 && ((int)ent->progs.sv->spawnflags & SPAWNFLAG_NOT_HARD )))
{
return false;
}
return true;
}
void SV_VM_Setup( void )
{
PRVM_Begin;
PRVM_InitProg( PRVM_SERVERPROG );
prog->reserved_edicts = maxclients->value;
prog->loadintoworld = true;
if( !prog->loaded )
{
prog->progs_mempool = Mem_AllocPool("Server Progs" );
prog->builtins = vm_sv_builtins;
prog->numbuiltins = vm_sv_numbuiltins;
prog->max_edicts = 512;
prog->limit_edicts = MAX_EDICTS;
prog->edictprivate_size = sizeof(sv_edict_t);
prog->name = "server";
prog->extensionstring = "";
prog->begin_increase_edicts = SV_VM_BeginIncreaseEdicts;
prog->end_increase_edicts = SV_VM_EndIncreaseEdicts;
prog->init_edict = SV_VM_InitEdict;
prog->free_edict = SV_VM_FreeEdict;
prog->count_edicts = SV_VM_CountEdicts;
prog->load_edict = SV_VM_LoadEdict;
prog->init_cmd = VM_Cmd_Init;
prog->reset_cmd = VM_Cmd_Reset;
prog->error_cmd = VM_Error;
PRVM_LoadProgs( "server.dat", 0, NULL, SV_NUM_REQFIELDS, sv_reqfields );
}
PRVM_End;
}
void SV_VM_Begin(void)
{
PRVM_Begin;
PRVM_SetProg( PRVM_SERVERPROG );
if(prog) *prog->time = sv.time;
}
void SV_VM_End(void)
{
PRVM_End;
}

View File

@ -11,8 +11,6 @@ netadr_t master_adr[MAX_MASTERS]; // address of group servers
client_state_t *sv_client; // current client
cvar_t *sv_paused;
cvar_t *sv_timedemo;
cvar_t *sv_enforcetime;
cvar_t *timeout; // seconds without any message
@ -304,8 +302,8 @@ void SVC_DirectConnect( void )
// force the IP key/value pair so the game can filter based on ip
Info_SetValueForKey (userinfo, "ip", NET_AdrToString(net_from));
// demo and movie playback servers are ONLY for local clients
if(Host_ServerState() == ss_demo || Host_ServerState() == ss_cinematic)
// movie playback servers are ONLY for local clients
if(Host_ServerState() == ss_cinematic)
{
if(!NET_IsLocalAddress (adr))
{
@ -753,7 +751,7 @@ void SV_Frame (float time)
SV_ReadPackets ();
// move autonomous things around if enough time has passed
if (!sv_timedemo->value && svs.realtime < sv.time)
if( svs.realtime < sv.time )
{
// never let the time get too far off
if (sv.time - svs.realtime > sv.frametime)
@ -948,7 +946,6 @@ void SV_Init (void)
zombietime = Cvar_Get ("zombietime", "2", 0);
sv_showclamp = Cvar_Get ("showclamp", "0", 0);
sv_paused = Cvar_Get ("paused", "0", 0);
sv_timedemo = Cvar_Get ("timedemo", "0", 0);
sv_enforcetime = Cvar_Get ("sv_enforcetime", "0", 0);
allow_download = Cvar_Get ("allow_download", "1", CVAR_ARCHIVE);
allow_download_players = Cvar_Get ("allow_download_players", "0", CVAR_ARCHIVE);
@ -1028,10 +1025,9 @@ void SV_Shutdown( bool reconnect )
if (svs.clients) SV_FinalMessage( host.finalmsg, reconnect);
Master_Shutdown();
SV_ShutdownGameProgs();
SV_FreeServerProgs();
// free current level
if (sv.demofile) FS_Close (sv.demofile);
memset (&sv, 0, sizeof(sv));
Host_SetServerState (sv.state);

View File

@ -372,7 +372,7 @@ bool Menu_ReadComment( char *comment, int savenum )
if(!savfile)
{
strncpy( comment, "<empty>", MAX_QPATH );
com.strncpy( comment, "<empty>", MAX_QPATH );
return false;
}

View File

@ -450,23 +450,6 @@ bool SV_SendClientDatagram (client_state_t *client)
return true;
}
/*
==================
SV_DemoCompleted
==================
*/
void SV_DemoCompleted (void)
{
if (sv.demofile)
{
FS_Close (sv.demofile);
sv.demofile = NULL;
}
SV_Nextserver ();
}
/*
=======================
SV_RateDrop
@ -515,33 +498,6 @@ void SV_SendClientMessages (void)
msglen = 0;
// read the next demo message if needed
if (sv.state == ss_demo && sv.demofile)
{
if (sv_paused->value) msglen = 0;
else
{
// get the next message
if(!FS_Read (sv.demofile, &msglen, 4))
{
SV_DemoCompleted ();
return;
}
msglen = LittleLong (msglen);
if (msglen == -1)
{
SV_DemoCompleted ();
return;
}
if (msglen > MAX_MSGLEN) Host_Error("SV_SendClientMessages: msglen > MAX_MSGLEN\n");
if(!FS_Read (sv.demofile, msgbuf, msglen))
{
SV_DemoCompleted ();
return;
}
}
}
// send a message to each connected client
for (i = 0, c = svs.clients; i < maxclients->value; i++, c++)
{
@ -556,7 +512,7 @@ void SV_SendClientMessages (void)
SV_DropClient (c);
}
if (sv.state == ss_cinematic || sv.state == ss_demo)
if (sv.state == ss_cinematic )
{
Netchan_Transmit (&c->netchan, msglen, msgbuf);
}

View File

@ -85,83 +85,6 @@ void SV_PutClientInServer (edict_t *ent)
SV_LinkEdict(ent);
}
/*
==============
SpawnEntities
Creates a server's entity / program execution context by
parsing textual entity definitions out of an ent file.
==============
*/
void SV_SpawnEntities( const char *mapname, const char *entities )
{
edict_t *ent;
int i;
MsgDev(D_NOTE, "SV_SpawnEntities()\n");
// used by PushMove to move back pushed entities
sv.moved_edicts = (edict_t **)PRVM_Alloc(prog->max_edicts * sizeof(edict_t *));
prog->protect_world = false; // allow to change world parms
ent = PRVM_EDICT_NUM( 0 );
memset (ent->progs.sv, 0, prog->progs->entityfields * 4);
ent->priv.sv->free = false;
ent->progs.sv->model = PRVM_SetEngineString(sv.configstrings[CS_MODELS]);
ent->progs.sv->modelindex = 1; // world model
ent->progs.sv->solid = SOLID_BSP;
ent->progs.sv->movetype = MOVETYPE_PUSH;
SV_ConfigString (CS_MAXCLIENTS, va("%i", (int)(maxclients->value)));
prog->globals.sv->mapname = PRVM_SetEngineString(sv.name);
// spawn the rest of the entities on the map
*prog->time = sv.time;
// set client fields on player ents
for (i = 1; i < maxclients->value; i++)
{
ent = PRVM_EDICT_NUM( i );
ent->priv.sv->client = svs.gclients + i - 1; // make links
}
PRVM_ED_LoadFromFile( entities );
prog->protect_world = true;// make world read-only
}
void SV_InitEdict (edict_t *e)
{
e->priv.sv->serialnumber = PRVM_NUM_FOR_EDICT(e);
}
/*
=================
SV_FreeEdict
Marks the edict as free
=================
*/
void SV_FreeEdict (edict_t *ed)
{
ed->priv.sv->freetime = sv.time;
ed->priv.sv->free = true;
ed->progs.sv->model = 0;
ed->progs.sv->takedamage = 0;
ed->progs.sv->modelindex = 0;
ed->progs.sv->skin = 0;
ed->progs.sv->frame = 0;
ed->progs.sv->solid = 0;
pe->RemoveBody( ed->priv.sv->physbody );
VectorClear(ed->progs.sv->origin);
VectorClear(ed->progs.sv->angles);
ed->progs.sv->nextthink = -1;
ed->priv.sv->physbody = NULL;
}
/*
============
SV_TouchTriggers

View File

@ -32,21 +32,6 @@ USER STRINGCMD EXECUTION
sv_client and sv_player will be valid.
============================================================
*/
/*
==================
SV_BeginDemoServer
==================
*/
void SV_BeginDemoserver (void)
{
char name[MAX_OSPATH];
sprintf (name, "demos/%s", sv.name);
sv.demofile = FS_Open(name, "rb" );
if (!sv.demofile) Host_Error("Couldn't open %s\n", name);
}
/*
================
SV_New_f
@ -66,13 +51,6 @@ void SV_New_f (void)
return;
}
// demo servers just dump the file message
if (sv.state == ss_demo)
{
SV_BeginDemoserver();
return;
}
// send the serverdata
MSG_WriteByte (&sv_client->netchan.message, svc_serverdata);
MSG_WriteLong (&sv_client->netchan.message, PROTOCOL_VERSION);
@ -366,43 +344,6 @@ void SV_ShowServerinfo_f (void)
Info_Print (Cvar_Serverinfo());
}
void SV_Nextserver (void)
{
char *v;
// can't nextserver while playing a normal game
if (sv.state == ss_game) return;
svs.spawncount++; // make sure another doesn't sneak in
v = Cvar_VariableString ("nextserver");
if (!v[0]) Cbuf_AddText ("killserver\n");
else
{
Cbuf_AddText (v);
Cbuf_AddText ("\n");
}
Cvar_Set ("nextserver","");
}
/*
==================
SV_Nextserver_f
A cinematic has completed or been aborted by a client, so move
to the next server,
==================
*/
void SV_Nextserver_f (void)
{
if ( atoi(Cmd_Argv(1)) != svs.spawncount )
{
MsgWarn("SV_Nextserver_f: loading wrong level, from %s\n", sv_client->name);
return; // leftover from last server
}
SV_Nextserver ();
}
typedef struct
{
char *name;
@ -416,7 +357,6 @@ ucmd_t ucmds[] =
{"configstrings", SV_Configstrings_f},
{"baselines", SV_Baselines_f},
{"begin", SV_Begin_f},
{"nextserver", SV_Nextserver_f},
{"disconnect", SV_Disconnect_f},
{"info", SV_ShowServerinfo_f},
{"download", SV_BeginDownload_f},

View File

@ -1469,43 +1469,3 @@ e10, e10 // #480-499 (LordHavoc)
const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t); //num of builtins
/*
===============
SV_ShutdownGameProgs
Called when either the entire server is being killed, or
it is changing to a different game directory.
===============
*/
void SV_ShutdownGameProgs (void)
{
edict_t *ent;
int i;
SV_VM_Begin();
for (i = 1; prog && i < prog->num_edicts; i++)
{
ent = PRVM_EDICT_NUM(i);
SV_FreeEdict( ent );// release physic
}
SV_VM_End();
if(!svs.gclients) return;
Mem_Free( svs.gclients );
svs.gclients = NULL;
}
/*
===============
SV_InitGameProgs
Init the game subsystem for a new map
===============
*/
void SV_InitGameProgs (void)
{
Msg("\n");
SV_VM_Setup();
}

View File

@ -14,17 +14,24 @@ fopen
1. вернуть обратно roq video OK
2. исправить проигрывание movie после загрузки карты
3. физика игрока на ньютоне
4. избавиться от sv.moved_edicts
1. переписать сервер
1. убить демки на сервере ОК
Список файлов на сервере:
1. Заголовки
server.h - главный заголовок для сервера
sv_game.h - интерфейс между виртуальной машиной и сервером
sv_client.c - игрок на сервере
sv_cmds.c - консольные команды сервера
sv_game.c - ресурсы server.dat
sv_init.c - инициализация сервера
sv_main.c - сервер
sv_world.c - мир на сервере
Alt+Enter для fullscreen