]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - svvm_cmds.c
protocol/dp8: Implement parting messages
[xonotic/darkplaces.git] / svvm_cmds.c
index aacc8568c5039bf155c3bb1323805a409e22f295..672ff70d1f8e7116237d6f81737fe2b8012a014b 100644 (file)
 
 
 
-const char *vm_sv_extensions =
-"BX_WAL_SUPPORT "
-"DP_BUTTONCHAT "
-"DP_BUTTONUSE "
-"DP_CL_LOADSKY "
-"DP_CON_ALIASPARAMETERS "
-"DP_CON_BESTWEAPON "
-"DP_CON_EXPANDCVAR "
-"DP_CON_SET "
-"DP_CON_SETA "
-"DP_CON_STARTMAP "
-"DP_CRYPTO "
-"DP_CSQC_BINDMAPS "
-"DP_CSQC_ENTITYWORLDOBJECT "
-"DP_CSQC_ENTITYMODELLIGHT "
-"DP_CSQC_ENTITYTRANSPARENTSORTING_OFFSET "
-"DP_CSQC_MAINVIEW "
-"DP_CSQC_MINFPS_QUALITY "
-"DP_CSQC_MULTIFRAME_INTERPOLATION "
-"DP_CSQC_BOXPARTICLES "
-"DP_CSQC_SPAWNPARTICLE "
-"DP_CSQC_QUERYRENDERENTITY "
-"DP_CSQC_ROTATEMOVES "
-"DP_CSQC_SETPAUSE "
-"DP_CSQC_V_CALCREFDEF_WIP1 "
-"DP_CSQC_V_CALCREFDEF_WIP2 "
-"DP_EF_ADDITIVE "
-"DP_EF_BLUE "
-"DP_EF_DOUBLESIDED "
-"DP_EF_DYNAMICMODELLIGHT "
-"DP_EF_FLAME "
-"DP_EF_FULLBRIGHT "
-"DP_EF_NODEPTHTEST "
-"DP_EF_NODRAW "
-"DP_EF_NOGUNBOB "
-"DP_EF_NOSELFSHADOW "
-"DP_EF_NOSHADOW "
-"DP_EF_RED "
-"DP_EF_RESTARTANIM_BIT "
-"DP_EF_STARDUST "
-"DP_EF_TELEPORT_BIT "
-"DP_ENT_ALPHA "
-"DP_ENT_COLORMOD "
-"DP_ENT_CUSTOMCOLORMAP "
-"DP_ENT_EXTERIORMODELTOCLIENT "
-"DP_ENT_GLOW "
-"DP_ENT_GLOWMOD "
-"DP_ENT_LOWPRECISION "
-"DP_ENT_SCALE "
-"DP_ENT_TRAILEFFECTNUM "
-"DP_ENT_VIEWMODEL "
-"DP_GFX_EXTERNALTEXTURES "
-"DP_GFX_EXTERNALTEXTURES_PERMAP "
-"DP_GFX_FOG "
-"DP_GFX_MODEL_INTERPOLATION "
-"DP_GFX_QUAKE3MODELTAGS "
-"DP_GFX_SKINFILES "
-"DP_GFX_SKYBOX "
-"DP_GFX_FONTS "
-"DP_GFX_FONTS_FREETYPE "
-"DP_UTF8 "
-"DP_FONT_VARIABLEWIDTH "
-"DP_HALFLIFE_MAP "
-"DP_HALFLIFE_MAP_CVAR "
-"DP_HALFLIFE_SPRITE "
-"DP_INPUTBUTTONS "
-"DP_LIGHTSTYLE_STATICVALUE "
-"DP_LITSPRITES "
-"DP_LITSUPPORT "
-"DP_MONSTERWALK "
-"DP_MOVETYPEBOUNCEMISSILE "
-"DP_MOVETYPEFLYWORLDONLY "
-"DP_MOVETYPEFOLLOW "
-"DP_NULL_MODEL "
-"DP_QC_ASINACOSATANATAN2TAN "
-"DP_QC_AUTOCVARS "
-"DP_QC_CHANGEPITCH "
-"DP_QC_CMD "
-"DP_QC_COPYENTITY "
-"DP_QC_CRC16 "
-"DP_QC_CVAR_DEFSTRING "
-"DP_QC_CVAR_DESCRIPTION "
-"DP_QC_CVAR_STRING "
-"DP_QC_CVAR_TYPE "
-"DP_QC_DIGEST "
-"DP_QC_DIGEST_SHA256 "
-"DP_QC_EDICT_NUM "
-"DP_QC_ENTITYDATA "
-"DP_QC_ENTITYSTRING "
-"DP_QC_ETOS "
-"DP_QC_EXTRESPONSEPACKET "
-"DP_QC_FINDCHAIN "
-"DP_QC_FINDCHAINFLAGS "
-"DP_QC_FINDCHAINFLOAT "
-"DP_QC_FINDCHAIN_TOFIELD "
-"DP_QC_FINDFLAGS "
-"DP_QC_FINDFLOAT "
-"DP_QC_FS_SEARCH "
-"DP_QC_GETLIGHT "
-"DP_QC_GETSURFACE "
-"DP_QC_GETSURFACETRIANGLE "
-"DP_QC_GETSURFACEPOINTATTRIBUTE "
-"DP_QC_GETTAGINFO "
-"DP_QC_GETTAGINFO_BONEPROPERTIES "
-"DP_QC_GETTIME "
-"DP_QC_GETTIME_CDTRACK "
-"DP_QC_I18N "
-"DP_QC_LOG "
-"DP_QC_MINMAXBOUND "
-"DP_QC_MULTIPLETEMPSTRINGS "
-"DP_QC_NUM_FOR_EDICT "
-"DP_QC_RANDOMVEC "
-"DP_QC_SINCOSSQRTPOW "
-"DP_QC_SPRINTF "
-"DP_QC_STRFTIME "
-"DP_QC_STRINGBUFFERS "
-"DP_QC_STRINGBUFFERS_CVARLIST "
-"DP_QC_STRINGBUFFERS_EXT_WIP "
-"DP_QC_STRINGCOLORFUNCTIONS "
-"DP_QC_STRING_CASE_FUNCTIONS "
-"DP_QC_STRREPLACE "
-"DP_QC_TOKENIZEBYSEPARATOR "
-"DP_QC_TOKENIZE_CONSOLE "
-"DP_QC_TRACEBOX "
-"DP_QC_TRACETOSS "
-"DP_QC_TRACE_MOVETYPE_HITMODEL "
-"DP_QC_TRACE_MOVETYPE_WORLDONLY "
-"DP_QC_UNLIMITEDTEMPSTRINGS "
-"DP_QC_URI_ESCAPE "
-"DP_QC_URI_GET "
-"DP_QC_URI_POST "
-"DP_QC_VECTOANGLES_WITH_ROLL "
-"DP_QC_VECTORVECTORS "
-"DP_QC_WHICHPACK "
-"DP_QUAKE2_MODEL "
-"DP_QUAKE2_SPRITE "
-"DP_QUAKE3_MAP "
-"DP_QUAKE3_MODEL "
-"DP_REGISTERCVAR "
-"DP_SKELETONOBJECTS "
-"DP_SND_DIRECTIONLESSATTNNONE "
-"DP_SND_FAKETRACKS "
-"DP_SND_SOUND7_WIP1 "
-"DP_SND_SOUND7_WIP2 "
-"DP_SND_OGGVORBIS "
-"DP_SND_SETPARAMS "
-"DP_SND_STEREOWAV "
-"DP_SND_GETSOUNDTIME "
-"DP_VIDEO_DPV "
-"DP_VIDEO_SUBTITLES "
-"DP_SOLIDCORPSE "
-"DP_SPRITE32 "
-"DP_SV_BOTCLIENT "
-"DP_SV_BOUNCEFACTOR "
-"DP_SV_CLIENTCAMERA "
-"DP_SV_CLIENTCOLORS "
-"DP_SV_CLIENTNAME "
-"DP_SV_CMD "
-"DP_SV_CUSTOMIZEENTITYFORCLIENT "
-"DP_SV_DISCARDABLEDEMO "
-"DP_SV_DRAWONLYTOCLIENT "
-"DP_SV_DROPCLIENT "
-"DP_SV_EFFECT "
-"DP_SV_ENTITYCONTENTSTRANSITION "
-"DP_SV_MODELFLAGS_AS_EFFECTS "
-"DP_SV_MOVETYPESTEP_LANDEVENT "
-"DP_SV_NETADDRESS "
-"DP_SV_NODRAWTOCLIENT "
-"DP_SV_ONENTITYNOSPAWNFUNCTION "
-"DP_SV_ONENTITYPREPOSTSPAWNFUNCTION "
-"DP_SV_PING "
-"DP_SV_PING_PACKETLOSS "
-"DP_SV_PLAYERPHYSICS "
-"DP_PHYSICS_ODE "
-"DP_SV_POINTPARTICLES "
-"DP_SV_POINTSOUND "
-"DP_SV_PRECACHEANYTIME "
-"DP_SV_PRINT "
-"DP_SV_PUNCHVECTOR "
-"DP_SV_QCSTATUS "
-"DP_SV_ROTATINGBMODEL "
-"DP_SV_SETCOLOR "
-"DP_SV_SHUTDOWN "
-"DP_SV_SLOWMO "
-"DP_SV_SPAWNFUNC_PREFIX "
-"DP_SV_WRITEPICTURE "
-"DP_SV_WRITEUNTERMINATEDSTRING "
-"DP_TE_BLOOD "
-"DP_TE_BLOODSHOWER "
-"DP_TE_CUSTOMFLASH "
-"DP_TE_EXPLOSIONRGB "
-"DP_TE_FLAMEJET "
-"DP_TE_PARTICLECUBE "
-"DP_TE_PARTICLERAIN "
-"DP_TE_PARTICLESNOW "
-"DP_TE_PLASMABURN "
-"DP_TE_QUADEFFECTS1 "
-"DP_TE_SMALLFLASH "
-"DP_TE_SPARK "
-"DP_TE_STANDARDEFFECTBUILTINS "
-"DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
-"DP_VIEWZOOM "
-"EXT_BITSHIFT "
-"FRIK_FILE "
-"FTE_CSQC_SKELETONOBJECTS "
-"FTE_QC_CHECKPVS "
-"FTE_STRINGS "
-"KRIMZON_SV_PARSECLIENTCOMMAND "
-"NEH_CMD_PLAY2 "
-"NEH_RESTOREGAME "
-"NEXUIZ_PLAYERMODEL "
-"NXQ_GFX_LETTERBOX "
-"PRYDON_CLIENTCURSOR "
-"TENEBRAE_GFX_DLIGHTS "
-"TW_SV_STEPCONTROL "
-"ZQ_PAUSE "
-//"EXT_CSQC " // not ready yet
-;
+const char *vm_sv_extensions[] = {
+"BX_WAL_SUPPORT",
+"DP_BUTTONCHAT",
+"DP_BUTTONUSE",
+"DP_CL_LOADSKY",
+"DP_CON_ALIASPARAMETERS",
+"DP_CON_BESTWEAPON",
+"DP_CON_EXPANDCVAR",
+"DP_CON_SET",
+"DP_CON_SETA",
+"DP_CON_STARTMAP",
+"DP_COVERAGE",
+"DP_CRYPTO",
+"DP_CSQC_BINDMAPS",
+"DP_CSQC_ENTITYWORLDOBJECT",
+"DP_CSQC_ENTITYMODELLIGHT",
+"DP_CSQC_ENTITYTRANSPARENTSORTING_OFFSET",
+"DP_CSQC_MAINVIEW",
+"DP_CSQC_MINFPS_QUALITY",
+"DP_CSQC_MULTIFRAME_INTERPOLATION",
+"DP_CSQC_BOXPARTICLES",
+"DP_CSQC_SPAWNPARTICLE",
+"DP_CSQC_QUERYRENDERENTITY",
+"DP_CSQC_ROTATEMOVES",
+"DP_CSQC_SETPAUSE",
+"DP_CSQC_V_CALCREFDEF_WIP1",
+"DP_CSQC_V_CALCREFDEF_WIP2",
+"DP_EF_ADDITIVE",
+"DP_EF_BLUE",
+"DP_EF_DOUBLESIDED",
+"DP_EF_DYNAMICMODELLIGHT",
+"DP_EF_FLAME",
+"DP_EF_FULLBRIGHT",
+"DP_EF_NODEPTHTEST",
+"DP_EF_NODRAW",
+"DP_EF_NOGUNBOB",
+"DP_EF_NOSELFSHADOW",
+"DP_EF_NOSHADOW",
+"DP_EF_RED",
+"DP_EF_RESTARTANIM_BIT",
+"DP_EF_STARDUST",
+"DP_EF_TELEPORT_BIT",
+"DP_ENT_ALPHA",
+"DP_ENT_COLORMOD",
+"DP_ENT_CUSTOMCOLORMAP",
+"DP_ENT_EXTERIORMODELTOCLIENT",
+"DP_ENT_GLOW",
+"DP_ENT_GLOWMOD",
+"DP_ENT_LOWPRECISION",
+"DP_ENT_SCALE",
+"DP_ENT_TRAILEFFECTNUM",
+"DP_ENT_VIEWMODEL",
+"DP_GFX_EXTERNALTEXTURES",
+"DP_GFX_EXTERNALTEXTURES_PERMAP",
+"DP_GFX_FOG",
+"DP_GFX_MODEL_INTERPOLATION",
+"DP_GFX_QUAKE3MODELTAGS",
+"DP_GFX_SKINFILES",
+"DP_GFX_SKYBOX",
+"DP_GFX_FONTS",
+"DP_GFX_FONTS_FREETYPE",
+"DP_UTF8",
+"DP_FONT_VARIABLEWIDTH",
+"DP_HALFLIFE_MAP",
+"DP_HALFLIFE_MAP_CVAR",
+"DP_HALFLIFE_SPRITE",
+"DP_INPUTBUTTONS",
+"DP_LIGHTSTYLE_STATICVALUE",
+"DP_LITSPRITES",
+"DP_LITSUPPORT",
+"DP_MONSTERWALK",
+"DP_MOVETYPEBOUNCEMISSILE",
+"DP_MOVETYPEFLYWORLDONLY",
+"DP_MOVETYPEFOLLOW",
+"DP_NULL_MODEL",
+"DP_QC_ASINACOSATANATAN2TAN",
+"DP_QC_AUTOCVARS",
+"DP_QC_CHANGEPITCH",
+"DP_QC_CMD",
+"DP_QC_COPYENTITY",
+"DP_QC_CRC16",
+"DP_QC_CVAR_DEFSTRING",
+"DP_QC_CVAR_DESCRIPTION",
+"DP_QC_CVAR_STRING",
+"DP_QC_CVAR_TYPE",
+"DP_QC_DIGEST",
+"DP_QC_DIGEST_SHA256",
+"DP_QC_EDICT_NUM",
+"DP_QC_ENTITYDATA",
+"DP_QC_ENTITYSTRING",
+"DP_QC_ETOS",
+"DP_QC_EXTRESPONSEPACKET",
+"DP_QC_FINDCHAIN",
+"DP_QC_FINDCHAINFLAGS",
+"DP_QC_FINDCHAINFLOAT",
+"DP_QC_FINDCHAIN_TOFIELD",
+"DP_QC_FINDFLAGS",
+"DP_QC_FINDFLOAT",
+"DP_QC_FS_SEARCH",
+"DP_QC_GETLIGHT",
+"DP_QC_GETSURFACE",
+"DP_QC_GETSURFACETRIANGLE",
+"DP_QC_GETSURFACEPOINTATTRIBUTE",
+"DP_QC_GETTAGINFO",
+"DP_QC_GETTAGINFO_BONEPROPERTIES",
+"DP_QC_GETTIME",
+"DP_QC_GETTIME_CDTRACK",
+"DP_QC_I18N",
+"DP_QC_LOG",
+"DP_QC_MINMAXBOUND",
+"DP_QC_MULTIPLETEMPSTRINGS",
+"DP_QC_NUM_FOR_EDICT",
+"DP_QC_RANDOMVEC",
+"DP_QC_SINCOSSQRTPOW",
+"DP_QC_SPRINTF",
+"DP_QC_STRFTIME",
+"DP_QC_STRINGBUFFERS",
+"DP_QC_STRINGBUFFERS_CVARLIST",
+"DP_QC_STRINGBUFFERS_EXT_WIP",
+"DP_QC_STRINGCOLORFUNCTIONS",
+"DP_QC_STRING_CASE_FUNCTIONS",
+"DP_QC_STRREPLACE",
+"DP_QC_TOKENIZEBYSEPARATOR",
+"DP_QC_TOKENIZE_CONSOLE",
+"DP_QC_TRACEBOX",
+"DP_QC_TRACETOSS",
+"DP_QC_TRACE_MOVETYPE_HITMODEL",
+"DP_QC_TRACE_MOVETYPE_WORLDONLY",
+"DP_QC_UNLIMITEDTEMPSTRINGS",
+"DP_QC_URI_ESCAPE",
+"DP_QC_URI_GET",
+"DP_QC_URI_POST",
+"DP_QC_VECTOANGLES_WITH_ROLL",
+"DP_QC_VECTORVECTORS",
+"DP_QC_WHICHPACK",
+"DP_QUAKE2_MODEL",
+"DP_QUAKE2_SPRITE",
+"DP_QUAKE3_MAP",
+"DP_QUAKE3_MODEL",
+"DP_REGISTERCVAR",
+"DP_SKELETONOBJECTS",
+"DP_SND_DIRECTIONLESSATTNNONE",
+"DP_SND_FAKETRACKS",
+"DP_SND_SOUND7_WIP1",
+"DP_SND_SOUND7_WIP2",
+"DP_SND_OGGVORBIS",
+"DP_SND_SETPARAMS",
+"DP_SND_STEREOWAV",
+"DP_SND_GETSOUNDTIME",
+"DP_VIDEO_DPV",
+"DP_VIDEO_SUBTITLES",
+"DP_SOLIDCORPSE",
+"DP_SPRITE32",
+"DP_SV_BOTCLIENT",
+"DP_SV_BOUNCEFACTOR",
+"DP_SV_CLIENTCAMERA",
+"DP_SV_CLIENTCOLORS",
+"DP_SV_CLIENTNAME",
+"DP_SV_CMD",
+"DP_SV_CUSTOMIZEENTITYFORCLIENT",
+"DP_SV_DISABLECLIENTPREDICTION",
+"DP_SV_DISCARDABLEDEMO",
+"DP_SV_DRAWONLYTOCLIENT",
+"DP_SV_DROPCLIENT",
+"DP_SV_EFFECT",
+"DP_SV_ENTITYCONTENTSTRANSITION",
+"DP_SV_MODELFLAGS_AS_EFFECTS",
+"DP_SV_MOVETYPESTEP_LANDEVENT",
+"DP_SV_NETADDRESS",
+"DP_SV_NODRAWTOCLIENT",
+"DP_SV_ONENTITYNOSPAWNFUNCTION",
+"DP_SV_ONENTITYPREPOSTSPAWNFUNCTION",
+"DP_SV_PING",
+"DP_SV_PING_PACKETLOSS",
+"DP_SV_PLAYERPHYSICS",
+"DP_PHYSICS_ODE",
+"DP_SV_POINTPARTICLES",
+"DP_SV_POINTSOUND",
+"DP_SV_PRECACHEANYTIME",
+"DP_SV_PRINT",
+"DP_SV_PUNCHVECTOR",
+"DP_SV_QCSTATUS",
+"DP_SV_ROTATINGBMODEL",
+"DP_SV_SETCOLOR",
+"DP_SV_SHUTDOWN",
+"DP_SV_SLOWMO",
+"DP_SV_SPAWNFUNC_PREFIX",
+"DP_SV_WRITEPICTURE",
+"DP_SV_WRITEUNTERMINATEDSTRING",
+"DP_TE_BLOOD",
+"DP_TE_BLOODSHOWER",
+"DP_TE_CUSTOMFLASH",
+"DP_TE_EXPLOSIONRGB",
+"DP_TE_FLAMEJET",
+"DP_TE_PARTICLECUBE",
+"DP_TE_PARTICLERAIN",
+"DP_TE_PARTICLESNOW",
+"DP_TE_PLASMABURN",
+"DP_TE_QUADEFFECTS1",
+"DP_TE_SMALLFLASH",
+"DP_TE_SPARK",
+"DP_TE_STANDARDEFFECTBUILTINS",
+"DP_TRACE_HITCONTENTSMASK_SURFACEINFO"
+"DP_USERMOVETYPES",
+"DP_VIEWZOOM",
+"EXT_BITSHIFT",
+"FRIK_FILE",
+"FTE_CSQC_SKELETONOBJECTS",
+"FTE_QC_CHECKPVS",
+"FTE_STRINGS",
+"KRIMZON_SV_PARSECLIENTCOMMAND",
+"NEH_CMD_PLAY2",
+"NEH_RESTOREGAME",
+"NEXUIZ_PLAYERMODEL",
+"NXQ_GFX_LETTERBOX",
+"PRYDON_CLIENTCURSOR",
+"TENEBRAE_GFX_DLIGHTS",
+"TW_SV_STEPCONTROL",
+"ZQ_PAUSE",
+"DP_RM_CLIPGROUP",
+"DP_QC_FS_SEARCH_PACKFILE",
+NULL
+//"EXT_CSQC" // not ready yet
+};
 
 /*
 =================
@@ -240,7 +246,7 @@ static void VM_SV_setorigin(prvm_prog_t *prog)
 {
        prvm_edict_t    *e;
 
-       VM_SAFEPARMCOUNT(2, VM_setorigin);
+       VM_SAFEPARMCOUNT(2, VM_SV_setorigin);
 
        e = PRVM_G_EDICT(OFS_PARM0);
        if (e == prog->edicts)
@@ -248,7 +254,7 @@ static void VM_SV_setorigin(prvm_prog_t *prog)
                VM_Warning(prog, "setorigin: can not modify world entity\n");
                return;
        }
-       if (e->priv.server->free)
+       if (e->free)
        {
                VM_Warning(prog, "setorigin: can not modify free entity\n");
                return;
@@ -260,7 +266,7 @@ static void VM_SV_setorigin(prvm_prog_t *prog)
 }
 
 // TODO: rotate param isnt used.. could be a bug. please check this and remove it if possible [1/10/2008 Black]
-static void SetMinMaxSize (prvm_prog_t *prog, prvm_edict_t *e, float *min, float *max, qboolean rotate)
+static void SetMinMaxSize (prvm_prog_t *prog, prvm_edict_t *e, float *min, float *max, qbool rotate)
 {
        int             i;
 
@@ -281,7 +287,7 @@ static void SetMinMaxSize (prvm_prog_t *prog, prvm_edict_t *e, float *min, float
 VM_SV_setsize
 
 the size box is rotated by the current angle
-LordHavoc: no it isn't...
+LadyHavoc: no it isn't...
 
 setsize (entity, minvector, maxvector)
 =================
@@ -291,7 +297,7 @@ static void VM_SV_setsize(prvm_prog_t *prog)
        prvm_edict_t    *e;
        vec3_t mins, maxs;
 
-       VM_SAFEPARMCOUNT(3, VM_setsize);
+       VM_SAFEPARMCOUNT(3, VM_SV_setsize);
 
        e = PRVM_G_EDICT(OFS_PARM0);
        if (e == prog->edicts)
@@ -299,7 +305,7 @@ static void VM_SV_setsize(prvm_prog_t *prog)
                VM_Warning(prog, "setsize: can not modify world entity\n");
                return;
        }
-       if (e->priv.server->free)
+       if (e->free)
        {
                VM_Warning(prog, "setsize: can not modify free entity\n");
                return;
@@ -321,10 +327,10 @@ static vec3_t quakemins = {-16, -16, -16}, quakemaxs = {16, 16, 16};
 static void VM_SV_setmodel(prvm_prog_t *prog)
 {
        prvm_edict_t    *e;
-       dp_model_t      *mod;
+       model_t *mod;
        int             i;
 
-       VM_SAFEPARMCOUNT(2, VM_setmodel);
+       VM_SAFEPARMCOUNT(2, VM_SV_setmodel);
 
        e = PRVM_G_EDICT(OFS_PARM0);
        if (e == prog->edicts)
@@ -332,7 +338,7 @@ static void VM_SV_setmodel(prvm_prog_t *prog)
                VM_Warning(prog, "setmodel: can not modify world entity\n");
                return;
        }
-       if (e->priv.server->free)
+       if (e->free)
        {
                VM_Warning(prog, "setmodel: can not modify free entity\n");
                return;
@@ -374,7 +380,7 @@ static void VM_SV_sprint(prvm_prog_t *prog)
        VM_VarString(prog, 1, string, sizeof(string));
 
        entnum = PRVM_G_EDICTNUM(OFS_PARM0);
-       // LordHavoc: div0 requested that sprintto world  operate like print
+       // LadyHavoc: div0 requested that sprintto world  operate like print
        if (entnum == 0)
        {
                Con_Print(string);
@@ -482,6 +488,9 @@ static void VM_SV_ambientsound(prvm_prog_t *prog)
        if (soundnum >= 256)
                large = true;
 
+       if(sv.protocol == PROTOCOL_NEHAHRABJP)
+               large = false;
+
        // add an svc_spawnambient command to the level signon packet
 
        if (large)
@@ -491,7 +500,7 @@ static void VM_SV_ambientsound(prvm_prog_t *prog)
 
        MSG_WriteVector(&sv.signon, pos, sv.protocol);
 
-       if (large || sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
+       if (large || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
                MSG_WriteShort (&sv.signon, soundnum);
        else
                MSG_WriteByte (&sv.signon, soundnum);
@@ -514,6 +523,7 @@ already running on that entity/channel pair.
 An attenuation of 0 will play full volume everywhere in the level.
 Larger attenuations will drop off.
 
+void(entity e, float chan, string samp, float volume[, float atten[, float pitchchange[, float flags]]]) sound (QUAKE)
 =================
 */
 static void VM_SV_sound(prvm_prog_t *prog)
