1
0
Fork 0
forked from fte/fteqw

Handle Hexen2's SOLID_PHASE more accurately, including warts, so corpses can be reliably whacked with melee weapons.

This commit is contained in:
Shpoike 2023-06-25 15:49:09 +01:00
parent e0c6c78c3d
commit 01a958e0a6
3 changed files with 30 additions and 4 deletions

View file

@ -671,7 +671,7 @@ unsigned int FTEToDPContents(unsigned int contents);
#define SOLID_BBOX 2 // touch on edge, block
#define SOLID_SLIDEBOX 3 // touch on edge, but not an onground
#define SOLID_BSP 4 // bsp clip, touch on edge, block
#define SOLID_PHASEH2 5 // hexen2 flag - these ents can be freely walked through or something
#define SOLID_PHASEH2 5 // hexen2 flag - this is apparently a modifier for movetype rather than solidity - passes through FL_MONSTER or MOVETYPE_WALK ents
#define SOLID_CORPSE 5 // non-solid to solid_slidebox entities and itself.
#define SOLID_LADDER 20 //spike: legacy. forces FTECONTENTS_LADDER.
#define SOLID_PORTAL 21 //1: traces always use point-size. 2: various movetypes automatically transform entities. 3: traces that impact portal bbox use a union. 4. traces ignore part of the world within the portal's box

View file

@ -649,6 +649,32 @@ static trace_t WPhys_PushEntity (world_t *w, wedict_t *ent, vec3_t push, unsigne
trace.ent = w->edicts;
}
}
#if defined(HAVE_SERVER) && defined(HEXEN2)
else if (ent->v->solid == SOLID_PHASEH2 && progstype == PROG_H2 && w == &sv.world && trace.fraction != 1 && trace.ent &&
(((int)((wedict_t*)trace.ent)->v->flags & FL_MONSTER) || (int)((wedict_t*)trace.ent)->v->movetype == MOVETYPE_WALK))
{ //hexen2's SOLID_PHASEH2 ents should pass through players+monsters, yet still trigger impacts. I would use MOVE_ENTCHAIN but that would corrupt .chain, perhaps that's okay though?
//continue the trace on to where we wold be if there had been no impact
trace_t trace2 = World_Move (w, trace.endpos, ent->v->mins, ent->v->maxs, end, traceflags|MOVE_NOMONSTERS|MOVE_MISSILE|MOVE_RESERVED/*Don't fuck up in the face of dp's MOVE_WORLDONLY*/, (wedict_t*)ent);
//do the first non-world impact
// if (trace.ent)
// VectorMA(trace.endpos, sv_impactpush.value, trace.plane.normal, ent->v->origin);
// else
VectorCopy (trace.endpos, ent->v->origin);
World_LinkEdict (w, ent, true);
if (trace.ent)
{
WPhys_Impact (w, ent, &trace);
if (ent->ereftype != ER_ENTITY)
return trace; //someone remove()d it. don't do weird stuff.
}
//and use our regular impact logic for the rest of it.
trace = trace2;
}
#endif
// if (trace.ent)
// VectorMA(trace.endpos, sv_impactpush.value, trace.plane.normal, ent->v->origin);
@ -1430,7 +1456,7 @@ static void WPhys_Physics_Toss (world_t *w, wedict_t *ent)
if (ent->xv->bouncefactor)
backoff = 1 + ent->xv->bouncefactor;
// else if (progstype == PROG_H2 && ent->v->solid == SOLID_PHASEH2 && ((int)((wedict_t*)trace.ent)->v->flags & (FL_MONSTER|FL_CLIENT)))
// backoff = 0;
// backoff = 0; //don't bounce/slide, just pass straight through.
else
backoff = w->remasterlogic?1.5/*gib...*/:2;
}

View file

@ -1029,7 +1029,7 @@ static trace_t World_ClipMoveToEntity (world_t *w, wedict_t *ent, vec3_t eorg, v
trace.startsolid = false;
hitmodel = false;
}
else if (solid == SOLID_CORPSE)
else if (solid == SOLID_CORPSE && w->usesolidcorpse)
goto scorpse;
else if (ent->v->skin < 0)
{ //if forcedcontents is set, then ALL brushes in this model are forced to the specified contents value.
@ -2501,7 +2501,7 @@ trace_t World_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t e
else
clip.hitcontentsmask = FTECONTENTS_SOLID|Q2CONTENTS_WINDOW | FTECONTENTS_BODY; //slidebox passes through corpses
}
else if (passedict->v->solid == SOLID_CORPSE)
else if (passedict->v->solid == SOLID_CORPSE && w->usesolidcorpse)
clip.hitcontentsmask = FTECONTENTS_SOLID|Q2CONTENTS_WINDOW | FTECONTENTS_BODY; //corpses ignore corpses
else if (passedict->v->solid == SOLID_TRIGGER||passedict->v->solid == SOLID_BSPTRIGGER)
clip.hitcontentsmask = FTECONTENTS_SOLID|Q2CONTENTS_WINDOW | FTECONTENTS_BODY; //triggers ignore corpses too, apparently