implemented DP_TRACE_HITCONTENTSMASK_SURFACEINFO extension, this allows QC to find...
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 22 Mar 2006 08:51:35 +0000 (08:51 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 22 Mar 2006 08:51:35 +0000 (08:51 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@6166 d7cf8633-e32d-0410-b094-e92efae38249

19 files changed:
cl_collision.c
cl_input.c
cl_particles.c
clvm_cmds.c
csprogs.c
csprogs.h
progs.h
progsvm.h
prvm_edict.c
r_crosshairs.c
snd_alsa.c
snd_sdl.c
sv_main.c
sv_phys.c
svvm_cmds.c
todo
view.c
world.c
world_cs.c

index 1e426d2..038c924 100644 (file)
@@ -137,7 +137,7 @@ trace_t CL_TraceBox(const vec3_t start, const vec3_t mins, const vec3_t maxs, co
 
                                Matrix4x4_Transform(&ent->inversematrix, start, starttransformed);
                                Matrix4x4_Transform(&ent->inversematrix, end, endtransformed);
-                               Collision_ClipTrace_Box(&trace, playermins, playermaxs, starttransformed, mins, maxs, endtransformed, hitsupercontentsmask, SUPERCONTENTS_SOLID);
+                               Collision_ClipTrace_Box(&trace, playermins, playermaxs, starttransformed, mins, maxs, endtransformed, hitsupercontentsmask, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
 
                                // LordHavoc: take the 'best' answers from the new trace and combine with existing data
                                if (trace.allsolid)
@@ -197,7 +197,7 @@ float CL_SelectTraceLine(const vec3_t start, const vec3_t end, vec3_t impact, ve
        if (hitent)
                *hitent = 0;
        if (cl.worldmodel && cl.worldmodel->TraceBox)
-               cl.worldmodel->TraceBox(cl.worldmodel, 0, &trace, start, start, end, end, SUPERCONTENTS_SOLID);
+               cl.worldmodel->TraceBox(cl.worldmodel, 0, &trace, start, start, end, end, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
 
        if (normal)
                VectorCopy(trace.plane.normal, normal);
@@ -245,7 +245,7 @@ float CL_SelectTraceLine(const vec3_t start, const vec3_t end, vec3_t impact, ve
                Matrix4x4_Transform(&ent->inversematrix, end, endtransformed);
 
                if (ent->model && ent->model->TraceBox)
-                       ent->model->TraceBox(ent->model, ent->frameblend[0].frame, &trace, starttransformed, starttransformed, endtransformed, endtransformed, SUPERCONTENTS_SOLID);
+                       ent->model->TraceBox(ent->model, ent->frameblend[0].frame, &trace, starttransformed, starttransformed, endtransformed, endtransformed, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY);
 
                if (maxrealfrac > trace.realfraction)
                {
index 3266a92..c2e7d47 100644 (file)
@@ -686,7 +686,7 @@ void CL_ClientMovement_Replay(void)
        VectorSet(neworigin2, currentorigin[0], currentorigin[1], currentorigin[2] - 1);
        if (cl.movement)
        {
-               trace = CL_TraceBox(currentorigin2, cl.playercrouchmins, cl.playercrouchmaxs, neworigin2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, true);
+               trace = CL_TraceBox(currentorigin2, cl.playercrouchmins, cl.playercrouchmaxs, neworigin2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true);
                onground = trace.fraction < 1 && trace.plane.normal[2] > 0.7;
                crouch = false; // this will be updated on first move
                canjump = true;
@@ -714,7 +714,7 @@ void CL_ClientMovement_Replay(void)
                                        // low ceiling first
                                        if (crouch)
                                        {
-                                               trace = CL_TraceBox(currentorigin, cl.playerstandmins, cl.playerstandmaxs, currentorigin, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, true);
+                                               trace = CL_TraceBox(currentorigin, cl.playerstandmins, cl.playerstandmaxs, currentorigin, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true);
                                                if (!trace.startsolid)
                                                        crouch = false;
                                        }
@@ -799,7 +799,7 @@ void CL_ClientMovement_Replay(void)
                                                {
                                                        VectorSet(currentorigin2, currentorigin[0] + currentvelocity[0]*(16/f), currentorigin[1] + currentvelocity[1]*(16/f), currentorigin[2] + playermins[2]);
                                                        VectorSet(neworigin2, currentorigin2[0], currentorigin2[1], currentorigin2[2] - 34);
-                                                       trace = CL_TraceBox(currentorigin2, vec3_origin, vec3_origin, neworigin2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, true);
+                                                       trace = CL_TraceBox(currentorigin2, vec3_origin, vec3_origin, neworigin2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true);
                                                        if (trace.fraction == 1)
                                                                edgefriction = movevars_edgefriction;
                                                }
@@ -841,18 +841,18 @@ void CL_ClientMovement_Replay(void)
                                for (bump = 0, t = frametime;bump < 8 && VectorLength2(currentvelocity) > 0;bump++)
                                {
                                        VectorMA(currentorigin, t, currentvelocity, neworigin);
-                                       trace = CL_TraceBox(currentorigin, playermins, playermaxs, neworigin, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, true);
+                                       trace = CL_TraceBox(currentorigin, playermins, playermaxs, neworigin, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true);
                                        if (trace.fraction < 1 && trace.plane.normal[2] == 0)
                                        {
                                                // may be a step or wall, try stepping up
                                                // first move forward at a higher level
                                                VectorSet(currentorigin2, currentorigin[0], currentorigin[1], currentorigin[2] + movevars_stepheight);
                                                VectorSet(neworigin2, neworigin[0], neworigin[1], currentorigin[2] + movevars_stepheight);
-                                               trace2 = CL_TraceBox(currentorigin2, playermins, playermaxs, neworigin2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, true);
+                                               trace2 = CL_TraceBox(currentorigin2, playermins, playermaxs, neworigin2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true);
                                                // then move down from there
                                                VectorCopy(trace2.endpos, currentorigin2);
                                                VectorSet(neworigin2, trace2.endpos[0], trace2.endpos[1], currentorigin[2]);
-                                               trace3 = CL_TraceBox(currentorigin2, playermins, playermaxs, neworigin2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_PLAYERCLIP, true);
+                                               trace3 = CL_TraceBox(currentorigin2, playermins, playermaxs, neworigin2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP, true);
                                                //Con_Printf("%f %f %f %f : %f %f %f %f : %f %f %f %f\n", trace.fraction, trace.endpos[0], trace.endpos[1], trace.endpos[2], trace2.fraction, trace2.endpos[0], trace2.endpos[1], trace2.endpos[2], trace3.fraction, trace3.endpos[0], trace3.endpos[1], trace3.endpos[2]);
                                                // accept the new trace if it made some progress
                                                if (fabs(trace3.endpos[0] - trace.endpos[0]) >= 0.03125 || fabs(trace3.endpos[1] - trace.endpos[1]) >= 0.03125)
index 5958617..202f32e 100644 (file)
@@ -1201,7 +1201,7 @@ void CL_MoveParticles (void)
                        VectorCopy(p->org, org);
                        if (p->bounce)
                        {
-                               trace = CL_TraceBox(oldorg, vec3_origin, vec3_origin, p->org, true, &hitent, SUPERCONTENTS_SOLID | (p->type == particletype + pt_rain ? SUPERCONTENTS_LIQUIDSMASK : 0), false);
+                               trace = CL_TraceBox(oldorg, vec3_origin, vec3_origin, p->org, true, &hitent, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | (p->type == particletype + pt_rain ? SUPERCONTENTS_LIQUIDSMASK : 0), false);
                                // if the trace started in or hit something of SUPERCONTENTS_NODROP
                                // or if the trace hit something flagged as NOIMPACT
                                // then remove the particle
@@ -1326,7 +1326,7 @@ void CL_MoveParticles (void)
                                break;
                        case pt_rain:
                                a = CL_PointSuperContents(p->org);
-                               if (a & (SUPERCONTENTS_SOLID | SUPERCONTENTS_LIQUIDSMASK))
+                               if (a & (SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_LIQUIDSMASK))
                                        p->type = NULL;
                                break;
                        case pt_snow:
@@ -1339,7 +1339,7 @@ void CL_MoveParticles (void)
                                        //p->vel[2] = p->relativedirection[2] + lhrandom(-32, 32);
                                }
                                a = CL_PointSuperContents(p->org);
-                               if (a & (SUPERCONTENTS_SOLID | SUPERCONTENTS_LIQUIDSMASK))
+                               if (a & (SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_LIQUIDSMASK))
                                        p->type = NULL;
                                break;
                        case pt_smoke:
index 28df1b6..6c132ee 100644 (file)
@@ -474,7 +474,7 @@ void VM_CL_checkbottom (void)
                {
                        start[0] = x ? maxs[0] : mins[0];
                        start[1] = y ? maxs[1] : mins[1];
-                       if (!(CL_PointSuperContents(start) & SUPERCONTENTS_SOLID))
+                       if (!(CL_PointSuperContents(start) & (SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY)))
                                goto realcheck;
                }
 
index 80a2707..2a63907 100644 (file)
--- a/csprogs.c
+++ b/csprogs.c
@@ -62,6 +62,7 @@ int csqc_fieldoff_scale;
 int csqc_fieldoff_renderflags;
 int csqc_fieldoff_tag_entity;
 int csqc_fieldoff_tag_index;
+int csqc_fieldoff_dphitcontentsmask;
 
 qboolean csqc_loaded = false;
 
index f37f4e7..e67578f 100644 (file)
--- a/csprogs.h
+++ b/csprogs.h
@@ -56,6 +56,7 @@ extern int csqc_fieldoff_scale;
 extern int csqc_fieldoff_renderflags;
 extern int csqc_fieldoff_tag_entity;
 extern int csqc_fieldoff_tag_index;
+extern int csqc_fieldoff_dphitcontentsmask;
 extern cvar_t csqc_progcrc;
 extern qboolean csqc_usecsqclistener;
 extern matrix4x4_t csqc_listenermatrix;
diff --git a/progs.h b/progs.h
index 7005dee..0eda527 100644 (file)
--- a/progs.h
+++ b/progs.h
@@ -129,6 +129,14 @@ extern int eval_playerskin;
 extern int eval_SendEntity;
 extern int eval_Version;
 extern int eval_customizeentityforclient;
+extern int eval_dphitcontentsmask;
+
+extern int gval_trace_dpstartcontents;
+extern int gval_trace_dphitcontents;
+extern int gval_trace_dphitq3surfaceflags;
+extern int gval_trace_dphittexturename;
+
+
 
 extern mfunction_t *SV_PlayerPhysicsQC;
 extern mfunction_t *EndFrameQC;
@@ -265,7 +273,6 @@ extern int eval_playerskin;
 
 #define PRVM_GETEDICTFIELDVALUE(ed, fieldoffset) (fieldoffset ? (prvm_eval_t *)((unsigned char *)ed->v + fieldoffset) : NULL)
 
-
 extern mfunction_t *SV_PlayerPhysicsQC;
 extern mfunction_t *EndFrameQC;
 //KrimZon - SERVER COMMANDS IN QUAKEC
index 0ef7dff..673caea 100644 (file)
--- a/progsvm.h
+++ b/progsvm.h
@@ -210,6 +210,7 @@ typedef struct prvm_edict_s
 } prvm_edict_t;
 
 #define PRVM_GETEDICTFIELDVALUE(ed, fieldoffset) (fieldoffset ? (prvm_eval_t *)((unsigned char *)ed->fields.vp + fieldoffset) : NULL)
+#define PRVM_GETGLOBALFIELDVALUE(fieldoffset) (fieldoffset ? (prvm_eval_t *)((unsigned char *)prog->globals.generic + fieldoffset) : NULL)
 
 /*// this struct is the basic requirement for a qc prog
 typedef struct prvm_pr_globalvars_s
@@ -433,6 +434,7 @@ void PRVM_CrashAll (void);
 void PRVM_Crash (void);
 
 int PRVM_ED_FindFieldOffset(const char *field);
+int PRVM_ED_FindGlobalOffset(const char *global);
 ddef_t *PRVM_ED_FindField (const char *name);
 mfunction_t *PRVM_ED_FindFunction (const char *name);
 
index e79cc5f..b78b987 100644 (file)
@@ -124,6 +124,16 @@ int PRVM_ED_FindFieldOffset(const char *field)
        return d->ofs*4;
 }
 
+ddef_t*        PRVM_ED_FindGlobal(const char *name);
+int PRVM_ED_FindGlobalOffset(const char *global)
+{
+       ddef_t *d;
+       d = PRVM_ED_FindGlobal(global);
+       if (!d)
+               return 0;
+       return d->ofs*4;
+}
+
 qboolean PRVM_ProgLoaded(int prognr)
 {
        if(prognr < 0 || prognr >= PRVM_MAXPROGS)
index 38e1b4c..e0fd5b2 100644 (file)
@@ -82,7 +82,7 @@ void R_DrawWorldCrosshair(void)
        AngleVectors(cl.viewangles, v2, NULL, NULL);
        //VectorCopy(r_vieworigin, v1);
        VectorMA(v1, 8192, v2, v2);
-       trace = CL_TraceBox(v1, vec3_origin, vec3_origin, v2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, false);
+       trace = CL_TraceBox(v1, vec3_origin, vec3_origin, v2, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, false);
        spritescale = trace.fraction * (8192.0f / 40.0f) * crosshair_size.value;
        VectorCopy(trace.endpos, spriteorigin);
 
index 03c713b..31f5c1e 100644 (file)
@@ -83,6 +83,10 @@ qboolean SNDDMA_Init (void)
                if ((i=COM_CheckParm("-sndstereo")) != 0)
                        if (channels != 2)
                                continue;
+// COMMANDLINEOPTION: Linux ALSA Sound: -sndquad sets sound output to 4 channel surround
+               if ((i=COM_CheckParm("-sndquad")) != 0)
+                       if (channels != 4)
+                               continue;
 
 // COMMANDLINEOPTION: Linux ALSA Sound: -sndpcm <devicename> selects which pcm device to us, default is "default"
                if (channels == 8)
index 5e4157e..cfeeb1b 100644 (file)
--- a/snd_sdl.c
+++ b/snd_sdl.c
@@ -101,6 +101,10 @@ qboolean SNDDMA_Init(void)
                if ((i=COM_CheckParm("-sndstereo")) != 0)
                        if (channels != 2)
                                continue;
+// COMMANDLINEOPTION: SDL Sound: -sndquad sets sound output to 4 channel surround
+               if ((i=COM_CheckParm("-sndquad")) != 0)
+                       if (channels != 4)
+                               continue;
                // Init the SDL Audio subsystem
                wantspec.callback = Buffer_Callback;
                wantspec.userdata = NULL;
index e6ce994..681fcf8 100644 (file)
--- a/sv_main.c
+++ b/sv_main.c
@@ -2154,6 +2154,12 @@ int eval_playerskin;
 int eval_SendEntity;
 int eval_Version;
 int eval_customizeentityforclient;
+int eval_dphitcontentsmask;
+
+int gval_trace_dpstartcontents;
+int gval_trace_dphitcontents;
+int gval_trace_dphitq3surfaceflags;
+int gval_trace_dphittexturename;
 
 mfunction_t *SV_PlayerPhysicsQC;
 mfunction_t *EndFrameQC;
@@ -2226,6 +2232,7 @@ void SV_VM_FindEdictFieldOffsets(void)
        eval_SendEntity = PRVM_ED_FindFieldOffset("SendEntity");
        eval_Version = PRVM_ED_FindFieldOffset("Version");
        eval_customizeentityforclient = PRVM_ED_FindFieldOffset("customizeentityforclient");
+       eval_dphitcontentsmask = PRVM_ED_FindFieldOffset("dphitcontentsmask");
 
        // LordHavoc: allowing QuakeC to override the player movement code
        SV_PlayerPhysicsQC = PRVM_ED_FindFunction ("SV_PlayerPhysics");
@@ -2239,6 +2246,11 @@ void SV_VM_FindEdictFieldOffsets(void)
                SV_InitCmd = PRVM_G_STRING(PRVM_ED_FindGlobal("SV_InitCmd")->ofs);
        else
                SV_InitCmd = NULL;
+
+       gval_trace_dpstartcontents = PRVM_ED_FindGlobalOffset("trace_dpstartcontents");
+       gval_trace_dphitcontents = PRVM_ED_FindGlobalOffset("trace_dphitcontents");
+       gval_trace_dphitq3surfaceflags = PRVM_ED_FindGlobalOffset("trace_dphitq3surfaceflags");
+       gval_trace_dphittexturename = PRVM_ED_FindGlobalOffset("trace_dphittexturename");
 }
 
 #define REQFIELDS (sizeof(reqfields) / sizeof(prvm_required_field_t))
index 15c6802..dcca2be 100644 (file)
--- a/sv_phys.c
+++ b/sv_phys.c
@@ -20,6 +20,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // sv_phys.c
 
 #include "quakedef.h"
+// used only for VM_GetTempString
+#include "prvm_cmds.h"
 
 /*
 
@@ -187,25 +189,73 @@ SV_Impact
 Two entities have touched, so run their touch functions
 ==================
 */
-void SV_Impact (prvm_edict_t *e1, prvm_edict_t *e2)
+void SV_Impact (prvm_edict_t *e1, trace_t *trace)
 {
        int old_self, old_other;
+       prvm_edict_t *e2 = (prvm_edict_t *)trace->ent;
+       prvm_eval_t *val;
 
        old_self = prog->globals.server->self;
        old_other = prog->globals.server->other;
 
        prog->globals.server->time = sv.time;
-       if (e1->fields.server->touch && e1->fields.server->solid != SOLID_NOT)
+       if (!e1->priv.server->free && !e2->priv.server->free && e1->fields.server->touch && e1->fields.server->solid != SOLID_NOT)
        {
                prog->globals.server->self = PRVM_EDICT_TO_PROG(e1);
                prog->globals.server->other = PRVM_EDICT_TO_PROG(e2);
+               prog->globals.server->trace_allsolid = trace->allsolid;
+               prog->globals.server->trace_startsolid = trace->startsolid;
+               prog->globals.server->trace_fraction = trace->fraction;
+               prog->globals.server->trace_inwater = trace->inwater;
+               prog->globals.server->trace_inopen = trace->inopen;
+               VectorCopy (trace->endpos, prog->globals.server->trace_endpos);
+               VectorCopy (trace->plane.normal, prog->globals.server->trace_plane_normal);
+               prog->globals.server->trace_plane_dist =  trace->plane.dist;
+               if (trace->ent)
+                       prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace->ent);
+               else
+                       prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
+               if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dpstartcontents)))
+                       val->_float = trace->startsupercontents;
+               if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitcontents)))
+                       val->_float = trace->hitsupercontents;
+               if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitq3surfaceflags)))
+                       val->_float = trace->hitq3surfaceflags;
+               if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphittexturename)))
+               {
+                       if (trace->hittexture)
+                       {
+                               char *s = VM_GetTempString();
+                               strlcpy(s, trace->hittexture->name, VM_STRINGTEMP_LENGTH);
+                               val->string = PRVM_SetEngineString(s);
+                       }
+                       else
+                               val->string = 0;
+               }
                PRVM_ExecuteProgram (e1->fields.server->touch, "QC function self.touch is missing");
        }
 
