diff --git a/docs/rh-log.txt b/docs/rh-log.txt index a5bee140a..5d758f967 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,4 +1,7 @@ September 24, 2009 +- Changed P_XYMovement() to not call P_SlideMove() if the act of being + blocked changed the actor's velocity. I'm not entirely happy with this, + but it gets push-activated force fields to work. - Fixed: FMultiPatchTexture::CopyTrueColorPixels() should clear the buffer first before drawing into it if the copy op passed to it is OP_OVERWRITE. FTexture::FillBuffer() sets this to erase whatever texture might have been diff --git a/src/p_lnspec.cpp b/src/p_lnspec.cpp index 17333f7d7..14585e016 100644 --- a/src/p_lnspec.cpp +++ b/src/p_lnspec.cpp @@ -2796,7 +2796,9 @@ FUNC(LS_ForceField) if (it != NULL) { P_DamageMobj (it, NULL, NULL, 16, NAME_None); - P_ThrustMobj (it, it->angle + ANGLE_180, 0x7D000); + angle_t an = (it->angle + ANGLE_180) >> ANGLETOFINESHIFT; + it->velx = FixedMul(0x7D000, finecosine[an]); + it->vely = FixedMul(0x7D000, finesine[an]); } return true; } diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index b070adef1..8449924ef 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1736,6 +1736,8 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) */ // [RH] If walking on a slope, stay on the slope // killough 3/15/98: Allow objects to drop off + fixed_t startvelx = mo->velx, startvely = mo->vely; + if (!P_TryMove (mo, ptryx, ptryy, true, walkplane, tm)) { // blocked move @@ -1759,35 +1761,44 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) { mo->velz = WATER_JUMP_SPEED; } - if (player && (i_compatflags & COMPATF_WALLRUN)) + // If the blocked move executed any push specials that changed the + // actor's velocity, do not attempt to slide. + if (mo->velx == startvelx && mo->vely == startvely) { - // [RH] Here is the key to wall running: The move is clipped using its full speed. - // If the move is done a second time (because it was too fast for one move), it - // is still clipped against the wall at its full speed, so you effectively - // execute two moves in one tic. - P_SlideMove (mo, mo->velx, mo->vely, 1); + if (player && (i_compatflags & COMPATF_WALLRUN)) + { + // [RH] Here is the key to wall running: The move is clipped using its full speed. + // If the move is done a second time (because it was too fast for one move), it + // is still clipped against the wall at its full speed, so you effectively + // execute two moves in one tic. + P_SlideMove (mo, mo->velx, mo->vely, 1); + } + else + { + P_SlideMove (mo, onestepx, onestepy, totalsteps); + } + if ((mo->velx | mo->vely) == 0) + { + steps = 0; + } + else + { + if (!player || !(i_compatflags & COMPATF_WALLRUN)) + { + xmove = mo->velx; + ymove = mo->vely; + onestepx = xmove / steps; + onestepy = ymove / steps; + P_CheckSlopeWalk (mo, xmove, ymove); + } + startx = mo->x - Scale (xmove, step, steps); + starty = mo->y - Scale (ymove, step, steps); + } } else - { - P_SlideMove (mo, onestepx, onestepy, totalsteps); - } - if ((mo->velx | mo->vely) == 0) { steps = 0; } - else - { - if (!player || !(i_compatflags & COMPATF_WALLRUN)) - { - xmove = mo->velx; - ymove = mo->vely; - onestepx = xmove / steps; - onestepy = ymove / steps; - P_CheckSlopeWalk (mo, xmove, ymove); - } - startx = mo->x - Scale (xmove, step, steps); - starty = mo->y - Scale (ymove, step, steps); - } } else { // slide against another actor