]> de.git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - svvm_cmds.c
Grant access to the FULLVOLUME flag from the QC VM (allows custom background music...
[xonotic/darkplaces.git] / svvm_cmds.c
index 043f2200a807fe8f9deb749cf80d8f6bb594b4e2..b41de028d7d00279a77fa3aa84d19715ae944e87 100644 (file)
@@ -19,6 +19,7 @@ const char *vm_sv_extensions =
 "DP_CON_SET "
 "DP_CON_SETA "
 "DP_CON_STARTMAP "
+"DP_COVERAGE "
 "DP_CRYPTO "
 "DP_CSQC_BINDMAPS "
 "DP_CSQC_ENTITYWORLDOBJECT "
@@ -33,9 +34,11 @@ const char *vm_sv_extensions =
 "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 "
@@ -123,6 +126,7 @@ const char *vm_sv_extensions =
 "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 "
@@ -164,6 +168,7 @@ const char *vm_sv_extensions =
 "DP_SV_CLIENTNAME "
 "DP_SV_CMD "
 "DP_SV_CUSTOMIZEENTITYFORCLIENT "
+"DP_SV_DISABLECLIENTPREDICTION "
 "DP_SV_DISCARDABLEDEMO "
 "DP_SV_DRAWONLYTOCLIENT "
 "DP_SV_DROPCLIENT "
@@ -206,6 +211,7 @@ const char *vm_sv_extensions =
 "DP_TE_SPARK "
 "DP_TE_STANDARDEFFECTBUILTINS "
 "DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
+"DP_USERMOVETYPES "
 "DP_VIEWZOOM "
 "EXT_BITSHIFT "
 "FRIK_FILE "
@@ -236,7 +242,6 @@ setorigin (entity, origin)
 static void VM_SV_setorigin(prvm_prog_t *prog)
 {
        prvm_edict_t    *e;
-       float   *org;
 
        VM_SAFEPARMCOUNT(2, VM_setorigin);
 
@@ -251,8 +256,7 @@ static void VM_SV_setorigin(prvm_prog_t *prog)
                VM_Warning(prog, "setorigin: can not modify free entity\n");
                return;
        }
-       org = PRVM_G_VECTOR(OFS_PARM1);
-       VectorCopy (org, PRVM_serveredictvector(e, origin));
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), PRVM_serveredictvector(e, origin));
        if(e->priv.required->mark == PRVM_EDICT_MARK_WAIT_FOR_SETORIGIN)
                e->priv.required->mark = PRVM_EDICT_MARK_SETORIGIN_CAUGHT;
        SV_LinkEdict(e);
@@ -288,7 +292,7 @@ setsize (entity, minvector, maxvector)
 static void VM_SV_setsize(prvm_prog_t *prog)
 {
        prvm_edict_t    *e;
-       float   *min, *max;
+       vec3_t mins, maxs;
 
        VM_SAFEPARMCOUNT(3, VM_setsize);
 
@@ -303,9 +307,9 @@ static void VM_SV_setsize(prvm_prog_t *prog)
                VM_Warning(prog, "setsize: can not modify free entity\n");
                return;
        }
-       min = PRVM_G_VECTOR(OFS_PARM1);
-       max = PRVM_G_VECTOR(OFS_PARM2);
-       SetMinMaxSize(prog, e, min, max, false);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), mins);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM2), maxs);
+       SetMinMaxSize(prog, e, mins, maxs, false);
 }
 
 
@@ -438,17 +442,17 @@ particle(origin, color, count)
 */
 static void VM_SV_particle(prvm_prog_t *prog)
 {
-       float           *org, *dir;
-       float           color;
-       float           count;
+       vec3_t          org, dir;
+       int             color;
+       int             count;
 
        VM_SAFEPARMCOUNT(4, VM_SV_particle);
 
-       org = PRVM_G_VECTOR(OFS_PARM0);
-       dir = PRVM_G_VECTOR(OFS_PARM1);
-       color = PRVM_G_FLOAT(OFS_PARM2);
-       count = PRVM_G_FLOAT(OFS_PARM3);
-       SV_StartParticle (org, dir, (int)color, (int)count);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), dir);
+       color = (int)PRVM_G_FLOAT(OFS_PARM2);
+       count = (int)PRVM_G_FLOAT(OFS_PARM3);
+       SV_StartParticle (org, dir, color, count);
 }
 
 
