*/
-cvar_t sv_gravity = {CVAR_NOTIFY, "sv_gravity","800", "how fast you fall (512 = roughly earth gravity)"};
-cvar_t sv_maxvelocity = {CVAR_NOTIFY, "sv_maxvelocity","2000", "universal speed limit on all entities"};
-cvar_t sv_nostep = {CVAR_NOTIFY, "sv_nostep","0", "prevents MOVETYPE_STEP entities (monsters) from moving"};
-cvar_t sv_jumpstep = {CVAR_NOTIFY, "sv_jumpstep", "0", "whether you can step up while jumping (sv_gameplayfix_stepwhilejumping must also be 1)"};
-cvar_t sv_newflymove = {CVAR_NOTIFY, "sv_newflymove", "0", "enables simpler/buggier player physics (not recommended)"};
-cvar_t sv_freezenonclients = {CVAR_NOTIFY, "sv_freezenonclients", "0", "freezes time, except for players, allowing you to walk around and take screenshots of explosions"};
-cvar_t sv_playerphysicsqc = {CVAR_NOTIFY, "sv_playerphysicsqc", "1", "enables QuakeC function to override player physics"};
-cvar_t sv_debugmove = {CVAR_NOTIFY, "sv_debugmove", "0", "disables collision detection optimizations for debugging purposes"};
-
-cvar_t sv_sound_watersplash = {0, "sv_sound_watersplash", "misc/h2ohit1.wav", "sound to play when MOVETYPE_FLY/TOSS/BOUNCE/STEP entity enters or leaves water (empty cvar disables the sound)"};
-cvar_t sv_sound_land = {0, "sv_sound_land", "demon/dland2.wav", "sound to play when MOVETYPE_STEP entity hits the ground at high speed (empty cvar disables the sound)"};
-
-// TODO: move this extern to server.h
-extern cvar_t sv_clmovement_waitforinput;
-
#define MOVE_EPSILON 0.01
void SV_Physics_Toss (prvm_edict_t *ent);
-void SV_Phys_Init (void)
-{
- Cvar_RegisterVariable(&sv_stepheight);
- Cvar_RegisterVariable(&sv_jumpstep);
- Cvar_RegisterVariable(&sv_wallfriction);
- Cvar_RegisterVariable(&sv_newflymove);
- Cvar_RegisterVariable(&sv_freezenonclients);
- Cvar_RegisterVariable(&sv_playerphysicsqc);
- Cvar_RegisterVariable(&sv_debugmove);
-
- Cvar_RegisterVariable(&sv_sound_watersplash);
- Cvar_RegisterVariable(&sv_sound_land);
-}
-
/*
===============================================================================
PRVM_G_FLOAT(OFS_PARM0) = ent->fields.server->watertype;
// New Contents
PRVM_G_FLOAT(OFS_PARM1) = nContents;
+ // Assign Self
+ prog->globals.server->self = PRVM_EDICT_TO_PROG(ent);
// Execute VM Function
PRVM_ExecuteProgram(contentstransition->function, "contentstransition: NULL function");
}
*/
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;
}
==================
*/
extern void VM_SetTraceGlobals(const trace_t *trace);
+extern sizebuf_t vm_tempstringsbuf;
void SV_Impact (prvm_edict_t *e1, trace_t *trace)
{
+ int restorevm_tempstringsbuf_cursize;
int old_self, old_other;
prvm_edict_t *e2 = (prvm_edict_t *)trace->ent;
prvm_eval_t *val;
old_self = prog->globals.server->self;
old_other = prog->globals.server->other;
+ restorevm_tempstringsbuf_cursize = vm_tempstringsbuf.cursize;
VM_SetTraceGlobals(trace);
prog->globals.server->self = old_self;
prog->globals.server->other = old_other;
+ vm_tempstringsbuf.cursize = restorevm_tempstringsbuf_cursize;
}
case MOVETYPE_FLYMISSILE:
case MOVETYPE_FLY:
// regular thinking
- if (SV_RunThink (ent) && runmove)
+ if (SV_RunThink (ent) && (runmove || !sv_gameplayfix_delayprojectiles.integer))
SV_Physics_Toss (ent);
break;
default: