]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - sv_main.c
added force_centerview to glx (by moving it to vid_shared)
[xonotic/darkplaces.git] / sv_main.c
index fc1cf11598ef8d7462f64c9038b8f42a65fc98f6..783e65363d7eb436fd06b2f1a6518c4531b3fb86 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -35,18 +35,7 @@ SV_Init
 */
 void SV_Init (void)
 {
-       int             i;
-       extern  cvar_t  sv_maxvelocity;
-       extern  cvar_t  sv_gravity;
-       extern  cvar_t  sv_nostep;
-       extern  cvar_t  sv_friction;
-       extern  cvar_t  sv_edgefriction;
-       extern  cvar_t  sv_stopspeed;
-       extern  cvar_t  sv_maxspeed;
-       extern  cvar_t  sv_accelerate;
-       extern  cvar_t  sv_idealpitchscale;
-       extern  cvar_t  sv_aim;
-       extern  cvar_t  sv_predict;
+       int i;
 
        Cvar_RegisterVariable (&sv_maxvelocity);
        Cvar_RegisterVariable (&sv_gravity);
@@ -59,8 +48,9 @@ void SV_Init (void)
        Cvar_RegisterVariable (&sv_aim);
        Cvar_RegisterVariable (&sv_nostep);
        Cvar_RegisterVariable (&sv_predict);
+       Cvar_RegisterVariable (&sv_deltacompress);
 
-       for (i=0 ; i<MAX_MODELS ; i++)
+       for (i = 0;i < MAX_MODELS;i++)
                sprintf (localmodels[i], "*%i", i);
 }
 
@@ -86,9 +76,9 @@ void SV_StartParticle (vec3_t org, vec3_t dir, int color, int count)
        if (sv.datagram.cursize > MAX_DATAGRAM-16)
                return; 
        MSG_WriteByte (&sv.datagram, svc_particle);
-       MSG_WriteCoord (&sv.datagram, org[0]);
-       MSG_WriteCoord (&sv.datagram, org[1]);
-       MSG_WriteCoord (&sv.datagram, org[2]);
+       MSG_WriteFloatCoord (&sv.datagram, org[0]);
+       MSG_WriteFloatCoord (&sv.datagram, org[1]);
+       MSG_WriteFloatCoord (&sv.datagram, org[2]);
        for (i=0 ; i<3 ; i++)
        {
                v = dir[i]*16;
@@ -102,6 +92,41 @@ void SV_StartParticle (vec3_t org, vec3_t dir, int color, int count)
        MSG_WriteByte (&sv.datagram, color);
 }           
 
