]> de.git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
implemented sv_gameplayfix_multiplethinksperframe
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 16 Jun 2007 22:22:06 +0000 (22:22 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Sat, 16 Jun 2007 22:22:06 +0000 (22:22 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@7432 d7cf8633-e32d-0410-b094-e92efae38249

server.h
sv_main.c
sv_phys.c

index 730e7fcf2347090b0044380050f8a566f92da6ec..07a3eb7012ccd16f603e3d765aa3ba6ca09d292c 100644 (file)
--- a/server.h
+++ b/server.h
@@ -345,6 +345,7 @@ extern cvar_t sv_gameplayfix_blowupfallenzombies;
 extern cvar_t sv_gameplayfix_droptofloorstartsolid;
 extern cvar_t sv_gameplayfix_findradiusdistancetobox;
 extern cvar_t sv_gameplayfix_grenadebouncedownslopes;
+extern cvar_t sv_gameplayfix_multiplethinksperframe;
 extern cvar_t sv_gameplayfix_noairborncorpse;
 extern cvar_t sv_gameplayfix_qwplayerphysics;
 extern cvar_t sv_gameplayfix_setmodelrealbox;
index 3d8ab6d52ffae45fc59fbb22aa0eaace0826b5be..e823572d3ca5831017106e1ed508ff1491750f8a 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -79,6 +79,7 @@ cvar_t sv_gameplayfix_blowupfallenzombies = {0, "sv_gameplayfix_blowupfallenzomb
 cvar_t sv_gameplayfix_droptofloorstartsolid = {0, "sv_gameplayfix_droptofloorstartsolid", "1", "prevents items and monsters that start in a solid area from falling out of the level (makes droptofloor treat trace_startsolid as an acceptable outcome)"};
 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_grenadebouncedownslopes = {0, "sv_gameplayfix_grenadebouncedownslopes", "1", "prevents MOVETYPE_BOUNCE (grenades) from getting stuck when fired down a downward sloping surface"};
+cvar_t sv_gameplayfix_multiplethinksperframe = {0, "sv_gameplayfix_multiplethinksperframe", "1", "allows entities to think more often than the server framerate, primarily useful for very high fire rate weapons"};
 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_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_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"};
@@ -343,6 +344,7 @@ void SV_Init (void)
        Cvar_RegisterVariable (&sv_gameplayfix_droptofloorstartsolid);
        Cvar_RegisterVariable (&sv_gameplayfix_findradiusdistancetobox);
        Cvar_RegisterVariable (&sv_gameplayfix_grenadebouncedownslopes);
+       Cvar_RegisterVariable (&sv_gameplayfix_multiplethinksperframe);
        Cvar_RegisterVariable (&sv_gameplayfix_noairborncorpse);
        Cvar_RegisterVariable (&sv_gameplayfix_qwplayerphysics);
        Cvar_RegisterVariable (&sv_gameplayfix_setmodelrealbox);
index 357327d37e4eb8bb59b5974c5176aa8d726a94d9..3a4a8b005e6e94bb66c847999b3eb47f99f5a26a 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -583,22 +583,27 @@ Returns false if the entity removed itself.
 */
 qboolean SV_RunThink (prvm_edict_t *ent)
 {
-       float thinktime;
-
-       thinktime = ent->fields.server->nextthink;
-       if (thinktime <= 0 || thinktime > sv.time + sv.frametime)
-               return true;
+       int iterations;
 
        // don't let things stay in the past.
        // it is possible to start that way by a trigger with a local time.
-       if (thinktime < sv.time)
-               thinktime = sv.time;
+       if (ent->fields.server->nextthink <= 0 || ent->fields.server->nextthink > sv.time + sv.frametime)
+               return true;
 
-       ent->fields.server->nextthink = 0;
-       prog->globals.server->time = thinktime;
-       prog->globals.server->self = PRVM_EDICT_TO_PROG(ent);
-       prog->globals.server->other = PRVM_EDICT_TO_PROG(prog->edicts);
-       PRVM_ExecuteProgram (ent->fields.server->think, "QC function self.think is missing");
+       for (iterations = 0;iterations < 128  && !ent->priv.server->free;iterations++)
+       {
+               prog->globals.server->time = max(sv.time, ent->fields.server->nextthink);
+               ent->fields.server->nextthink = 0;
+               prog->globals.server->self = PRVM_EDICT_TO_PROG(ent);
+               prog->globals.server->other = PRVM_EDICT_TO_PROG(prog->edicts);
+               PRVM_ExecuteProgram (ent->fields.server->think, "QC function self.think is missing");
+               // mods often set nextthink to time to cause a think every frame,
+               // we don't want to loop in that case, so exit if the new nextthink is
+               // <= the time the qc was told, also exit if it is past the end of the
+               // frame
+               if (ent->fields.server->nextthink <= prog->globals.server->time || ent->fields.server->nextthink > sv.time + sv.frametime || !sv_gameplayfix_multiplethinksperframe.integer)
+                       break;
+       }
        return !ent->priv.server->free;
 }