-       if (e2->fields.server->touch && e2->fields.server->solid != SOLID_NOT)
+       if (!e1->priv.server->free && !e2->priv.server->free && e2->fields.server->touch && e2->fields.server->solid != SOLID_NOT)
        {
                prog->globals.server->self = PRVM_EDICT_TO_PROG(e2);
                prog->globals.server->other = PRVM_EDICT_TO_PROG(e1);
+               prog->globals.server->trace_allsolid = false;
+               prog->globals.server->trace_startsolid = false;
+               prog->globals.server->trace_fraction = 1;
+               prog->globals.server->trace_inwater = false;
+               prog->globals.server->trace_inopen = true;
+               VectorCopy (e2->fields.server->origin, prog->globals.server->trace_endpos);
+               VectorSet (prog->globals.server->trace_plane_normal, 0, 0, 1);
+               prog->globals.server->trace_plane_dist = 0;
+               prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(e1);
+               if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dpstartcontents)))
+                       val->_float = 0;
+               if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitcontents)))
+                       val->_float = 0;
+               if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitq3surfaceflags)))
+                       val->_float = 0;
+               if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphittexturename)))
+                       val->string = 0;
                PRVM_ExecuteProgram (e2->fields.server->touch, "QC function self.touch is missing");
        }
 
