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 "VERTICALFLIP", // Vertically flip sprite/allow upside-down physics
"GOOWATER", // Goo water "GOOWATER", // Goo water
"PUSHED", // Mobj was already pushed this tic "PUSHED", // Mobj was already pushed this tic
"SPRUNG", // Mobj was already sprung this tic
NULL NULL
}; };

View File

@ -273,7 +273,6 @@ boolean P_LookForPlayers(mobj_t *actor, boolean allaround, boolean tracer, fixed
extern boolean floatok; extern boolean floatok;
extern fixed_t tmfloorz; extern fixed_t tmfloorz;
extern fixed_t tmceilingz; extern fixed_t tmceilingz;
extern boolean tmsprung;
extern mobj_t *tmfloorthing, *tmthing; extern mobj_t *tmfloorthing, *tmthing;
extern camera_t *mapcampointer; 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 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) 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, // keep track of the line that lowers the ceiling,
// so missiles don't explode against sky hack walls // so missiles don't explode against sky hack walls
line_t *ceilingline; line_t *ceilingline;
@ -113,6 +110,9 @@ void P_DoSpring(mobj_t *spring, mobj_t *object)
fixed_t horizspeed = spring->info->damage; fixed_t horizspeed = spring->info->damage;
fixed_t origvertispeed = vertispeed; // for vertical flipping fixed_t origvertispeed = vertispeed; // for vertical flipping
if (object->eflags & MFE_SPRUNG) // Object was already sprung this tic
return;
// Spectators don't trigger springs. // Spectators don't trigger springs.
if (object->player && object->player->spectator) if (object->player && object->player->spectator)
return; return;
@ -122,7 +122,8 @@ void P_DoSpring(mobj_t *spring, mobj_t *object)
/*Someone want to make these work like bumpers?*/ /*Someone want to make these work like bumpers?*/
return; return;
} }
object->eflags |= MFE_SPRUNG; // apply this flag asap!
spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify spring->flags &= ~(MF_SOLID|MF_SPECIAL); // De-solidify
if (horizspeed && vertispeed) // Mimic SA if (horizspeed && vertispeed) // Mimic SA
@ -367,10 +368,11 @@ static boolean PIT_CheckThing(mobj_t *thing)
fixed_t blockdist; fixed_t blockdist;
// don't clip against self // don't clip against self
tmsprung = false; if (thing == tmthing)
return true;
// Ignore... things. // Ignore... things.
if (!tmthing || !thing) if (!tmthing || !thing || P_MobjWasRemoved(thing))
return true; return true;
I_Assert(!P_MobjWasRemoved(tmthing)); 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))) if (!(thing->flags & (MF_SOLID|MF_SPECIAL|MF_PAIN|MF_SHOOTABLE)))
return true; return true;
if (!tmthing || !thing || thing == tmthing || P_MobjWasRemoved(thing))
return true;
// Don't collide with your buddies while NiGHTS-flying. // Don't collide with your buddies while NiGHTS-flying.
if (tmthing->player && thing->player && (maptol & TOL_NIGHTS) if (tmthing->player && thing->player && (maptol & TOL_NIGHTS)
&& ((tmthing->player->pflags & PF_NIGHTSMODE) || (thing->player->pflags & PF_NIGHTSMODE))) && ((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)) if ((tmznext <= thzh && tmz > thzh) || (tmznext > thzh - sprarea && tmznext < thzh))
{ {
P_DoSpring(thing, tmthing); P_DoSpring(thing, tmthing);
tmsprung = true;
return true; return true;
} }
else if (tmz > thzh - sprarea && tmz < thzh) // Don't damage people springing up / down 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) if (thing->type == MT_FAN || thing->type == MT_STEAM)
P_DoFanAndGasJet(thing, tmthing); P_DoFanAndGasJet(thing, tmthing);
else if (thing->flags & MF_SPRING)
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))))
{ {
if (thing->flags & MF_SPRING) if ( thing->z <= tmthing->z + tmthing->height
{ && tmthing->z <= thing->z + thing->height)
P_DoSpring(thing, tmthing); 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) if (thing->type == MT_FAN || thing->type == MT_STEAM)
P_DoFanAndGasJet(thing, tmthing); 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? // 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) && thing->z + thing->height + FixedMul(FRACUNIT, thing->scale) >= tmthing->z)
{ {
if (thing->flags & MF_SPRING) if (thing->flags & MF_MONITOR
{
P_DoSpring(thing, tmthing);
tmsprung = true;
}
else if (thing->flags & MF_MONITOR
&& tmthing->player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING)) && tmthing->player->pflags & (PF_JUMPED|PF_SPINNING|PF_GLIDING))
{ {
SINT8 flipval = P_MobjFlip(thing); // Save this value in case monitor gets removed. 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. *momz = -*momz; // Therefore, you should be thrust in the opposite direction, vertically.
return false; 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, // 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 // 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) 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; boolean oldfltok = floatok;
fixed_t oldflrz = tmfloorz; fixed_t oldflrz = tmfloorz;
fixed_t oldceilz = tmceilingz; fixed_t oldceilz = tmceilingz;
boolean oldsprung = tmsprung;
mobj_t *oldflrthing = tmfloorthing; mobj_t *oldflrthing = tmfloorthing;
mobj_t *oldthing = tmthing; mobj_t *oldthing = tmthing;
line_t *oldceilline = ceilingline; line_t *oldceilline = ceilingline;
@ -1779,7 +1770,6 @@ boolean PIT_PushableMoved(mobj_t *thing)
floatok = oldfltok; floatok = oldfltok;
tmfloorz = oldflrz; tmfloorz = oldflrz;
tmceilingz = oldceilz; tmceilingz = oldceilz;
tmsprung = oldsprung;
tmfloorthing = oldflrthing; tmfloorthing = oldflrthing;
P_SetTarget(&tmthing, oldthing); P_SetTarget(&tmthing, oldthing);
ceilingline = oldceilline; ceilingline = oldceilline;

View File

@ -1154,7 +1154,7 @@ void P_XYMovement(mobj_t *mo)
if (CheckForBustableBlocks && mo->flags & MF_PUSHABLE) if (CheckForBustableBlocks && mo->flags & MF_PUSHABLE)
P_PushableCheckBustables(mo); 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 // blocked move
@ -5448,7 +5448,7 @@ void P_MobjThinker(mobj_t *mobj)
if (mobj->tracer && P_MobjWasRemoved(mobj->tracer)) if (mobj->tracer && P_MobjWasRemoved(mobj->tracer))
P_SetTarget(&mobj->tracer, NULL); P_SetTarget(&mobj->tracer, NULL);
mobj->eflags &= ~MFE_PUSHED; mobj->eflags &= ~(MFE_PUSHED|MFE_SPRUNG);
// 970 allows ANY mobj to trigger a linedef exec // 970 allows ANY mobj to trigger a linedef exec
if (mobj->subsector && GETSECSPECIAL(mobj->subsector->sector->special, 2) == 8) if (mobj->subsector && GETSECSPECIAL(mobj->subsector->sector->special, 2) == 8)

View File

@ -233,6 +233,9 @@ typedef enum
MFE_GOOWATER = 1<<6, MFE_GOOWATER = 1<<6,
// Mobj was already pushed this tic // Mobj was already pushed this tic
MFE_PUSHED = 1<<7, MFE_PUSHED = 1<<7,
// Mobj was already sprung this tic
MFE_SPRUNG = 1<<8,
// free: to and including 1<<15
} mobjeflag_t; } mobjeflag_t;
// //
@ -286,7 +289,7 @@ typedef struct mobj_s
state_t *state; state_t *state;
UINT32 flags; // flags from mobjinfo tables UINT32 flags; // flags from mobjinfo tables
UINT32 flags2; // MF2_ flags 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) void *skin; // overrides 'sprite' when non-NULL (for player bodies to 'remember' the skin)
// Player and mobj sprites in multiplayer modes are modified // 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) if (diff & MD_FRAME)
WRITEUINT32(save_p, mobj->frame); WRITEUINT32(save_p, mobj->frame);
if (diff & MD_EFLAGS) if (diff & MD_EFLAGS)
WRITEUINT8(save_p, mobj->eflags); WRITEUINT16(save_p, mobj->eflags);
if (diff & MD_PLAYER) if (diff & MD_PLAYER)
WRITEUINT8(save_p, mobj->player-players); WRITEUINT8(save_p, mobj->player-players);
if (diff & MD_MOVEDIR) if (diff & MD_MOVEDIR)
@ -2000,7 +2000,7 @@ static void LoadMobjThinker(actionf_p1 thinker)
else else
mobj->frame = mobj->state->frame; mobj->frame = mobj->state->frame;
if (diff & MD_EFLAGS) if (diff & MD_EFLAGS)
mobj->eflags = READUINT8(save_p); mobj->eflags = READUINT16(save_p);
if (diff & MD_PLAYER) if (diff & MD_PLAYER)
{ {
i = READUINT8(save_p); i = READUINT8(save_p);