+/*  
+==================
+SV_StartEffect
+
+Make sure the event gets sent to all clients
+==================
+*/
+void SV_StartEffect (vec3_t org, int modelindex, int startframe, int framecount, int framerate)
+{
+       if (sv.datagram.cursize > MAX_DATAGRAM-18)
+               return; 
+       if (modelindex >= 256 || startframe >= 256)
+       {
+               MSG_WriteByte (&sv.datagram, svc_effect2);
+               MSG_WriteFloatCoord (&sv.datagram, org[0]);
+               MSG_WriteFloatCoord (&sv.datagram, org[1]);
+               MSG_WriteFloatCoord (&sv.datagram, org[2]);
+               MSG_WriteShort (&sv.datagram, modelindex);
+               MSG_WriteShort (&sv.datagram, startframe);
+               MSG_WriteByte (&sv.datagram, framecount);
+               MSG_WriteByte (&sv.datagram, framerate);
+       }
+       else
+       {
+               MSG_WriteByte (&sv.datagram, svc_effect);
+               MSG_WriteFloatCoord (&sv.datagram, org[0]);
+               MSG_WriteFloatCoord (&sv.datagram, org[1]);
+               MSG_WriteFloatCoord (&sv.datagram, org[2]);
+               MSG_WriteByte (&sv.datagram, modelindex);
+               MSG_WriteByte (&sv.datagram, startframe);
+               MSG_WriteByte (&sv.datagram, framecount);
+               MSG_WriteByte (&sv.datagram, framerate);
+       }
+}           
+
 /*  
 ==================
 SV_StartSound
@@ -110,7 +135,7 @@ Each entity can have eight independant sound sources, like voice,
 weapon, feet, etc.
 
 Channel 0 is an auto-allocate channel, the others override anything
-allready running on that entity/channel pair.
+already running on that entity/channel pair.
 
 An attenuation of 0 will play full volume everywhere in the level.
 Larger attenuations will drop off.  (max 4 attenuation)
@@ -159,17 +184,23 @@ void SV_StartSound (edict_t *entity, int channel, char *sample, int volume,
        if (attenuation != DEFAULT_SOUND_PACKET_ATTENUATION)
                field_mask |= SND_ATTENUATION;
 
-// directed messages go only to the entity the are targeted on
-       MSG_WriteByte (&sv.datagram, svc_sound);
+// directed messages go only to the entity they are targeted on
+       if (sound_num >= 256)
+               MSG_WriteByte (&sv.datagram, svc_sound2);
+       else
+               MSG_WriteByte (&sv.datagram, svc_sound);
        MSG_WriteByte (&sv.datagram, field_mask);
        if (field_mask & SND_VOLUME)
                MSG_WriteByte (&sv.datagram, volume);
        if (field_mask & SND_ATTENUATION)
                MSG_WriteByte (&sv.datagram, attenuation*64);
        MSG_WriteShort (&sv.datagram, channel);
-       MSG_WriteByte (&sv.datagram, sound_num);
+       if (sound_num >= 256)
+               MSG_WriteShort (&sv.datagram, sound_num);
+       else
+               MSG_WriteByte (&sv.datagram, sound_num);
        for (i=0 ; i<3 ; i++)
-               MSG_WriteCoord (&sv.datagram, entity->v.origin[i]+0.5*(entity->v.mins[i]+entity->v.maxs[i]));
+               MSG_WriteFloatCoord (&sv.datagram, entity->v.origin[i]+0.5*(entity->v.mins[i]+entity->v.maxs[i]));
 }           
 
 /*
@@ -198,7 +229,7 @@ void SV_SendServerinfo (client_t *client)
        MSG_WriteString (&client->message,message);
 
        MSG_WriteByte (&client->message, svc_serverinfo);
-       MSG_WriteLong (&client->message, PROTOCOL_VERSION);
+       MSG_WriteLong (&client->message, DPPROTOCOL_VERSION);
        MSG_WriteByte (&client->message, svs.maxclients);
 
        if (!coop.value && deathmatch.value)
@@ -422,10 +453,10 @@ SV_WriteEntitiesToClient
 */
 void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
 {
-       int             e, i, clentnum, bits, alpha, glowcolor, glowsize, scale, colormod, modred, modgreen, modblue, dodelta, effects;
+       int             e, i, clentnum, bits, alpha, glowcolor, glowsize, scale, colormod, effects;
        byte    *pvs;
        vec3_t  org, origin, angles;
-       float   movelerp, moveilerp;
+       float   movelerp, moveilerp, nextfullupdate;
        edict_t *ent;
        eval_t  *val;
        entity_state_t *baseline; // LordHavoc: delta or startup baseline
@@ -446,15 +477,23 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
        clentnum = EDICT_TO_PROG(clent); // LordHavoc: for comparison purposes
 // send over all entities (except the client) that touch the pvs
        ent = NEXT_EDICT(sv.edicts);
-       for (e=1 ; e<sv.num_edicts ; e++, ent = NEXT_EDICT(ent))
+       for (e = 1;e < sv.num_edicts;e++, ent = NEXT_EDICT(ent))
        {
                bits = 0;
+
+               // prevent delta compression against this frame (unless actually sent, which will restore this later)
+               nextfullupdate = client->nextfullupdate[e];
+               client->nextfullupdate[e] = -1;
+
                if (ent != clent) // LordHavoc: always send player
                {
                        if ((val = GETEDICTFIELDVALUE(ent, eval_viewmodelforclient)) && val->edict)
                        {
                                if (val->edict != clentnum)
-                                       continue; // don't show to anyone else
+                               {
+                                       // don't show to anyone else
+                                       continue;
+                               }
                                else
                                        bits |= U_VIEWMODEL; // show relative to the view
                        }
@@ -466,15 +505,21 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                                if ((val = GETEDICTFIELDVALUE(ent, eval_drawonlytoclient)) && val->edict && val->edict != clentnum)
                                        continue;
                                // ignore if not touching a PV leaf
-                               for (i=0 ; i < ent->num_leafs ; i++)
+                               for (i = 0;i < ent->num_leafs;i++)
                                        if (pvs[ent->leafnums[i] >> 3] & (1 << (ent->leafnums[i]&7) ))
                                                break;
                                        
                                if (i == ent->num_leafs)
-                                       continue;               // not visible
+                               {
+                                       // not visible
+                                       continue;
+                               }
                        }
                }
 
+               if ((val = GETEDICTFIELDVALUE(ent, eval_exteriormodeltoclient)) && val->edict == clentnum)
+                       bits = bits | U_EXTERIORMODEL;
+
                // don't send if flagged for NODRAW and there are no effects
                alpha = 255;
                scale = 16;
@@ -484,12 +529,17 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                effects = ent->v.effects;
 
                if ((val = GETEDICTFIELDVALUE(ent, eval_alpha)))
-               if ((alpha = (int) (val->_float * 255.0)) == 0)
-                       alpha = 255;
-               if ((val = GETEDICTFIELDVALUE(ent, eval_renderamt)) && val->_float != 0) // HalfLife support
+               if (val->_float != 0)
+                       alpha = (int) (val->_float * 255.0);
+
+               // HalfLife support
+               if ((val = GETEDICTFIELDVALUE(ent, eval_renderamt)))
+               if (val->_float != 0)
                        alpha = (int) val->_float;
-               if (alpha < 0) alpha = 0;
-               if (alpha > 255) alpha = 255;
+
+               if (alpha == 0)
+                       alpha = 255;
+               alpha = bound(0, alpha, 255);
 
                if ((val = GETEDICTFIELDVALUE(ent, eval_glow_size)))
                        glowsize = (int) val->_float >> 2;
@@ -515,16 +565,11 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
 
                if ((val = GETEDICTFIELDVALUE(ent, eval_colormod)))
                if (val->vector[0] != 0 || val->vector[1] != 0 || val->vector[2] != 0)
-               {
-                       modred = val->vector[0] * 8.0;if (modred < 0) modred = 0;if (modred > 7) modred = 7;
-                       modgreen = val->vector[1] * 8.0;if (modgreen < 0) modgreen = 0;if (modgreen > 7) modgreen = 7;
-                       modblue = val->vector[2] * 4.0;if (modblue < 0) modblue = 0;if (modblue > 3) modblue = 3;
-                       colormod = (modred << 5) | (modgreen << 2) | modblue;
-               }
+                       colormod = (bound(0, (int) (val->vector[0] * 8.0), 7) << 5) | (bound(0, (int) (val->vector[1] * 8.0), 7) << 2) | bound(0, (int) (val->vector[2] * 4.0), 3);
 
                if (ent != clent)
                {
-                       if (glowsize == 0 && bits == 0) // no effects
+                       if (glowsize == 0 && (bits & U_GLOWTRAIL) == 0) // no effects
                        {
                                if (ent->v.modelindex && pr_strings[ent->v.model]) // model
                                {
@@ -539,29 +584,35 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                if (msg->maxsize - msg->cursize < 32) // LordHavoc: increased check from 16 to 32
                {
                        Con_Printf ("packet overflow\n");
+                       // mark the rest of the entities so they can't be delta compressed against this frame
+                       for (;e < sv.num_edicts;e++)
+                               client->nextfullupdate[e] = -1;
                        return;
                }
 
 // send an update
-               bits = 0;
+               baseline = &ent->baseline;
 
-               dodelta = FALSE;
-               if ((int)ent->v.effects & EF_DELTA)
-                       dodelta = sv.time < client->nextfullupdate[e]; // every half second a full update is forced
-
-               if (dodelta)
+               if (((int)ent->v.effects & EF_DELTA) && sv_deltacompress.value)
                {
-                       bits |= U_DELTA;
-                       baseline = &ent->deltabaseline;
+                       // every half second a full update is forced
+                       if (realtime < client->nextfullupdate[e])
+                       {
+                               bits |= U_DELTA;
+                               baseline = &ent->deltabaseline;
+                       }
+                       else
+                               nextfullupdate = realtime + 0.5f;
                }
                else
-               {
-                       client->nextfullupdate[e] = sv.time + 0.5;
-                       baseline = &ent->baseline;
-               }
+                       nextfullupdate = realtime + 0.5f;
+
+               // restore nextfullupdate since this is being sent
+               client->nextfullupdate[e] = nextfullupdate;
 
                if (e >= 256)
                        bits |= U_LONGENTITY;
+
                if (ent->v.movetype == MOVETYPE_STEP)
                        bits |= U_STEP;
                
@@ -619,17 +670,20 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                }
 
                // LordHavoc: old stuff, but rewritten to have more exact tolerances
-               if ((int)(origin[0]*8.0) != (int)(baseline->origin[0]*8.0))                                             bits |= U_ORIGIN1;
-               if ((int)(origin[1]*8.0) != (int)(baseline->origin[1]*8.0))                                             bits |= U_ORIGIN2;
-               if ((int)(origin[2]*8.0) != (int)(baseline->origin[2]*8.0))                                             bits |= U_ORIGIN3;
+//             if ((int)(origin[0]*8.0) != (int)(baseline->origin[0]*8.0))                                             bits |= U_ORIGIN1;
+//             if ((int)(origin[1]*8.0) != (int)(baseline->origin[1]*8.0))                                             bits |= U_ORIGIN2;
+//             if ((int)(origin[2]*8.0) != (int)(baseline->origin[2]*8.0))                                             bits |= U_ORIGIN3;
+               if (origin[0] != baseline->origin[0])                                                                                   bits |= U_ORIGIN1;
+               if (origin[1] != baseline->origin[1])                                                                                   bits |= U_ORIGIN2;
+               if (origin[2] != baseline->origin[2])                                                                                   bits |= U_ORIGIN3;
                if ((int)(angles[0]*(256.0/360.0)) != (int)(baseline->angles[0]*(256.0/360.0))) bits |= U_ANGLE1;
                if ((int)(angles[1]*(256.0/360.0)) != (int)(baseline->angles[1]*(256.0/360.0))) bits |= U_ANGLE2;
                if ((int)(angles[2]*(256.0/360.0)) != (int)(baseline->angles[2]*(256.0/360.0))) bits |= U_ANGLE3;
-               if (baseline->colormap != (int) ent->v.colormap)                                                                bits |= U_COLORMAP;
-               if (baseline->skin != (int) ent->v.skin)                                                                                bits |= U_SKIN;
+               if (baseline->colormap != (byte) ent->v.colormap)                                                               bits |= U_COLORMAP;
+               if (baseline->skin != (byte) ent->v.skin)                                                                               bits |= U_SKIN;
                if ((baseline->frame & 0x00FF) != ((int) ent->v.frame & 0x00FF))                                bits |= U_FRAME;
                if ((baseline->effects & 0x00FF) != ((int) ent->v.effects & 0x00FF))                    bits |= U_EFFECTS;
-               if (baseline->modelindex != (int) ent->v.modelindex)                                                    bits |= U_MODEL;
+               if ((baseline->modelindex & 0x00FF) != ((int) ent->v.modelindex & 0x00FF))              bits |= U_MODEL;
 
                // LordHavoc: new stuff
                if (baseline->alpha != alpha)                                                                                                   bits |= U_ALPHA;
@@ -639,6 +693,7 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                if (baseline->glowcolor != glowcolor)                                                                                   bits |= U_GLOWCOLOR;
                if (baseline->colormod != colormod)                                                                                             bits |= U_COLORMOD;
                if (((int) baseline->frame & 0xFF00) != ((int) ent->v.frame & 0xFF00))                  bits |= U_FRAME2;
+               if (((int) baseline->frame & 0xFF00) != ((int) ent->v.modelindex & 0xFF00))             bits |= U_MODEL2;
 
                // update delta baseline
                VectorCopy(ent->v.origin, ent->deltabaseline.origin);
@@ -654,6 +709,9 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                ent->deltabaseline.glowcolor = glowcolor;
                ent->deltabaseline.colormod = colormod;
 
+               if (bits & (U_ALPHA | U_SCALE | U_EFFECTS2 | U_GLOWSIZE | U_GLOWCOLOR | U_COLORMOD | U_FRAME2 | U_MODEL2))
+                       i = -1;
+
                // write the message
                if (bits >= 16777216)
                        bits |= U_EXTEND2;
@@ -682,11 +740,11 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                if (bits & U_COLORMAP)  MSG_WriteByte (msg, ent->v.colormap);
                if (bits & U_SKIN)              MSG_WriteByte (msg, ent->v.skin);
                if (bits & U_EFFECTS)   MSG_WriteByte (msg, ent->v.effects);
-               if (bits & U_ORIGIN1)   MSG_WriteCoord (msg, origin[0]);
+               if (bits & U_ORIGIN1)   MSG_WriteFloatCoord (msg, origin[0]);
                if (bits & U_ANGLE1)    MSG_WriteAngle(msg, angles[0]);
-               if (bits & U_ORIGIN2)   MSG_WriteCoord (msg, origin[1]);
+               if (bits & U_ORIGIN2)   MSG_WriteFloatCoord (msg, origin[1]);
                if (bits & U_ANGLE2)    MSG_WriteAngle(msg, angles[1]);
-               if (bits & U_ORIGIN3)   MSG_WriteCoord (msg, origin[2]);
+               if (bits & U_ORIGIN3)   MSG_WriteFloatCoord (msg, origin[2]);
                if (bits & U_ANGLE3)    MSG_WriteAngle(msg, angles[2]);
 
                // LordHavoc: new stuff
@@ -697,6 +755,7 @@ void SV_WriteEntitiesToClient (client_t *client, edict_t *clent, sizebuf_t *msg)
                if (bits & U_GLOWCOLOR) MSG_WriteByte(msg, glowcolor);
                if (bits & U_COLORMOD)  MSG_WriteByte(msg, colormod);
                if (bits & U_FRAME2)    MSG_WriteByte(msg, (int)ent->v.frame >> 8);
+               if (bits & U_MODEL2)    MSG_WriteByte(msg, (int)ent->v.modelindex >> 8);
        }
 }
 
@@ -732,6 +791,7 @@ void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
        edict_t *other;
        int             items;
        eval_t  *val;
+       vec3_t  punchvector;
 
 //
 // send a damage message
@@ -743,7 +803,7 @@ void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
                MSG_WriteByte (msg, ent->v.dmg_save);
                MSG_WriteByte (msg, ent->v.dmg_take);
                for (i=0 ; i<3 ; i++)
-                       MSG_WriteCoord (msg, other->v.origin[i] + 0.5*(other->v.mins[i] + other->v.maxs[i]));
+                       MSG_WriteFloatCoord (msg, other->v.origin[i] + 0.5*(other->v.mins[i] + other->v.maxs[i]));
        
                ent->v.dmg_take = 0;
                ent->v.dmg_save = 0;
@@ -788,10 +848,17 @@ void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
        if ( ent->v.waterlevel >= 2)
                bits |= SU_INWATER;
        
+       // dpprotocol
+       VectorClear(punchvector);
+       if ((val = GETEDICTFIELDVALUE(ent, eval_punchvector)))
+               VectorCopy(val->vector, punchvector);
+
        for (i=0 ; i<3 ; i++)
        {
                if (ent->v.punchangle[i])
                        bits |= (SU_PUNCH1<<i);
+               if (punchvector[i]) // dpprotocol
+                       bits |= (SU_PUNCHVEC1<<i); // dpprotocol
                if (ent->v.velocity[i])
                        bits |= (SU_VELOCITY1<<i);
        }
@@ -805,10 +872,19 @@ void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
 //     if (ent->v.weapon)
                bits |= SU_WEAPON;
 
+       if (bits >= 65536)
+               bits |= SU_EXTEND1;
+       if (bits >= 16777216)
+               bits |= SU_EXTEND2;
+
 // send the data
 
        MSG_WriteByte (msg, svc_clientdata);
        MSG_WriteShort (msg, bits);
+       if (bits & SU_EXTEND1)
+               MSG_WriteByte(msg, bits >> 16);
+       if (bits & SU_EXTEND2)
+               MSG_WriteByte(msg, bits >> 24);
 
        if (bits & SU_VIEWHEIGHT)
                MSG_WriteChar (msg, ent->v.view_ofs[2]);
@@ -819,7 +895,9 @@ void SV_WriteClientdataToMessage (edict_t *ent, sizebuf_t *msg)
        for (i=0 ; i<3 ; i++)
        {
                if (bits & (SU_PUNCH1<<i))
-                       MSG_WriteChar (msg, ent->v.punchangle[i]);
+                       MSG_WritePreciseAngle(msg, ent->v.punchangle[i]); // dpprotocol
+               if (bits & (SU_PUNCHVEC1<<i)) // dpprotocol
+                       MSG_WriteFloatCoord(msg, punchvector[i]); // dpprotocol
                if (bits & (SU_VELOCITY1<<i))
                        MSG_WriteChar (msg, ent->v.velocity[i]/16);
        }
@@ -1069,21 +1147,25 @@ SV_CreateBaseline
 */
 void SV_CreateBaseline (void)
 {
-       int                     i;
-       edict_t                 *svent;
-       int                             entnum; 
-               
-       for (entnum = 0; entnum < sv.num_edicts ; entnum++)
+       int i, entnum, large;
+       edict_t *svent;
+
+       // LordHavoc: clear *all* states (note just active ones)
+       for (entnum = 0; entnum < MAX_EDICTS ; entnum++)
        {
-       // get the current server version
+               // get the current server version
                svent = EDICT_NUM(entnum);
+
+               // LordHavoc: always clear state values, whether the entity is in use or not
+               ClearStateToDefault(&svent->baseline);
+
                if (svent->free)
                        continue;
                if (entnum > svs.maxclients && !svent->v.modelindex)
                        continue;
 
        //
-       // create entity baseline
+               // create entity baseline
        //
                VectorCopy (svent->v.origin, svent->baseline.origin);
                VectorCopy (svent->v.angles, svent->baseline.angles);
@@ -1097,28 +1179,36 @@ void SV_CreateBaseline (void)
                else
                {
                        svent->baseline.colormap = 0;
-                       svent->baseline.modelindex =
-                               SV_ModelIndex(pr_strings + svent->v.model);
+                       svent->baseline.modelindex = svent->v.modelindex; //SV_ModelIndex(pr_strings + svent->v.model);
                }
-               svent->baseline.alpha = 255;
-               svent->baseline.scale = 16;
-               svent->baseline.glowsize = 0;
-               svent->baseline.glowcolor = 254;
-               svent->baseline.colormod = 255;
-               
+
+               large = false;
+               if (svent->baseline.modelindex & 0xFF00 || svent->baseline.frame & 0xFF00)
+                       large = true;
        //
-       // add to the message
+               // add to the message
        //
-               MSG_WriteByte (&sv.signon,svc_spawnbaseline);           
-               MSG_WriteShort (&sv.signon,entnum);
+               if (large)
+                       MSG_WriteByte (&sv.signon, svc_spawnbaseline2);
+               else
+                       MSG_WriteByte (&sv.signon, svc_spawnbaseline);
+               MSG_WriteShort (&sv.signon, entnum);
 
-               MSG_WriteByte (&sv.signon, svent->baseline.modelindex);
-               MSG_WriteByte (&sv.signon, svent->baseline.frame);
+               if (large)
+               {
+                       MSG_WriteShort (&sv.signon, svent->baseline.modelindex);
+                       MSG_WriteShort (&sv.signon, svent->baseline.frame);
+               }
+               else
+               {
+                       MSG_WriteByte (&sv.signon, svent->baseline.modelindex);
+                       MSG_WriteByte (&sv.signon, svent->baseline.frame);
+               }
                MSG_WriteByte (&sv.signon, svent->baseline.colormap);
                MSG_WriteByte (&sv.signon, svent->baseline.skin);
                for (i=0 ; i<3 ; i++)
                {
-                       MSG_WriteCoord(&sv.signon, svent->baseline.origin[i]);
+                       MSG_WriteFloatCoord(&sv.signon, svent->baseline.origin[i]);
                        MSG_WriteAngle(&sv.signon, svent->baseline.angles[i]);
                }
        }
@@ -1302,7 +1392,6 @@ void SV_SpawnServer (char *server)
        ent->v.modelindex = 1;          // world model
        ent->v.solid = SOLID_BSP;
        ent->v.movetype = MOVETYPE_PUSH;
-       ent->v.angles[0] = ent->v.angles[1] = ent->v.angles[2] = 0;
 
        if (coop.value)
                pr_global_struct->coop = coop.value;
@@ -1316,7 +1405,7 @@ void SV_SpawnServer (char *server)
        
        ED_LoadFromFile (sv.worldmodel->entities);
        // LordHavoc: clear world angles (to fix e3m3.bsp)
-       sv.edicts->v.angles[0] = sv.edicts->v.angles[1] = sv.edicts->v.angles[2] = 0;
+       VectorClear(sv.edicts->v.angles);
 
        sv.active = true;
 
@@ -1324,7 +1413,7 @@ void SV_SpawnServer (char *server)
        sv.state = ss_active;
        
 // run two frames to allow everything to settle
-       host_frametime = 0.1;
+       sv.frametime = pr_global_struct->frametime = host_frametime = 0.1;
        SV_Physics ();
        SV_Physics ();