@@ -521,7 +531,7 @@ static void VM_SV_sound(prvm_prog_t *prog)
        const char      *sample;
        int                     channel;
        prvm_edict_t            *entity;
-       int             volume;
+       int             nvolume;
        int flags;
        float attenuation;
        float pitchchange;
@@ -531,7 +541,7 @@ static void VM_SV_sound(prvm_prog_t *prog)
        entity = PRVM_G_EDICT(OFS_PARM0);
        channel = (int)PRVM_G_FLOAT(OFS_PARM1);
        sample = PRVM_G_STRING(OFS_PARM2);
-       volume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
+       nvolume = (int)(PRVM_G_FLOAT(OFS_PARM3) * 255);
        if (prog->argc < 5)
        {
                Con_DPrintf("VM_SV_sound: given only 4 parameters, expected 5, assuming attenuation = ATTN_NORMAL\n");
@@ -549,14 +559,17 @@ static void VM_SV_sound(prvm_prog_t *prog)
                flags = 0;
                if(channel >= 8 && channel <= 15) // weird QW feature
                {
-                       flags |= CHANFLAG_RELIABLE;
+                       flags |= CHANNELFLAG_RELIABLE;
                        channel -= 8;
                }
        }
        else
-               flags = PRVM_G_FLOAT(OFS_PARM6);
+       {
+               // LadyHavoc: we only let the qc set certain flags, others are off-limits
+               flags = (int)PRVM_G_FLOAT(OFS_PARM6) & (CHANNELFLAG_RELIABLE | CHANNELFLAG_FORCELOOP | CHANNELFLAG_PAUSED | CHANNELFLAG_FULLVOLUME);
+       }
 
-       if (volume < 0 || volume > 255)
+       if (nvolume < 0 || nvolume > 255)
        {
                VM_Warning(prog, "SV_StartSound: volume must be in range 0-1\n");
                return;
@@ -576,7 +589,7 @@ static void VM_SV_sound(prvm_prog_t *prog)
                return;
        }
 
-       SV_StartSound (entity, channel, sample, volume, attenuation, flags & CHANFLAG_RELIABLE, pitchchange);
+       SV_StartSound (entity, channel, sample, nvolume, attenuation, flags & CHANNELFLAG_RELIABLE, pitchchange);
 }
 
 /*
@@ -592,7 +605,7 @@ is omitted (since no entity is being tracked).
 static void VM_SV_pointsound(prvm_prog_t *prog)
 {
        const char      *sample;
-       int             volume;
+       int             nvolume;
        float           attenuation;
        float           pitchchange;
        vec3_t          org;
@@ -601,11 +614,11 @@ static void VM_SV_pointsound(prvm_prog_t *prog)
 
        VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
        sample = PRVM_G_STRING(OFS_PARM1);
-       volume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
+       nvolume = (int)(PRVM_G_FLOAT(OFS_PARM2) * 255);
        attenuation = PRVM_G_FLOAT(OFS_PARM3);
        pitchchange = prog->argc < 5 ? 0 : PRVM_G_FLOAT(OFS_PARM4) * 0.01f;
 
-       if (volume < 0 || volume > 255)
+       if (nvolume < 0 || nvolume > 255)
        {
                VM_Warning(prog, "SV_StartPointSound: volume must be in range 0-1\n");
                return;
@@ -617,7 +630,7 @@ static void VM_SV_pointsound(prvm_prog_t *prog)
                return;
        }
 
-       SV_StartPointSound (org, sample, volume, attenuation, pitchchange);
+       SV_StartPointSound (org, sample, nvolume, attenuation, pitchchange);
 }
 
 /*
@@ -650,7 +663,7 @@ static void VM_SV_traceline(prvm_prog_t *prog)
        if (VEC_IS_NAN(v1[0]) || VEC_IS_NAN(v1[1]) || VEC_IS_NAN(v1[2]) || VEC_IS_NAN(v2[0]) || VEC_IS_NAN(v2[1]) || VEC_IS_NAN(v2[2]))
                prog->error_cmd("%s: NAN errors detected in traceline('%f %f %f', '%f %f %f', %i, entity %i)\n", prog->name, v1[0], v1[1], v1[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
 
-       trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
+       trace = SV_TraceLine(v1, v2, move, ent, SV_GenericHitSuperContentsMask(ent), 0, 0, collision_extendtracelinelength.value);
 
        VM_SetTraceGlobals(prog, &trace);
 }
@@ -667,7 +680,7 @@ if the tryents flag is set.
 tracebox (vector1, vector mins, vector maxs, vector2, tryents)
 =================
 */
-// LordHavoc: added this for my own use, VERY useful, similar to traceline
+// LadyHavoc: added this for my own use, VERY useful, similar to traceline
 static void VM_SV_tracebox(prvm_prog_t *prog)
 {
        vec3_t v1, v2, m1, m2;
@@ -689,7 +702,7 @@ static void VM_SV_tracebox(prvm_prog_t *prog)
        if (VEC_IS_NAN(v1[0]) || VEC_IS_NAN(v1[1]) || VEC_IS_NAN(v1[2]) || VEC_IS_NAN(v2[0]) || VEC_IS_NAN(v2[1]) || VEC_IS_NAN(v2[2]))
                prog->error_cmd("%s: NAN errors detected in tracebox('%f %f %f', '%f %f %f', '%f %f %f', '%f %f %f', %i, entity %i)\n", prog->name, v1[0], v1[1], v1[2], m1[0], m1[1], m1[2], m2[0], m2[1], m2[2], v2[0], v2[1], v2[2], move, PRVM_EDICT_TO_PROG(ent));
 
-       trace = SV_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent));
+       trace = SV_TraceBox(v1, m1, m2, v2, move, ent, SV_GenericHitSuperContentsMask(ent), 0, 0, collision_extendtraceboxlength.value);
 
        VM_SetTraceGlobals(prog, &trace);
 }
@@ -715,7 +728,7 @@ static trace_t SV_Trace_Toss(prvm_prog_t *prog, prvm_edict_t *tossent, prvm_edic
                gravity = 1.0f;
        gravity *= sv_gravity.value * 0.025;
 
-       for (i = 0;i < 200;i++) // LordHavoc: sanity check; never trace more than 10 seconds
+       for (i = 0;i < 200;i++) // LadyHavoc: sanity check; never trace more than 10 seconds
        {
                SV_CheckVelocity (tossent);
                PRVM_serveredictvector(tossent, velocity)[2] -= gravity;
@@ -725,7 +738,7 @@ static trace_t SV_Trace_Toss(prvm_prog_t *prog, prvm_edict_t *tossent, prvm_edic
                VectorCopy(PRVM_serveredictvector(tossent, origin), tossentorigin);
                VectorCopy(PRVM_serveredictvector(tossent, mins), tossentmins);
                VectorCopy(PRVM_serveredictvector(tossent, maxs), tossentmaxs);
-               trace = SV_TraceBox(tossentorigin, tossentmins, tossentmaxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
+               trace = SV_TraceBox(tossentorigin, tossentmins, tossentmaxs, end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent), 0, 0, collision_extendmovelength.value);
                VectorCopy (trace.endpos, PRVM_serveredictvector(tossent, origin));
                PRVM_serveredictvector(tossent, velocity)[2] -= gravity;
 
@@ -793,7 +806,7 @@ static int VM_SV_newcheckclient(prvm_prog_t *prog, int check)
                // look up the client's edict
                ent = PRVM_EDICT_NUM(i);
                // check if it is to be ignored, but never ignore the one we started on (prevent infinite loop)
-               if (i != check && (ent->priv.server->free || PRVM_serveredictfloat(ent, health) <= 0 || ((int)PRVM_serveredictfloat(ent, flags) & FL_NOTARGET)))
+               if (i != check && (ent->free || PRVM_serveredictfloat(ent, health) <= 0 || ((int)PRVM_serveredictfloat(ent, flags) & FL_NOTARGET)))
                        continue;
                // found a valid client (possibly the same one again)
                break;
@@ -840,7 +853,7 @@ static void VM_SV_checkclient(prvm_prog_t *prog)
 
        // return check if it might be visible
        ent = PRVM_EDICT_NUM(sv.lastcheck);
-       if (ent->priv.server->free || PRVM_serveredictfloat(ent, health) <= 0)
+       if (ent->free || PRVM_serveredictfloat(ent, health) <= 0)
        {
                VM_RETURN_EDICT(prog->edicts);
                return;
@@ -888,7 +901,7 @@ static void VM_SV_checkpvs(prvm_prog_t *prog)
        VectorCopy(PRVM_G_VECTOR(OFS_PARM0), viewpos);
        viewee = PRVM_G_EDICT(OFS_PARM1);
 
-       if(viewee->priv.server->free)
+       if(viewee->free)
        {
                VM_Warning(prog, "checkpvs: can not check free entity\n");
                PRVM_G_FLOAT(OFS_RETURN) = 4;
@@ -962,7 +975,7 @@ static void VM_SV_stuffcmd(prvm_prog_t *prog)
 
        old = host_client;
        host_client = svs.clients + entnum-1;
-       Host_ClientCommands ("%s", string);
+       SV_ClientCommands ("%s", string);
        host_client = old;
 }
 
@@ -1021,7 +1034,7 @@ static void VM_SV_findradius(prvm_prog_t *prog)
                // (note: this is the reason you can't blow up fallen zombies)
                if (PRVM_serveredictfloat(ent, solid) == SOLID_NOT && !sv_gameplayfix_blowupfallenzombies.integer)
                        continue;
-               // LordHavoc: compare against bounding box rather than center so it
+               // LadyHavoc: compare against bounding box rather than center so it
                // doesn't miss large objects, and use DotProduct instead of Length
                // for a major speedup
                VectorSubtract(org, PRVM_serveredictvector(ent, origin), eorg);
@@ -1070,7 +1083,7 @@ static void VM_SV_walkmove(prvm_prog_t *prog)
        vec3_t  move;
        mfunction_t     *oldf;
        int     oldself;
-       qboolean        settrace;
+       qbool   settrace;
 
        VM_SAFEPARMCOUNTRANGE(2, 3, VM_SV_walkmove);
 
@@ -1083,7 +1096,7 @@ static void VM_SV_walkmove(prvm_prog_t *prog)
                VM_Warning(prog, "walkmove: can not modify world entity\n");
                return;
        }
-       if (ent->priv.server->free)
+       if (ent->free)
        {
                VM_Warning(prog, "walkmove: can not modify free entity\n");
                return;
@@ -1138,7 +1151,7 @@ static void VM_SV_droptofloor(prvm_prog_t *prog)
                VM_Warning(prog, "droptofloor: can not modify world entity\n");
                return;
        }
-       if (ent->priv.server->free)
+       if (ent->free)
        {
                VM_Warning(prog, "droptofloor: can not modify free entity\n");
                return;
@@ -1148,25 +1161,22 @@ static void VM_SV_droptofloor(prvm_prog_t *prog)
        end[2] -= 256;
 
        if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
-               if (sv_gameplayfix_unstickentities.integer)
-                       SV_UnstickEntity(ent);
+               SV_NudgeOutOfSolid(ent);
 
        VectorCopy(PRVM_serveredictvector(ent, origin), entorigin);
        VectorCopy(PRVM_serveredictvector(ent, mins), entmins);
        VectorCopy(PRVM_serveredictvector(ent, maxs), entmaxs);
-       trace = SV_TraceBox(entorigin, entmins, entmaxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
+       trace = SV_TraceBox(entorigin, entmins, entmaxs, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value);
        if (trace.startsolid && sv_gameplayfix_droptofloorstartsolid.integer)
        {
                vec3_t offset, org;
                VectorSet(offset, 0.5f * (PRVM_serveredictvector(ent, mins)[0] + PRVM_serveredictvector(ent, maxs)[0]), 0.5f * (PRVM_serveredictvector(ent, mins)[1] + PRVM_serveredictvector(ent, maxs)[1]), PRVM_serveredictvector(ent, mins)[2]);
                VectorAdd(PRVM_serveredictvector(ent, origin), offset, org);
-               trace = SV_TraceLine(org, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent));
+               trace = SV_TraceLine(org, end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(ent), 0, 0, collision_extendmovelength.value);
                VectorSubtract(trace.endpos, offset, trace.endpos);
                if (trace.startsolid)
                {
                        Con_DPrintf("droptofloor at %f %f %f - COULD NOT FIX BADLY PLACED ENTITY\n", PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]);
-                       if (sv_gameplayfix_unstickentities.integer)
-                               SV_UnstickEntity(ent);
                        SV_LinkEdict(ent);
                        PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) | FL_ONGROUND;
                        PRVM_serveredictedict(ent, groundentity) = 0;
@@ -1176,8 +1186,8 @@ static void VM_SV_droptofloor(prvm_prog_t *prog)
                {
                        Con_DPrintf("droptofloor at %f %f %f - FIXED BADLY PLACED ENTITY\n", PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2]);
                        VectorCopy (trace.endpos, PRVM_serveredictvector(ent, origin));
-                       if (sv_gameplayfix_unstickentities.integer)
-                               SV_UnstickEntity(ent);
+                       if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
+                               SV_NudgeOutOfSolid(ent);
                        SV_LinkEdict(ent);
                        PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) | FL_ONGROUND;
                        PRVM_serveredictedict(ent, groundentity) = PRVM_EDICT_TO_PROG(trace.ent);
@@ -1188,10 +1198,9 @@ static void VM_SV_droptofloor(prvm_prog_t *prog)
        }
        else
        {
-               if (trace.fraction != 1)
+               if (!trace.allsolid && trace.fraction < 1)
                {
-                       if (trace.fraction < 1)
-                               VectorCopy (trace.endpos, PRVM_serveredictvector(ent, origin));
+                       VectorCopy (trace.endpos, PRVM_serveredictvector(ent, origin));
                        SV_LinkEdict(ent);
                        PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) | FL_ONGROUND;
                        PRVM_serveredictedict(ent, groundentity) = PRVM_EDICT_TO_PROG(trace.ent);
@@ -1264,7 +1273,7 @@ static void VM_SV_pointcontents(prvm_prog_t *prog)
        vec3_t point;
        VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
        VectorCopy(PRVM_G_VECTOR(OFS_PARM0), point);
-       PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(point));
+       PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(SV_PointSuperContents(point));
 }
 
 /*
@@ -1298,7 +1307,7 @@ static void VM_SV_aim(prvm_prog_t *prog)
                VM_Warning(prog, "aim: can not use world entity\n");
                return;
        }
-       if (ent->priv.server->free)
+       if (ent->free)
        {
                VM_Warning(prog, "aim: can not use free entity\n");
                return;
@@ -1311,7 +1320,7 @@ static void VM_SV_aim(prvm_prog_t *prog)
 // try sending a trace straight
        VectorCopy (PRVM_serverglobalvector(v_forward), dir);
        VectorMA (start, 2048, dir, end);
-       tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
+       tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY, 0, 0, collision_extendmovelength.value);
        if (tr.ent && PRVM_serveredictfloat(((prvm_edict_t *)tr.ent), takedamage) == DAMAGE_AIM
        && (!teamplay.integer || PRVM_serveredictfloat(ent, team) <=0 || PRVM_serveredictfloat(ent, team) != PRVM_serveredictfloat(((prvm_edict_t *)tr.ent), team)) )
        {
@@ -1343,7 +1352,7 @@ static void VM_SV_aim(prvm_prog_t *prog)
                dist = DotProduct (dir, PRVM_serverglobalvector(v_forward));
                if (dist < bestdist)
                        continue;       // to far to turn
-               tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
+               tr = SV_TraceLine(start, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY, 0, 0, collision_extendmovelength.value);
                if (tr.ent == check)
                {       // can shoot at this one
                        bestdist = dist;
@@ -1488,7 +1497,7 @@ static void VM_SV_WritePicture(prvm_prog_t *prog)
        VM_SAFEPARMCOUNT(3, VM_SV_WritePicture);
 
        imgname = PRVM_G_STRING(OFS_PARM1);
-       size = (int) PRVM_G_FLOAT(OFS_PARM2);
+       size = (size_t) PRVM_G_FLOAT(OFS_PARM2);
        if(size > 65535)
                size = 65535;
 
@@ -1496,8 +1505,8 @@ static void VM_SV_WritePicture(prvm_prog_t *prog)
        if(Image_Compress(imgname, size, &buf, &size))
        {
                // actual picture
-               MSG_WriteShort(WriteDest(prog), size);
-               SZ_Write(WriteDest(prog), (unsigned char *) buf, size);
+               MSG_WriteShort(WriteDest(prog), (int)size);
+               SZ_Write(WriteDest(prog), (unsigned char *) buf, (int)size);
        }
        else
        {
@@ -1526,7 +1535,7 @@ static void VM_SV_makestatic(prvm_prog_t *prog)
                VM_Warning(prog, "makestatic: can not modify world entity\n");
                return;
        }
-       if (ent->priv.server->free)
+       if (ent->free)
        {
                VM_Warning(prog, "makestatic: can not modify free entity\n");
                return;
@@ -1536,17 +1545,17 @@ static void VM_SV_makestatic(prvm_prog_t *prog)
        if (PRVM_serveredictfloat(ent, modelindex) >= 256 || PRVM_serveredictfloat(ent, frame) >= 256)
                large = true;
 
-       if (large)
+       if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
        {
-               MSG_WriteByte (&sv.signon,svc_spawnstatic2);
+               MSG_WriteByte (&sv.signon,svc_spawnstatic);
                MSG_WriteShort (&sv.signon, (int)PRVM_serveredictfloat(ent, modelindex));
-               MSG_WriteShort (&sv.signon, (int)PRVM_serveredictfloat(ent, frame));
+               MSG_WriteByte (&sv.signon, (int)PRVM_serveredictfloat(ent, frame));
        }
-       else if (sv.protocol == PROTOCOL_NEHAHRABJP || sv.protocol == PROTOCOL_NEHAHRABJP2 || sv.protocol == PROTOCOL_NEHAHRABJP3)
+       else if (large)
        {
-               MSG_WriteByte (&sv.signon,svc_spawnstatic);
+               MSG_WriteByte (&sv.signon,svc_spawnstatic2);
                MSG_WriteShort (&sv.signon, (int)PRVM_serveredictfloat(ent, modelindex));
-               MSG_WriteByte (&sv.signon, (int)PRVM_serveredictfloat(ent, frame));
+               MSG_WriteShort (&sv.signon, (int)PRVM_serveredictfloat(ent, frame));
        }
        else
        {
@@ -1624,21 +1633,17 @@ static void VM_SV_getlight(prvm_prog_t *prog)
 
 typedef struct
 {
-       unsigned char   type;   // 1/2/8 or other value if isn't used
+       unsigned char   type;   // 1/2/8 or 0 to indicate unused
        int             fieldoffset;
 }customstat_t;
 
-static customstat_t *vm_customstats = NULL;    //[515]: it starts from 0, not 32
+static customstat_t vm_customstats[MAX_CL_STATS]; // matches the regular stat numbers, but only MIN_VM_STAT to MAX_VM_STAT range is used if things are working properly (can register stats from MAX_VM_STAT to MAX_CL_STATS but will warn)
 static int vm_customstats_last;
 
 void VM_CustomStats_Clear (void)
 {
-       if(vm_customstats)
-       {
-               Z_Free(vm_customstats);
-               vm_customstats = NULL;
-               vm_customstats_last = -1;
-       }
+       memset(vm_customstats, 0, sizeof(vm_customstats));
+       vm_customstats_last = -1;
 }
 
 void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *msg, int *stats)
@@ -1646,11 +1651,12 @@ void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *ms
        prvm_prog_t *prog = SVVM_prog;
        int                     i;
        char            s[17];
+       union {
+               int i;
+               float f;
+       } u;
 
-       if(!vm_customstats)
-               return;
-
-       for(i=0; i<vm_customstats_last+1 ;i++)
+       for(i=MIN_VM_STAT; i<=vm_customstats_last ;i++)
        {
                if(!vm_customstats[i].type)
                        continue;
@@ -1660,18 +1666,20 @@ void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *ms
                case 1:
                        memset(s, 0, 17);
                        strlcpy(s, PRVM_E_STRING(ent, vm_customstats[i].fieldoffset), 16);
-                       stats[i+32] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
-                       stats[i+33] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
-                       stats[i+34] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
-                       stats[i+35] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
+                       stats[i] = s[ 0] + s[ 1] * 256 + s[ 2] * 65536 + s[ 3] * 16777216;
+                       stats[i+1] = s[ 4] + s[ 5] * 256 + s[ 6] * 65536 + s[ 7] * 16777216;
+                       stats[i+2] = s[ 8] + s[ 9] * 256 + s[10] * 65536 + s[11] * 16777216;
+                       stats[i+3] = s[12] + s[13] * 256 + s[14] * 65536 + s[15] * 16777216;
                        break;
                //float field sent as-is
                case 8:
-                       stats[i+32] = PRVM_E_INT(ent, vm_customstats[i].fieldoffset);
+                       // can't directly use PRVM_E_INT on the field because it may be PRVM_64 and a double is not the representation we want to send
+                       u.f = PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
+                       stats[i] = u.i;
                        break;
                //integer value of float field
                case 2:
-                       stats[i+32] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
+                       stats[i] = (int)PRVM_E_FLOAT(ent, vm_customstats[i].fieldoffset);
                        break;
                default:
                        break;
@@ -1679,6 +1687,8 @@ void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *ms
        }
 }
 
+extern cvar_t sv_gameplayfix_customstats;
+
 // void(float index, float type, .void field) SV_AddStat = #232;
 // Set up an auto-sent player stat.
 // Client's get thier own fields sent to them. Index may not be less than 32.
@@ -1688,40 +1698,51 @@ void VM_SV_UpdateCustomStats (client_t *client, prvm_edict_t *ent, sizebuf_t *ms
 //          8: integer (one stat, not converted to an int, so this can be used to transport floats as floats - what a unique idea!)
 static void VM_SV_AddStat(prvm_prog_t *prog)
 {
-       int             off, i;
-       unsigned char   type;
+       int             off, i, type;
 
        VM_SAFEPARMCOUNT(3, VM_SV_AddStat);
 
-       if(!vm_customstats)
-       {
-               vm_customstats = (customstat_t *)Z_Malloc((MAX_CL_STATS-32) * sizeof(customstat_t));
-               if(!vm_customstats)
-               {
-                       VM_Warning(prog, "PF_SV_AddStat: not enough memory\n");
-                       return;
-               }
-       }
        i               = (int)PRVM_G_FLOAT(OFS_PARM0);
        type    = (int)PRVM_G_FLOAT(OFS_PARM1);
        off             = PRVM_G_INT  (OFS_PARM2);
-       i -= 32;
 
-       if(i < 0)
+       switch (type)
        {
-               VM_Warning(prog, "PF_SV_AddStat: index may not be less than 32\n");
+       case 1:
+       case 2:
+       case 8:
+               break;
+       default:
+               VM_Warning(prog, "PF_SV_AddStat: unrecognized type %i - supported types are 1 (string up to 16 bytes, takes 4 stat slots), 2 (truncate to int32), 8 (send as float)", type);
                return;
        }
-       if(i >= (MAX_CL_STATS-32))
+
+       if (i < 0)
        {
-               VM_Warning(prog, "PF_SV_AddStat: index >= MAX_CL_STATS\n");
+               VM_Warning(prog, "PF_SV_AddStat: index (%i) may not be less than %i\n", i, MIN_VM_STAT);
                return;
        }
-       if(i > (MAX_CL_STATS-32-4) && type == 1)
+
+       if (i >= MAX_CL_STATS)
        {
-               VM_Warning(prog, "PF_SV_AddStat: index > (MAX_CL_STATS-4) with string\n");
+               VM_Warning(prog, "PF_SV_AddStat: index (%i) >= MAX_CL_STATS (%i), not supported by protocol, and AddStat beyond MAX_VM_STAT (%i) conflicts with engine MOVEVARS\n", i, MAX_CL_STATS, MAX_VM_STAT);
                return;
        }
+
+       if (i > (MAX_CL_STATS - 4) && type == 1)
+       {
+               VM_Warning(prog, "PF_SV_AddStat: index (%i) > (MAX_CL_STATS (%i) - 4) with string type won't fit in the protocol, and AddStat beyond MAX_VM_STAT conflicts with engine MOVEVARS\n", i, MAX_CL_STATS);
+               return;
+       }
+
+       // these are hazardous to override but sort of allowed if one wants to be adventurous...  and enjoys warnings.
+       if (i < MIN_VM_STAT)
+               VM_Warning(prog, "PF_SV_AddStat: index (%i) < MIN_VM_STAT (%i) may conflict with engine stats - allowed, but this may break things\n", i, MIN_VM_STAT);
+       else if (i >= MAX_VM_STAT && !sv_gameplayfix_customstats.integer)
+               VM_Warning(prog, "PF_SV_AddStat: index (%i) >= MAX_VM_STAT (%i) conflicts with engine stats - allowed, but this may break slowmo and stuff\n", i, MAX_VM_STAT);
+       else if (i > (MAX_VM_STAT - 4) && type == 1 && !sv_gameplayfix_customstats.integer)
+               VM_Warning(prog, "PF_SV_AddStat: index (%i) >= MAX_VM_STAT (%i) - 4 with string type won't fit within MAX_VM_STAT, thus conflicting with engine stats - allowed, but this may break slowmo and stuff\n", i, MAX_VM_STAT);
+
        vm_customstats[i].type          = type;
        vm_customstats[i].fieldoffset   = off;
        if(vm_customstats_last < i)
@@ -1747,7 +1768,7 @@ static void VM_SV_copyentity(prvm_prog_t *prog)
                VM_Warning(prog, "copyentity: can not read world entity\n");
                return;
        }
-       if (in->priv.server->free)
+       if (in->free)
        {
                VM_Warning(prog, "copyentity: can not read free entity\n");
                return;
@@ -1758,12 +1779,14 @@ static void VM_SV_copyentity(prvm_prog_t *prog)
                VM_Warning(prog, "copyentity: can not modify world entity\n");
                return;
        }
-       if (out->priv.server->free)
+       if (out->free)
        {
                VM_Warning(prog, "copyentity: can not modify free entity\n");
                return;
        }
        memcpy(out->fields.fp, in->fields.fp, prog->entityfields * sizeof(prvm_vec_t));
+       if (VectorCompare(PRVM_serveredictvector(out, absmin), PRVM_serveredictvector(out, absmax)))
+               return;
        SV_LinkEdict(out);
 }
 
@@ -2319,7 +2342,7 @@ static void VM_SV_te_flamejet(prvm_prog_t *prog)
 }
 
 //void(entity e, string s) clientcommand = #440; // executes a command string as if it came from the specified client
-//this function originally written by KrimZon, made shorter by LordHavoc
+//this function originally written by KrimZon, made shorter by LadyHavoc
 static void VM_SV_clientcommand(prvm_prog_t *prog)
 {
        client_t *temp_client;
@@ -2336,7 +2359,7 @@ static void VM_SV_clientcommand(prvm_prog_t *prog)
 
        temp_client = host_client;
        host_client = svs.clients + i;
-       Cmd_ExecuteString (PRVM_G_STRING(OFS_PARM1), src_client, true);
+       Cmd_ExecuteString(cmd_serverfromclient, PRVM_G_STRING(OFS_PARM1), src_client, true);
        host_client = temp_client;
 }
 
@@ -2346,7 +2369,7 @@ static void VM_SV_setattachment(prvm_prog_t *prog)
        prvm_edict_t *e = PRVM_G_EDICT(OFS_PARM0);
        prvm_edict_t *tagentity = PRVM_G_EDICT(OFS_PARM1);
        const char *tagname = PRVM_G_STRING(OFS_PARM2);
-       dp_model_t *model;
+       model_t *model;
        int tagindex;
        VM_SAFEPARMCOUNT(3, VM_SV_setattachment);
 
@@ -2355,7 +2378,7 @@ static void VM_SV_setattachment(prvm_prog_t *prog)
                VM_Warning(prog, "setattachment: can not modify world entity\n");
                return;
        }
-       if (e->priv.server->free)
+       if (e->free)
        {
                VM_Warning(prog, "setattachment: can not modify free entity\n");
                return;
@@ -2400,7 +2423,7 @@ static int SV_GetTagIndex (prvm_prog_t *prog, prvm_edict_t *e, const char *tagna
 static int SV_GetExtendedTagInfo (prvm_prog_t *prog, prvm_edict_t *e, int tagindex, int *parentindex, const char **tagname, matrix4x4_t *tag_localmatrix)
 {
        int r;
-       dp_model_t *model;
+       model_t *model;
 
        *tagname = NULL;
        *parentindex = 0;
@@ -2419,7 +2442,7 @@ static int SV_GetExtendedTagInfo (prvm_prog_t *prog, prvm_edict_t *e, int tagind
        return 1;
 }
 
-void SV_GetEntityMatrix (prvm_prog_t *prog, prvm_edict_t *ent, matrix4x4_t *out, qboolean viewmatrix)
+void SV_GetEntityMatrix (prvm_prog_t *prog, prvm_edict_t *ent, matrix4x4_t *out, qbool viewmatrix)
 {
        float scale;
        float pitchsign = 1;
@@ -2439,7 +2462,7 @@ void SV_GetEntityMatrix (prvm_prog_t *prog, prvm_edict_t *ent, matrix4x4_t *out,
 
 static int SV_GetEntityLocalTagMatrix(prvm_prog_t *prog, prvm_edict_t *ent, int tagindex, matrix4x4_t *out)
 {
-       dp_model_t *model;
+       model_t *model;
        if (tagindex >= 0 && (model = SV_GetModelFromEdict(ent)) && model->animscenes)
        {
                VM_GenerateFrameGroupBlend(prog, ent->priv.server->framegroupblend, ent);
@@ -2458,21 +2481,18 @@ static int SV_GetEntityLocalTagMatrix(prvm_prog_t *prog, prvm_edict_t *ent, int
 // 3 - null or non-precached model
 // 4 - no tags with requested index
 // 5 - runaway loop at attachment chain
-extern cvar_t cl_bob;
-extern cvar_t cl_bobcycle;
-extern cvar_t cl_bobup;
 static int SV_GetTagMatrix (prvm_prog_t *prog, matrix4x4_t *out, prvm_edict_t *ent, int tagindex)
 {
        int ret;
        int modelindex, attachloop;
        matrix4x4_t entitymatrix, tagmatrix, attachmatrix;
-       dp_model_t *model;
+       model_t *model;
 
        *out = identitymatrix; // warnings and errors return identical matrix
 
        if (ent == prog->edicts)
                return 1;
-       if (ent->priv.server->free)
+       if (ent->free)
                return 2;
 
        modelindex = (int)PRVM_serveredictfloat(ent, modelindex);
@@ -2519,29 +2539,6 @@ static int SV_GetTagMatrix (prvm_prog_t *prog, matrix4x4_t *out, prvm_edict_t *e
 
                SV_GetEntityMatrix(prog, ent, &entitymatrix, true);
                Matrix4x4_Concat(out, &entitymatrix, &tagmatrix);
-
-               /*
-               // Cl_bob, ported from rendering code
-               if (PRVM_serveredictfloat(ent, health) > 0 && cl_bob.value && cl_bobcycle.value)
-               {
-                       double bob, cycle;
-                       // LordHavoc: this code is *weird*, but not replacable (I think it
-                       // should be done in QC on the server, but oh well, quake is quake)
-                       // LordHavoc: figured out bobup: the time at which the sin is at 180
-                       // degrees (which allows lengthening or squishing the peak or valley)
-                       cycle = sv.time/cl_bobcycle.value;
-                       cycle -= (int)cycle;
-                       if (cycle < cl_bobup.value)
-                               cycle = sin(M_PI * cycle / cl_bobup.value);
-                       else
-                               cycle = sin(M_PI + M_PI * (cycle-cl_bobup.value)/(1.0 - cl_bobup.value));
-                       // bob is proportional to velocity in the xy plane
-                       // (don't count Z, or jumping messes it up)
-                       bob = sqrt(PRVM_serveredictvector(ent, velocity)[0]*PRVM_serveredictvector(ent, velocity)[0] + PRVM_serveredictvector(ent, velocity)[1]*PRVM_serveredictvector(ent, velocity)[1])*cl_bob.value;
-                       bob = bob*0.3 + bob*0.7*cycle;
-                       Matrix4x4_AdjustOrigin(out, 0, 0, bound(-7, bob, 4));
-               }
-               */
        }
        return 0;
 }
