]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - sv_main.c
implemented sv_gameplayfix_qwplayerphysics
[xonotic/darkplaces.git] / sv_main.c
index 84c5e042b15a6a3085082e71280e72b68e6c0c75..9463489c32cfa152bfd134e0c1ffde4d064e1881 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -43,12 +43,13 @@ static cvar_t sv_entpatch = {0, "sv_entpatch", "1", "enables loading of .ent fil
 
 cvar_t sv_gameplayfix_grenadebouncedownslopes = {0, "sv_gameplayfix_grenadebouncedownslopes", "1", "prevents MOVETYPE_BOUNCE (grenades) from getting stuck when fired down a downward sloping surface"};
 cvar_t sv_gameplayfix_noairborncorpse = {0, "sv_gameplayfix_noairborncorpse", "1", "causes entities (corpses) sitting ontop of moving entities (players) to fall when the moving entity (player) is no longer supporting them"};
-cvar_t sv_gameplayfix_stepdown = {0, "sv_gameplayfix_stepdown", "1", "attempts to step down stairs, not just up them (prevents the familiar thud..thud..thud.. when running down stairs and slopes)"};
+cvar_t sv_gameplayfix_stepdown = {0, "sv_gameplayfix_stepdown", "0", "attempts to step down stairs, not just up them (prevents the familiar thud..thud..thud.. when running down stairs and slopes)"};
 cvar_t sv_gameplayfix_stepwhilejumping = {0, "sv_gameplayfix_stepwhilejumping", "1", "applies step-up onto a ledge even while airborn, useful if you would otherwise just-miss the floor when running across small areas with gaps (for instance running across the moving platforms in dm2, or jumping to the megahealth and red armor in dm2 rather than using the bridge)"};
 cvar_t sv_gameplayfix_swiminbmodels = {0, "sv_gameplayfix_swiminbmodels", "1", "causes pointcontents (used to determine if you are in a liquid) to check bmodel entities as well as the world model, so you can swim around in (possibly moving) water bmodel entities"};
 cvar_t sv_gameplayfix_setmodelrealbox = {0, "sv_gameplayfix_setmodelrealbox", "1", "fixes a bug in Quake that made setmodel always set the entity box to ('-16 -16 -16', '16 16 16') rather than properly checking the model box, breaks some poorly coded mods"};
 cvar_t sv_gameplayfix_blowupfallenzombies = {0, "sv_gameplayfix_blowupfallenzombies", "1", "causes findradius to detect SOLID_NOT entities such as zombies and corpses on the floor, allowing splash damage to apply to them"};
 cvar_t sv_gameplayfix_findradiusdistancetobox = {0, "sv_gameplayfix_findradiusdistancetobox", "1", "causes findradius to check the distance to the corner of a box rather than the center of the box, makes findradius detect bmodels such as very large doors that would otherwise be unaffected by splash damage"};
+cvar_t sv_gameplayfix_qwplayerphysics = {0, "sv_gameplayfix_qwplayerphysics", "1", "changes water jumping to make it easier to get out of water, and prevents friction on landing when bunnyhopping"};
 
 cvar_t sv_progs = {0, "sv_progs", "progs.dat", "selects which quakec progs.dat file to run" };
 
@@ -74,11 +75,14 @@ void SV_Init (void)
        Cvar_RegisterVariable (&sv_maxvelocity);
        Cvar_RegisterVariable (&sv_gravity);
        Cvar_RegisterVariable (&sv_friction);
+       Cvar_RegisterVariable (&sv_waterfriction);
        Cvar_RegisterVariable (&sv_edgefriction);
        Cvar_RegisterVariable (&sv_stopspeed);
        Cvar_RegisterVariable (&sv_maxspeed);
        Cvar_RegisterVariable (&sv_maxairspeed);
        Cvar_RegisterVariable (&sv_accelerate);
+       Cvar_RegisterVariable (&sv_airaccelerate);
+       Cvar_RegisterVariable (&sv_wateraccelerate);
        Cvar_RegisterVariable (&sv_idealpitchscale);
        Cvar_RegisterVariable (&sv_aim);
        Cvar_RegisterVariable (&sv_nostep);
@@ -94,6 +98,7 @@ void SV_Init (void)
        Cvar_RegisterVariable (&sv_gameplayfix_setmodelrealbox);
        Cvar_RegisterVariable (&sv_gameplayfix_blowupfallenzombies);
        Cvar_RegisterVariable (&sv_gameplayfix_findradiusdistancetobox);
+       Cvar_RegisterVariable (&sv_gameplayfix_qwplayerphysics);
        Cvar_RegisterVariable (&sv_protocolname);
        Cvar_RegisterVariable (&sv_ratelimitlocalplayer);
        Cvar_RegisterVariable (&sv_maxrate);
@@ -136,7 +141,7 @@ Make sure the event gets sent to all clients
 */
 void SV_StartParticle (vec3_t org, vec3_t dir, int color, int count)
 {
-       int             i, v;
+       int i;
 
        if (sv.datagram.cursize > MAX_PACKETFRAGMENT-18)
                return;
@@ -145,14 +150,7 @@ void SV_StartParticle (vec3_t org, vec3_t dir, int color, int count)
        MSG_WriteCoord (&sv.datagram, org[1], sv.protocol);
        MSG_WriteCoord (&sv.datagram, org[2], sv.protocol);
        for (i=0 ; i<3 ; i++)
-       {
-               v = dir[i]*16;
-               if (v > 127)
-                       v = 127;
-               else if (v < -128)
-                       v = -128;
-               MSG_WriteChar (&sv.datagram, v);
-       }
+               MSG_WriteChar (&sv.datagram, (int)bound(-128, dir[i]*16, 127));
        MSG_WriteByte (&sv.datagram, count);
        MSG_WriteByte (&sv.datagram, color);
 }
@@ -257,7 +255,7 @@ void SV_StartSound (prvm_edict_t *entity, int channel, const char *sample, int v
        if (field_mask & SND_VOLUME)
                MSG_WriteByte (&sv.datagram, volume);
        if (field_mask & SND_ATTENUATION)
-               MSG_WriteByte (&sv.datagram, attenuation*64);
+               MSG_WriteByte (&sv.datagram, (int)(attenuation*64));
        if (field_mask & SND_LARGEENTITY)
        {
                MSG_WriteShort (&sv.datagram, ent);
@@ -327,7 +325,7 @@ void SV_SendServerinfo (client_t *client)
 
        SZ_Clear (&client->netconnection->message);
        MSG_WriteByte (&client->netconnection->message, svc_print);
-       dpsnprintf (message, sizeof (message), "\002\nServer: %s build %s (progs %i crc)", gamename, buildstring, prog->filecrc);
+       dpsnprintf (message, sizeof (message), "\nServer: %s build %s (progs %i crc)", gamename, buildstring, prog->filecrc);
        MSG_WriteString (&client->netconnection->message,message);
 
        // FIXME: LordHavoc: this does not work on dedicated servers, needs fixing.
@@ -362,8 +360,8 @@ void SV_SendServerinfo (client_t *client)
 
 // send music
        MSG_WriteByte (&client->netconnection->message, svc_cdtrack);
-       MSG_WriteByte (&client->netconnection->message, prog->edicts->fields.server->sounds);
-       MSG_WriteByte (&client->netconnection->message, prog->edicts->fields.server->sounds);
+       MSG_WriteByte (&client->netconnection->message, (int)prog->edicts->fields.server->sounds);
+       MSG_WriteByte (&client->netconnection->message, (int)prog->edicts->fields.server->sounds);
 
 // set view
        MSG_WriteByte (&client->netconnection->message, svc_setview);
@@ -426,10 +424,10 @@ void SV_ConnectClient (int clientnum, netconn_t *netconnection)
                PRVM_ExecuteProgram (prog->globals.server->SetNewParms, "QC function SetNewParms is missing");
                for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
                        client->spawn_parms[i] = (&prog->globals.server->parm1)[i];
-       }
 
-       // set up the entity for this client (including .colormap, .team, etc)
-       PRVM_ED_ClearEdict(client->edict);
+               // set up the entity for this client (including .colormap, .team, etc)
+               PRVM_ED_ClearEdict(client->edict);
+       }
 
        // don't call SendServerinfo for a fresh botclient because its fields have
        // not been set up by the qc yet
@@ -526,9 +524,9 @@ qboolean SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *cs, int
                if (effects & 32)
                {
                        effects &= ~32;
-                       light[0] = 0.2;
-                       light[1] = 1;
-                       light[2] = 0.2;
+                       light[0] = (int)(0.2*256);
+                       light[1] = (int)(1.0*256);
+                       light[2] = (int)(0.2*256);
                        light[3] = 200;
                        lightpflags |= PFLAGS_FULLDYNAMIC;
                }
@@ -600,9 +598,9 @@ qboolean SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *cs, int
        val = PRVM_GETEDICTFIELDVALUE(ent, eval_colormod);
        if (val->vector[0] || val->vector[1] || val->vector[2])
        {
-               i = val->vector[0] * 32.0f;cs->colormod[0] = bound(0, i, 255);
-               i = val->vector[1] * 32.0f;cs->colormod[1] = bound(0, i, 255);
-               i = val->vector[2] * 32.0f;cs->colormod[2] = bound(0, i, 255);
+               i = (int)(val->vector[0] * 32.0f);cs->colormod[0] = bound(0, i, 255);
+               i = (int)(val->vector[1] * 32.0f);cs->colormod[1] = bound(0, i, 255);
+               i = (int)(val->vector[2] * 32.0f);cs->colormod[2] = bound(0, i, 255);
        }
 
        cs->modelindex = modelindex;
@@ -680,8 +678,9 @@ qboolean SV_PrepareEntityForSending (prvm_edict_t *ent, entity_state_t *cs, int
        }
        else
        {
-               VectorCopy(cs->origin, cullmins);
-               VectorCopy(cs->origin, cullmaxs);
+               // if there is no model (or it could not be loaded), use the physics box
+               VectorAdd(cs->origin, ent->fields.server->mins, cullmins);
+               VectorAdd(cs->origin, ent->fields.server->maxs, cullmaxs);
        }
        if (specialvisibilityradius)
        {
@@ -829,7 +828,7 @@ void SV_MarkWriteEntityStateToClient(entity_state_t *s)
                                testorigin[0] = (ed->priv.server->cullmins[0] + ed->priv.server->cullmaxs[0]) * 0.5f;
                                testorigin[1] = (ed->priv.server->cullmins[1] + ed->priv.server->cullmaxs[1]) * 0.5f;
                                testorigin[2] = (ed->priv.server->cullmins[2] + ed->priv.server->cullmaxs[2]) * 0.5f;
-                               sv.worldmodel->TraceBox(sv.worldmodel, 0, &trace, sv_writeentitiestoclient_testeye, sv_writeentitiestoclient_testeye, testorigin, testorigin, SUPERCONTENTS_SOLID);
+                               sv.worldmodel->TraceBox(sv.worldmodel, 0, &trace, sv_writeentitiestoclient_testeye, vec3_origin, vec3_origin, testorigin, SUPERCONTENTS_SOLID);
                                if (trace.fraction == 1 || BoxesOverlap(trace.endpos, trace.endpos, ed->priv.server->cullmins, ed->priv.server->cullmaxs))
                                        sv_writeentitiestoclient_client->visibletime[s->number] = realtime + 1;
                                else
@@ -838,7 +837,7 @@ void SV_MarkWriteEntityStateToClient(entity_state_t *s)
                                        testorigin[0] = lhrandom(ed->priv.server->cullmins[0], ed->priv.server->cullmaxs[0]);
                                        testorigin[1] = lhrandom(ed->priv.server->cullmins[1], ed->priv.server->cullmaxs[1]);
                                        testorigin[2] = lhrandom(ed->priv.server->cullmins[2], ed->priv.server->cullmaxs[2]);
-                                       sv.worldmodel->TraceBox(sv.worldmodel, 0, &trace, sv_writeentitiestoclient_testeye, sv_writeentitiestoclient_testeye, testorigin, testorigin, SUPERCONTENTS_SOLID);
+                                       sv.worldmodel->TraceBox(sv.worldmodel, 0, &trace, sv_writeentitiestoclient_testeye, vec3_origin, vec3_origin, testorigin, SUPERCONTENTS_SOLID);
                                        if (trace.fraction == 1 || BoxesOverlap(trace.endpos, trace.endpos, ed->priv.server->cullmins, ed->priv.server->cullmaxs))
                                                sv_writeentitiestoclient_client->visibletime[s->number] = realtime + 1;
                                        else
@@ -849,7 +848,7 @@ void SV_MarkWriteEntityStateToClient(entity_state_t *s)
                                                        testorigin[0] = lhrandom(ed->priv.server->cullmins[0], ed->priv.server->cullmaxs[0]);
                                                        testorigin[1] = lhrandom(ed->priv.server->cullmins[1], ed->priv.server->cullmaxs[1]);
                                                        testorigin[2] = lhrandom(ed->priv.server->cullmins[2], ed->priv.server->cullmaxs[2]);
-                                                       sv.worldmodel->TraceBox(sv.worldmodel, 0, &trace, sv_writeentitiestoclient_testeye, sv_writeentitiestoclient_testeye, testorigin, testorigin, SUPERCONTENTS_SOLID);
+                                                       sv.worldmodel->TraceBox(sv.worldmodel, 0, &trace, sv_writeentitiestoclient_testeye, vec3_origin, vec3_origin, testorigin, SUPERCONTENTS_SOLID);
                                                        if (trace.fraction == 1 || BoxesOverlap(trace.endpos, trace.endpos, ed->priv.server->cullmins, ed->priv.server->cullmaxs))
                                                                sv_writeentitiestoclient_client->visibletime[s->number] = realtime + 1;
                                                }
@@ -961,7 +960,7 @@ void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t
        int             items;
        prvm_eval_t     *val;
        vec3_t  punchvector;
-       unsigned char   viewzoom;
+       int             viewzoom;
        const char *s;
 
 //
@@ -971,8 +970,8 @@ void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t
        {
                other = PRVM_PROG_TO_EDICT(ent->fields.server->dmg_inflictor);
                MSG_WriteByte (msg, svc_damage);
-               MSG_WriteByte (msg, ent->fields.server->dmg_save);
-               MSG_WriteByte (msg, ent->fields.server->dmg_take);
+               MSG_WriteByte (msg, (int)ent->fields.server->dmg_save);
+               MSG_WriteByte (msg, (int)ent->fields.server->dmg_take);
                for (i=0 ; i<3 ; i++)
                        MSG_WriteCoord (msg, other->fields.server->origin[i] + 0.5*(other->fields.server->mins[i] + other->fields.server->maxs[i]), sv.protocol);
 
@@ -1017,7 +1016,7 @@ void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t
 
        viewzoom = 255;
        if ((val = PRVM_GETEDICTFIELDVALUE(ent, eval_viewzoom)))
-               viewzoom = val->_float * 255.0f;
+               viewzoom = (int)(val->_float * 255.0f);
        if (viewzoom == 0)
                viewzoom = 255;
 
@@ -1042,18 +1041,18 @@ void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t
        }
 
        memset(stats, 0, sizeof(int[MAX_CL_STATS]));
-       stats[STAT_VIEWHEIGHT] = ent->fields.server->view_ofs[2];
+       stats[STAT_VIEWHEIGHT] = (int)ent->fields.server->view_ofs[2];
        stats[STAT_ITEMS] = items;
-       stats[STAT_WEAPONFRAME] = ent->fields.server->weaponframe;
-       stats[STAT_ARMOR] = ent->fields.server->armorvalue;
+       stats[STAT_WEAPONFRAME] = (int)ent->fields.server->weaponframe;
+       stats[STAT_ARMOR] = (int)ent->fields.server->armorvalue;
        stats[STAT_WEAPON] = client->weaponmodelindex;
-       stats[STAT_HEALTH] = ent->fields.server->health;
-       stats[STAT_AMMO] = ent->fields.server->currentammo;
-       stats[STAT_SHELLS] = ent->fields.server->ammo_shells;
-       stats[STAT_NAILS] = ent->fields.server->ammo_nails;
-       stats[STAT_ROCKETS] = ent->fields.server->ammo_rockets;
-       stats[STAT_CELLS] = ent->fields.server->ammo_cells;
-       stats[STAT_ACTIVEWEAPON] = ent->fields.server->weapon;
+       stats[STAT_HEALTH] = (int)ent->fields.server->health;
+       stats[STAT_AMMO] = (int)ent->fields.server->currentammo;
+       stats[STAT_SHELLS] = (int)ent->fields.server->ammo_shells;
+       stats[STAT_NAILS] = (int)ent->fields.server->ammo_nails;
+       stats[STAT_ROCKETS] = (int)ent->fields.server->ammo_rockets;
+       stats[STAT_CELLS] = (int)ent->fields.server->ammo_cells;
+       stats[STAT_ACTIVEWEAPON] = (int)ent->fields.server->weapon;
        stats[STAT_VIEWZOOM] = viewzoom;
        // the QC bumps these itself by sending svc_'s, so we have to keep them
        // zero or they'll be corrected by the engine
@@ -1092,14 +1091,14 @@ void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t
                MSG_WriteChar (msg, stats[STAT_VIEWHEIGHT]);
 
        if (bits & SU_IDEALPITCH)
-               MSG_WriteChar (msg, ent->fields.server->idealpitch);
+               MSG_WriteChar (msg, (int)ent->fields.server->idealpitch);
 
        for (i=0 ; i<3 ; i++)
        {
                if (bits & (SU_PUNCH1<<i))
                {
                        if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE)
-                               MSG_WriteChar(msg, ent->fields.server->punchangle[i]);
+                               MSG_WriteChar(msg, (int)ent->fields.server->punchangle[i]);
                        else
                                MSG_WriteAngle16i(msg, ent->fields.server->punchangle[i]);
                }
@@ -1113,7 +1112,7 @@ void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t
                if (bits & (SU_VELOCITY1<<i))
                {
                        if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4)
-                               MSG_WriteChar(msg, ent->fields.server->velocity[i] * (1.0f / 16.0f));
+                               MSG_WriteChar(msg, (int)(ent->fields.server->velocity[i] * (1.0f / 16.0f)));
                        else
                                MSG_WriteCoord32f(msg, ent->fields.server->velocity[i]);
                }
