From fc4a5f1101c87081f94ad550d6b3fd1beee37b54 Mon Sep 17 00:00:00 2001 From: cloudwalk Date: Tue, 26 May 2020 13:38:28 +0000 Subject: [PATCH] Implement clipgroup extension from DarkplacesRM This allows magical things to happen, such as disabling teammate collision in Xonotic. git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@12585 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_collision.c | 18 ++++++++++++++++++ dpdefs/dpextensions.qc | 8 ++++++++ prvm_offsets.h | 3 +++ sv_phys.c | 18 ++++++++++++++++++ svvm_cmds.c | 1 + 5 files changed, 48 insertions(+) diff --git a/cl_collision.c b/cl_collision.c index 56eac018..924d017c 100644 --- a/cl_collision.c +++ b/cl_collision.c @@ -227,6 +227,7 @@ trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int // list of entities to test for collisions int numtouchedicts; static prvm_edict_t *touchedicts[MAX_EDICTS]; + int clipgroup; if (hitnetworkentity) *hitnetworkentity = 0; @@ -280,6 +281,8 @@ trace_t CL_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int // precalculate passedict's owner edict pointer for comparisons traceowner = passedict ? PRVM_PROG_TO_EDICT(PRVM_clientedictedict(passedict, owner)) : NULL; + clipgroup = passedict ? (int)PRVM_clientedictfloat(passedict, clipgroup) : 0; + // collide against network entities if (hitnetworkbrushmodels) { @@ -381,6 +384,9 @@ skipnetworkplayers: // don't clip owner against owned entities if (passedictprog == PRVM_clientedictedict(touch, owner)) continue; + // don't clip against any entities in the same clipgroup (DP_RM_CLIPGROUP) + if (clipgroup && clipgroup == (int)PRVM_clientedictfloat(touch, clipgroup)) + continue; // don't clip points against points (they can't collide) if (VectorCompare(PRVM_clientedictvector(touch, mins), PRVM_clientedictvector(touch, maxs)) && (type != MOVE_MISSILE || !((int)PRVM_clientedictfloat(touch, flags) & FL_MONSTER))) continue; @@ -442,6 +448,7 @@ trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_ // list of entities to test for collisions int numtouchedicts; static prvm_edict_t *touchedicts[MAX_EDICTS]; + int clipgroup; if (VectorCompare(start, end)) return CL_TracePoint(start, type, passedict, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask, hitnetworkbrushmodels, hitnetworkplayers, hitnetworkentity, hitcsqcentities); @@ -498,6 +505,8 @@ trace_t CL_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_ // precalculate passedict's owner edict pointer for comparisons traceowner = passedict ? PRVM_PROG_TO_EDICT(PRVM_clientedictedict(passedict, owner)) : NULL; + clipgroup = passedict ? (int)PRVM_clientedictfloat(passedict, clipgroup) : 0; + // collide against network entities if (hitnetworkbrushmodels) { @@ -599,6 +608,9 @@ skipnetworkplayers: // don't clip owner against owned entities if (passedictprog == PRVM_clientedictedict(touch, owner)) continue; + // don't clip against any entities in the same clipgroup (DP_RM_CLIPGROUP) + if (clipgroup && clipgroup == (int)PRVM_clientedictfloat(touch, clipgroup)) + continue; // don't clip points against points (they can't collide) if (VectorCompare(PRVM_clientedictvector(touch, mins), PRVM_clientedictvector(touch, maxs)) && (type != MOVE_MISSILE || !((int)PRVM_clientedictfloat(touch, flags) & FL_MONSTER))) continue; @@ -664,6 +676,7 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co // list of entities to test for collisions int numtouchedicts; static prvm_edict_t *touchedicts[MAX_EDICTS]; + int clipgroup; if (VectorCompare(mins, maxs)) { vec3_t shiftstart, shiftend; @@ -743,6 +756,8 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co // precalculate passedict's owner edict pointer for comparisons traceowner = passedict ? PRVM_PROG_TO_EDICT(PRVM_clientedictedict(passedict, owner)) : NULL; + clipgroup = passedict ? (int)PRVM_clientedictfloat(passedict, clipgroup) : 0; + // collide against network entities if (hitnetworkbrushmodels) { @@ -844,6 +859,9 @@ skipnetworkplayers: // don't clip owner against owned entities if (passedictprog == PRVM_clientedictedict(touch, owner)) continue; + // don't clip against any entities in the same clipgroup (DP_RM_CLIPGROUP) + if (clipgroup && clipgroup == (int)PRVM_clientedictfloat(touch, clipgroup)) + continue; // don't clip points against points (they can't collide) if (pointtrace && VectorCompare(PRVM_clientedictvector(touch, mins), PRVM_clientedictvector(touch, maxs)) && (type != MOVE_MISSILE || !((int)PRVM_clientedictfloat(touch, flags) & FL_MONSTER))) continue; diff --git a/dpdefs/dpextensions.qc b/dpdefs/dpextensions.qc index f1e48f07..9cdeb695 100644 --- a/dpdefs/dpextensions.qc +++ b/dpdefs/dpextensions.qc @@ -2608,3 +2608,11 @@ float MOVETYPE_USER_FIRST = 128; float MOVETYPE_USER_LAST = 191; //description: //user defined movetypes can be added between the start and end points, without producing unknown movetype warnings + +//DP_RM_CLIPGROUP +//idea: Akari +//darkplaces implementation: Akari +//field definitions: +.float clipgroup; +//description: +//If two entities have this field set to the same non-zero integer value, they won't collide with each other. diff --git a/prvm_offsets.h b/prvm_offsets.h index 1563a051..5eada948 100644 --- a/prvm_offsets.h +++ b/prvm_offsets.h @@ -8,6 +8,7 @@ PRVM_DECLARE_clientfieldfloat(alpha) PRVM_DECLARE_clientfieldfloat(bouncefactor) PRVM_DECLARE_clientfieldfloat(bouncestop) PRVM_DECLARE_clientfieldfloat(colormap) +PRVM_DECLARE_clientfieldfloat(clipgroup) PRVM_DECLARE_clientfieldfloat(dphitcontentsmask) PRVM_DECLARE_clientfieldfloat(drawmask) PRVM_DECLARE_clientfieldfloat(effects) @@ -256,6 +257,7 @@ PRVM_DECLARE_field(classname) PRVM_DECLARE_field(clientcamera) PRVM_DECLARE_field(clientcolors) PRVM_DECLARE_field(clientstatus) +PRVM_DECLARE_field(clipgroup) PRVM_DECLARE_field(color) PRVM_DECLARE_field(colormap) PRVM_DECLARE_field(colormod) @@ -647,6 +649,7 @@ PRVM_DECLARE_serverfieldfloat(button16) PRVM_DECLARE_serverfieldfloat(buttonchat) PRVM_DECLARE_serverfieldfloat(buttonuse) PRVM_DECLARE_serverfieldfloat(clientcolors) +PRVM_DECLARE_serverfieldfloat(clipgroup) PRVM_DECLARE_serverfieldfloat(colormap) PRVM_DECLARE_serverfieldfloat(currentammo) PRVM_DECLARE_serverfieldfloat(cursor_active) diff --git a/sv_phys.c b/sv_phys.c index 1a774216..94587293 100644 --- a/sv_phys.c +++ b/sv_phys.c @@ -126,6 +126,7 @@ trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int // list of entities to test for collisions int numtouchedicts; static prvm_edict_t *touchedicts[MAX_EDICTS]; + int clipgroup; //return SV_TraceBox(start, vec3_origin, vec3_origin, end, type, passedict, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask); @@ -176,6 +177,8 @@ trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int // precalculate passedict's owner edict pointer for comparisons traceowner = passedict ? PRVM_PROG_TO_EDICT(PRVM_serveredictedict(passedict, owner)) : 0; + clipgroup = passedict ? (int)PRVM_serveredictfloat(passedict, clipgroup) : 0; + // clip to entities // because this uses World_EntitiestoBox, we know all entity boxes overlap // the clip region, so we can skip culling checks in the loop below @@ -206,6 +209,9 @@ trace_t SV_TracePoint(const vec3_t start, int type, prvm_edict_t *passedict, int // don't clip owner against owned entities if (passedictprog == PRVM_serveredictedict(touch, owner)) continue; + // don't clip against any entities in the same clipgroup (DP_RM_CLIPGROUP) + if (clipgroup && clipgroup == (int)PRVM_serveredictfloat(touch, clipgroup)) + continue; // don't clip points against points (they can't collide) if (VectorCompare(PRVM_serveredictvector(touch, mins), PRVM_serveredictvector(touch, maxs)) && (type != MOVE_MISSILE || !((int)PRVM_serveredictfloat(touch, flags) & FL_MONSTER))) continue; @@ -272,6 +278,7 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_ // list of entities to test for collisions int numtouchedicts; static prvm_edict_t *touchedicts[MAX_EDICTS]; + int clipgroup; if (VectorCompare(start, end)) return SV_TracePoint(start, type, passedict, hitsupercontentsmask, skipsupercontentsmask, skipmaterialflagsmask); @@ -325,6 +332,8 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_ // precalculate passedict's owner edict pointer for comparisons traceowner = passedict ? PRVM_PROG_TO_EDICT(PRVM_serveredictedict(passedict, owner)) : 0; + clipgroup = passedict ? (int)PRVM_serveredictfloat(passedict, clipgroup) : 0; + // clip to entities // because this uses World_EntitiestoBox, we know all entity boxes overlap // the clip region, so we can skip culling checks in the loop below @@ -355,6 +364,9 @@ trace_t SV_TraceLine(const vec3_t start, const vec3_t end, int type, prvm_edict_ // don't clip owner against owned entities if (passedictprog == PRVM_serveredictedict(touch, owner)) continue; + // don't clip against any entities in the same clipgroup (DP_RM_CLIPGROUP) + if (clipgroup && clipgroup == (int)PRVM_serveredictfloat(touch, clipgroup)) + continue; // don't clip points against points (they can't collide) if (VectorCompare(PRVM_serveredictvector(touch, mins), PRVM_serveredictvector(touch, maxs)) && (type != MOVE_MISSILE || !((int)PRVM_serveredictfloat(touch, flags) & FL_MONSTER))) continue; @@ -429,6 +441,7 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co // list of entities to test for collisions int numtouchedicts; static prvm_edict_t *touchedicts[MAX_EDICTS]; + int clipgroup; if (VectorCompare(mins, maxs)) { vec3_t shiftstart, shiftend; @@ -503,6 +516,8 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co // precalculate passedict's owner edict pointer for comparisons traceowner = passedict ? PRVM_PROG_TO_EDICT(PRVM_serveredictedict(passedict, owner)) : 0; + clipgroup = passedict ? (int)PRVM_serveredictfloat(passedict, clipgroup) : 0; + // clip to entities // because this uses World_EntitiestoBox, we know all entity boxes overlap // the clip region, so we can skip culling checks in the loop below @@ -533,6 +548,9 @@ trace_t SV_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co // don't clip owner against owned entities if (passedictprog == PRVM_serveredictedict(touch, owner)) continue; + // don't clip against any entities in the same clipgroup (DP_RM_CLIPGROUP) + if (clipgroup && clipgroup == (int)PRVM_serveredictfloat(touch, clipgroup)) + continue; // don't clip points against points (they can't collide) if (pointtrace && VectorCompare(PRVM_serveredictvector(touch, mins), PRVM_serveredictvector(touch, maxs)) && (type != MOVE_MISSILE || !((int)PRVM_serveredictfloat(touch, flags) & FL_MONSTER))) continue; diff --git a/svvm_cmds.c b/svvm_cmds.c index fbfe70ad..0e1a8720 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -227,6 +227,7 @@ const char *vm_sv_extensions = "TENEBRAE_GFX_DLIGHTS " "TW_SV_STEPCONTROL " "ZQ_PAUSE " +"DP_RM_CLIPGROUP " //"EXT_CSQC " // not ready yet ; -- 2.39.2