@@ -461,13 +465,13 @@ VM_SV_ambientsound
 static void VM_SV_ambientsound(prvm_prog_t *prog)
 {
        const char      *samp;
-       float           *pos;
-       float           vol, attenuation;
+       vec3_t          pos;
+       prvm_vec_t      vol, attenuation;
        int                     soundnum, large;
 
        VM_SAFEPARMCOUNT(4, VM_SV_ambientsound);
 
-       pos = PRVM_G_VECTOR (OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), pos);
        samp = PRVM_G_STRING(OFS_PARM1);
        vol = PRVM_G_FLOAT(OFS_PARM2);
        attenuation = PRVM_G_FLOAT(OFS_PARM3);
@@ -520,7 +524,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;
@@ -530,7 +534,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");
@@ -548,14 +552,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);
+       {
+               // LordHavoc: 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;
@@ -575,7 +582,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);
 }
 
 /*
@@ -591,7 +598,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;
@@ -600,11 +607,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;
@@ -616,7 +623,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);
 }
 
 /*
@@ -632,7 +639,7 @@ traceline (vector1, vector2, movetype, ignore)
 */
 static void VM_SV_traceline(prvm_prog_t *prog)
 {
-       float   *v1, *v2;
+       vec3_t  v1, v2;
        trace_t trace;
        int             move;
        prvm_edict_t    *ent;
@@ -641,15 +648,15 @@ static void VM_SV_traceline(prvm_prog_t *prog)
 
        prog->xfunction->builtinsprofile += 30;
 
-       v1 = PRVM_G_VECTOR(OFS_PARM0);
-       v2 = PRVM_G_VECTOR(OFS_PARM1);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), v1);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), v2);
        move = (int)PRVM_G_FLOAT(OFS_PARM2);
        ent = PRVM_G_EDICT(OFS_PARM3);
 
-       if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v2[1]) || IS_NAN(v2[2]))
+       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, collision_extendtracelinelength.value);
 
        VM_SetTraceGlobals(prog, &trace);
 }
@@ -669,7 +676,7 @@ tracebox (vector1, vector mins, vector maxs, vector2, tryents)
 // LordHavoc: added this for my own use, VERY useful, similar to traceline
 static void VM_SV_tracebox(prvm_prog_t *prog)
 {
-       float   *v1, *v2, *m1, *m2;
+       vec3_t v1, v2, m1, m2;
        trace_t trace;
        int             move;
        prvm_edict_t    *ent;
@@ -678,17 +685,17 @@ static void VM_SV_tracebox(prvm_prog_t *prog)
 
        prog->xfunction->builtinsprofile += 30;
 
-       v1 = PRVM_G_VECTOR(OFS_PARM0);
-       m1 = PRVM_G_VECTOR(OFS_PARM1);
-       m2 = PRVM_G_VECTOR(OFS_PARM2);
-       v2 = PRVM_G_VECTOR(OFS_PARM3);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), v1);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM1), m1);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM2), m2);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM3), v2);
        move = (int)PRVM_G_FLOAT(OFS_PARM4);
        ent = PRVM_G_EDICT(OFS_PARM5);
 
-       if (IS_NAN(v1[0]) || IS_NAN(v1[1]) || IS_NAN(v1[2]) || IS_NAN(v2[0]) || IS_NAN(v2[1]) || IS_NAN(v2[2]))
+       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, collision_extendtraceboxlength.value);
 
        VM_SetTraceGlobals(prog, &trace);
 }