@@ -1138,7 +1137,7 @@ void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t
                MSG_WriteShort (msg, stats[STAT_CELLS]);
                MSG_WriteShort (msg, stats[STAT_ACTIVEWEAPON]);
                if (bits & SU_VIEWZOOM)
-                       MSG_WriteShort (msg, min(stats[STAT_VIEWZOOM], 65535));
+                       MSG_WriteShort (msg, bound(0, stats[STAT_VIEWZOOM], 65535));
        }
        else if (sv.protocol == PROTOCOL_QUAKE || sv.protocol == PROTOCOL_QUAKEDP || sv.protocol == PROTOCOL_NEHAHRAMOVIE || sv.protocol == PROTOCOL_DARKPLACES1 || sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4)
        {
@@ -1166,9 +1165,9 @@ void SV_WriteClientdataToMessage (client_t *client, prvm_edict_t *ent, sizebuf_t
                if (bits & SU_VIEWZOOM)
                {
                        if (sv.protocol == PROTOCOL_DARKPLACES2 || sv.protocol == PROTOCOL_DARKPLACES3 || sv.protocol == PROTOCOL_DARKPLACES4)
-                               MSG_WriteByte (msg, min(stats[STAT_VIEWZOOM], 255));
+                               MSG_WriteByte (msg, bound(0, stats[STAT_VIEWZOOM], 255));
                        else
-                               MSG_WriteShort (msg, min(stats[STAT_VIEWZOOM], 65535));
+                               MSG_WriteShort (msg, bound(0, stats[STAT_VIEWZOOM], 65535));
                }
        }
 }
