From: havoc Date: Sat, 16 Jun 2007 22:22:06 +0000 (+0000) Subject: implemented sv_gameplayfix_multiplethinksperframe X-Git-Tag: xonotic-v0.1.0preview~3029 X-Git-Url: http://git.xonotic.org/?a=commitdiff_plain;h=ad3882107f0d4c034ede6b13ba15a23086be4f6d;p=xonotic%2Fdarkplaces.git implemented sv_gameplayfix_multiplethinksperframe git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@7432 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/server.h b/server.h index 730e7fcf..07a3eb70 100644 --- 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; diff --git a/sv_main.c b/sv_main.c index 3d8ab6d5..e823572d 100644 --- 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); diff --git a/sv_phys.c b/sv_phys.c index 357327d3..3a4a8b00 100644 --- 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; }