@@ -697,7 +704,7 @@ static trace_t SV_Trace_Toss(prvm_prog_t *prog, prvm_edict_t *tossent, prvm_edic
 {
        int i;
        float gravity;
-       vec3_t move, end;
+       vec3_t move, end, tossentorigin, tossentmins, tossentmaxs;
        vec3_t original_origin;
        vec3_t original_velocity;
        vec3_t original_angles;
@@ -721,7 +728,10 @@ static trace_t SV_Trace_Toss(prvm_prog_t *prog, prvm_edict_t *tossent, prvm_edic
                VectorMA (PRVM_serveredictvector(tossent, angles), 0.05, PRVM_serveredictvector(tossent, avelocity), PRVM_serveredictvector(tossent, angles));
                VectorScale (PRVM_serveredictvector(tossent, velocity), 0.05, move);
                VectorAdd (PRVM_serveredictvector(tossent, origin), move, end);
-               trace = SV_TraceBox(PRVM_serveredictvector(tossent, origin), PRVM_serveredictvector(tossent, mins), PRVM_serveredictvector(tossent, maxs), end, MOVE_NORMAL, tossent, SV_GenericHitSuperContentsMask(tossent));
+               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), 0, collision_extendmovelength.value);
                VectorCopy (trace.endpos, PRVM_serveredictvector(tossent, origin));
                PRVM_serveredictvector(tossent, velocity)[2] -= gravity;
 
@@ -871,7 +881,7 @@ float checkpvs(vector viewpos, entity viewee) = #240;
 */
 static void VM_SV_checkpvs(prvm_prog_t *prog)
 {
-       vec3_t viewpos;
+       vec3_t viewpos, absmin, absmax;
        prvm_edict_t *viewee;
 #if 1
        unsigned char *pvs;
@@ -892,7 +902,7 @@ static void VM_SV_checkpvs(prvm_prog_t *prog)
        }
 
 #if 1
-       if(!sv.worldmodel->brush.GetPVS || !sv.worldmodel->brush.BoxTouchingPVS)
+       if(!sv.worldmodel || !sv.worldmodel->brush.GetPVS || !sv.worldmodel->brush.BoxTouchingPVS)
        {
                // no PVS support on this worldmodel... darn
                PRVM_G_FLOAT(OFS_RETURN) = 3;
@@ -905,10 +915,12 @@ static void VM_SV_checkpvs(prvm_prog_t *prog)
                PRVM_G_FLOAT(OFS_RETURN) = 2;
                return;
        }
-       PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, pvs, PRVM_serveredictvector(viewee, absmin), PRVM_serveredictvector(viewee, absmax));
+       VectorCopy(PRVM_serveredictvector(viewee, absmin), absmin);
+       VectorCopy(PRVM_serveredictvector(viewee, absmax), absmax);
+       PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, pvs, absmin, absmax);
 #else
        // using fat PVS like FTEQW does (slow)
-       if(!sv.worldmodel->brush.FatPVS || !sv.worldmodel->brush.BoxTouchingPVS)
+       if(!sv.worldmodel || !sv.worldmodel->brush.FatPVS || !sv.worldmodel->brush.BoxTouchingPVS)
        {
                // no PVS support on this worldmodel... darn
                PRVM_G_FLOAT(OFS_RETURN) = 3;
@@ -921,7 +933,9 @@ static void VM_SV_checkpvs(prvm_prog_t *prog)
                PRVM_G_FLOAT(OFS_RETURN) = 2;
                return;
        }
-       PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, fatpvs, PRVM_serveredictvector(viewee, absmin), PRVM_serveredictvector(viewee, absmax));
+       VectorCopy(PRVM_serveredictvector(viewee, absmin), absmin);
+       VectorCopy(PRVM_serveredictvector(viewee, absmax), absmax);
+       PRVM_G_FLOAT(OFS_RETURN) = sv.worldmodel->brush.BoxTouchingPVS(sv.worldmodel, fatpvs, absmin, absmax);
 #endif
 }
 
@@ -1116,7 +1130,7 @@ void() droptofloor
 static void VM_SV_droptofloor(prvm_prog_t *prog)
 {
        prvm_edict_t            *ent;
-       vec3_t          end;
+       vec3_t          end, entorigin, entmins, entmaxs;
        trace_t         trace;
 
        VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
@@ -1140,22 +1154,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);
 