@@ -377,7 +427,7 @@ int SV_FlyMove (prvm_edict_t *ent, float time, float *stepnormal)
                // run the impact function
                if (impact)
                {
-                       SV_Impact(ent, (prvm_edict_t *)trace.ent);
+                       SV_Impact(ent, &trace);
 
                        // break if removed by the impact function
                        if (ent->priv.server->free)
@@ -530,7 +580,7 @@ trace_t SV_PushEntity (prvm_edict_t *ent, vec3_t push)
        SV_LinkEdict (ent, true);
 
        if (trace.ent && (!((int)ent->fields.server->flags & FL_ONGROUND) || ent->fields.server->groundentity != PRVM_EDICT_TO_PROG(trace.ent)))
-               SV_Impact (ent, (prvm_edict_t *)trace.ent);
+               SV_Impact (ent, &trace);
        return trace;
 }
 
@@ -675,7 +725,7 @@ void SV_PushMove (prvm_edict_t *pusher, float movetime)
                if (!(((int)check->fields.server->flags & FL_ONGROUND) && PRVM_PROG_TO_EDICT(check->fields.server->groundentity) == pusher))
                {
                        // if the entity is not inside the pusher's final position, leave it alone
-                       if (!SV_ClipMoveToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, 0, SUPERCONTENTS_SOLID).startsolid)
+                       if (!SV_ClipMoveToEntity(pusher, check->fields.server->origin, check->fields.server->mins, check->fields.server->maxs, check->fields.server->origin, 0, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY).startsolid)
                                continue;
                        // remove the onground flag for non-players
                        if (check->fields.server->movetype != MOVETYPE_WALK)
