X-Git-Url: https://git.xonotic.org/?a=blobdiff_plain;f=svvm_cmds.c;h=a9d50af10c50008f3640642f8e8ac0a622eda71e;hb=fdc2140da5dc11b2970915454a4202968bed4381;hp=bb26170012cb22c7f0b73493b3aa290994e73767;hpb=7fdd505021831c99de0c571a035ca1adc07a3533;p=xonotic%2Fdarkplaces.git diff --git a/svvm_cmds.c b/svvm_cmds.c index bb261700..a9d50af1 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -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