From 00141603df070f44751efaf4afbf9c8cfc7e2e74 Mon Sep 17 00:00:00 2001 From: havoc Date: Wed, 22 Mar 2006 08:51:35 +0000 Subject: [PATCH] implemented DP_TRACE_HITCONTENTSMASK_SURFACEINFO extension, this allows QC to find out if a projectile hit sky, among other capabilities git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@6166 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_collision.c | 6 ++--- cl_input.c | 12 +++++----- cl_particles.c | 6 ++--- clvm_cmds.c | 2 +- csprogs.c | 1 + csprogs.h | 1 + progs.h | 9 +++++++- progsvm.h | 2 ++ prvm_edict.c | 10 ++++++++ r_crosshairs.c | 2 +- snd_alsa.c | 4 ++++ snd_sdl.c | 4 ++++ sv_main.c | 12 ++++++++++ sv_phys.c | 62 +++++++++++++++++++++++++++++++++++++++++++++----- svvm_cmds.c | 56 ++++++++++++++++++++++++++++++++++++++++++++- todo | 2 ++ view.c | 2 +- world.c | 30 ++++++++++++++---------- world_cs.c | 31 +++++++++++++++---------- 19 files changed, 207 insertions(+), 47 deletions(-) diff --git a/cl_collision.c b/cl_collision.c index 1e426d24..038c9249 100644 --- a/cl_collision.c +++ b/cl_collision.c @@ -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) { diff --git a/cl_input.c b/cl_input.c index 3266a92e..c2e7d473 100644 --- a/cl_input.c +++ b/cl_input.c @@ -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) diff --git a/cl_particles.c b/cl_particles.c index 59586171..202f32e9 100644 --- a/cl_particles.c +++ b/cl_particles.c @@ -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: diff --git a/clvm_cmds.c b/clvm_cmds.c index 28df1b6c..6c132eea 100644 --- a/clvm_cmds.c +++ b/clvm_cmds.c @@ -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; } diff --git a/csprogs.c b/csprogs.c index 80a27074..2a639075 100644 --- 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; diff --git a/csprogs.h b/csprogs.h index f37f4e79..e67578ff 100644 --- 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 7005deec..0eda5274 100644 --- 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 diff --git a/progsvm.h b/progsvm.h index 0ef7dff3..673caea3 100644 --- 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); diff --git a/prvm_edict.c b/prvm_edict.c index e79cc5f1..b78b9879 100644 --- a/prvm_edict.c +++ b/prvm_edict.c @@ -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) diff --git a/r_crosshairs.c b/r_crosshairs.c index 38e1b4c5..e0fd5b2a 100644 --- a/r_crosshairs.c +++ b/r_crosshairs.c @@ -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); diff --git a/snd_alsa.c b/snd_alsa.c index 03c713bf..31f5c1e4 100644 --- a/snd_alsa.c +++ b/snd_alsa.c @@ -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 selects which pcm device to us, default is "default" if (channels == 8) diff --git a/snd_sdl.c b/snd_sdl.c index 5e4157e6..cfeeb1b4 100644 --- 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; diff --git a/sv_main.c b/sv_main.c index e6ce9942..681fcf86 100644 --- 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)) diff --git a/sv_phys.c b/sv_phys.c index 15c68026..dcca2be3 100644 --- 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) diff --git a/svvm_cmds.c b/svvm_cmds.c index 860d7a02..c5db79be 100644 --- a/svvm_cmds.c +++ b/svvm_cmds.c @@ -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 20746e3e..fcccd528 100644 --- 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 562e487b..73acc74e 100644 --- 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 b294e223..70b2099b 100644 --- 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 diff --git a/world_cs.c b/world_cs.c index a3837e48..a90fb266 100644 --- a/world_cs.c +++ b/world_cs.c @@ -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 -- 2.39.2