index 860d7a0..c5db79b 100644 (file)
@@ -111,6 +111,7 @@ char *vm_sv_extensions =
 "DP_TE_SMALLFLASH "
 "DP_TE_SPARK "
 "DP_TE_STANDARDEFFECTBUILTINS "
+"DP_TRACE_HITCONTENTSMASK_SURFACEINFO "
 "DP_VIEWZOOM "
 "EXT_BITSHIFT "
 //"EXT_CSQC " // not ready yet
@@ -431,6 +432,7 @@ void PF_traceline (void)
        trace_t trace;
        int             move;
        prvm_edict_t    *ent;
+       prvm_eval_t *val;
 
        prog->xfunction->builtinsprofile += 30;
 
@@ -456,7 +458,23 @@ void PF_traceline (void)
                prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
        else
                prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
-       // FIXME: add trace_endcontents
+       if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dpstartcontents)))
+               val->_float = trace.startsupercontents;
+       if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitcontents)))
+               val->_float = trace.hitsupercontents;
+       if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitq3surfaceflags)))
+               val->_float = trace.hitq3surfaceflags;
+       if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphittexturename)))
+       {
+               if (trace.hittexture)
+               {
+                       char *s = VM_GetTempString();
+                       strlcpy(s, trace.hittexture->name, VM_STRINGTEMP_LENGTH);
+                       val->string = PRVM_SetEngineString(s);
+               }
+               else
+                       val->string = 0;
+       }
 }
 
 
