Merge branch 'hotfix-pltz' into 'next'

Re-add/fix broken platform momz mobj code.

The changes in this branch re-add the platform's momentum to players and mobjs which leave the platform (eg. by jumping) so that they move with relative velocity as expected. This behavior was unintentionally broken in SRB2 2.0, which adds a lot of artificial difficulty to certain segments of the levels, where you have to jump between high velocity moving platforms which seemingly cut your jump height to nothing.

Not only has the behavior been fixed, but it has now been enhanced to move the camera while free-falling between platforms as well, completing the illusion of full relative velocity with minimal hiccups. [Observe.](http://i.imgur.com/zmSfUyp.gifv)

See merge request !14
This commit is contained in:
Alam Ed Arias 2015-06-18 10:04:54 -04:00
commit a03fc205b4
6 changed files with 57 additions and 69 deletions

View file

@ -7207,6 +7207,7 @@ static const char *const MOBJEFLAG_LIST[] = {
"GOOWATER", // Goo water
"PUSHED", // Mobj was already pushed this tic
"SPRUNG", // Mobj was already sprung this tic
"APPLYPMOMZ", // Platform movement
NULL
};

View file

@ -449,6 +449,7 @@ static int mobj_set(lua_State *L)
break;
case mobj_pmomz:
mo->pmomz = (fixed_t)luaL_checkinteger(L, 3);
mo->eflags |= MFE_APPLYPMOMZ;
break;
case mobj_tics:
mo->tics = luaL_checkinteger(L, 3);

View file

@ -2042,6 +2042,7 @@ boolean P_SceneryTryMove(mobj_t *thing, fixed_t x, fixed_t y)
//
static boolean P_ThingHeightClip(mobj_t *thing)
{
boolean floormoved;
fixed_t oldfloorz = thing->floorz;
boolean onfloor = P_IsObjectOnGround(thing);//(thing->z <= thing->floorz);
@ -2053,6 +2054,9 @@ static boolean P_ThingHeightClip(mobj_t *thing)
if (P_MobjWasRemoved(thing))
return true;
floormoved = (thing->eflags & MFE_VERTICALFLIP && tmceilingz != thing->ceilingz)
|| (!(thing->eflags & MFE_VERTICALFLIP) && tmfloorz != thing->floorz);
thing->floorz = tmfloorz;
thing->ceilingz = tmceilingz;
@ -2061,20 +2065,13 @@ static boolean P_ThingHeightClip(mobj_t *thing)
if (tmfloorz > oldfloorz+thing->height)
return true;
if (/*!tmfloorthing && */onfloor && !(thing->flags & MF_NOGRAVITY))
if (onfloor && !(thing->flags & MF_NOGRAVITY) && floormoved)
{
if (thing->eflags & MFE_VERTICALFLIP)
thing->pmomz = thing->ceilingz - (thing->z + thing->height);
else
thing->pmomz = thing->floorz - thing->z;
if (thing->player)
{
if (splitscreen && camera2.chase && thing->player == &players[secondarydisplayplayer])
camera2.z += thing->pmomz;
else if (camera.chase && thing->player == &players[displayplayer])
camera.z += thing->pmomz;
}
thing->eflags |= MFE_APPLYPMOMZ;
if (thing->eflags & MFE_VERTICALFLIP)
thing->z = thing->ceilingz - thing->height;

View file

@ -1493,10 +1493,10 @@ static void P_RingZMovement(mobj_t *mo)
P_AdjustMobjFloorZ_PolyObjs(mo, mo->subsector);
// adjust height
if (mo->pmomz && mo->z != mo->floorz)
if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo))
{
mo->momz += mo->pmomz;
mo->pmomz = 0;
mo->eflags &= ~MFE_APPLYPMOMZ;
}
mo->z += mo->momz;
@ -1562,10 +1562,10 @@ static boolean P_ZMovement(mobj_t *mo)
P_AdjustMobjFloorZ_PolyObjs(mo, mo->subsector);
// adjust height
if (mo->pmomz && mo->z != mo->floorz)
if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo))
{
mo->momz += mo->pmomz;
mo->pmomz = 0;
mo->eflags &= ~MFE_APPLYPMOMZ;
}
mo->z += mo->momz;
@ -1987,11 +1987,11 @@ static void P_PlayerZMovement(mobj_t *mo)
}
// adjust height
/* if (mo->pmomz && mo->z > mo->floorz && !(mo->player->pflags & PF_JUMPED))
if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo))
{
mo->momz += mo->pmomz;
mo->pmomz = 0;
}*/
mo->eflags &= ~MFE_APPLYPMOMZ;
}
mo->z += mo->momz;
@ -2008,7 +2008,7 @@ static void P_PlayerZMovement(mobj_t *mo)
else
mo->z = mo->floorz;
if (mo->player && (mo->player->pflags & PF_NIGHTSMODE))
if (mo->player->pflags & PF_NIGHTSMODE)
{
if (mo->player->flyangle < 90 || mo->player->flyangle >= 270)
mo->player->flyangle += P_MobjFlip(mo)*90;
@ -2023,12 +2023,11 @@ static void P_PlayerZMovement(mobj_t *mo)
if (P_MobjFlip(mo)*mo->momz < 0) // falling
{
mo->pmomz = 0; // We're on a new floor, don't keep doing platform movement.
// Squat down. Decrease viewheight for a moment after hitting the ground (hard),
if (mo->player)
{
if (P_MobjFlip(mo)*mo->momz < -FixedMul(8*FRACUNIT, mo->scale))
mo->player->deltaviewheight = (P_MobjFlip(mo)*mo->momz)>>3; // make sure momz is negative
}
if (!tmfloorthing || tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR)
|| tmfloorthing->flags2 & MF2_STANDONME || tmfloorthing->type == MT_PLAYER) // Spin Attack
@ -2101,14 +2100,14 @@ static void P_PlayerZMovement(mobj_t *mo)
// Cut momentum in half when you hit the ground and
// aren't pressing any controls.
if (!mo->player || (!(mo->player->cmd.forwardmove || mo->player->cmd.sidemove) && !mo->player->cmomx && !mo->player->cmomy && !(mo->player->pflags & PF_SPINNING)))
if (!(mo->player->cmd.forwardmove || mo->player->cmd.sidemove) && !mo->player->cmomx && !mo->player->cmomy && !(mo->player->pflags & PF_SPINNING))
{
mo->momx = mo->momx/2;
mo->momy = mo->momy/2;
}
}
if (mo->health && mo->player)
if (mo->health)
{
if (mo->player->pflags & PF_GLIDING) // ground gliding
{
@ -2154,7 +2153,7 @@ static void P_PlayerZMovement(mobj_t *mo)
mo->player->powers[pw_tailsfly] = 0;
}
}
if (mo->player && !(mo->player->pflags & PF_SPINNING))
if (!(mo->player->pflags & PF_SPINNING))
mo->player->pflags &= ~PF_STARTDASH;
if (tmfloorthing && (tmfloorthing->flags & (MF_PUSHABLE|MF_MONITOR)
@ -2197,7 +2196,7 @@ nightsdone:
else
mo->z = mo->ceilingz - mo->height;
if (mo->player && (mo->player->pflags & PF_NIGHTSMODE))
if (mo->player->pflags & PF_NIGHTSMODE)
{
if (mo->player->flyangle < 90 || mo->player->flyangle >= 270)
mo->player->flyangle -= P_MobjFlip(mo)*90;
@ -2212,7 +2211,7 @@ nightsdone:
{
msecnode_t *node;
if (CheckForMarioBlocks && mo->player && !(netgame && mo->player->spectator)) // Only let the player punch
if (CheckForMarioBlocks && !(netgame && mo->player->spectator)) // Only let the player punch
{
// Search the touching sectors, from side-to-side...
for (node = mo->touching_sectorlist; node; node = node->m_snext)
@ -2240,7 +2239,7 @@ nightsdone:
if (mariomode)
S_StartSound(mo, sfx_mario1);
if (!(mo->player && mo->player->climbing))
if (!mo->player->climbing)
mo->momz = 0;
}
}
@ -2255,10 +2254,10 @@ static boolean P_SceneryZMovement(mobj_t *mo)
P_AdjustMobjFloorZ_PolyObjs(mo, mo->subsector);
// adjust height
if (mo->pmomz && mo->z != mo->floorz)
if (mo->eflags & MFE_APPLYPMOMZ && !P_IsObjectOnGround(mo))
{
mo->momz += mo->pmomz;
mo->pmomz = 0;
mo->eflags &= ~MFE_APPLYPMOMZ;
}
mo->z += mo->momz;
@ -2838,10 +2837,10 @@ boolean P_CameraThinker(player_t *player, camera_t *thiscam, boolean resetcalled
thiscam->floorz = tmfloorz;
thiscam->ceilingz = tmceilingz;
if (thiscam->momz)
if (thiscam->momz || player->mo->pmomz)
{
// adjust height
thiscam->z += thiscam->momz;
thiscam->z += thiscam->momz + player->mo->pmomz;
if (!itsatwodlevel && !(player->pflags & PF_NOCLIP))
{
@ -2899,6 +2898,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
msecnode_t *node;
I_Assert(mobj != NULL);
I_Assert(mobj->player != NULL);
I_Assert(!P_MobjWasRemoved(mobj));
P_MobjCheckWater(mobj);
@ -2917,7 +2917,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
P_CheckPosition(mobj, mobj->x, mobj->y);
goto animonly;
}
else if (mobj->player && (mobj->player->pflags & PF_MACESPIN) && mobj->tracer)
else if (mobj->player->pflags & PF_MACESPIN && mobj->tracer)
{
P_CheckPosition(mobj, mobj->x, mobj->y);
goto animonly;
@ -2936,7 +2936,7 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
else
P_TryMove(mobj, mobj->x, mobj->y, true);
if (!(netgame && mobj->player && mobj->player->spectator))
if (!(netgame && mobj->player->spectator))
{
// Crumbling platforms
for (node = mobj->touching_sectorlist; node; node = node->m_snext)
@ -3018,8 +3018,6 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
return;
}
else
{
if (mobj->player)
{
mobj->player->jumping = 0;
mobj->player->pflags &= ~PF_JUMPED;
@ -3029,8 +3027,6 @@ static void P_PlayerMobjThinker(mobj_t *mobj)
mobj->player->powers[pw_tailsfly] = 0;
P_SetPlayerMobjState(mobj, S_PLAY_RUN1);
}
}
mobj->pmomz = 0;
mobj->eflags &= ~MFE_JUSTHITFLOOR;
}
@ -6648,17 +6644,6 @@ for (i = ((mobj->flags2 & MF2_STRONGBOX) ? strongboxamt : weakboxamt); i; --i) s
}
else
{
if (mobj->player)
{
mobj->player->jumping = 0;
mobj->player->pflags &= ~PF_JUMPED;
if (mobj->player->secondjump || mobj->player->powers[pw_tailsfly])
{
mobj->player->secondjump = 0;
mobj->player->powers[pw_tailsfly] = 0;
P_SetPlayerMobjState(mobj, S_PLAY_RUN1);
}
}
mobj->pmomz = 0; // to prevent that weird rocketing gargoyle bug
mobj->eflags &= ~MFE_JUSTHITFLOOR;
}
@ -6859,17 +6844,6 @@ void P_SceneryThinker(mobj_t *mobj)
}
else
{
if (mobj->player)
{
mobj->player->jumping = 0;
mobj->player->pflags &= ~PF_JUMPED;
if (mobj->player->secondjump || mobj->player->powers[pw_tailsfly])
{
mobj->player->secondjump = 0;
mobj->player->powers[pw_tailsfly] = 0;
P_SetPlayerMobjState(mobj, S_PLAY_RUN1);
}
}
mobj->pmomz = 0; // to prevent that weird rocketing gargoyle bug
mobj->eflags &= ~MFE_JUSTHITFLOOR;
}

View file

@ -235,6 +235,8 @@ typedef enum
MFE_PUSHED = 1<<7,
// Mobj was already sprung this tic
MFE_SPRUNG = 1<<8,
// Platform movement
MFE_APPLYPMOMZ = 1<<9,
// free: to and including 1<<15
} mobjeflag_t;

View file

@ -3635,11 +3635,22 @@ void P_DoJump(player_t *player, boolean soundandstate)
// set just an eensy above the ground
if (player->mo->eflags & MFE_VERTICALFLIP)
{
player->mo->z--;
if (player->mo->pmomz < 0)
player->mo->momz += player->mo->pmomz; // Add the platform's momentum to your jump.
else
player->mo->pmomz = 0;
}
else
{
player->mo->z++;
player->mo->z += player->mo->pmomz; // Solves problem of 'hitting around again after jumping on a moving platform'.
if (player->mo->pmomz > 0)
player->mo->momz += player->mo->pmomz; // Add the platform's momentum to your jump.
else
player->mo->pmomz = 0;
}
player->mo->eflags &= ~MFE_APPLYPMOMZ;
player->pflags |= PF_JUMPED;
@ -9046,7 +9057,6 @@ void P_PlayerThink(player_t *player)
player->mo->tracer->flags2 &= ~MF2_DONTDRAW;
}
player->mo->pmomz = 0;
player->pflags &= ~PF_SLIDING;
/*
@ -9399,4 +9409,7 @@ void P_PlayerAfterThink(player_t *player)
player->mo->flags2 |= MF2_DONTDRAW;
player->mo->flags |= MF_NOGRAVITY;
}
if (P_IsObjectOnGround(player->mo))
player->mo->pmomz = 0;
}