diff --git a/src/actor.h b/src/actor.h index 4bd19f1aaf..ab04b176db 100644 --- a/src/actor.h +++ b/src/actor.h @@ -414,6 +414,7 @@ enum EBounceFlags // for them that are not present in ZDoom, so it is necessary to identify it properly. BOUNCE_MBF = 1<<12, // This in itself is not a valid mode, but replaces MBF's MF_BOUNCE flag. BOUNCE_AutoOffFloorOnly = 1<<13, // like BOUNCE_AutoOff, but only on floors + BOUNCE_UseBounceState = 1<<14, // Use Bounce[.*] states BOUNCE_TypeMask = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors | BOUNCE_AutoOff | BOUNCE_HereticType | BOUNCE_MBF, @@ -1006,6 +1007,11 @@ public: return GetClass()->ActorInfo->FindState(2, names, exact); } + FState *FindState(int numnames, FName *names, bool exact = false) const + { + return GetClass()->ActorInfo->FindState(numnames, names, exact); + } + bool HasSpecialDeathStates () const; }; diff --git a/src/namedef.h b/src/namedef.h index f3ac248bfd..22b21c41c3 100644 --- a/src/namedef.h +++ b/src/namedef.h @@ -181,6 +181,13 @@ xx(Idle) xx(GenericFreezeDeath) xx(GenericCrush) +// Bounce state names +xx(Bounce) +xx(Wall) +xx(Floor) +xx(Ceiling) +xx(Creature) + // Compatible death names for the decorate parser. xx(XDeath) xx(Burn) diff --git a/src/p_map.cpp b/src/p_map.cpp index 657b90d83f..618aa81dc0 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -2869,6 +2869,14 @@ bool FSlide::BounceWall (AActor *mo) } mo->velx = FixedMul(movelen, finecosine[deltaangle]); mo->vely = FixedMul(movelen, finesine[deltaangle]); + if (mo->BounceFlags & BOUNCE_UseBounceState) + { + FState *bouncestate = mo->FindState(NAME_Bounce, NAME_Wall); + if (bouncestate != NULL) + { + mo->SetState(bouncestate); + } + } return true; } @@ -2906,6 +2914,22 @@ bool P_BounceActor (AActor *mo, AActor *BlockingMobj, bool ontop) mo->velx = FixedMul (speed, finecosine[angle]); mo->vely = FixedMul (speed, finesine[angle]); mo->PlayBounceSound(true); + if (mo->BounceFlags & BOUNCE_UseBounceState) + { + FName names[] = { NAME_Bounce, NAME_Actor, NAME_Creature }; + FState *bouncestate; + int count = 2; + + if ((BlockingMobj->flags & MF_SHOOTABLE) && !(BlockingMobj->flags & MF_NOBLOOD)) + { + count = 3; + } + bouncestate = mo->FindState(count, names); + if (bouncestate != NULL) + { + mo->SetState(bouncestate); + } + } } else { diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 2c7092da9f..ccc4540358 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -1383,6 +1383,22 @@ bool AActor::FloorBounceMissile (secplane_t &plane) } PlayBounceSound(true); + + // Set bounce state + if (BounceFlags & BOUNCE_UseBounceState) + { + FName names[2]; + FState *bouncestate; + + names[0] = NAME_Bounce; + names[1] = plane.c < 0 ? NAME_Ceiling : NAME_Floor; + bouncestate = FindState(2, names); + if (bouncestate != NULL) + { + SetState(bouncestate); + } + } + if (BounceFlags & BOUNCE_MBF) // Bring it to rest below a certain speed { if (abs(velz) < (fixed_t)(Mass * GetGravity() / 64)) diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index c542c895dc..301427ad40 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -255,6 +255,7 @@ static FFlagDef ActorFlags[]= DEFINE_FLAG2(BOUNCE_ExplodeOnWater, EXPLODEONWATER, AActor, BounceFlags), DEFINE_FLAG2(BOUNCE_MBF, MBFBOUNCER, AActor, BounceFlags), DEFINE_FLAG2(BOUNCE_AutoOffFloorOnly, BOUNCEAUTOOFFFLOORONLY, AActor, BounceFlags), + DEFINE_FLAG2(BOUNCE_UseBounceState, USEBOUNCESTATE, AActor, BounceFlags), // Deprecated flags. Handling must be performed in HandleDeprecatedFlags DEFINE_DEPRECATED_FLAG(FIREDAMAGE),