From f8e64a13af7ab0a90accbf0869600bb134139a14 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 26 Apr 2012 03:50:11 +0000 Subject: [PATCH] - On second thought, using FloorBounceMissile() for bouncing off the top of an actor might not be the best idea. SVN r3598 (trunk) --- src/p_local.h | 4 ++-- src/p_map.cpp | 64 ++++++++++++++++++++++++++++++++++++++++---------- src/p_mobj.cpp | 9 ++++--- 3 files changed, 58 insertions(+), 19 deletions(-) diff --git a/src/p_local.h b/src/p_local.h index 97b5e5fa38..e71fba1241 100644 --- a/src/p_local.h +++ b/src/p_local.h @@ -417,8 +417,8 @@ bool P_TeleportMove (AActor* thing, fixed_t x, fixed_t y, fixed_t z, bool telefr void P_PlayerStartStomp (AActor *actor); // [RH] Stomp on things for a newly spawned player void P_SlideMove (AActor* mo, fixed_t tryx, fixed_t tryy, int numsteps); bool P_BounceWall (AActor *mo); -bool P_BounceActor (AActor *mo, AActor * BlockingMobj); -bool P_CheckSight (const AActor* t1, const AActor* t2, int flags=0); +bool P_BounceActor (AActor *mo, AActor *BlockingMobj, bool ontop); +bool P_CheckSight (const AActor *t1, const AActor *t2, int flags=0); enum ESightFlags { diff --git a/src/p_map.cpp b/src/p_map.cpp index 9b5c2101ac..b221736cf8 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -2854,7 +2854,7 @@ bool P_BounceWall (AActor *mo) //========================================================================== extern FRandom pr_bounce; -bool P_BounceActor (AActor *mo, AActor * BlockingMobj) +bool P_BounceActor (AActor *mo, AActor *BlockingMobj, bool ontop) { if (mo && BlockingMobj && ((mo->BounceFlags & BOUNCE_AllActors) || ((mo->flags & MF_MISSILE) && (BlockingMobj->flags2 & MF2_REFLECTIVE)) @@ -2862,17 +2862,57 @@ bool P_BounceActor (AActor *mo, AActor * BlockingMobj) )) { if (mo->bouncecount > 0 && --mo->bouncecount == 0) return false; - - fixed_t speed; - angle_t angle = R_PointToAngle2 (BlockingMobj->x, - BlockingMobj->y, mo->x, mo->y) + ANGLE_1*((pr_bounce()%16)-8); - speed = P_AproxDistance (mo->velx, mo->vely); - speed = FixedMul (speed, mo->wallbouncefactor); // [GZ] was 0.75, using wallbouncefactor seems more consistent - mo->angle = angle; - angle >>= ANGLETOFINESHIFT; - mo->velx = FixedMul (speed, finecosine[angle]); - mo->vely = FixedMul (speed, finesine[angle]); - mo->PlayBounceSound(true); + + if (!ontop) + { + fixed_t speed; + angle_t angle = R_PointToAngle2 (BlockingMobj->x, + BlockingMobj->y, mo->x, mo->y) + ANGLE_1*((pr_bounce()%16)-8); + speed = P_AproxDistance (mo->velx, mo->vely); + speed = FixedMul (speed, mo->wallbouncefactor); // [GZ] was 0.75, using wallbouncefactor seems more consistent + mo->angle = angle; + angle >>= ANGLETOFINESHIFT; + mo->velx = FixedMul (speed, finecosine[angle]); + mo->vely = FixedMul (speed, finesine[angle]); + mo->PlayBounceSound(true); + } + else + { + fixed_t dot = mo->velz; + + if (mo->BounceFlags & (BOUNCE_HereticType | BOUNCE_MBF)) + { + mo->velz -= MulScale15 (FRACUNIT, dot); + if (!(mo->BounceFlags & BOUNCE_MBF)) // Heretic projectiles die, MBF projectiles don't. + { + mo->flags |= MF_INBOUNCE; + mo->SetState(mo->FindState(NAME_Death)); + mo->flags &= ~MF_INBOUNCE; + return false; + } + else + { + mo->velz = FixedMul(mo->velz, mo->bouncefactor); + } + } + else // Don't run through this for MBF-style bounces + { + // The reflected velocity keeps only about 70% of its original speed + mo->velz = FixedMul(mo->velz - MulScale15(FRACUNIT, dot), mo->bouncefactor); + } + + mo->PlayBounceSound(true); + if (mo->BounceFlags & BOUNCE_MBF) // Bring it to rest below a certain speed + { + if (abs(mo->velz) < (fixed_t)(mo->Mass * mo->GetGravity() / 64)) + mo->velz = 0; + } + else if (mo->BounceFlags & BOUNCE_AutoOff) + { + if (!(mo->flags & MF_NOGRAVITY) && (mo->velz < 3*FRACUNIT)) + mo->BounceFlags &= ~BOUNCE_TypeMask; + } + } return true; } return false; diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index a0784dbf0f..8df97f1db7 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1763,7 +1763,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) line_t *BlockingLine = mo->BlockingLine; if (!(mo->flags & MF_MISSILE) && (mo->BounceFlags & BOUNCE_MBF) - && (BlockingMobj != NULL ? P_BounceActor(mo, BlockingMobj) : P_BounceWall(mo))) + && (BlockingMobj != NULL ? P_BounceActor(mo, BlockingMobj, false) : P_BounceWall(mo))) { // Do nothing, relevant actions already done in the condition. // This allows to avoid setting velocities to 0 in the final else of this series. @@ -1858,7 +1858,7 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) if (mo->BounceFlags & BOUNCE_Actors) { // Bounce test and code moved to P_BounceActor - if (!P_BounceActor(mo, BlockingMobj)) + if (!P_BounceActor(mo, BlockingMobj, false)) { // Struck a player/creature P_ExplodeMissile (mo, NULL, BlockingMobj); } @@ -3305,10 +3305,9 @@ void AActor::Tick () } z = onmo->z + onmo->height; } - if (velz != 0 && (flags & MF_MISSILE) && (BounceFlags & BOUNCE_Actors)) + if (velz != 0 && (BounceFlags & BOUNCE_Actors)) { - secplane_t plane = { 0, 0, FRACUNIT, -z, FRACUNIT }; - FloorBounceMissile(plane); + P_BounceActor(this, onmo, true); } else {