@@ -2564,7 +2561,7 @@ static void VM_SV_gettagindex(prvm_prog_t *prog)
                VM_Warning(prog, "VM_SV_gettagindex(entity #%i): can't affect world entity\n", PRVM_NUM_FOR_EDICT(ent));
                return;
        }
-       if (ent->priv.server->free)
+       if (ent->free)
        {
                VM_Warning(prog, "VM_SV_gettagindex(entity #%i): can't affect free entity\n", PRVM_NUM_FOR_EDICT(ent));
                return;
@@ -2594,7 +2591,7 @@ static void VM_SV_gettaginfo(prvm_prog_t *prog)
        const char *tagname;
        int returncode;
        vec3_t forward, left, up, origin;
-       const dp_model_t *model;
+       const model_t *model;
 
        VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
 
@@ -2660,7 +2657,7 @@ static void VM_SV_dropclient(prvm_prog_t *prog)
        }
        oldhostclient = host_client;
        host_client = svs.clients + clientnum;
-       SV_DropClient(false);
+       SV_DropClient(false, "Client dropped");
        host_client = oldhostclient;
 }
 
@@ -2723,7 +2720,7 @@ static void VM_SV_serverkey(prvm_prog_t *prog)
 static void VM_SV_setmodelindex(prvm_prog_t *prog)
 {
        prvm_edict_t    *e;
-       dp_model_t      *mod;
+       model_t *mod;
        int             i;
        VM_SAFEPARMCOUNT(2, VM_SV_setmodelindex);
 
@@ -2733,7 +2730,7 @@ static void VM_SV_setmodelindex(prvm_prog_t *prog)
                VM_Warning(prog, "setmodelindex: can not modify world entity\n");
                return;
        }
