mirror of
https://github.com/ZDoom/gzdoom.git
synced 2025-01-18 07:32:28 +00:00
Fixed bouncing on 3D floors (#2835)
This commit is contained in:
parent
5576e66670
commit
5240c52b07
5 changed files with 31 additions and 15 deletions
|
@ -873,7 +873,7 @@ public:
|
|||
void PlayPushSound();
|
||||
|
||||
// Called when an actor with MF_MISSILE and MF2_FLOORBOUNCE hits the floor
|
||||
bool FloorBounceMissile (secplane_t &plane);
|
||||
bool FloorBounceMissile (secplane_t &plane, bool is3DFloor);
|
||||
|
||||
// Called by RoughBlockCheck
|
||||
bool IsOkayToAttack (AActor *target);
|
||||
|
|
|
@ -2486,7 +2486,9 @@ bool P_TryMove(AActor *thing, const DVector2 &pos,
|
|||
// If it's a bouncer, let it bounce off its new floor, too.
|
||||
if (thing->BounceFlags & BOUNCE_Floors)
|
||||
{
|
||||
thing->FloorBounceMissile(tm.floorsector->floorplane);
|
||||
F3DFloor* ff = nullptr;
|
||||
NextLowestFloorAt(tm.sector, tm.pos.X, tm.pos.Y, tm.pos.Z, 0, thing->MaxStepHeight, nullptr, &ff);
|
||||
thing->FloorBounceMissile(ff != nullptr ? *ff->top.plane : tm.floorsector->floorplane, ff != nullptr);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3603,14 +3605,17 @@ bool FSlide::BounceWall(AActor *mo)
|
|||
{ // Could not find a wall, so bounce off the floor/ceiling instead.
|
||||
double floordist = mo->Z() - mo->floorz;
|
||||
double ceildist = mo->ceilingz - mo->Z();
|
||||
F3DFloor* ff = nullptr;
|
||||
if (floordist <= ceildist)
|
||||
{
|
||||
mo->FloorBounceMissile(mo->Sector->floorplane);
|
||||
NextLowestFloorAt(mo->Sector, mo->X(), mo->Y(), mo->Z(), 0, mo->MaxStepHeight, nullptr, &ff);
|
||||
mo->FloorBounceMissile(ff != nullptr ? *ff->top.plane : mo->floorsector->floorplane, ff != nullptr);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
mo->FloorBounceMissile(mo->Sector->ceilingplane);
|
||||
NextHighestCeilingAt(mo->Sector, mo->X(), mo->Y(), mo->Z(), mo->Top(), 0, nullptr, &ff);
|
||||
mo->FloorBounceMissile(ff != nullptr ? *ff->bottom.plane : mo->ceilingsector->ceilingplane, ff != nullptr);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1732,7 +1732,7 @@ void AActor::PlayBounceSound(bool onfloor)
|
|||
// Returns true if the missile was destroyed
|
||||
//----------------------------------------------------------------------------
|
||||
|
||||
bool AActor::FloorBounceMissile (secplane_t &plane)
|
||||
bool AActor::FloorBounceMissile (secplane_t &plane, bool is3DFloor)
|
||||
{
|
||||
if (flags & MF_MISSILE)
|
||||
{
|
||||
|
@ -1808,11 +1808,15 @@ bool AActor::FloorBounceMissile (secplane_t &plane)
|
|||
return true;
|
||||
}
|
||||
|
||||
double dot = (Vel | plane.Normal()) * 2;
|
||||
DVector3 norm = plane.Normal();
|
||||
if (is3DFloor)
|
||||
norm = -norm;
|
||||
|
||||
double dot = (Vel | norm) * 2;
|
||||
|
||||
if (BounceFlags & (BOUNCE_HereticType | BOUNCE_MBF))
|
||||
{
|
||||
Vel -= plane.Normal() * dot;
|
||||
Vel -= norm * dot;
|
||||
AngleFromVel();
|
||||
if (!(BounceFlags & BOUNCE_MBF)) // Heretic projectiles die, MBF projectiles don't.
|
||||
{
|
||||
|
@ -1826,7 +1830,7 @@ bool AActor::FloorBounceMissile (secplane_t &plane)
|
|||
else // Don't run through this for MBF-style bounces
|
||||
{
|
||||
// The reflected velocity keeps only about 70% of its original speed
|
||||
Vel = (Vel - plane.Normal() * dot) * bouncefactor;
|
||||
Vel = (Vel - norm * dot) * bouncefactor;
|
||||
AngleFromVel();
|
||||
}
|
||||
|
||||
|
@ -1850,10 +1854,10 @@ bool AActor::FloorBounceMissile (secplane_t &plane)
|
|||
}
|
||||
else if (BounceFlags & (BOUNCE_AutoOff|BOUNCE_AutoOffFloorOnly))
|
||||
{
|
||||
if (plane.fC() > 0 || (BounceFlags & BOUNCE_AutoOff))
|
||||
if (norm.Z > 0 || (BounceFlags & BOUNCE_AutoOff))
|
||||
{
|
||||
// AutoOff only works when bouncing off a floor, not a ceiling (or in compatibility mode.)
|
||||
if (!(flags & MF_NOGRAVITY) && (Vel.Z < 3))
|
||||
if (!(flags & MF_NOGRAVITY) && ((Vel | norm) < 3))
|
||||
BounceFlags &= ~BOUNCE_TypeMask;
|
||||
}
|
||||
}
|
||||
|
@ -2646,7 +2650,9 @@ static void P_ZMovement (AActor *mo, double oldfloorz)
|
|||
mo->SetZ(mo->floorz);
|
||||
if (mo->BounceFlags & BOUNCE_Floors)
|
||||
{
|
||||
mo->FloorBounceMissile (mo->floorsector->floorplane);
|
||||
F3DFloor* ff = nullptr;
|
||||
NextLowestFloorAt(mo->Sector, mo->X(), mo->Y(), mo->Z(), 0, mo->MaxStepHeight, nullptr, &ff);
|
||||
mo->FloorBounceMissile (ff != nullptr ? *ff->top.plane : mo->floorsector->floorplane, ff != nullptr);
|
||||
/* if (!CanJump(mo)) */ return;
|
||||
}
|
||||
else if (mo->flags3 & MF3_NOEXPLODEFLOOR)
|
||||
|
@ -2682,7 +2688,9 @@ static void P_ZMovement (AActor *mo, double oldfloorz)
|
|||
}
|
||||
else if (mo->BounceFlags & BOUNCE_MBF && mo->Vel.Z) // check for MBF-like bounce on non-missiles
|
||||
{
|
||||
mo->FloorBounceMissile(mo->floorsector->floorplane);
|
||||
F3DFloor* ff = nullptr;
|
||||
NextLowestFloorAt(mo->Sector, mo->X(), mo->Y(), mo->Z(), 0, mo->MaxStepHeight, nullptr, &ff);
|
||||
mo->FloorBounceMissile(ff != nullptr ? *ff->top.plane : mo->floorsector->floorplane, ff != nullptr);
|
||||
}
|
||||
if (mo->flags3 & MF3_ISMONSTER) // Blasted mobj falling
|
||||
{
|
||||
|
@ -2753,7 +2761,9 @@ static void P_ZMovement (AActor *mo, double oldfloorz)
|
|||
mo->SetZ(mo->ceilingz - mo->Height);
|
||||
if (mo->BounceFlags & BOUNCE_Ceilings)
|
||||
{ // ceiling bounce
|
||||
mo->FloorBounceMissile (mo->ceilingsector->ceilingplane);
|
||||
F3DFloor* ff = nullptr;
|
||||
NextHighestCeilingAt(mo->Sector, mo->X(), mo->Y(), mo->Z(), mo->Top(), 0, nullptr, &ff);
|
||||
mo->FloorBounceMissile(ff != nullptr ? *ff->bottom.plane : mo->ceilingsector->ceilingplane, ff != nullptr);
|
||||
/* if (!CanJump(mo)) */ return;
|
||||
}
|
||||
if (mo->flags & MF_SKULLFLY)
|
||||
|
|
|
@ -1851,8 +1851,9 @@ DEFINE_ACTION_FUNCTION(AActor, BouncePlane)
|
|||
{
|
||||
PARAM_SELF_PROLOGUE(AActor);
|
||||
PARAM_POINTER(plane, secplane_t);
|
||||
PARAM_BOOL(is3DFloor);
|
||||
|
||||
ACTION_RETURN_BOOL(self->FloorBounceMissile(*plane));
|
||||
ACTION_RETURN_BOOL(self->FloorBounceMissile(*plane, is3DFloor));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(AActor, PlayBounceSound)
|
||||
|
|
|
@ -866,7 +866,7 @@ class Actor : Thinker native
|
|||
native void PlayPushSound();
|
||||
native bool BounceActor(Actor blocking, bool onTop);
|
||||
native bool BounceWall(Line l = null);
|
||||
native bool BouncePlane(readonly<SecPlane> plane);
|
||||
native bool BouncePlane(readonly<SecPlane> plane, bool is3DFloor = false);
|
||||
native void PlayBounceSound(bool onFloor);
|
||||
native bool ReflectOffActor(Actor blocking);
|
||||
|
||||
|
|
Loading…
Reference in a new issue