@@ -478,6 +496,7 @@ void PF_tracebox (void)
        trace_t trace;
        int             move;
        prvm_edict_t    *ent;
+       prvm_eval_t *val;
 
        prog->xfunction->builtinsprofile += 30;
 
@@ -505,6 +524,23 @@ void PF_tracebox (void)
                prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
        else
                prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
+       if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dpstartcontents)))
+               val->_float = trace.startsupercontents;
+       if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitcontents)))
+               val->_float = trace.hitsupercontents;
+       if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitq3surfaceflags)))
+               val->_float = trace.hitq3surfaceflags;
+       if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphittexturename)))
+       {
+               if (trace.hittexture)
+               {
+                       char *s = VM_GetTempString();
+                       strlcpy(s, trace.hittexture->name, VM_STRINGTEMP_LENGTH);
+                       val->string = PRVM_SetEngineString(s);
+               }
+               else
+                       val->string = 0;
+       }
 }
 
 extern trace_t SV_Trace_Toss (prvm_edict_t *ent, prvm_edict_t *ignore);
@@ -513,6 +549,7 @@ void PF_tracetoss (void)
        trace_t trace;
        prvm_edict_t    *ent;
        prvm_edict_t    *ignore;
+       prvm_eval_t *val;
 
        prog->xfunction->builtinsprofile += 600;
 
