diff --git a/src/d_main.cpp b/src/d_main.cpp index a4e8f5eb96f..c570eddc40f 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -713,6 +713,8 @@ CVAR (Flag, compat_railing, compatflags2, COMPATF2_RAILING); CVAR (Flag, compat_avoidhazard, compatflags2, COMPATF2_AVOID_HAZARDS); CVAR (Flag, compat_stayonlift, compatflags2, COMPATF2_STAYONLIFT); CVAR (Flag, compat_nombf21, compatflags2, COMPATF2_NOMBF21); +CVAR (Flag, compat_voodoozombies, compatflags2, COMPATF2_VOODOO_ZOMBIES); +CVAR (Flag, compat_fdteleport, compatflags2, COMPATF2_FDTELEPORT); CVAR(Bool, vid_activeinbackground, false, CVAR_ARCHIVE | CVAR_GLOBALCONFIG) diff --git a/src/doomdef.h b/src/doomdef.h index 98fa88d939b..811b4fa5e0b 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -241,6 +241,7 @@ enum : unsigned int COMPATF2_STAYONLIFT = 1 << 13, // yet another MBF thing. COMPATF2_NOMBF21 = 1 << 14, // disable MBF21 features that may clash with certain maps COMPATF2_VOODOO_ZOMBIES = 1 << 15, // [RL0] allow playerinfo, playerpawn, and voodoo health to all be different, and skip killing the player's mobj if a voodoo doll dies to allow voodoo zombies + COMPATF2_FDTELEPORT = 1 << 16, // Emulate Final Doom's teleporter z glitch. }; diff --git a/src/maploader/compatibility.cpp b/src/maploader/compatibility.cpp index 802ec3465ec..7caddc90a6d 100644 --- a/src/maploader/compatibility.cpp +++ b/src/maploader/compatibility.cpp @@ -173,6 +173,7 @@ static FCompatOption Options[] = { "scriptwait", COMPATF2_SCRIPTWAIT, SLOT_COMPAT2 }, { "nombf21", COMPATF2_NOMBF21, SLOT_COMPAT2 }, { "voodoozombies", COMPATF2_VOODOO_ZOMBIES, SLOT_COMPAT2 }, + { "fdteleport", COMPATF2_FDTELEPORT, SLOT_COMPAT2 }, { NULL, 0, 0 } }; diff --git a/src/playsim/p_lnspec.cpp b/src/playsim/p_lnspec.cpp index 73666d0c398..00318dfbb19 100644 --- a/src/playsim/p_lnspec.cpp +++ b/src/playsim/p_lnspec.cpp @@ -1120,7 +1120,7 @@ FUNC(LS_Teleport_NewMap) FUNC(LS_Teleport) // Teleport (tid, sectortag, bNoSourceFog) { - int flags = TELF_DESTFOG; + int flags = TELF_DESTFOG | TELF_FDCOMPAT; if (!arg2) { flags |= TELF_SOURCEFOG; diff --git a/src/playsim/p_spec.h b/src/playsim/p_spec.h index 5d602eb1dbd..cc7d990a97c 100644 --- a/src/playsim/p_spec.h +++ b/src/playsim/p_spec.h @@ -141,6 +141,7 @@ enum TELF_KEEPHEIGHT = 16, TELF_ROTATEBOOM = 32, TELF_ROTATEBOOMINVERSE = 64, + TELF_FDCOMPAT = 128, }; //Spawns teleport fog. Pass the actor to pluck TeleFogFromType and TeleFogToType. 'from' determines if this is the fog to spawn at the old position (true) or new (false). diff --git a/src/playsim/p_teleport.cpp b/src/playsim/p_teleport.cpp index 1643b1b7627..a69d3654c03 100644 --- a/src/playsim/p_teleport.cpp +++ b/src/playsim/p_teleport.cpp @@ -128,7 +128,15 @@ bool P_Teleport (AActor *thing, DVector3 pos, DAngle angle, int flags) } else { - pos.Z = floorheight; + if (!(thing->Level->i_compatflags2 & COMPATF2_FDTELEPORT) || !(flags & TELF_FDCOMPAT) || floorheight > thing->Z()) + { + pos.Z = floorheight; + } + else + { + pos.Z = thing->Z(); + } + if (!(flags & TELF_KEEPORIENTATION)) { resetpitch = false; @@ -145,7 +153,16 @@ bool P_Teleport (AActor *thing, DVector3 pos, DAngle angle, int flags) } else { - pos.Z = floorheight; + // emulation of Final Doom's teleport glitch. + // For walking monsters we still have to force them to the ground because the handling of off-ground monsters is different from vanilla. + if (!(thing->Level->i_compatflags2 & COMPATF2_FDTELEPORT) || !(flags & TELF_FDCOMPAT) || !(thing->flags & MF_NOGRAVITY) || floorheight > pos.Z) + { + pos.Z = floorheight; + } + else + { + pos.Z = thing->Z(); + } } } // [MK] notify thing of incoming teleport, check for an early cancel @@ -245,7 +262,7 @@ DEFINE_ACTION_FUNCTION(AActor, Teleport) PARAM_FLOAT(z); PARAM_ANGLE(an); PARAM_INT(flags); - ACTION_RETURN_BOOL(P_Teleport(self, DVector3(x, y, z), an, flags)); + ACTION_RETURN_BOOL(P_Teleport(self, DVector3(x, y, z), an, flags & ~TELF_FDCOMPAT)); } //----------------------------------------------------------------------------- diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 2440ef55f40..f8c3fe45334 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -332,3 +332,8 @@ F1EB6927F53047F219A54997DAD9DC81 // mm2.wad map20 rebuildnodes trace } + +BA2247ED1465C8107192AC4215B2A5F3 // saturnia.wad map10 +{ + fdteleport +} diff --git a/wadsrc/static/menudef.txt b/wadsrc/static/menudef.txt index fe289c6c88c..a213f593ffe 100644 --- a/wadsrc/static/menudef.txt +++ b/wadsrc/static/menudef.txt @@ -1760,6 +1760,7 @@ OptionMenu "CompatActorMenu" protected Option "$CMPTMNU_INVISIBILITY", "compat_INVISIBILITY", "YesNo" Option "$CMPTMNU_MINOTAUR", "compat_MINOTAUR", "YesNo" Option "$CMPTMNU_NOTOSSDROPS", "compat_NOTOSSDROPS", "YesNo" + Option "$CMPTMNU_VOODOOZOMBIES", "compat_voodoozombies", "YesNo" Class "CompatibilityMenu" } @@ -1786,6 +1787,7 @@ OptionMenu "CompatMapMenu" protected Option "$CMPTMNU_POINTONLINE", "compat_pointonline", "YesNo" Option "$CMPTMNU_MULTIEXIT", "compat_multiexit", "YesNo" Option "$CMPTMNU_TELEPORT", "compat_teleport", "YesNo" + Option "$CMPTMNU_FDTELEPORT", "compat_fdteleport", "YesNo" Option "$CMPTMNU_PUSHWINDOW", "compat_pushwindow", "YesNo" Option "$CMPTMNU_CHECKSWITCHRANGE", "compat_checkswitchrange", "YesNo" Option "$CMPTMNU_RAILINGHACK", "compat_railing", "YesNo"