tmsprung is dead, long live MFE_SPRUNG a bunch of other painful tweaks to springs to fix this long-standing "AAA IM STUCK FOREVER UNDER A SPRING" thing when you touch a vertical spring from below (or above for reverse)

git-svn-id: https://code.orospakr.ca/svn/srb2/trunk@9037 6de4a73c-47e2-0310-b8c1-93d6ecd3f8cd
This commit is contained in:
MonsterIestyn 2015-02-11 20:54:11 +00:00 committed by Alam Ed Arias
parent 2480382b6b
commit 34c396825f
6 changed files with 30 additions and 37 deletions

View file

@ -7203,6 +7203,7 @@ static const char *const MOBJEFLAG_LIST[] = {
"VERTICALFLIP", // Vertically flip sprite/allow upside-down physics
"GOOWATER", // Goo water
"PUSHED", // Mobj was already pushed this tic
"SPRUNG", // Mobj was already sprung this tic
NULL
};

View file

@ -273,7 +273,6 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed
extern boolean floatok;
extern fixed_t tmfloorz;
extern fixed_t tmceilingz;
extern boolean tmsprung;
extern mobj_t *tmfloorthing, *tmthing;
extern camera_t *mapcampointer;

View file

@ -49,9 +49,6 @@ static fixed_t tmdropoffz, tmdrpoffceilz; // drop-off floor/ceiling heights
mobj_t *tmfloorthing; // the thing corresponding to tmfloorz or NULL if tmfloorz is from a sector
static mobj_t *tmhitthing; // the solid thing you bumped into (for collisions)
// turned on or off in PIT_CheckThing
boolean tmsprung;
// keep track of the line that lowers the ceiling,
// so missiles don't explode against sky hack walls
line_t *ceilingline;
@ -113,6 +110,9 @@ void P_DoSpring(mobj_t *spring, mobj_t *object)
fixed_t horizspeed = spring->info->damage;
fixed_t origvertispeed = vertispeed; // for vertical flipping
if (object->eflags & MFE_SPRUNG) // Object was already sprung this tic
return;
// Spectators don't trigger springs.
if (object->player && object->player->spectator)
return;
@ -122,7 +122,8 @@ void P_DoSpring(mobj_t *spring, mobj_t *object)
/*Someone want to make these work like bumpers?*/
return;
}
object->eflags |= MFE_SPRUNG; // apply this flag asap!
spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify
if (horizspeed && vertispeed) // Mimic SA
@ -367,10 +368,11 @@ static boolean PIT_CheckThing(mobj_t *thing)
fixed_t blockdist;
// don't clip against self
tmsprung = false;
if (thing == tmthing)
return true;
// Ignore... things.
if (!tmthing || !thing)
if (!tmthing || !thing || P_MobjWasRemoved(thing))
return true;
I_Assert(!P_MobjWasRemoved(tmthing));
@ -438,9 +440,6 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE)))
return true;
if (!tmthing || !thing || thing == tmthing || P_MobjWasRemoved(thing))
return true;
// Don't collide with your buddies while NiGHTS-flying.
if (tmthing->player && thing->player && (maptol & TOL_NIGHTS)
&& ((tmthing->player->pflags & PF_NIGHTSMODE) || (thing->player->pflags & PF_NIGHTSMODE)))
@ -549,7 +548,6 @@ static boolean PIT_CheckThing(mobj_t *thing)
if ((tmznext <= thzh && tmz > thzh) || (tmznext > thzh - sprarea && tmznext < thzh))
{
P_DoSpring(thing, tmthing);
tmsprung = true;
return true;
}
else if (tmz > thzh - sprarea && tmz < thzh) // Don't damage people springing up / down
@ -818,15 +816,11 @@ static boolean PIT_CheckThing(mobj_t *thing)
{
if (thing->type == MT_FAN || thing->type == MT_STEAM)
P_DoFanAndGasJet(thing, tmthing);
if ((!(thing->eflags & MFE_VERTICALFLIP) && (tmthing->z <= (thing->z + thing->height + FixedMul(FRACUNIT, thing->scale)) && (tmthing->z + tmthing->height) >= thing->z))
|| ((thing->eflags & MFE_VERTICALFLIP) && (tmthing->z + tmthing->height >= (thing->z - FixedMul(FRACUNIT, thing->scale)) && tmthing->z <= (thing->z + thing->height))))
else if (thing->flags & MF_SPRING)
{
if (thing->flags & MF_SPRING)
{
if ( thing->z <= tmthing->z + tmthing->height
&& tmthing->z <= thing->z + thing->height)
P_DoSpring(thing, tmthing);
tmsprung = true;
}
}
}
@ -909,17 +903,17 @@ static boolean PIT_CheckThing(mobj_t *thing)
if (thing->type == MT_FAN || thing->type == MT_STEAM)
P_DoFanAndGasJet(thing, tmthing);
else if (thing->flags & MF_SPRING)
{
if ( thing->z <= tmthing->z + tmthing->height
&& tmthing->z <= thing->z + thing->height)
P_DoSpring(thing, tmthing);
}
// Are you touching the side of the object you're interacting with?
if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height
else if (thing->z - FixedMul(FRACUNIT, thing->scale) <= tmthing->z + tmthing->height
&& thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) >= tmthing->z)
{
if (thing->flags & MF_SPRING)
{
P_DoSpring(thing, tmthing);
tmsprung = true;
}
else if (thing->flags & MF_MONITOR
if (thing->flags & MF_MONITOR
&& tmthing->player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING))
{
SINT8 flipval = P_MobjFlip(thing); // Save this value in case monitor gets removed.
@ -932,14 +926,12 @@ static boolean PIT_CheckThing(mobj_t *thing)
*momz = -*momz; // Therefore, you should be thrust in the opposite direction, vertically.
return false;
}
/*
else if ((thing->flags & (MF_SOLID|MF_NOCLIP|MF_PUSHABLE)) == MF_SOLID)
return false; // this fixes both monitors and non-pushable solids being walked through on bobbing FOFs... for now!
*/
}
}
if (thing->flags & MF_SPRING && (tmthing->player || tmthing->flags & MF_PUSHABLE));
else
// Monitors are not treated as solid to players who are jumping, spinning or gliding,
// unless it's a CTF team monitor and you're on the wrong team
if (thing->flags & MF_MONITOR && tmthing->player && tmthing->player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)
@ -1766,7 +1758,6 @@ boolean PIT_PushableMoved(mobj_t *thing)
boolean oldfltok = floatok;
fixed_t oldflrz = tmfloorz;
fixed_t oldceilz = tmceilingz;
boolean oldsprung = tmsprung;
mobj_t *oldflrthing = tmfloorthing;
mobj_t *oldthing = tmthing;
line_t *oldceilline = ceilingline;
@ -1779,7 +1770,6 @@ boolean PIT_PushableMoved(mobj_t *thing)
floatok = oldfltok;
tmfloorz = oldflrz;
tmceilingz = oldceilz;
tmsprung = oldsprung;
tmfloorthing = oldflrthing;
P_SetTarget(&tmthing, oldthing);
ceilingline = oldceilline;

