]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - svvm_cmds.c
Save cvars cl_rollangle and cl_rollspeed to config.cfg
[xonotic/darkplaces.git] / svvm_cmds.c
index bb26170012cb22c7f0b73493b3aa290994e73767..a9d50af10c50008f3640642f8e8ac0a622eda71e 100644 (file)
@@ -100,6 +100,7 @@ const char *vm_sv_extensions[] = {
 "DP_QC_ENTITYSTRING",
 "DP_QC_ETOS",
 "DP_QC_EXTRESPONSEPACKET",
+"DP_QC_FINDBOX",
 "DP_QC_FINDCHAIN",
 "DP_QC_FINDCHAINFLAGS",
 "DP_QC_FINDCHAINFLOAT",
@@ -107,6 +108,7 @@ const char *vm_sv_extensions[] = {
 "DP_QC_FINDFLAGS",
 "DP_QC_FINDFLOAT",
 "DP_QC_FS_SEARCH",
+"DP_QC_FS_SEARCH_PACKFILE",
 "DP_QC_GETLIGHT",
 "DP_QC_GETSURFACE",
 "DP_QC_GETSURFACETRIANGLE",
@@ -119,6 +121,7 @@ const char *vm_sv_extensions[] = {
 "DP_QC_LOG",
 "DP_QC_MINMAXBOUND",
 "DP_QC_MULTIPLETEMPSTRINGS",
+"DP_QC_NUDGEOUTOFSOLID",
 "DP_QC_NUM_FOR_EDICT",
 "DP_QC_RANDOMVEC",
 "DP_QC_SINCOSSQRTPOW",
@@ -228,8 +231,6 @@ const char *vm_sv_extensions[] = {
 "TW_SV_STEPCONTROL",
 "ZQ_PAUSE",
 "DP_RM_CLIPGROUP",
-"DP_QC_FS_SEARCH_PACKFILE",
-"DP_QC_FINDBOX",
 NULL
 //"EXT_CSQC" // not ready yet
 };
@@ -1178,12 +1179,18 @@ VM_SV_droptofloor
 void() droptofloor
 ===============
 */
-
+inline static qbool droptofloor_bsp_failcond(trace_t *trace)
+{
+       if (sv.worldmodel->brush.isq3bsp || sv.worldmodel->brush.isq2bsp)
+               return trace->startsolid;
+       else
+               return trace->allsolid || trace->fraction == 1;
+}
 static void VM_SV_droptofloor(prvm_prog_t *prog)
 {
-       prvm_edict_t            *ent;
-       vec3_t          end, entorigin, entmins, entmaxs;
-       trace_t         trace;
+       prvm_edict_t *ent;
+       vec3_t        end;
+       trace_t       trace;
 
        VM_SAFEPARMCOUNTRANGE(0, 2, VM_SV_droptofloor); // allow 2 parameters because the id1 defs.qc had an incorrect prototype
 
@@ -1202,14 +1209,6 @@ static void VM_SV_droptofloor(prvm_prog_t *prog)
                return;
        }
 
-       VectorCopy (PRVM_serveredictvector(ent, origin), end);
-       if (sv.worldmodel->brush.isq3bsp)
-               end[2] -= 4096;
-       else if (sv.worldmodel->brush.isq2bsp)
-               end[2] -= 128;
-       else
-               end[2] -= 256; // Quake, QuakeWorld
-
        if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
        {
                int n = PHYS_NudgeOutOfSolid(prog, ent);
@@ -1219,55 +1218,62 @@ static void VM_SV_droptofloor(prvm_prog_t *prog)
                        VM_Warning(prog, "droptofloor at \"%f %f %f\": sv_gameplayfix_droptofloorstartsolid_nudgetocorrect FIXED badly placed entity \"%s\" before drop\n", PRVM_gameedictvector(ent, origin)[0], PRVM_gameedictvector(ent, origin)[1], PRVM_gameedictvector(ent, origin)[2], PRVM_GetString(prog, PRVM_gameedictstring(ent, classname)));
        }
 
-       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, 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), 0, 0, collision_extendmovelength.value);
-               VectorSubtract(trace.endpos, offset, trace.endpos);
-               if (trace.startsolid)
-               {
-                       VM_Warning(prog, "droptofloor at \"%f %f %f\": sv_gameplayfix_droptofloorstartsolid COULD NOT FIX badly placed entity \"%s\"\n", PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2], PRVM_GetString(prog, PRVM_gameedictstring(ent, classname)));
-                       SV_LinkEdict(ent);
-                       PRVM_serveredictfloat(ent, flags) = (int)PRVM_serveredictfloat(ent, flags) | FL_ONGROUND;
-                       PRVM_serveredictedict(ent, groundentity) = 0;
-                       PRVM_G_FLOAT(OFS_RETURN) = 1;
-               }
-               else if (trace.fraction < 1)
+       VectorCopy (PRVM_serveredictvector(ent, origin), end);
+       if (sv.worldmodel->brush.isq3bsp)
+               end[2] -= 4096;
+       else if (sv.worldmodel->brush.isq2bsp)
+               end[2] -= 128;
+       else
+               end[2] -= 256; // Quake, QuakeWorld
+
+       /* bones_was_here: not using SV_GenericHitSuperContentsMask(ent) anymore because it was setting:
+        * items:    SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY
+        * monsters: SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP
+        * explobox: SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_CORPSE
+        * which caused (startsolid == true) when, for example, a health was touching a monster.
+        * Changing MOVE_NORMAL also fixes that, but other engines are using MOVE_NORMAL here.
+        */
+       trace = SV_TraceBox(PRVM_serveredictvector(ent, origin), PRVM_serveredictvector(ent, mins), PRVM_serveredictvector(ent, maxs), end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID, 0, 0, collision_extendmovelength.value);
+       if (droptofloor_bsp_failcond(&trace))
+       {
+               if (sv_gameplayfix_droptofloorstartsolid.integer)
                {
+                       vec3_t offset, org;
+
+                       offset[0] = 0.5f * (PRVM_serveredictvector(ent, mins)[0] + PRVM_serveredictvector(ent, maxs)[0]);
+                       offset[1] = 0.5f * (PRVM_serveredictvector(ent, mins)[1] + PRVM_serveredictvector(ent, maxs)[1]);
+                       offset[2] = PRVM_serveredictvector(ent, mins)[2];
+                       VectorAdd(PRVM_serveredictvector(ent, origin), offset, org);
+                       VectorAdd(end, offset, end);
+
+                       trace = SV_TraceLine(org, end, MOVE_NORMAL, ent, SUPERCONTENTS_SOLID, 0, 0, collision_extendmovelength.value);
+                       if (droptofloor_bsp_failcond(&trace))
+                       {
+                               VM_Warning(prog, "droptofloor at \"%f %f %f\": sv_gameplayfix_droptofloorstartsolid COULD NOT FIX badly placed entity \"%s\"\n", PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2], PRVM_GetString(prog, PRVM_gameedictstring(ent, classname)));
+                               return;
+                       }
                        VM_Warning(prog, "droptofloor at \"%f %f %f\": sv_gameplayfix_droptofloorstartsolid FIXED badly placed entity \"%s\"\n", PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2], PRVM_GetString(prog, PRVM_gameedictstring(ent, classname)));
