diff --git a/src/compatibility.cpp b/src/compatibility.cpp index 4ddc670e9..da4ab4945 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -109,6 +109,7 @@ static FCompatOption Options[] = { "rebuildnodes", BCOMPATF_REBUILDNODES, SLOT_BCOMPAT }, { "linkfrozenprops", BCOMPATF_LINKFROZENPROPS, SLOT_BCOMPAT }, { "disablepushwindowcheck", BCOMPATF_NOWINDOWCHECK, SLOT_BCOMPAT }, + { "floatbob", BCOMPATF_FLOATBOB, SLOT_BCOMPAT }, // list copied from g_mapinfo.cpp { "shorttex", COMPATF_SHORTTEX, SLOT_COMPAT }, @@ -434,6 +435,11 @@ void CheckCompatibility(MapData *map) // Reset i_compatflags compatflags.Callback(); compatflags2.Callback(); + // Set floatbob compatibility for all maps with an original Hexen MAPINFO. + if (level.flags2 & LEVEL2_HEXENHACK) + { + ib_compatflags |= BCOMPATF_FLOATBOB; + } } //========================================================================== diff --git a/src/doomdef.h b/src/doomdef.h index 767f97661..c8aa66c17 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -354,6 +354,7 @@ enum BCOMPATF_REBUILDNODES = 1 << 5, // Force node rebuild BCOMPATF_LINKFROZENPROPS = 1 << 6, // Clearing PROP_TOTALLYFROZEN or PROP_FROZEN also clears the other BCOMPATF_NOWINDOWCHECK = 1 << 7, // Disable the window check in CheckForPushSpecial() + BCOMPATF_FLOATBOB = 1 << 8, // Use Hexen's original method of preventing floatbobbing items from falling down }; // phares 3/20/98: diff --git a/src/p_mobj.cpp b/src/p_mobj.cpp index b27c79d91..2235c7820 100644 --- a/src/p_mobj.cpp +++ b/src/p_mobj.cpp @@ -2314,6 +2314,16 @@ void P_ZMovement (AActor *mo, fixed_t oldfloorz) } } + // Hexen compatibility handling for floatbobbing. Ugh... + // Hexen yanked all items to the floor, except those being spawned at map start in the air. + // Those were kept at their original height. + // Do this only if the item was actually spawned by the map above ground to avoid problems. + if (mo->special1 > 0 && (mo->flags2 & MF2_FLOATBOB) && (ib_compatflags & BCOMPATF_FLOATBOB)) + { + mo->z = mo->floorz + mo->special1; + } + + // // adjust height // @@ -2616,8 +2626,6 @@ void P_NightmareRespawn (AActor *mobj) z = ONCEILINGZ; else if (info->flags2 & MF2_SPAWNFLOAT) z = FLOATRANDZ; - else if (info->flags2 & MF2_FLOATBOB) - z = mobj->SpawnPoint[2]; else z = ONFLOORZ; @@ -4869,7 +4877,13 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) mobj = AActor::StaticSpawn (i, x, y, z, NO_REPLACE, true); if (z == ONFLOORZ) + { mobj->z += mthing->z; + if ((mobj->flags2 & MF2_FLOATBOB) && (ib_compatflags & BCOMPATF_FLOATBOB)) + { + mobj->special1 = mthing->z; + } + } else if (z == ONCEILINGZ) mobj->z -= mthing->z; @@ -4882,7 +4896,11 @@ AActor *P_SpawnMapThing (FMapThing *mthing, int position) else if (mthing->gravity > 0) mobj->gravity = FixedMul(mobj->gravity, mthing->gravity); else mobj->flags &= ~MF_NOGRAVITY; - P_FindFloorCeiling(mobj, FFCF_SAMESECTOR | FFCF_ONLY3DFLOORS | FFCF_3DRESTRICT); + // For Hexen floatbob 'compatibility' we do not really want to alter the floorz. + if (mobj->special1 == 0 || !(mobj->flags2 & MF2_FLOATBOB) || !(ib_compatflags & BCOMPATF_FLOATBOB)) + { + P_FindFloorCeiling(mobj, FFCF_SAMESECTOR | FFCF_ONLY3DFLOORS | FFCF_3DRESTRICT); + } if (!(mobj->flags2 & MF2_ARGSDEFINED)) {