]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - host.c
Several changes to the SFX lock code in the sound engine, mainly to make sure SFXs...
[xonotic/darkplaces.git] / host.c
diff --git a/host.c b/host.c
index a9b94def6706cef0454b939f40fa307b086acdcf..ad337c596e6d73ebc3618e1b7be6faa24fef6f22 100644 (file)
--- a/host.c
+++ b/host.c
@@ -406,7 +406,9 @@ void SV_DropClient(qboolean crash)
        int i;
        Con_Printf("Client \"%s\" dropped\n", host_client->name);
 
-       // send any final messages (don't check for errors)
+       // make sure edict is not corrupt (from a level change for example)
+       host_client->edict = EDICT_NUM(host_client - svs.clients + 1);
+
        if (host_client->netconnection)
        {
                // free the client (the body stays around)
@@ -416,27 +418,25 @@ void SV_DropClient(qboolean crash)
                        MSG_WriteByte(&host_client->message, svc_disconnect);
                        NetConn_SendUnreliableMessage(host_client->netconnection, &host_client->message);
                }
-
                // break the net connection
                NetConn_Close(host_client->netconnection);
                host_client->netconnection = NULL;
+       }
 
-               // LordHavoc: don't call QC if server is dead (avoids recursive
-               // Host_Error in some mods when they run out of edicts)
-               if (sv.active && host_client->edict && host_client->spawned)
-               {
-                       // call the prog function for removing a client
-                       // this will set the body to a dead frame, among other things
-                       int saveSelf = pr_global_struct->self;
-                       pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
-                       PR_ExecuteProgram(pr_global_struct->ClientDisconnect, "QC function ClientDisconnect is missing");
-                       pr_global_struct->self = saveSelf;
-               }
+       // call qc ClientDisconnect function
+       // LordHavoc: don't call QC if server is dead (avoids recursive
+       // Host_Error in some mods when they run out of edicts)
+       if (host_client->active && sv.active && host_client->edict && host_client->spawned)
+       {
+               // call the prog function for removing a client
+               // this will set the body to a dead frame, among other things
+               int saveSelf = pr_global_struct->self;
+               pr_global_struct->self = EDICT_TO_PROG(host_client->edict);
+               PR_ExecuteProgram(pr_global_struct->ClientDisconnect, "QC function ClientDisconnect is missing");
+               pr_global_struct->self = saveSelf;
        }
 
        // remove leaving player from scoreboard
-       // clear a fields that matter to DP_SV_CLIENTNAME and DP_SV_CLIENTCOLORS, and also frags
-       ED_ClearEdict(host_client->edict);
        //host_client->edict->v->netname = PR_SetString(host_client->name);
        //if ((val = GETEDICTFIELDVALUE(host_client->edict, eval_clientcolors)))
        //      val->_float = 0;
@@ -464,6 +464,13 @@ void SV_DropClient(qboolean crash)
                EntityFrame4_FreeDatabase(host_client->entitydatabase4);
        if (host_client->entitydatabase5)
                EntityFrame5_FreeDatabase(host_client->entitydatabase5);
+       
+       if (sv.active)
+       {
+               // clear a fields that matter to DP_SV_CLIENTNAME and DP_SV_CLIENTCOLORS, and also frags
+               ED_ClearEdict(host_client->edict);
+       }
+       
        // clear the client struct (this sets active to false)
        memset(host_client, 0, sizeof(*host_client));
 
@@ -590,9 +597,23 @@ qboolean Host_FilterTime (double time)
        timeleft = (oldrealtime - realtime) + timecap;
        if (timeleft > 0)
        {
+               int msleft;
                // don't totally hog the CPU
-               if (timeleft >= 0.03)
-                       Sys_Sleep((int)(timeleft * 1000) - 10);
+               if (cls.state == ca_dedicated)
+               {
+                       // if dedicated, try to use as little cpu as possible by waiting
+                       // just a little longer than necessary
+                       // (yes this means it doesn't quite keep up with the framerate)
+                       msleft = (int)ceil(timeleft * 1000);
+               }
+               else
+               {
+                       // if not dedicated, try to hit exactly a steady framerate by not
+                       // sleeping the full amount
+                       msleft = (int)floor(timeleft * 1000);
+               }
+               if (msleft > 0)
+                       Sys_Sleep(msleft);
                return false;
        }
 
@@ -913,6 +934,7 @@ void Host_Init (void)
        if (cls.state != ca_dedicated)
        {
                VID_Open();
+               CL_InitTEnts ();  // We must wait after sound startup to load tent sounds
                SCR_BeginLoadingPlaque();
                MR_Init();
        }