- yet another case of adding a workaround to preserve a side effect in Doom's original movement code that's bound to be inadvertently exploited:

When a spechit results in teleportation, P_TryMove never accounted for that, so that subsequent spechits either failed or succeeded, depending on where the teleport ends up.
With portal-aware positions stored within the spechit this no longer worked, so some handling is needed to revert to the original behavior in case there's no portals to consider.

The ideal solution would have been to stop checking spechits (or to block further teleports) once this happens but the likelihood of some old maps depending on this is high.
This commit is contained in:
Christoph Oelckers 2016-03-09 11:44:01 +01:00
parent 03118d441f
commit b3f7a57518

View file

@ -2405,11 +2405,18 @@ bool P_TryMove(AActor *thing, fixed_t x, fixed_t y,
if (!(thing->flags & (MF_TELEPORT | MF_NOCLIP)))
{
spechit_t spec;
fixedvec3 lastpos = thing->Pos();
while (spechit.Pop(spec))
{
line_t *ld = spec.line;
// see if the line was crossed
side = P_PointOnLineSide(spec.refpos.x, spec.refpos.y, ld);
// One more case of trying to preserve some side effects from the original:
// If the reference position is the same as the actor's position before checking the spechits,
// we use the thing's actual position, including all the side effects of the original.
// If some portal transition has to be considered here, we cannot do that and use the reference position stored with the spechit.
bool posisoriginal = (spec.refpos.x == lastpos.x && spec.refpos.y == lastpos.y);
side = posisoriginal? P_PointOnLineSide(thing->X(), thing->Y(), ld) : P_PointOnLineSide(spec.refpos.x, spec.refpos.y, ld);
oldside = P_PointOnLineSide(spec.oldrefpos.x, spec.oldrefpos.y, ld);
if (side != oldside && ld->special && !(thing->flags6 & MF6_NOTRIGGER))
{