]> git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
Implement clipgroup extension from DarkplacesRM
authorcloudwalk <cloudwalk@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 26 May 2020 13:38:28 +0000 (13:38 +0000)
committercloudwalk <cloudwalk@d7cf8633-e32d-0410-b094-e92efae38249>
Tue, 26 May 2020 13:38:28 +0000 (13:38 +0000)
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
dpdefs/dpextensions.qc
prvm_offsets.h
sv_phys.c
svvm_cmds.c

index 56eac0188cffd579ac64ea8e498bcac7d06940f2..924d017cef0c8fbaa8d1540e804f68a78c8e460a 100644 (file)
@@ -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;
index f1e48f07ff6e99f7223f711675c68b105ca22dc6..9cdeb695744219f529aed58e1636d992980b6c8f 100644 (file)
@@ -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.
index 1563a0510f29264f475cfb436d0ec11b8395231f..5eada9486c6e350bfdea85ccce2c5b55fbf4b8da 100644 (file)
@@ -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)
index 1a7742167ecfb03cd93c7d6fdcdb52cc11d14a05..94587293cf4956671d6cc7b253460a6fe7908724 100644 (file)
--- 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;
index fbfe70ad4635b60d4d21e2950ec7a04ba0a52b14..0e1a8720f61f1ab652fd2d81f1317c6a1eb4a988 100644 (file)
@@ -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
 ;