View file

@ -1154,7 +1154,7 @@ void P_XYMovement(mobj_t *mo)
if (CheckForBustableBlocks && mo->flags & MF_PUSHABLE)
P_PushableCheckBustables(mo);
if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true) && !tmsprung)
if (!P_TryMove(mo, mo->x + xmove, mo->y + ymove, true) && !(mo->eflags & MFE_SPRUNG))
{
// blocked move
@ -5448,7 +5448,7 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->tracer && P_MobjWasRemoved(mobj->tracer))
P_SetTarget(&mobj->tracer, NULL);
mobj->eflags &= ~MFE_PUSHED;
mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG);
// 970 allows ANY mobj to trigger a linedef exec
if (mobj->subsector && GETSECSPECIAL(mobj->subsector->sector->special, 2) == 8)

View file

@ -233,6 +233,9 @@ typedef enum
MFE_GOOWATER = 1<<6,
// Mobj was already pushed this tic
MFE_PUSHED = 1<<7,
// Mobj was already sprung this tic
MFE_SPRUNG = 1<<8,
// free: to and including 1<<15
} mobjeflag_t;
//
@ -286,7 +289,7 @@ typedef struct mobj_s
state_t *state;
UINT32 flags; // flags from mobjinfo tables
UINT32 flags2; // MF2_ flags
UINT8 eflags; // extra flags
UINT16 eflags; // extra flags
void *skin; // overrides 'sprite' when non-NULL (for player bodies to 'remember' the skin)
// Player and mobj sprites in multiplayer modes are modified

View file

@ -1174,7 +1174,7 @@ static void SaveMobjThinker(const thinker_t *th, const UINT8 type)
if (diff & MD_FRAME)
WRITEUINT32(save_p, mobj->frame);
if (diff & MD_EFLAGS)
WRITEUINT8(save_p, mobj->eflags);
WRITEUINT16(save_p, mobj->eflags);
if (diff & MD_PLAYER)
WRITEUINT8(save_p, mobj->player-players);
if (diff & MD_MOVEDIR)
@ -2000,7 +2000,7 @@ static void LoadMobjThinker(actionf_p1 thinker)
else
mobj->frame = mobj->state->frame;
if (diff & MD_EFLAGS)
mobj->eflags = READUINT8(save_p);
mobj->eflags = READUINT16(save_p);
if (diff & MD_PLAYER)
{
i = READUINT8(save_p);