@@ -535,6 +572,23 @@ void PF_tracetoss (void)
                prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(trace.ent);
        else
                prog->globals.server->trace_ent = PRVM_EDICT_TO_PROG(prog->edicts);
+       if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dpstartcontents)))
+               val->_float = trace.startsupercontents;
+       if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitcontents)))
+               val->_float = trace.hitsupercontents;
+       if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphitq3surfaceflags)))
+               val->_float = trace.hitq3surfaceflags;
+       if ((val = PRVM_GETGLOBALFIELDVALUE(gval_trace_dphittexturename)))
+       {
+               if (trace.hittexture)
+               {
+                       char *s = VM_GetTempString();
+                       strlcpy(s, trace.hittexture->name, VM_STRINGTEMP_LENGTH);
+                       val->string = PRVM_SetEngineString(s);
+               }
+               else
+                       val->string = 0;
+       }
 }
 
 
diff --git a/todo b/todo
index 20746e3..fcccd52 100644 (file)
--- a/todo
+++ b/todo
@@ -39,6 +39,8 @@
 -d (yummyluv) feature darkplaces protocol: add buttons 9-16 (yummyluv)
 -f (James D) bug darkplaces server: losing runes on episode completion, completing episode 1 then 2 then 3 causes it to forget 1, then 4 causes it to forget 2 and 3, making it impossible to open the boss gate (James D)
 -f (Wazat) bug darkplaces: client's slowmo detection (measuring packet times and comparing to game time changes) may be making the game unpleasant (Wazat)