@@ -1246,7 +1245,7 @@ void SV_SendClientDatagram (client_t *client)
        }
 
 // send the datagram
-       NetConn_SendUnreliableMessage (client->netconnection, &msg);
+       NetConn_SendUnreliableMessage (client->netconnection, &msg, sv.protocol);
 }
 
 /*
@@ -1349,6 +1348,9 @@ void SV_SendClientMessages (void)
 {
        int i, prepared = false;
 
+       if (sv.protocol == PROTOCOL_QUAKEWORLD)
+               Sys_Error("SV_SendClientMessages: no quakeworld support\n");
+
 // update frags, names, etc
        SV_UpdateToReliableMessages();
 
@@ -1513,8 +1515,8 @@ void SV_CreateBaseline (void)
                // create entity baseline
                VectorCopy (svent->fields.server->origin, svent->priv.server->baseline.origin);
                VectorCopy (svent->fields.server->angles, svent->priv.server->baseline.angles);
-               svent->priv.server->baseline.frame = svent->fields.server->frame;
-               svent->priv.server->baseline.skin = svent->fields.server->skin;
+               svent->priv.server->baseline.frame = (int)svent->fields.server->frame;
+               svent->priv.server->baseline.skin = (int)svent->fields.server->skin;
                if (entnum > 0 && entnum <= svs.maxclients)
                {
                        svent->priv.server->baseline.colormap = entnum;
@@ -1523,7 +1525,7 @@ void SV_CreateBaseline (void)
                else
                {
                        svent->priv.server->baseline.colormap = 0;
-                       svent->priv.server->baseline.modelindex = svent->fields.server->modelindex;
+                       svent->priv.server->baseline.modelindex = (int)svent->fields.server->modelindex;
                }
 
                large = false;
@@ -1570,7 +1572,7 @@ void SV_SaveSpawnparms (void)
 {
        int             i, j;
 
-       svs.serverflags = prog->globals.server->serverflags;
+       svs.serverflags = (int)prog->globals.server->serverflags;
 
        for (i = 0, host_client = svs.clients;i < svs.maxclients;i++, host_client++)
        {
@@ -1670,9 +1672,15 @@ void SV_SpawnServer (const char *server)
 //
        if (sv.active)
        {
-               // Tell all the clients that the server is changing levels
-               MSG_WriteByte(&sv.reliable_datagram, svc_stufftext);
-               MSG_WriteString(&sv.reliable_datagram, "reconnect\n");
+               client_t *client;
+               for (i = 0, client = svs.clients;i < svs.maxclients;i++, client++)
+               {
+                       if (client->netconnection)
+                       {
+                               MSG_WriteByte(&client->netconnection->message, svc_stufftext);
+                               MSG_WriteString(&client->netconnection->message, "reconnect\n");
+                       }
+               }
        }
        else
        {
@@ -1693,9 +1701,10 @@ void SV_SpawnServer (const char *server)
 //
 // set up the new server
 //
-       Host_ClearMemory ();
-
        memset (&sv, 0, sizeof(sv));
+       // if running a local client, make sure it doesn't try to access the last
+       // level's data which is no longer valiud
+       cls.signon = 0;
 
        SV_VM_Setup();
 
@@ -1819,10 +1828,7 @@ void SV_SpawnServer (const char *server)
        }
 
        // load replacement entity file if found
-       entities = NULL;
-       if (sv_entpatch.integer)
-               entities = (char *)FS_LoadFile(va("maps/%s.ent", sv.name), tempmempool, true, NULL);
-       if (entities)
+       if (sv_entpatch.integer && (entities = (char *)FS_LoadFile(va("maps/%s.ent", sv.name), tempmempool, true, NULL)))
        {
                Con_Printf("Loaded maps/%s.ent\n", sv.name);
                PRVM_ED_LoadFromFile (entities);
@@ -1842,7 +1848,7 @@ void SV_SpawnServer (const char *server)
 // run two frames to allow everything to settle
        for (i = 0;i < 2;i++)
        {
-               sv.frametime = host_frametime = 0.1;
+               sv.frametime = 0.1;
                SV_Physics ();
        }
 
@@ -2150,6 +2156,12 @@ int eval_playerskin;
 int eval_SendEntity;
 int eval_Version;
 int eval_customizeentityforclient;
+int eval_dphitcontentsmask;
+
+int gval_trace_dpstartcontents;
+int gval_trace_dphitcontents;
+int gval_trace_dphitq3surfaceflags;
+int gval_trace_dphittexturename;
 
 mfunction_t *SV_PlayerPhysicsQC;
 mfunction_t *EndFrameQC;
@@ -2222,6 +2234,7 @@ void SV_VM_FindEdictFieldOffsets(void)
        eval_SendEntity = PRVM_ED_FindFieldOffset("SendEntity");
        eval_Version = PRVM_ED_FindFieldOffset("Version");
        eval_customizeentityforclient = PRVM_ED_FindFieldOffset("customizeentityforclient");
+       eval_dphitcontentsmask = PRVM_ED_FindFieldOffset("dphitcontentsmask");
 
        // LordHavoc: allowing QuakeC to override the player movement code
        SV_PlayerPhysicsQC = PRVM_ED_FindFunction ("SV_PlayerPhysics");
@@ -2235,6 +2248,11 @@ void SV_VM_FindEdictFieldOffsets(void)
                SV_InitCmd = PRVM_G_STRING(PRVM_ED_FindGlobal("SV_InitCmd")->ofs);
        else
                SV_InitCmd = NULL;
+
+       gval_trace_dpstartcontents = PRVM_ED_FindGlobalOffset("trace_dpstartcontents");
+       gval_trace_dphitcontents = PRVM_ED_FindGlobalOffset("trace_dphitcontents");
+       gval_trace_dphitq3surfaceflags = PRVM_ED_FindGlobalOffset("trace_dphitq3surfaceflags");
+       gval_trace_dphittexturename = PRVM_ED_FindGlobalOffset("trace_dphittexturename");
 }
 
 #define REQFIELDS (sizeof(reqfields) / sizeof(prvm_required_field_t))