-                       VectorCopy (trace.endpos, PRVM_serveredictvector(ent, origin));
+                       VectorSubtract(trace.endpos, offset, PRVM_serveredictvector(ent, origin));
+
+                       // only because we dropped it without considering its bbox
                        if (sv_gameplayfix_droptofloorstartsolid_nudgetocorrect.integer)
                                PHYS_NudgeOutOfSolid(prog, 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);
-                       PRVM_G_FLOAT(OFS_RETURN) = 1;
-                       // if support is destroyed, keep suspended (gross hack for floating items in various maps)
-                       ent->priv.server->suspendedinairflag = true;
                }
-       }
-       else
-       {
-               if (trace.startsolid)
-                       VM_Warning(prog, "droptofloor at \"%f %f %f\": badly placed entity \"%s\", startsolid: %d allsolid: %d\n", PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2], PRVM_GetString(prog, PRVM_gameedictstring(ent, classname)), trace.startsolid, trace.allsolid);
-
-               if (!trace.allsolid && trace.fraction < 1)
+               else
                {
-                       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);
-                       PRVM_G_FLOAT(OFS_RETURN) = 1;
-                       // if support is destroyed, keep suspended (gross hack for floating items in various maps)
-                       ent->priv.server->suspendedinairflag = true;
+                       VM_Warning(prog, "droptofloor at \"%f %f %f\": badly placed entity \"%s\", startsolid: %d allsolid: %d\n", PRVM_serveredictvector(ent, origin)[0], PRVM_serveredictvector(ent, origin)[1], PRVM_serveredictvector(ent, origin)[2], PRVM_GetString(prog, PRVM_gameedictstring(ent, classname)), trace.startsolid, trace.allsolid);
+                       return;
                }
        }
+       else
+               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);
+       PRVM_G_FLOAT(OFS_RETURN) = 1;
+       // if support is destroyed, keep suspended (gross hack for floating items in various maps)
+       ent->priv.server->suspendedinairflag = true;
 }
 
 /*
@@ -3373,7 +3379,7 @@ VM_fclose,                                                // #111 void(float fhandle) fclose (FRIK_FILE)
 VM_fgets,                                              // #112 string(float fhandle) fgets (FRIK_FILE)
 VM_fputs,                                              // #113 void(float fhandle, string s) fputs (FRIK_FILE)
 VM_strlen,                                             // #114 float(string s) strlen (FRIK_FILE)
-VM_strcat,                                             // #115 string(string s1, string s2, ...) strcat (FRIK_FILE)
+VM_strcat,                                             // #115 string(string s, string...) strcat (FRIK_FILE)
 VM_substring,                                  // #116 string(string s, float start, float length) substring (FRIK_FILE)
 VM_stov,                                               // #117 vector(string) stov (FRIK_FILE)
 VM_strzone,                                            // #118 string(string s) strzone (FRIK_FILE)
@@ -3828,7 +3834,7 @@ NULL,                                                     // #563
 NULL,                                                  // #564
 NULL,                                                  // #565
 VM_SV_findbox,                                 // #566 entity(vector mins, vector maxs) findbox = #566; (DP_QC_FINDBOX)
-NULL,                                                  // #567
+VM_nudgeoutofsolid,                            // #567 float(entity ent) nudgeoutofsolid = #567; (DP_QC_NUDGEOUTOFSOLID)
 NULL,                                                  // #568
 NULL,                                                  // #569
 NULL,                                                  // #570