mirror of
https://github.com/Shpoike/Quakespasm.git
synced 2024-11-10 07:21:58 +00:00
Added FTE_ENT_SKIN_CONTENTS support.
This commit is contained in:
parent
ef5d841e80
commit
81b7ba9e4b
9 changed files with 110 additions and 16 deletions
|
@ -177,6 +177,8 @@ typedef struct
|
|||
#define CONTENTS_CURRENT_UP -13
|
||||
#define CONTENTS_CURRENT_DOWN -14
|
||||
|
||||
#define CONTENTS_LADDER -16
|
||||
|
||||
|
||||
// !!! if this is changed, it must be changed in asm_i386.h too !!!
|
||||
typedef struct
|
||||
|
|
|
@ -111,7 +111,7 @@ mleaf_t *Mod_PointInLeaf (vec3_t p, qmodel_t *model)
|
|||
if (!model || !model->nodes)
|
||||
Sys_Error ("Mod_PointInLeaf: bad model");
|
||||
|
||||
node = model->nodes;
|
||||
node = model->nodes + model->hulls[0].firstclipnode;
|
||||
while (1)
|
||||
{
|
||||
if (node->contents < 0)
|
||||
|
|
|
@ -555,6 +555,8 @@ R_SetupView -- johnfitz -- this is the stuff that needs to be done once per fram
|
|||
*/
|
||||
void R_SetupView (void)
|
||||
{
|
||||
int viewcontents; //spike -- rewrote this a little
|
||||
int i;
|
||||
Fog_SetupFrame (); //johnfitz
|
||||
|
||||
// build the transformation matrix for the given view angles
|
||||
|
@ -564,8 +566,25 @@ void R_SetupView (void)
|
|||
// current viewleaf
|
||||
r_oldviewleaf = r_viewleaf;
|
||||
r_viewleaf = Mod_PointInLeaf (r_origin, cl.worldmodel);
|
||||
viewcontents = r_viewleaf->contents;
|
||||
|
||||
V_SetContentsColor (r_viewleaf->contents);
|
||||
//spike -- added this loop for moving water volumes
|
||||
for (i = 0; i < cl.num_entities && viewcontents == CONTENTS_EMPTY; i++)
|
||||
{
|
||||
mleaf_t *subleaf;
|
||||
vec3_t relpos;
|
||||
if (cl.entities[i].model && cl.entities[i].model->type==mod_brush)
|
||||
{
|
||||
VectorSubtract(r_origin, cl.entities[i].origin, relpos);
|
||||
subleaf = Mod_PointInLeaf (relpos, cl.entities[i].model);
|
||||
if ((char)cl.entities[i].skinnum < 0)
|
||||
viewcontents = ((subleaf->contents == CONTENTS_SOLID)?(char)cl.entities[i].skinnum:CONTENTS_EMPTY);
|
||||
else
|
||||
viewcontents = subleaf->contents;
|
||||
}
|
||||
}
|
||||
|
||||
V_SetContentsColor (viewcontents);
|
||||
V_CalcBlend ();
|
||||
|
||||
r_cache_thrash = false;
|
||||
|
@ -575,8 +594,7 @@ void R_SetupView (void)
|
|||
r_fovy = r_refdef.fov_y;
|
||||
if (r_waterwarp.value)
|
||||
{
|
||||
int contents = Mod_PointInLeaf (r_origin, cl.worldmodel)->contents;
|
||||
if (contents == CONTENTS_WATER || contents == CONTENTS_SLIME || contents == CONTENTS_LAVA)
|
||||
if (viewcontents == CONTENTS_WATER || viewcontents == CONTENTS_SLIME || viewcontents == CONTENTS_LAVA)
|
||||
{
|
||||
//variance is a percentage of width, where width = 2 * tan(fov / 2) otherwise the effect is too dramatic at high FOV and too subtle at low FOV. what a mess!
|
||||
r_fovx = atan(tan(DEG2RAD(r_refdef.fov_x) / 2) * (0.97 + sin(cl.time * 1.5) * 0.03)) * 2 / M_PI_DIV_180;
|
||||
|
|
|
@ -5706,6 +5706,7 @@ static const char *extnames[] =
|
|||
"DP_TE_STANDARDEFFECTBUILTINS",
|
||||
"EXT_BITSHIFT",
|
||||
"FRIK_FILE", //lacks the file part, but does have the strings part.
|
||||
"FTE_ENT_SKIN_CONTENTS", //SOLID_BSP&&skin==CONTENTS_FOO changes CONTENTS_SOLID to CONTENTS_FOO, allowing you to swim in moving ents without qc hacks, as well as correcting view cshifts etc.
|
||||
#ifdef PSET_SCRIPT
|
||||
"FTE_PART_SCRIPT",
|
||||
"FTE_PART_NAMESPACES",
|
||||
|
|
|
@ -48,6 +48,7 @@ typedef struct edict_s
|
|||
entity_state_t baseline;
|
||||
unsigned char alpha; /* johnfitz -- hack to support alpha since it's not part of entvars_t */
|
||||
qboolean sendinterval; /* johnfitz -- send time until nextthink to client for better lerp timing */
|
||||
qboolean onladder; /* spike -- content_ladder stuff */
|
||||
|
||||
float freetime; /* sv.time when the object was freed */
|
||||
entvars_t v; /* C exported fields from progs */
|
||||
|
|
|
@ -508,8 +508,16 @@ void SV_PushMove (edict_t *pusher, float movetime)
|
|||
continue;
|
||||
|
||||
// see if the ent's bbox is inside the pusher's final position
|
||||
if (!SV_TestEntityPosition (check))
|
||||
continue;
|
||||
if (pusher->v.skin < 0)
|
||||
{ //a more precise check...
|
||||
if (!SV_ClipMoveToEntity (pusher, check->v.origin, check->v.mins, check->v.maxs, check->v.origin).startsolid)
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!SV_TestEntityPosition (check))
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// remove the onground flag for non-players
|
||||
|
@ -530,10 +538,18 @@ void SV_PushMove (edict_t *pusher, float movetime)
|
|||
// try moving the contacted entity
|
||||
pusher->v.solid = SOLID_NOT;
|
||||
SV_PushEntity (check, move);
|
||||
pusher->v.solid = solid_backup;
|
||||
|
||||
// if it is still inside the pusher, block
|
||||
block = SV_TestEntityPosition (check);
|
||||
if (pusher->v.skin < 0)
|
||||
{ //if it has forced contents then do things in a slightly different order, so water can push properly.
|
||||
block = SV_TestEntityPosition (check);
|
||||
pusher->v.solid = solid_backup;
|
||||
}
|
||||
else
|
||||
{
|
||||
pusher->v.solid = solid_backup;
|
||||
block = SV_TestEntityPosition (check);
|
||||
}
|
||||
}
|
||||
else
|
||||
block = NULL;
|
||||
|
@ -689,6 +705,26 @@ qboolean SV_CheckWater (edict_t *ent)
|
|||
{
|
||||
vec3_t point;
|
||||
int cont;
|
||||
trace_t tr;
|
||||
|
||||
//Spike -- FTE_ENT_SKIN_CONTENTS -- check if we're on a ladder, and if so fire a trace forwards to ensure its a valid ladder instead of a random volume
|
||||
tr = SV_Move(ent->v.origin, ent->v.mins, ent->v.maxs, ent->v.origin, MOVE_HITALLCONTENTS, ent);
|
||||
if (tr.contents == CONTENTS_LADDER)
|
||||
{
|
||||
vec3_t flatforward;
|
||||
flatforward[0] = cos((M_PI/180)*ent->v.angles[1]);
|
||||
flatforward[1] = sin((M_PI/180)*ent->v.angles[1]);
|
||||
flatforward[2] = 0;
|
||||
VectorMA (ent->v.origin, 24, flatforward, point);
|
||||
|
||||
tr = SV_Move(ent->v.origin, ent->v.mins, ent->v.maxs, point, 0, ent);
|
||||
if (tr.fraction < 1)
|
||||
sv_player->onladder = true;
|
||||
else
|
||||
sv_player->onladder = false;
|
||||
}
|
||||
else
|
||||
sv_player->onladder = false;
|
||||
|
||||
point[0] = ent->v.origin[0];
|
||||
point[1] = ent->v.origin[1];
|
||||
|
@ -696,18 +732,19 @@ qboolean SV_CheckWater (edict_t *ent)
|
|||
|
||||
ent->v.waterlevel = 0;
|
||||
ent->v.watertype = CONTENTS_EMPTY;
|
||||
cont = SV_PointContents (point);
|
||||
//Spike -- FTE_ENT_SKIN_CONTENTS -- check submodels too, because we can.
|
||||
cont = SV_PointContentsAllBsps (point, ent);
|
||||
if (cont <= CONTENTS_WATER)
|
||||
{
|
||||
ent->v.watertype = cont;
|
||||
ent->v.waterlevel = 1;
|
||||
point[2] = ent->v.origin[2] + (ent->v.mins[2] + ent->v.maxs[2])*0.5;
|
||||
cont = SV_PointContents (point);
|
||||
cont = SV_PointContentsAllBsps (point, ent);
|
||||
if (cont <= CONTENTS_WATER)
|
||||
{
|
||||
ent->v.waterlevel = 2;
|
||||
point[2] = ent->v.origin[2] + ent->v.view_ofs[2];
|
||||
cont = SV_PointContents (point);
|
||||
cont = SV_PointContentsAllBsps (point, ent);
|
||||
if (cont <= CONTENTS_WATER)
|
||||
ent->v.waterlevel = 3;
|
||||
}
|
||||
|
@ -948,7 +985,8 @@ void SV_Physics_Client (edict_t *ent, int num)
|
|||
if (!SV_RunThink (ent))
|
||||
return;
|
||||
if (!SV_CheckWater (ent) && ! ((int)ent->v.flags & FL_WATERJUMP) )
|
||||
SV_AddGravity (ent);
|
||||
if (!sv_player->onladder)
|
||||
SV_AddGravity (ent);
|
||||
SV_CheckStuck (ent);
|
||||
SV_WalkMove (ent);
|
||||
break;
|
||||
|
|
|
@ -236,7 +236,14 @@ void SV_WaterMove (void)
|
|||
for (i=0 ; i<3 ; i++)
|
||||
wishvel[i] = forward[i]*cmd.forwardmove + right[i]*cmd.sidemove;
|
||||
|
||||
if (!cmd.forwardmove && !cmd.sidemove && !cmd.upmove)
|
||||
if (sv_player->onladder)
|
||||
{
|
||||
wishvel[2] *= 1+fabs(wishvel[2]/200)*9; //exaggerate vertical movement.
|
||||
if (sv_player->v.button2)
|
||||
wishvel[2] += 400; //make jump climb (you can turn around and move off to fall)
|
||||
}
|
||||
|
||||
if (!cmd.forwardmove && !cmd.sidemove && !cmd.upmove && !sv_player->onladder)
|
||||
wishvel[2] -= 60; // drift towards bottom
|
||||
else
|
||||
wishvel[2] += cmd.upmove;
|
||||
|
@ -422,7 +429,7 @@ void SV_ClientThink (void)
|
|||
//johnfitz -- alternate noclip
|
||||
if (sv_player->v.movetype == MOVETYPE_NOCLIP && sv_altnoclip.value)
|
||||
SV_NoclipMove ();
|
||||
else if (sv_player->v.waterlevel >= 2 && sv_player->v.movetype != MOVETYPE_NOCLIP)
|
||||
else if ((sv_player->v.waterlevel >= 2||sv_player->onladder) && sv_player->v.movetype != MOVETYPE_NOCLIP)
|
||||
SV_WaterMove ();
|
||||
else
|
||||
SV_AirMove ();
|
||||
|
|
|
@ -41,6 +41,7 @@ typedef struct
|
|||
float *start, *end;
|
||||
trace_t trace;
|
||||
int type;
|
||||
unsigned int hitcontents; //content types to impact upon... (1<<-CONTENTS_FOO) bitmask
|
||||
edict_t *passedict;
|
||||
} moveclip_t;
|
||||
|
||||
|
@ -555,6 +556,14 @@ int SV_TruePointContents (vec3_t p)
|
|||
return SV_HullPointContents (&qcvm->worldmodel->hulls[0], 0, p);
|
||||
}
|
||||
|
||||
int SV_PointContentsAllBsps(vec3_t p, edict_t *forent)
|
||||
{
|
||||
trace_t trace = SV_Move (p, vec3_origin, vec3_origin, p, MOVE_NOMONSTERS|MOVE_HITALLCONTENTS, forent);
|
||||
if (trace.contents <= CONTENTS_CURRENT_0 && trace.contents >= CONTENTS_CURRENT_DOWN)
|
||||
trace.contents = CONTENTS_WATER;
|
||||
return trace.contents;
|
||||
}
|
||||
|
||||
//===========================================================================
|
||||
|
||||
/*
|
||||
|
@ -629,6 +638,7 @@ reenter:
|
|||
if (num < 0)
|
||||
{
|
||||
/*hit a leaf*/
|
||||
trace->contents = num;
|
||||
if (num == CONTENTS_SOLID)
|
||||
{
|
||||
if (trace->allsolid)
|
||||
|
@ -741,7 +751,9 @@ qboolean SV_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec
|
|||
if (p1[0]==p2[0] && p1[1]==p2[1] && p1[2]==p2[2])
|
||||
{
|
||||
/*points cannot cross planes, so do it faster*/
|
||||
switch(SV_HullPointContents(hull, num, p1))
|
||||
int c = SV_HullPointContents(hull, num, p1);
|
||||
trace->contents = c;
|
||||
switch(c)
|
||||
{
|
||||
case CONTENTS_SOLID:
|
||||
trace->startsolid = true;
|
||||
|
@ -875,6 +887,11 @@ void SV_ClipToLinks ( areanode_t *node, moveclip_t *clip )
|
|||
trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins2, clip->maxs2, clip->end);
|
||||
else
|
||||
trace = SV_ClipMoveToEntity (touch, clip->start, clip->mins, clip->maxs, clip->end);
|
||||
if (trace.contents == CONTENTS_SOLID && touch->v.skin < 0)
|
||||
trace.contents = touch->v.skin;
|
||||
if (!((1<<(-trace.contents)) & clip->hitcontents))
|
||||
continue;
|
||||
|
||||
if (trace.allsolid || trace.startsolid ||
|
||||
trace.fraction < clip->trace.fraction)
|
||||
{
|
||||
|
@ -951,8 +968,12 @@ trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, e
|
|||
clip.end = end;
|
||||
clip.mins = mins;
|
||||
clip.maxs = maxs;
|
||||
clip.type = type;
|
||||
clip.type = type&3;
|
||||
clip.passedict = passedict;
|
||||
if (type & MOVE_HITALLCONTENTS)
|
||||
clip.hitcontents = ~0u;
|
||||
else
|
||||
clip.hitcontents = (1<<(-CONTENTS_SOLID)) | (1<<(-CONTENTS_CLIP));
|
||||
|
||||
if (type == MOVE_MISSILE)
|
||||
{
|
||||
|
|
|
@ -38,6 +38,8 @@ typedef struct
|
|||
vec3_t endpos; // final position
|
||||
plane_t plane; // surface normal at impact
|
||||
edict_t *ent; // entity the surface is on
|
||||
|
||||
int contents; // spike -- the content type(s) that we found.
|
||||
} trace_t;
|
||||
|
||||
|
||||
|
@ -45,6 +47,8 @@ typedef struct
|
|||
#define MOVE_NOMONSTERS 1
|
||||
#define MOVE_MISSILE 2
|
||||
|
||||
#define MOVE_HITALLCONTENTS (1<<9)
|
||||
|
||||
|
||||
void SV_ClearWorld (void);
|
||||
// called after the world model has been loaded, before linking any entities
|
||||
|
@ -60,6 +64,7 @@ void SV_LinkEdict (edict_t *ent, qboolean touch_triggers);
|
|||
// sets ent->v.absmin and ent->v.absmax
|
||||
// if touchtriggers, calls prog functions for the intersected triggers
|
||||
|
||||
int SV_PointContentsAllBsps(vec3_t p, edict_t *forent); //check all SOLID_BSP ents
|
||||
int SV_PointContents (vec3_t p);
|
||||
int SV_TruePointContents (vec3_t p);
|
||||
// returns the CONTENTS_* value from the world at the given point.
|
||||
|
@ -68,6 +73,7 @@ int SV_TruePointContents (vec3_t p);
|
|||
|
||||
edict_t *SV_TestEntityPosition (edict_t *ent);
|
||||
|
||||
trace_t SV_ClipMoveToEntity (edict_t *ent, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end);
|
||||
trace_t SV_Move (vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int type, edict_t *passedict);
|
||||
// mins and maxs are reletive
|
||||
|
||||
|
|
Loading…
Reference in a new issue