From c1a578ba08c2627ee667ba7e9fca32ba8981754f Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 6 Sep 2009 01:49:17 +0000 Subject: [PATCH] - Split the bounce types completely into separate flags and consolidated the various bounce-related flags spread across the different Actor flags field into a single BounceFlags field. - Fixed: P_BounceWall() should calculate the XY velocity using a real square root and not P_AproxDistance(), because the latter can cause them to speed up or slow down. SVN r1796 (trunk) --- docs/rh-log.txt | 8 +++ src/actor.h | 63 +++++++++++++++-------- src/d_dehacked.cpp | 2 +- src/g_heretic/a_hereticweaps.cpp | 4 +- src/g_hexen/a_flechette.cpp | 2 +- src/p_map.cpp | 15 +++--- src/p_mobj.cpp | 77 ++++++++++++++++++++-------- src/thingdef/olddecorations.cpp | 6 +-- src/thingdef/thingdef_data.cpp | 18 +++++-- src/thingdef/thingdef_properties.cpp | 25 ++++++--- 10 files changed, 150 insertions(+), 70 deletions(-) diff --git a/docs/rh-log.txt b/docs/rh-log.txt index b5d30a2e2c..ef0e8f2f5e 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,3 +1,11 @@ +September 5, 2009 +- Split the bounce types completely into separate flags and consolidated + the various bounce-related flags spread across the different Actor flags + field into a single BounceFlags field. +- Fixed: P_BounceWall() should calculate the XY velocity using a real + square root and not P_AproxDistance(), because the latter can cause + them to speed up or slow down. + September 5, 2009 (Changes by Graf Zahl) - made menu dimming a mapping option but kept the CVARS as user override. diff --git a/src/actor.h b/src/actor.h index e866a586f1..3e59c86b47 100644 --- a/src/actor.h +++ b/src/actor.h @@ -191,14 +191,6 @@ enum MF2_SEEKERMISSILE = 0x40000000, // is a seeker (for reflection) MF2_REFLECTIVE = 0x80000000, // reflects missiles - // The three types of bounciness are: - // HERETIC - Missile will only bounce off the floor once and then enter - // its death state. It does not bounce off walls at all. - // HEXEN - Missile bounces off of walls and floors indefinitely. - // DOOM - Like Hexen, but the bounce turns off if its vertical velocity - // is too low. - - // --- mobj.flags3 --- MF3_FLOORHUGGER = 0x00000001, // Missile stays on floor @@ -224,8 +216,8 @@ enum MF3_NOBLOCKMONST = 0x00100000, // Can cross ML_BLOCKMONSTERS lines MF3_CRASHED = 0x00200000, // Actor entered its crash state MF3_FULLVOLDEATH = 0x00400000, // DeathSound is played full volume (for missiles) - MF3_CANBOUNCEWATER = 0x00800000, // Missile can bounce on water - MF3_NOWALLBOUNCESND = 0x01000000, // Don't make noise when bouncing off a wall + /* = 0x00800000, */ + /* = 0x01000000, */ MF3_FOILINVUL = 0x02000000, // Actor can hurt MF2_INVULNERABLE things MF3_NOTELEOTHER = 0x04000000, // Monster is unaffected by teleport other artifact MF3_BLOODLESSIMPACT = 0x08000000, // Projectile does not leave blood @@ -268,13 +260,13 @@ enum MF4_NOEXTREMEDEATH = 0x10000000, // this projectile or weapon never gibs its victim MF4_EXTREMEDEATH = 0x20000000, // this projectile or weapon always gibs its victim MF4_FRIGHTENED = 0x40000000, // Monster runs away from player - MF4_NOBOUNCESOUND = 0x80000000, // Strife's grenades don't make a bouncing sound. + /* = 0x80000000, */ MF5_FASTER = 0x00000001, // moves faster when DF_FAST_MONSTERS or nightmare is on. MF5_FASTMELEE = 0x00000002, // has a faster melee attack when DF_FAST_MONSTERS or nightmare is on. MF5_NODROPOFF = 0x00000004, // cannot drop off under any circumstances. - MF5_BOUNCEONACTORS = 0x00000008, // bouncing missile doesn't explode when it hits an actor - MF5_EXPLODEONWATER = 0x00000010, // bouncing missile explodes when hitting a water surface + /* = 0x00000008, */ + /* = 0x00000010, */ MF5_AVOIDINGDROPOFF = 0x00000020, // Used to move monsters away from dropoffs MF5_NODAMAGE = 0x00000040, // Actor can be shot and reacts to being shot but takes no damage MF5_CHASEGOAL = 0x00000080, // Walks to goal instead of target if a valid goal is set. @@ -379,19 +371,46 @@ enum replace_t enum EBounceType { - BOUNCE_None=0, - BOUNCE_Doom=1, - BOUNCE_Heretic=2, - BOUNCE_Hexen=3, + BOUNCE_Walls = 1<<0, // bounces off of walls + BOUNCE_Floors = 1<<1, // bounces off of floors + BOUNCE_Ceilings = 1<<2, // bounces off of ceilings + BOUNCE_Actors = 1<<3, // bounces off of some actors + BOUNCE_AllActors = 1<<4, // bounces off of all actors (requires BOUNCE_Actors to be set, too) + BOUNCE_AutoOff = 1<<5, // when bouncing off a floor, if the new Z velocity is below 3.0, disable further bouncing + BOUNCE_HereticType = 1<<6, // only works with floors and ceilings; you probably don't want to use it - BOUNCE_TypeMask = 3, - BOUNCE_UseSeeSound = 4, // compatibility fallback. Thios will only be - // set by the compatibility handlers for the old bounce flags. + BOUNCE_UseSeeSound = 1<<7, // compatibility fallback. This will only be set by + // the compatibility handlers for the old bounce flags. + BOUNCE_NoWallSound = 1<<8, // don't make noise when bouncing off a wall + BOUNCE_Quiet = 1<<9, // Strife's grenades don't make a bouncing sound + BOUNCE_ExplodeOnWater = 1<<10, // explodes when hitting a water surface + BOUNCE_CanBounceWater = 1<<11, // can bounce on water + + BOUNCE_TypeMask = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors | BOUNCE_AutoOff | BOUNCE_HereticType, + + // The three "standard" types of bounciness are: + // HERETIC - Missile will only bounce off the floor once and then enter + // its death state. It does not bounce off walls at all. + // HEXEN - Missile bounces off of walls and floors indefinitely. + // DOOM - Like Hexen, but the bounce turns off if its vertical velocity + // is too low. + BOUNCE_None = 0, + BOUNCE_Heretic = BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_HereticType, + BOUNCE_Doom = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors | BOUNCE_AutoOff, + BOUNCE_Hexen = BOUNCE_Walls | BOUNCE_Floors | BOUNCE_Ceilings | BOUNCE_Actors, // combined types BOUNCE_DoomCompat = BOUNCE_Doom | BOUNCE_UseSeeSound, BOUNCE_HereticCompat = BOUNCE_Heretic | BOUNCE_UseSeeSound, - BOUNCE_HexenCompat = BOUNCE_Hexen | BOUNCE_UseSeeSound, + BOUNCE_HexenCompat = BOUNCE_Hexen | BOUNCE_UseSeeSound + + // The distinction between BOUNCE_Actors and BOUNCE_AllActors: A missile with + // BOUNCE_Actors set will bounce off of reflective and "non-sentient" actors. + // A missile that also has BOUNCE_AllActors set will bounce off of any actor. + // For compatibility reasons when BOUNCE_Actors was implied by the bounce type + // being "Doom" or "Hexen" and BOUNCE_AllActors was the separate + // MF5_BOUNCEONACTORS, you must set BOUNCE_Actors for BOUNCE_AllActors to have + // an effect. }; // [RH] Like msecnode_t, but for the blockmap @@ -733,13 +752,13 @@ public: BYTE boomwaterlevel; // splash information for non-swimmable water sectors BYTE MinMissileChance;// [RH] If a random # is > than this, then missile attack. SBYTE LastLookPlayerNumber;// Player number last looked for (if TIDtoHate == 0) + WORD BounceFlags; // which bouncing type? WORD SpawnFlags; fixed_t meleerange; // specifies how far a melee attack reaches. fixed_t meleethreshold; // Distance below which a monster doesn't try to shoot missiles anynore // but instead tries to come closer for a melee attack. // This is not the same as meleerange fixed_t maxtargetrange; // any target farther away cannot be attacked - int bouncetype; // which bouncing type? fixed_t bouncefactor; // Strife's grenades use 50%, Hexen's Flechettes 70. fixed_t wallbouncefactor; // The bounce factor for walls can be different. int bouncecount; // Strife's grenades only bounce twice before exploding diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 7879ba6052..f344dc8b71 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -839,7 +839,7 @@ static int PatchThing (int thingy) if (info->flags2 & 0x00000004) // old BOUNCE1 { info->flags2 &= ~4; - info->bouncetype = BOUNCE_DoomCompat; + info->BounceFlags = BOUNCE_DoomCompat; } // Damage types that once were flags but now are not if (info->flags2 & 0x20000000) diff --git a/src/g_heretic/a_hereticweaps.cpp b/src/g_heretic/a_hereticweaps.cpp index 2ae66599f6..f17e725452 100644 --- a/src/g_heretic/a_hereticweaps.cpp +++ b/src/g_heretic/a_hereticweaps.cpp @@ -483,7 +483,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact) { // Bounce self->health = MAGIC_JUNK; self->velz = (self->velz * 192) >> 8; - self->bouncetype = BOUNCE_None; + self->BounceFlags = BOUNCE_None; self->SetState (self->SpawnState); S_Sound (self, CHAN_BODY, "weapons/macebounce", 1, ATTN_NORM); } @@ -555,7 +555,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_MaceBallImpact2) boom: self->velx = self->vely = self->velz = 0; self->flags |= MF_NOGRAVITY; - self->bouncetype = BOUNCE_None; + self->BounceFlags = BOUNCE_None; self->gravity = FRACUNIT; } } diff --git a/src/g_hexen/a_flechette.cpp b/src/g_hexen/a_flechette.cpp index 68c304bd5d..884e356fda 100644 --- a/src/g_hexen/a_flechette.cpp +++ b/src/g_hexen/a_flechette.cpp @@ -372,7 +372,7 @@ DEFINE_ACTION_FUNCTION(AActor, A_CheckThrowBomb2) self->SetState (self->SpawnState + 6); self->z = self->floorz; self->velz = 0; - self->bouncetype = BOUNCE_None; + self->BounceFlags = BOUNCE_None; self->flags &= ~MF_MISSILE; } CALL_ACTION(A_CheckThrowBomb, self); diff --git a/src/p_map.cpp b/src/p_map.cpp index e37f9aea78..b445d64537 100644 --- a/src/p_map.cpp +++ b/src/p_map.cpp @@ -889,13 +889,11 @@ bool PIT_CheckThing (AActor *thing, FCheckPosition &tm) return true; } - int bt = tm.thing->bouncetype & BOUNCE_TypeMask; - if (bt == BOUNCE_Doom || bt == BOUNCE_Hexen) + // [RH] What is the point of this check, again? In Hexen, it is unconditional, + // but here we only do it if the missile's damage is 0. + if ((tm.thing->BounceFlags & BOUNCE_Actors) && tm.thing->Damage == 0) { - if (tm.thing->Damage == 0) - { - return (tm.thing->target == thing || !(thing->flags & MF_SOLID)); - } + return (tm.thing->target == thing || !(thing->flags & MF_SOLID)); } switch (tm.thing->SpecialMissileHit (thing)) @@ -2543,8 +2541,7 @@ bool FSlide::BounceWall (AActor *mo) fixed_t movelen; line_t *line; - int bt = mo->bouncetype & BOUNCE_TypeMask; - if (bt != BOUNCE_Doom && bt != BOUNCE_Hexen) + if (!(mo->BounceFlags & BOUNCE_Walls)) { return false; } @@ -2615,7 +2612,7 @@ bool FSlide::BounceWall (AActor *mo) lineangle >>= ANGLETOFINESHIFT; deltaangle >>= ANGLETOFINESHIFT; - movelen = P_AproxDistance (mo->velx, mo->vely); + movelen = fixed_t(sqrt(double(mo->velx)*mo->velx + double(mo->vely)*mo->vely)); movelen = FixedMul(movelen, mo->wallbouncefactor); FBoundingBox box(mo->x, mo->y, mo->radius); diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index 39ae7fdefa..f3f076b95b 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -280,9 +280,36 @@ void AActor::Serialize (FArchive &arc) << MeleeState << MissileState << MaxDropOffHeight - << MaxStepHeight - << bouncetype - << bouncefactor + << MaxStepHeight; + if (SaveVersion < 1796) + { + int bouncetype, bounceflags; + arc << bouncetype; + + bounceflags = 0; + if (bouncetype & 4) + bounceflags |= BOUNCE_UseSeeSound; + bouncetype &= 3; + if (bouncetype == 1) bounceflags |= BOUNCE_Doom; + else if (bouncetype == 2) bounceflags |= BOUNCE_Heretic; + else if (bouncetype == 3) bounceflags |= BOUNCE_Hexen; + if (flags3 & 0x00800000) + flags3 &= ~0x00800000, bounceflags |= BOUNCE_CanBounceWater; + if (flags3 & 0x01000000) + flags3 &= ~0x01000000, bounceflags |= BOUNCE_NoWallSound; + if (flags4 & 0x80000000) + flags4 &= ~0x80000000, bounceflags |= BOUNCE_Quiet; + if (flags5 & 0x00000008) + flags5 &= ~0x00000008, bounceflags |= BOUNCE_AllActors; + if (flags5 & 0x00000010) + flags5 &= ~0x00000010, bounceflags |= BOUNCE_ExplodeOnWater; + BounceFlags = bounceflags; + } + else + { + arc << BounceFlags; + } + arc << bouncefactor << wallbouncefactor << bouncecount << maxtargetrange @@ -1258,14 +1285,14 @@ void P_ExplodeMissile (AActor *mo, line_t *line, AActor *target) void AActor::PlayBounceSound(bool onfloor) { - if (!onfloor && (flags3 & MF3_NOWALLBOUNCESND)) + if (!onfloor && (BounceFlags & BOUNCE_NoWallSound)) { return; } - if (!(flags4 & MF4_NOBOUNCESOUND)) + if (!(BounceFlags & BOUNCE_Quiet)) { - if (bouncetype & BOUNCE_UseSeeSound) + if (BounceFlags & BOUNCE_UseSeeSound) { S_Sound (this, CHAN_VOICE, SeeSound, 1, ATTN_IDLE); } @@ -1292,18 +1319,29 @@ bool AActor::FloorBounceMissile (secplane_t &plane) if (z <= floorz && P_HitFloor (this)) { // Landed in some sort of liquid - if (flags5 & MF5_EXPLODEONWATER) + if (BounceFlags & BOUNCE_ExplodeOnWater) { P_ExplodeMissile(this, NULL, NULL); return true; } - if (!(flags3 & MF3_CANBOUNCEWATER)) + if (!(BounceFlags & BOUNCE_CanBounceWater)) { Destroy (); return true; } } + if (plane.c < 0) + { // on ceiling + if (!(BounceFlags & BOUNCE_Ceilings)) + return true; + } + else + { // on floor + if (!(BounceFlags & BOUNCE_Floors)) + return true; + } + // The amount of bounces is limited if (bouncecount>0 && --bouncecount==0) { @@ -1312,9 +1350,8 @@ bool AActor::FloorBounceMissile (secplane_t &plane) } fixed_t dot = TMulScale16 (velx, plane.a, vely, plane.b, velz, plane.c); - int bt = bouncetype & BOUNCE_TypeMask; - if (bt == BOUNCE_Heretic) + if (BounceFlags & BOUNCE_HereticType) { velx -= MulScale15 (plane.a, dot); vely -= MulScale15 (plane.b, dot); @@ -1327,18 +1364,17 @@ bool AActor::FloorBounceMissile (secplane_t &plane) } // The reflected velocity keeps only about 70% of its original speed - long bouncescale = 0x4000 * bouncefactor; - velx = MulScale30 (velx - MulScale15 (plane.a, dot), bouncescale); - vely = MulScale30 (vely - MulScale15 (plane.b, dot), bouncescale); - velz = MulScale30 (velz - MulScale15 (plane.c, dot), bouncescale); + velx = FixedMul (velx - MulScale15 (plane.a, dot), bouncefactor); + vely = FixedMul (vely - MulScale15 (plane.b, dot), bouncefactor); + velz = FixedMul (velz - MulScale15 (plane.c, dot), bouncefactor); angle = R_PointToAngle2 (0, 0, velx, vely); PlayBounceSound(true); - if (bt == BOUNCE_Doom) + if (BounceFlags & BOUNCE_AutoOff) { if (!(flags & MF_NOGRAVITY) && (velz < 3*FRACUNIT)) { - bouncetype = BOUNCE_None; + BounceFlags &= ~BOUNCE_TypeMask; } } return false; @@ -1765,10 +1801,9 @@ fixed_t P_XYMovement (AActor *mo, fixed_t scrollx, fixed_t scrolly) steps = 0; if (BlockingMobj) { - int bt = mo->bouncetype & BOUNCE_TypeMask; - if (bt == BOUNCE_Doom || bt == BOUNCE_Hexen) + if (mo->BounceFlags & BOUNCE_Actors) { - if (mo->flags5&MF5_BOUNCEONACTORS || + if ((mo->BounceFlags & BOUNCE_AllActors) || (BlockingMobj->flags2 & MF2_REFLECTIVE) || ((!BlockingMobj->player) && (!(BlockingMobj->flags3 & MF3_ISMONSTER)))) @@ -2129,7 +2164,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) (!(gameinfo.gametype & GAME_DoomChex) || !(mo->flags & MF_NOCLIP))) { mo->z = mo->floorz; - if (mo->bouncetype != BOUNCE_None) + if (mo->BounceFlags & BOUNCE_Floors) { mo->FloorBounceMissile (mo->floorsector->floorplane); return; @@ -2222,7 +2257,7 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) if (mo->z + mo->height > mo->ceilingz) { mo->z = mo->ceilingz - mo->height; - if (mo->bouncetype != BOUNCE_None) + if (mo->BounceFlags & BOUNCE_Ceilings) { // ceiling bounce mo->FloorBounceMissile (mo->ceilingsector->ceilingplane); return; diff --git a/src/thingdef/olddecorations.cpp b/src/thingdef/olddecorations.cpp index 40e03ff8ae..5948bc55dd 100644 --- a/src/thingdef/olddecorations.cpp +++ b/src/thingdef/olddecorations.cpp @@ -552,15 +552,15 @@ static void ParseInsideDecoration (Baggage &bag, AActor *defaults, } else if (def == DEF_Projectile && sc.Compare ("DoomBounce")) { - defaults->bouncetype = BOUNCE_DoomCompat; + defaults->BounceFlags = BOUNCE_DoomCompat; } else if (def == DEF_Projectile && sc.Compare ("HereticBounce")) { - defaults->bouncetype = BOUNCE_HereticCompat; + defaults->BounceFlags = BOUNCE_HereticCompat; } else if (def == DEF_Projectile && sc.Compare ("HexenBounce")) { - defaults->bouncetype = BOUNCE_HexenCompat; + defaults->BounceFlags = BOUNCE_HexenCompat; } else if (def == DEF_Pickup && sc.Compare ("PickupSound")) { diff --git a/src/thingdef/thingdef_data.cpp b/src/thingdef/thingdef_data.cpp index 711592c80d..b99f6e38a6 100644 --- a/src/thingdef/thingdef_data.cpp +++ b/src/thingdef/thingdef_data.cpp @@ -142,8 +142,6 @@ static FFlagDef ActorFlags[]= DEFINE_FLAG(MF3, DONTGIB, AActor, flags3), DEFINE_FLAG(MF3, NOBLOCKMONST, AActor, flags3), DEFINE_FLAG(MF3, FULLVOLDEATH, AActor, flags3), - DEFINE_FLAG(MF3, CANBOUNCEWATER, AActor, flags3), - DEFINE_FLAG(MF3, NOWALLBOUNCESND, AActor, flags3), DEFINE_FLAG(MF3, FOILINVUL, AActor, flags3), DEFINE_FLAG(MF3, NOTELEOTHER, AActor, flags3), DEFINE_FLAG(MF3, BLOODLESSIMPACT, AActor, flags3), @@ -176,15 +174,12 @@ static FFlagDef ActorFlags[]= DEFINE_FLAG(MF4, EXTREMEDEATH, AActor, flags4), DEFINE_FLAG(MF4, NOEXTREMEDEATH, AActor, flags4), DEFINE_FLAG(MF4, FRIGHTENED, AActor, flags4), - DEFINE_FLAG(MF4, NOBOUNCESOUND, AActor, flags4), DEFINE_FLAG(MF4, NOSKIN, AActor, flags4), DEFINE_FLAG(MF4, BOSSDEATH, AActor, flags4), DEFINE_FLAG(MF5, FASTER, AActor, flags5), DEFINE_FLAG(MF5, FASTMELEE, AActor, flags5), DEFINE_FLAG(MF5, NODROPOFF, AActor, flags5), - DEFINE_FLAG(MF5, BOUNCEONACTORS, AActor, flags5), - DEFINE_FLAG(MF5, EXPLODEONWATER, AActor, flags5), DEFINE_FLAG(MF5, NODAMAGE, AActor, flags5), DEFINE_FLAG(MF5, BLOODSPLATTER, AActor, flags5), DEFINE_FLAG(MF5, OLDRADIUSDMG, AActor, flags5), @@ -228,6 +223,19 @@ static FFlagDef ActorFlags[]= DEFINE_FLAG(RF, FORCEYBILLBOARD, AActor, renderflags), DEFINE_FLAG(RF, FORCEXYBILLBOARD, AActor, renderflags), + // Bounce flags + DEFINE_FLAG2(BOUNCE_Walls, BOUNCEONWALLS, AActor, BounceFlags), + DEFINE_FLAG2(BOUNCE_Floors, BOUNCEONFLOORS, AActor, BounceFlags), + DEFINE_FLAG2(BOUNCE_Ceilings, BOUNCEONCEILINGS, AActor, BounceFlags), + DEFINE_FLAG2(BOUNCE_Actors, ALLOWBOUNCEONACTORS, AActor, BounceFlags), + DEFINE_FLAG2(BOUNCE_AutoOff, BOUNCEAUTOOFF, AActor, BounceFlags), + DEFINE_FLAG2(BOUNCE_HereticType, BOUNCELIKEHERETIC, AActor, BounceFlags), + DEFINE_FLAG2(BOUNCE_CanBounceWater, CANBOUNCEWATER, AActor, BounceFlags), + DEFINE_FLAG2(BOUNCE_NoWallSound, NOWALLBOUNCESND, AActor, BounceFlags), + DEFINE_FLAG2(BOUNCE_Quiet, NOBOUNCESOUND, AActor, BounceFlags), + DEFINE_FLAG2(BOUNCE_AllActors, BOUNCEONACTORS, AActor, BounceFlags), + DEFINE_FLAG2(BOUNCE_ExplodeOnWater, EXPLODEONWATER, AActor, BounceFlags), + // Deprecated flags. Handling must be performed in HandleDeprecatedFlags DEFINE_DEPRECATED_FLAG(FIREDAMAGE), DEFINE_DEPRECATED_FLAG(ICEDAMAGE), diff --git a/src/thingdef/thingdef_properties.cpp b/src/thingdef/thingdef_properties.cpp index 9429a14167..dced3cf026 100644 --- a/src/thingdef/thingdef_properties.cpp +++ b/src/thingdef/thingdef_properties.cpp @@ -129,14 +129,17 @@ void HandleDeprecatedFlags(AActor *defaults, FActorInfo *info, bool set, int ind info->SetDamageFactor(NAME_Fire, set? FRACUNIT/2 : FRACUNIT); break; // the bounce flags will set the compatibility bounce modes to remain compatible - case DEPF_HERETICBOUNCE: - defaults->bouncetype = set? BOUNCE_HereticCompat : 0; + case DEPF_HERETICBOUNCE: + defaults->BounceFlags &= ~BOUNCE_TypeMask; + if (set) defaults->BounceFlags |= BOUNCE_HereticCompat; break; case DEPF_HEXENBOUNCE: - defaults->bouncetype = set? BOUNCE_HexenCompat : 0; + defaults->BounceFlags &= ~BOUNCE_TypeMask; + if (set) defaults->BounceFlags |= BOUNCE_HexenCompat; break; case DEPF_DOOMBOUNCE: - defaults->bouncetype = set? BOUNCE_DoomCompat : 0; + defaults->BounceFlags &= ~BOUNCE_TypeMask; + if (set) defaults->BounceFlags |= BOUNCE_DoomCompat; break; case DEPF_PICKUPFLASH: if (set) @@ -846,9 +849,19 @@ DEFINE_PROPERTY(bloodtype, Sss, Actor) //========================================================================== DEFINE_PROPERTY(bouncetype, S, Actor) { - const char *names[] = { "None", "Doom", "Heretic", "Hexen", "*", "DoomCompat", "HereticCompat", "HexenCompat", NULL }; + static const char *names[] = { "None", "Doom", "Heretic", "Hexen", "DoomCompat", "HereticCompat", "HexenCompat", NULL }; + static const BYTE flags[] = { BOUNCE_None, + BOUNCE_Doom, BOUNCE_Heretic, BOUNCE_Hexen, + BOUNCE_DoomCompat, BOUNCE_HereticCompat, BOUNCE_HexenCompat }; PROP_STRING_PARM(id, 0); - defaults->bouncetype = MatchString(id, names); + int match = MatchString(id, names); + if (match < 0) + { + I_Error("Unknown bouncetype %s", id); + match = 0; + } + defaults->BounceFlags &= ~(BOUNCE_TypeMask | BOUNCE_UseSeeSound); + defaults->BounceFlags |= flags[match]; } //==========================================================================