+0 change darkplaces client: particles shouldn't be using contents checks to decide whether to die, they should use movement traces
+0 bug darkplaces renderer: deluxemaps are not detected in some maps that do have them?  (SavageX)
 0 bug darkplaces client: GAME_NEHAHRA: make sure cutscenes and movies work, got a report of seeing a black screen (NightFright)
 0 bug darkplaces client: fix cl_bobmodel bug which momentarily jolts the gun when you pass through a trigger, pick up an item, etc, Sajt thinks this is related to console prints as well as centerprint (Sajt)
 0 bug darkplaces client: prydon cursor highlighting of EF_SELECTABLE entities flickers with lower server framerate than client framerate (carni)
diff --git a/view.c b/view.c
index 562e487..73acc74 100644 (file)
--- a/view.c
+++ b/view.c
@@ -406,7 +406,7 @@ void V_CalcRefdef (void)
                                chase_dest[0] = vieworg[0] + forward[0] * dist;
                                chase_dest[1] = vieworg[1] + forward[1] * dist;
                                chase_dest[2] = vieworg[2] + forward[2] * dist + camup;
-                               trace = CL_TraceBox(vieworg, vec3_origin, vec3_origin, chase_dest, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_SKY, false);
+                               trace = CL_TraceBox(vieworg, vec3_origin, vec3_origin, chase_dest, true, NULL, SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_SKY, false);
                                VectorMAMAM(1, trace.endpos, 8, forward, 4, trace.plane.normal, vieworg);
                        }
                        else
diff --git a/world.c b/world.c
index b294e22..70b2099 100644 (file)
--- a/world.c
+++ b/world.c
@@ -476,7 +476,7 @@ trace_t SV_ClipMoveToEntity(prvm_edict_t *ent, const vec3_t start, const vec3_t
                model->TraceBox(model, frame, &trace, starttransformed, mins, maxs, endtransformed, hitsupercontents);
        }
        else
-               Collision_ClipTrace_Box(&trace, ent->fields.server->mins, ent->fields.server->maxs, starttransformed, mins, maxs, endtransformed, hitsupercontents, SUPERCONTENTS_SOLID);
+               Collision_ClipTrace_Box(&trace, ent->fields.server->mins, ent->fields.server->maxs, starttransformed, mins, maxs, endtransformed, hitsupercontents, ent->fields.server->solid == SOLID_CORPSE ? SUPERCONTENTS_CORPSE : SUPERCONTENTS_BODY);
        trace.fraction = bound(0, trace.fraction, 1);
        trace.realfraction = bound(0, trace.realfraction, 1);
 
@@ -529,6 +529,7 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const
        int passedictprog;
        qboolean pointtrace;
        prvm_edict_t *traceowner, *touch;
+       prvm_eval_t *val;
        trace_t trace;
        // bounding box of entire move area
        vec3_t clipboxmins, clipboxmaxs;
@@ -553,14 +554,25 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const
        Con_Printf("move(%f %f %f,%f %f %f)", clipstart[0], clipstart[1], clipstart[2], clipend[0], clipend[1], clipend[2]);
 #endif
 
-       hitsupercontentsmask = SUPERCONTENTS_SOLID;
        if (passedict)
        {
-               if (passedict->fields.server->solid == SOLID_SLIDEBOX)
-                       hitsupercontentsmask |= SUPERCONTENTS_PLAYERCLIP;
-               if ((int)passedict->fields.server->flags & FL_MONSTER)
-                       hitsupercontentsmask |= SUPERCONTENTS_MONSTERCLIP;
+               val = PRVM_GETEDICTFIELDVALUE(passedict, eval_dphitcontentsmask);
+               if (val && val->_float)
+                       hitsupercontentsmask = (int)val->_float;
+               else if (passedict->fields.server->solid == SOLID_SLIDEBOX)
+               {
+                       if ((int)passedict->fields.server->flags & FL_MONSTER)
+                               hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_MONSTERCLIP;
+                       else
+                               hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP;
+               }
+               else if (passedict->fields.server->solid == SOLID_CORPSE)
+                       hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY;
+               else
+                       hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_CORPSE;
        }
+       else
+               hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_CORPSE;
 
        // clip to world
        cliptrace = SV_ClipMoveToWorld(clipstart, clipmins, clipmaxs, clipend, type, hitsupercontentsmask);
@@ -644,12 +656,6 @@ trace_t SV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, const
                        // don't clip points against points (they can't collide)
                        if (pointtrace && VectorCompare(touch->fields.server->mins, touch->fields.server->maxs) && (type != MOVE_MISSILE || !((int)touch->fields.server->flags & FL_MONSTER)))
                                continue;