-       if (e->priv.server->free)
+       if (e->free)
        {
                VM_Warning(prog, "setmodelindex: can not modify free entity\n");
                return;
@@ -2853,13 +2850,27 @@ static void VM_SV_pointparticles(prvm_prog_t *prog)
        SV_FlushBroadcastMessages();
 }
 
+qbool SV_VM_ConsoleCommand (const char *text)
+{
+       prvm_prog_t *prog = SVVM_prog;
+       return PRVM_ConsoleCommand(prog, text, &prog->funcoffsets.ConsoleCmd, true, PRVM_EDICT_TO_PROG(sv.world.prog->edicts), sv.time,  !(!sv.active || !prog || !prog->loaded), "QC function ConsoleCmd is missing"); 
+}
+
+// #352 void(string cmdname) registercommand (EXT_CSQC)
+static void VM_SV_registercommand (prvm_prog_t *prog)
+{
+       VM_SAFEPARMCOUNT(1, VM_SV_registercmd);
+       if(!Cmd_Exists(cmd_local, PRVM_G_STRING(OFS_PARM0)))
+               Cmd_AddCommand(CF_SERVER, PRVM_G_STRING(OFS_PARM0), NULL, "console command created by QuakeC");
+}
+
 //PF_setpause,    // void(float pause) setpause        = #531;
 static void VM_SV_setpause(prvm_prog_t *prog) {
        int pauseValue;
        pauseValue = (int)PRVM_G_FLOAT(OFS_PARM0);
        if (pauseValue != 0) { //pause the game
                sv.paused = 1;
-               sv.pausedstart = realtime;
+               sv.pausedstart = host.realtime;
        } else { //disable pause, in case it was enabled
                if (sv.paused != 0) {
                        sv.paused = 0;
@@ -2875,7 +2886,7 @@ static void VM_SV_setpause(prvm_prog_t *prog) {
 static void VM_SV_skel_create(prvm_prog_t *prog)
 {
        int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
-       dp_model_t *model = SV_GetModelByIndex(modelindex);
+       model_t *model = SV_GetModelByIndex(modelindex);
        skeleton_t *skeleton;
        int i;
        PRVM_G_FLOAT(OFS_RETURN) = 0;
@@ -2905,14 +2916,13 @@ static void VM_SV_skel_build(prvm_prog_t *prog)
        float retainfrac = PRVM_G_FLOAT(OFS_PARM3);
        int firstbone = PRVM_G_FLOAT(OFS_PARM4) - 1;
        int lastbone = PRVM_G_FLOAT(OFS_PARM5) - 1;
-       dp_model_t *model = SV_GetModelByIndex(modelindex);
-       float blendfrac;
+       model_t *model = SV_GetModelByIndex(modelindex);
        int numblends;
        int bonenum;
        int blendindex;
        framegroupblend_t framegroupblend[MAX_FRAMEGROUPBLENDS];
        frameblend_t frameblend[MAX_FRAMEBLENDS];
-       matrix4x4_t blendedmatrix;
+       matrix4x4_t bonematrix;
        matrix4x4_t matrix;
        PRVM_G_FLOAT(OFS_RETURN) = 0;
        if (skeletonindex < 0 || skeletonindex >= MAX_EDICTS || !(skeleton = prog->skeletons[skeletonindex]))
@@ -2922,19 +2932,18 @@ static void VM_SV_skel_build(prvm_prog_t *prog)
        lastbone = min(lastbone, skeleton->model->num_bones - 1);
        VM_GenerateFrameGroupBlend(prog, framegroupblend, ed);
        VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model, sv.time);
-       blendfrac = 1.0f - retainfrac;
        for (numblends = 0;numblends < MAX_FRAMEBLENDS && frameblend[numblends].lerp;numblends++)
-               frameblend[numblends].lerp *= blendfrac;
+               ;
        for (bonenum = firstbone;bonenum <= lastbone;bonenum++)
        {
-               memset(&blendedmatrix, 0, sizeof(blendedmatrix));
-               Matrix4x4_Accumulate(&blendedmatrix, &skeleton->relativetransforms[bonenum], retainfrac);
+               memset(&bonematrix, 0, sizeof(bonematrix));
                for (blendindex = 0;blendindex < numblends;blendindex++)
                {
                        Matrix4x4_FromBonePose7s(&matrix, model->num_posescale, model->data_poses7s + 7 * (frameblend[blendindex].subframe * model->num_bones + bonenum));
-                       Matrix4x4_Accumulate(&blendedmatrix, &matrix, frameblend[blendindex].lerp);
+                       Matrix4x4_Accumulate(&bonematrix, &matrix, frameblend[blendindex].lerp);
                }
-               skeleton->relativetransforms[bonenum] = blendedmatrix;
+               Matrix4x4_Normalize3(&bonematrix, &bonematrix);
+               Matrix4x4_Interpolate(&skeleton->relativetransforms[bonenum], &bonematrix, &skeleton->relativetransforms[bonenum], retainfrac);
        }
        PRVM_G_FLOAT(OFS_RETURN) = skeletonindex + 1;
 }
@@ -3150,7 +3159,7 @@ static void VM_SV_skel_delete(prvm_prog_t *prog)
 static void VM_SV_frameforname(prvm_prog_t *prog)
 {
        int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
-       dp_model_t *model = SV_GetModelByIndex(modelindex);
+       model_t *model = SV_GetModelByIndex(modelindex);
        const char *name = PRVM_G_STRING(OFS_PARM1);
        int i;
        PRVM_G_FLOAT(OFS_RETURN) = -1;
@@ -3170,7 +3179,7 @@ static void VM_SV_frameforname(prvm_prog_t *prog)
 static void VM_SV_frameduration(prvm_prog_t *prog)
 {
        int modelindex = (int)PRVM_G_FLOAT(OFS_PARM0);
-       dp_model_t *model = SV_GetModelByIndex(modelindex);
+       model_t *model = SV_GetModelByIndex(modelindex);
        int framenum = (int)PRVM_G_FLOAT(OFS_PARM1);
        PRVM_G_FLOAT(OFS_RETURN) = 0;
        if (!model || !model->animscenes || framenum < 0 || framenum >= model->numframes)
@@ -3189,7 +3198,7 @@ VM_SV_setsize,                                    // #4 void(entity e, vector min, vector max) setsize (QUAKE)
 NULL,                                                  // #5 void(entity e, vector min, vector max) setabssize (QUAKE)
 VM_break,                                              // #6 void() break (QUAKE)
 VM_random,                                             // #7 float() random (QUAKE)
-VM_SV_sound,                                   // #8 void(entity e, float chan, string samp) sound (QUAKE)
+VM_SV_sound,                                   // #8 void(entity e, float chan, string samp, float volume[, float atten[, float pitchchange[, float flags]]]) sound (QUAKE)
 VM_normalize,                                  // #9 vector(vector v) normalize (QUAKE)
 VM_error,                                              // #10 void(string e) error (QUAKE)
 VM_objerror,                                   // #11 void(string e) objerror (QUAKE)
@@ -3227,7 +3236,7 @@ NULL,                                                     // #42 (QUAKE)
 VM_fabs,                                               // #43 float(float f) fabs (QUAKE)
 VM_SV_aim,                                             // #44 vector(entity e, float speed) aim (QUAKE)
 VM_cvar,                                               // #45 float(string s) cvar (QUAKE)
-VM_localcmd,                                   // #46 void(string s) localcmd (QUAKE)
+VM_localcmd_server,                            // #46 void(string s) localcmd (QUAKE)
 VM_nextent,                                            // #47 entity(entity e) nextent (QUAKE)
 VM_SV_particle,                                        // #48 void(vector o, vector d, float color, float count) particle (QUAKE)
 VM_changeyaw,                                  // #49 void() ChangeYaw (QUAKE)
@@ -3428,7 +3437,7 @@ NULL,                                                     // #241
 NULL,                                                  // #242
 NULL,                                                  // #243
 NULL,                                                  // #244
-NULL,                                                  // #245
+VM_modulo,                                             // #245
 NULL,                                                  // #246
 NULL,                                                  // #247
 NULL,                                                  // #248
@@ -3536,7 +3545,7 @@ NULL,                                                     // #348 string(float playernum, string keyname) getplayerkeyvalue (E
 NULL,                                                  // #349 float() isdemo (EXT_CSQC)
 VM_isserver,                                   // #350 float() isserver (EXT_CSQC)
 NULL,                                                  // #351 void(vector origin, vector forward, vector right, vector up) SetListener (EXT_CSQC)
-NULL,                                                  // #352 void(string cmdname) registercommand (EXT_CSQC)
+VM_SV_registercommand,                 // #352 void(string cmdname) registercommand (EXT_CSQC)
 VM_wasfreed,                                   // #353 float(entity ent) wasfreed (EXT_CSQC) (should be availabe on server too)
 VM_SV_serverkey,                               // #354 string(string key) serverkey (EXT_CSQC)
 NULL,                                                  // #355
@@ -3584,7 +3593,7 @@ NULL,                                                     // #396
 NULL,                                                  // #397
 NULL,                                                  // #398
 NULL,                                                  // #399
-// LordHavoc's range #400-#499
+// LadyHavoc's range #400-#499
 VM_SV_copyentity,                              // #400 void(entity from, entity to) copyentity (DP_QC_COPYENTITY)
 VM_SV_setcolor,                                        // #401 void(entity ent, float colors) setcolor (DP_QC_SETCOLOR)
 VM_findchain,                                  // #402 entity(.string fld, string match) findchain (DP_QC_FINDCHAIN)
@@ -3826,6 +3835,9 @@ NULL,                                                     // #637
 NULL,                                                  // #638
 VM_digest_hex,                                         // #639
 NULL,                                                  // #640
+NULL,                                                  // #641
+VM_coverage,                                           // #642
+NULL,                                                  // #643
 };
 
 const int vm_sv_numbuiltins = sizeof(vm_sv_builtins) / sizeof(prvm_builtin_t);
@@ -3838,7 +3850,8 @@ void SVVM_init_cmd(prvm_prog_t *prog)
 void SVVM_reset_cmd(prvm_prog_t *prog)
 {
        World_End(&sv.world);
-       if(PRVM_serverfunction(SV_Shutdown))
+
+       if(prog->loaded && PRVM_serverfunction(SV_Shutdown))
        {
                func_t s = PRVM_serverfunction(SV_Shutdown);
                PRVM_serverglobalfloat(time) = sv.time;