-       trace = SV_TraceBox(PRVM_serveredictvector(ent, origin), PRVM_serveredictvector(ent, mins), PRVM_serveredictvector(ent, maxs), end, MOVE_NORMAL, ent, SV_GenericHitSuperContentsMask(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), 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, 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;
@@ -1165,8 +1179,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);
@@ -1177,10 +1191,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);
@@ -1250,8 +1263,10 @@ VM_SV_pointcontents
 */
 static void VM_SV_pointcontents(prvm_prog_t *prog)
 {
+       vec3_t point;
        VM_SAFEPARMCOUNT(1, VM_SV_pointcontents);
-       PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(PRVM_G_VECTOR(OFS_PARM0)));
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), point);
+       PRVM_G_FLOAT(OFS_RETURN) = Mod_Q1BSP_NativeContentsFromSuperContents(NULL, SV_PointSuperContents(point));
 }
 
 /*
@@ -1298,7 +1313,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, 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)) )
        {
@@ -1330,7 +1345,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, collision_extendmovelength.value);
                if (tr.ent == check)
                {       // can shoot at this one
                        bestdist = dist;
@@ -1475,7 +1490,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;
 
@@ -1483,8 +1498,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
        {
@@ -1598,9 +1613,9 @@ getlight(vector)
 static void VM_SV_getlight(prvm_prog_t *prog)
 {
        vec3_t ambientcolor, diffusecolor, diffusenormal;
-       vec_t *p;
+       vec3_t p;
        VM_SAFEPARMCOUNT(1, VM_SV_getlight);
-       p = PRVM_G_VECTOR(OFS_PARM0);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), p);
        VectorClear(ambientcolor);
        VectorClear(diffusecolor);
        VectorClear(diffusenormal);
@@ -1750,7 +1765,7 @@ static void VM_SV_copyentity(prvm_prog_t *prog)
                VM_Warning(prog, "copyentity: can not modify free entity\n");
                return;
        }
-       memcpy(out->fields.vp, in->fields.vp, prog->entityfields * 4);
+       memcpy(out->fields.fp, in->fields.fp, prog->entityfields * sizeof(prvm_vec_t));
        SV_LinkEdict(out);
 }
 
@@ -1807,6 +1822,7 @@ static void VM_SV_effect(prvm_prog_t *prog)
 {
        int i;
        const char *s;
+       vec3_t org;
        VM_SAFEPARMCOUNT(5, VM_SV_effect);
        s = PRVM_G_STRING(OFS_PARM1);
        if (!s[0])
@@ -1834,7 +1850,8 @@ static void VM_SV_effect(prvm_prog_t *prog)
                return;
        }
 
-       SV_StartEffect(PRVM_G_VECTOR(OFS_PARM0), i, (int)PRVM_G_FLOAT(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4));
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM0), org);
+       SV_StartEffect(org, i, (int)PRVM_G_FLOAT(OFS_PARM2), (int)PRVM_G_FLOAT(OFS_PARM3), (int)PRVM_G_FLOAT(OFS_PARM4));
 }
 
 static void VM_SV_te_blood(prvm_prog_t *prog)
@@ -2428,7 +2445,7 @@ static int SV_GetEntityLocalTagMatrix(prvm_prog_t *prog, prvm_edict_t *ent, int
        if (tagindex >= 0 && (model = SV_GetModelFromEdict(ent)) && model->animscenes)
        {
                VM_GenerateFrameGroupBlend(prog, ent->priv.server->framegroupblend, ent);
-               VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
+               VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model, sv.time);
                VM_UpdateEdictSkeleton(prog, ent, model, ent->priv.server->frameblend);
                return Mod_Alias_GetTagMatrix(model, ent->priv.server->frameblend, &ent->priv.server->skeleton, tagindex, out);
        }
@@ -2467,7 +2484,7 @@ static int SV_GetTagMatrix (prvm_prog_t *prog, matrix4x4_t *out, prvm_edict_t *e
        model = SV_GetModelByIndex(modelindex);
 
        VM_GenerateFrameGroupBlend(prog, ent->priv.server->framegroupblend, ent);
-       VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model);
+       VM_FrameBlendFromFrameGroupBlend(ent->priv.server->frameblend, ent->priv.server->framegroupblend, model, sv.time);
        VM_UpdateEdictSkeleton(prog, ent, model, ent->priv.server->frameblend);
 
        tagmatrix = identitymatrix;
@@ -2578,7 +2595,7 @@ static void VM_SV_gettaginfo(prvm_prog_t *prog)
        int parentindex;
        const char *tagname;
        int returncode;
-       vec3_t fo, le, up, trans;
+       vec3_t forward, left, up, origin;
        const dp_model_t *model;
 
        VM_SAFEPARMCOUNT(2, VM_SV_gettaginfo);
@@ -2587,21 +2604,24 @@ static void VM_SV_gettaginfo(prvm_prog_t *prog)
        tagindex = (int)PRVM_G_FLOAT(OFS_PARM1);
 
        returncode = SV_GetTagMatrix(prog, &tag_matrix, e, tagindex);
-       Matrix4x4_ToVectors(&tag_matrix, PRVM_serverglobalvector(v_forward), le, PRVM_serverglobalvector(v_up), PRVM_G_VECTOR(OFS_RETURN));
-       VectorScale(le, -1, PRVM_serverglobalvector(v_right));
+       Matrix4x4_ToVectors(&tag_matrix, forward, left, up, origin);
+       VectorCopy(forward, PRVM_serverglobalvector(v_forward));
+       VectorNegate(left, PRVM_serverglobalvector(v_right));
+       VectorCopy(up, PRVM_serverglobalvector(v_up));
+       VectorCopy(origin, PRVM_G_VECTOR(OFS_RETURN));
        model = SV_GetModelFromEdict(e);
        VM_GenerateFrameGroupBlend(prog, e->priv.server->framegroupblend, e);
-       VM_FrameBlendFromFrameGroupBlend(e->priv.server->frameblend, e->priv.server->framegroupblend, model);
+       VM_FrameBlendFromFrameGroupBlend(e->priv.server->frameblend, e->priv.server->framegroupblend, model, sv.time);
        VM_UpdateEdictSkeleton(prog, e, model, e->priv.server->frameblend);
        SV_GetExtendedTagInfo(prog, e, tagindex, &parentindex, &tagname, &tag_localmatrix);
-       Matrix4x4_ToVectors(&tag_localmatrix, fo, le, up, trans);
+       Matrix4x4_ToVectors(&tag_localmatrix, forward, left, up, origin);
 
        PRVM_serverglobalfloat(gettaginfo_parent) = parentindex;
        PRVM_serverglobalstring(gettaginfo_name) = tagname ? PRVM_SetTempString(prog, tagname) : 0;
-       VectorCopy(trans, PRVM_serverglobalvector(gettaginfo_offset));
-       VectorCopy(fo, PRVM_serverglobalvector(gettaginfo_forward));
-       VectorScale(le, -1, PRVM_serverglobalvector(gettaginfo_right));
+       VectorCopy(forward, PRVM_serverglobalvector(gettaginfo_forward));
+       VectorNegate(left, PRVM_serverglobalvector(gettaginfo_right));
        VectorCopy(up, PRVM_serverglobalvector(gettaginfo_up));
+       VectorCopy(origin, PRVM_serverglobalvector(gettaginfo_offset));
 
        switch(returncode)
        {
@@ -2785,6 +2805,7 @@ static void VM_SV_particleeffectnum(prvm_prog_t *prog)
 // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC)
 static void VM_SV_trailparticles(prvm_prog_t *prog)
 {
+       vec3_t start, end;
        VM_SAFEPARMCOUNT(4, VM_SV_trailparticles);
 
        if ((int)PRVM_G_FLOAT(OFS_PARM0) < 0)
@@ -2793,8 +2814,10 @@ static void VM_SV_trailparticles(prvm_prog_t *prog)
        MSG_WriteByte(&sv.datagram, svc_trailparticles);
        MSG_WriteShort(&sv.datagram, PRVM_G_EDICTNUM(OFS_PARM0));
        MSG_WriteShort(&sv.datagram, (int)PRVM_G_FLOAT(OFS_PARM1));
-       MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM2), sv.protocol);
-       MSG_WriteVector(&sv.datagram, PRVM_G_VECTOR(OFS_PARM3), sv.protocol);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM2), start);
+       VectorCopy(PRVM_G_VECTOR(OFS_PARM3), end);
+       MSG_WriteVector(&sv.datagram, start, sv.protocol);
+       MSG_WriteVector(&sv.datagram, end, sv.protocol);
        SV_FlushBroadcastMessages();
 }
 
@@ -2865,7 +2888,7 @@ static void VM_SV_skel_create(prvm_prog_t *prog)
                        break;
        if (i == MAX_EDICTS)
                return;
-       prog->skeletons[i] = skeleton = (skeleton_t *)Mem_Alloc(cls.levelmempool, sizeof(skeleton_t) + model->num_bones * sizeof(matrix4x4_t));
+       prog->skeletons[i] = skeleton = (skeleton_t *)Mem_Alloc(prog->progs_mempool, sizeof(skeleton_t) + model->num_bones * sizeof(matrix4x4_t));
        PRVM_G_FLOAT(OFS_RETURN) = i + 1;
        skeleton->model = model;
        skeleton->relativetransforms = (matrix4x4_t *)(skeleton+1);
@@ -2885,13 +2908,12 @@ static void VM_SV_skel_build(prvm_prog_t *prog)
        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;
        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]))
@@ -2900,20 +2922,19 @@ static void VM_SV_skel_build(prvm_prog_t *prog)
        lastbone = min(lastbone, model->num_bones - 1);
        lastbone = min(lastbone, skeleton->model->num_bones - 1);
        VM_GenerateFrameGroupBlend(prog, framegroupblend, ed);
-       VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model);
-       blendfrac = 1.0f - retainfrac;
+       VM_FrameBlendFromFrameGroupBlend(frameblend, framegroupblend, model, sv.time);
        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_FromBonePose6s(&matrix, model->num_posescale, model->data_poses6s + 6 * (frameblend[blendindex].subframe * model->num_bones + bonenum));
-                       Matrix4x4_Accumulate(&blendedmatrix, &matrix, frameblend[blendindex].lerp);
+                       Matrix4x4_FromBonePose7s(&matrix, model->num_posescale, model->data_poses7s + 7 * (frameblend[blendindex].subframe * model->num_bones + bonenum));
+                       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;
 }
@@ -3699,10 +3720,10 @@ VM_SV_setpause,                                 // #531 void(float pause) setpause = #531;
 VM_log,                                                        // #532
 VM_getsoundtime,                               // #533 float(entity e, float channel) getsoundtime = #533; (DP_SND_GETSOUNDTIME)
 VM_soundlength,                                        // #534 float(string sample) soundlength = #534; (DP_SND_GETSOUNDTIME)
-NULL,                                                  // #535
-NULL,                                                  // #536
-NULL,                                                  // #537
-NULL,                                                  // #538
+VM_buf_loadfile,                // #535 float(string filename, float bufhandle) buf_loadfile (DP_QC_STRINGBUFFERS_EXT_WIP)
+VM_buf_writefile,               // #536 float(float filehandle, float bufhandle, float startpos, float numstrings) buf_writefile (DP_QC_STRINGBUFFERS_EXT_WIP)
+VM_bufstr_find,                 // #537 float(float bufhandle, string match, float matchrule, float startpos) bufstr_find (DP_QC_STRINGBUFFERS_EXT_WIP)
+VM_matchpattern,                // #538 float(string s, string pattern, float matchrule) matchpattern (DP_QC_STRINGBUFFERS_EXT_WIP)
 NULL,                                                  // #539
 VM_physics_enable,                             // #540 void(entity e, float physics_enabled) physics_enable = #540; (DP_PHYSICS_ODE)
 VM_physics_addforce,                   // #541 void(entity e, vector force, vector relative_ofs) physics_addforce = #541; (DP_PHYSICS_ODE)
@@ -3805,6 +3826,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);
@@ -3817,7 +3841,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;