-                       // don't clip corpse against character
-                       if (passedict->fields.server->solid == SOLID_CORPSE && (touch->fields.server->solid == SOLID_SLIDEBOX || touch->fields.server->solid == SOLID_CORPSE))
-                               continue;
-                       // don't clip character against corpse
-                       if (passedict->fields.server->solid == SOLID_SLIDEBOX && touch->fields.server->solid == SOLID_CORPSE)
-                               continue;
                }
 
                // might interact, so do an exact clip
index a3837e4..a90fb26 100644 (file)
@@ -20,6 +20,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 // world.c -- world query functions
 
 #include "quakedef.h"
+#include "csprogs.h"
 
 /*
 
@@ -501,7 +502,7 @@ trace_t CSSV_ClipMoveToEntity(prvm_edict_t *ent, const vec3_t start, const vec3_
                model->TraceBox(model, frame, &trace, starttransformed, mins, maxs, endtransformed, hitsupercontents);
        }
        else
-               Collision_ClipTrace_Box(&trace, ent->fields.client->mins, ent->fields.client->maxs, starttransformed, mins, maxs, endtransformed, hitsupercontents, SUPERCONTENTS_SOLID);
+               Collision_ClipTrace_Box(&trace, ent->fields.client->mins, ent->fields.client->maxs, starttransformed, mins, maxs, endtransformed, hitsupercontents, ent->fields.client->solid == SOLID_CORPSE ? SUPERCONTENTS_CORPSE : SUPERCONTENTS_BODY);
        trace.fraction = bound(0, trace.fraction, 1);
        trace.realfraction = bound(0, trace.realfraction, 1);
 
@@ -537,6 +538,7 @@ trace_t CSSV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, cons
        int passedictprog;
        qboolean pointtrace;
        prvm_edict_t *traceowner, *touch;
+       prvm_eval_t *val;
        trace_t trace;
        // bounding box of entire move area
        vec3_t clipboxmins, clipboxmaxs;
@@ -561,14 +563,25 @@ trace_t CSSV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, cons
        Con_Printf("move(%f %f %f,%f %f %f)", clipstart[0], clipstart[1], clipstart[2], clipend[0], clipend[1], clipend[2]);
 #endif
 
-       hitsupercontentsmask = SUPERCONTENTS_SOLID;
        if (passedict)
        {
-               if (passedict->fields.client->solid == SOLID_SLIDEBOX)
-                       hitsupercontentsmask |= SUPERCONTENTS_PLAYERCLIP;
-               if ((int)passedict->fields.client->flags & FL_MONSTER)
-                       hitsupercontentsmask |= SUPERCONTENTS_MONSTERCLIP;
+               val = PRVM_GETEDICTFIELDVALUE(passedict, csqc_fieldoff_dphitcontentsmask);
+               if (val && val->_float)
+                       hitsupercontentsmask = (int)val->_float;
+               else if (passedict->fields.client->solid == SOLID_SLIDEBOX)
+               {
+                       if ((int)passedict->fields.client->flags & FL_MONSTER)
+                               hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_MONSTERCLIP;
+                       else
+                               hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_PLAYERCLIP;
+               }
+               else if (passedict->fields.client->solid == SOLID_CORPSE)
+                       hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY;
+               else
+                       hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_CORPSE;
        }
+       else
+               hitsupercontentsmask = SUPERCONTENTS_SOLID | SUPERCONTENTS_BODY | SUPERCONTENTS_CORPSE;
 
        // clip to world
        cliptrace = CSSV_ClipMoveToEntity(prog->edicts, clipstart, clipmins, clipmaxs, clipend, type, hitsupercontentsmask);
@@ -652,12 +665,6 @@ trace_t CSSV_Move(const vec3_t start, const vec3_t mins, const vec3_t maxs, cons
                        // don't clip points against points (they can't collide)
                        if (pointtrace && VectorCompare(touch->fields.client->mins, touch->fields.client->maxs) && (type != MOVE_MISSILE || !((int)touch->fields.client->flags & FL_MONSTER)))
                                continue;
-                       // don't clip corpse against character
-                       if (passedict->fields.client->solid == SOLID_CORPSE && (touch->fields.client->solid == SOLID_SLIDEBOX || touch->fields.client->solid == SOLID_CORPSE))
-                               continue;
-                       // don't clip character against corpse
-                       if (passedict->fields.client->solid == SOLID_SLIDEBOX && touch->fields.client->solid == SOLID_CORPSE)
-                               continue;
                }
 
                // might interact, so do an exact clip