From e4d0d6bcdbec7f211fa88c23c635d032fcc69747 Mon Sep 17 00:00:00 2001 From: Christoph Oelckers Date: Sun, 11 Apr 2010 11:18:33 +0000 Subject: [PATCH] - added a Sector_CopyScroller special to allow setting scrollers to sectors with special tags. - extended compatibility text to allow changing line flags and setting line specials on specific linedefs. - removed Strain MAP07 hack and replaced it by a clean 'clearlineflags' option. - Added Doomo format translations for Sector_CopyScroller because this looks like something that might be useful for making some Boom maps work without having to resort to compatibility.txt. - added a compatibility setting for UAC Ultra MAP07 which exploited some undefined scrolling behavior in Boom. (What lengths are we going to make sloppily created maps work? This entire commit was just to address this particular problem...) SVN r2280 (trunk) --- src/actionspecials.h | 1 + src/compatibility.cpp | 126 ++++++++++++++++++++++++++++++-- src/compatibility.h | 2 + src/doomdef.h | 3 +- src/p_setup.cpp | 10 +-- src/p_spec.cpp | 47 ++++++++++++ src/statnums.h | 6 +- wadsrc/static/compatibility.txt | 8 +- wadsrc/static/xlat/base.txt | 4 + 9 files changed, 187 insertions(+), 20 deletions(-) diff --git a/src/actionspecials.h b/src/actionspecials.h index cd49504c3..de2d86bfb 100644 --- a/src/actionspecials.h +++ b/src/actionspecials.h @@ -56,6 +56,7 @@ DEFINE_SPECIAL(Sector_ChangeFlags, 54, 3, 3, 3) DEFINE_SPECIAL(Line_SetBlocking, 55, 3, 3, 3) DEFINE_SPECIAL(Line_SetTextureScale, 56, 5, 5, 5) DEFINE_SPECIAL(Sector_SetPortal, 57, -1, -1, 5) +DEFINE_SPECIAL(Sector_CopyScroller, 58, -1, -1, 2) DEFINE_SPECIAL(Plat_PerpetualRaise, 60, 3, 3, 3) DEFINE_SPECIAL(Plat_Stop, 61, 1, 1, 1) diff --git a/src/compatibility.cpp b/src/compatibility.cpp index f4fbaa529..caaaaf871 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -43,10 +43,13 @@ #include "sc_man.h" #include "cmdlib.h" #include "doomdef.h" +#include "doomdata.h" #include "doomstat.h" #include "c_dispatch.h" #include "gi.h" #include "g_level.h" +#include "p_lnspec.h" +#include "r_state.h" // MACROS ------------------------------------------------------------------ @@ -59,6 +62,14 @@ struct FCompatOption int BCompatFlags; }; +enum +{ + CP_END, + CP_CLEARFLAGS, + CP_SETFLAGS, + CP_SETSPECIAL +}; + // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- // PUBLIC FUNCTION PROTOTYPES ---------------------------------------------- @@ -77,7 +88,6 @@ static FCompatOption Options[] = { { "setslopeoverflow", 0, BCOMPATF_SETSLOPEOVERFLOW }, { "resetplayerspeed", 0, BCOMPATF_RESETPLAYERSPEED }, - { "spechitoverflow", 0, BCOMPATF_SPECHITOVERFLOW }, { "vileghosts", 0, BCOMPATF_VILEGHOSTS }, // list copied from g_mapinfo.cpp @@ -109,6 +119,9 @@ static FCompatOption Options[] = { NULL, 0, 0 } }; +static TArray CompatParams; +static int ii_compatparams; + // CODE -------------------------------------------------------------------- //========================================================================== @@ -170,12 +183,57 @@ void ParseCompatibility() } while (!sc.Compare("{")); flags.CompatFlags = 0; flags.BCompatFlags = 0; - while (sc.MustGetString(), (i = sc.MatchString(&Options[0].Name, sizeof(*Options))) >= 0) + flags.ExtCommandIndex = -1; + while (sc.GetString()) { - flags.CompatFlags |= Options[i].CompatFlags; - flags.BCompatFlags |= Options[i].BCompatFlags; + if ((i = sc.MatchString(&Options[0].Name, sizeof(*Options))) >= 0) + { + flags.CompatFlags |= Options[i].CompatFlags; + flags.BCompatFlags |= Options[i].BCompatFlags; + } + else if (sc.Compare("clearlineflags")) + { + if (flags.ExtCommandIndex == -1) flags.ExtCommandIndex = CompatParams.Size(); + CompatParams.Push(CP_CLEARFLAGS); + sc.MustGetNumber(); + CompatParams.Push(sc.Number); + sc.MustGetNumber(); + CompatParams.Push(sc.Number); + } + else if (sc.Compare("setlineflags")) + { + if (flags.ExtCommandIndex == -1) flags.ExtCommandIndex = CompatParams.Size(); + CompatParams.Push(CP_SETFLAGS); + sc.MustGetNumber(); + CompatParams.Push(sc.Number); + sc.MustGetNumber(); + CompatParams.Push(sc.Number); + } + else if (sc.Compare("setlinespecial")) + { + if (flags.ExtCommandIndex == -1) flags.ExtCommandIndex = CompatParams.Size(); + CompatParams.Push(CP_SETSPECIAL); + sc.MustGetNumber(); + CompatParams.Push(sc.Number); + + sc.MustGetString(); + CompatParams.Push(P_FindLineSpecial(sc.String, NULL, NULL)); + for(int i=0;i<5;i++) + { + sc.MustGetNumber(); + CompatParams.Push(sc.Number); + } + } + else + { + sc.UnGet(); + break; + } + } + if (flags.ExtCommandIndex != -1) + { + CompatParams.Push(CP_END); } - sc.UnGet(); sc.MustGetStringName("}"); for (j = 0; j < md5array.Size(); ++j) { @@ -201,6 +259,7 @@ void CheckCompatibility(MapData *map) { ii_compatflags = COMPATF_SHORTTEX; ib_compatflags = 0; + ii_compatparams = -1; } else { @@ -223,17 +282,74 @@ void CheckCompatibility(MapData *map) { ii_compatflags = flags->CompatFlags; ib_compatflags = flags->BCompatFlags; + ii_compatparams = flags->ExtCommandIndex; } else { ii_compatflags = 0; ib_compatflags = 0; + ii_compatparams = -1; } } // Reset i_compatflags compatflags.Callback(); } +//========================================================================== +// +// SetCompatibilityParams +// +//========================================================================== + +void SetCompatibilityParams() +{ + if (ii_compatparams != -1) + { + unsigned i = ii_compatparams; + + while (CompatParams[i] != CP_END && i < CompatParams.Size()) + { + switch (CompatParams[i]) + { + case CP_CLEARFLAGS: + { + if (CompatParams[i+1] < numlines) + { + line_t *line = &lines[CompatParams[i+1]]; + line->flags &= ~CompatParams[i+2]; + } + i+=3; + break; + } + case CP_SETFLAGS: + { + if (CompatParams[i+1] < numlines) + { + line_t *line = &lines[CompatParams[i+1]]; + line->flags |= CompatParams[i+2]; + } + i+=3; + break; + } + case CP_SETSPECIAL: + { + if (CompatParams[i+1] < numlines) + { + line_t *line = &lines[CompatParams[i+1]]; + line->special = CompatParams[i+2]; + for(int ii=0;ii<5;ii++) + { + line->args[ii] = CompatParams[i+ii+3]; + } + } + i+=8; + break; + } + } + } + } +} + //========================================================================== // // CCMD mapchecksum diff --git a/src/compatibility.h b/src/compatibility.h index f80314cbd..5726955b5 100644 --- a/src/compatibility.h +++ b/src/compatibility.h @@ -16,6 +16,7 @@ struct FCompatValues { int CompatFlags; int BCompatFlags; + unsigned int ExtCommandIndex; }; struct FMD5HashTraits @@ -37,5 +38,6 @@ extern TMap BCompatMap; void ParseCompatibility(); void CheckCompatibility(MapData *map); +void SetCompatibilityParams(); #endif diff --git a/src/doomdef.h b/src/doomdef.h index 485f15a5e..42636f9cb 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -333,8 +333,7 @@ enum { BCOMPATF_SETSLOPEOVERFLOW = 1 << 0, // SetSlope things can overflow BCOMPATF_RESETPLAYERSPEED = 1 << 1, // Set player speed to 1.0 when changing maps - BCOMPATF_SPECHITOVERFLOW = 1 << 2, // Emulate spechit overflow (e.g. Strain MAP07) - BCOMPATF_VILEGHOSTS = 1 << 3, // Monsters' radius and height aren't restored properly when resurrected. + BCOMPATF_VILEGHOSTS = 1 << 2, // Monsters' radius and height aren't restored properly when resurrected. }; // phares 3/20/98: diff --git a/src/p_setup.cpp b/src/p_setup.cpp index c27da8e56..d9b285c03 100644 --- a/src/p_setup.cpp +++ b/src/p_setup.cpp @@ -3516,15 +3516,7 @@ void P_SetupLevel (char *lumpname, int position) else P_LoadThings2 (map); // [RH] Load Hexen-style things - if (ib_compatflags & BCOMPATF_SPECHITOVERFLOW) - { - // restoring the original behavior doesn't work so we have to patch the levels in other ways. - // Fortunately the only known level depending on this bug is Strain's MAP07 and that's easy to fix. - if (numlines == 1022) - { - lines[1021].flags &= ~ML_BLOCKING; - } - } + SetCompatibilityParams(); } else { diff --git a/src/p_spec.cpp b/src/p_spec.cpp index 737ccc226..9f634ab56 100644 --- a/src/p_spec.cpp +++ b/src/p_spec.cpp @@ -1501,6 +1501,20 @@ static void P_SpawnScrollers(void) { int i; line_t *l = lines; + TArray copyscrollers; + + for (i = 0; i < numlines; i++) + { + if (lines[i].special == Sector_CopyScroller) + { + // don't allow copying the scroller if the sector has the same tag as it would just duplicate it. + if (lines[i].args[0] != lines[i].frontsector->tag) + { + copyscrollers.Push(i); + } + lines[i].special = 0; + } + } for (i = 0; i < numlines; i++, l++) { @@ -1571,20 +1585,53 @@ static void P_SpawnScrollers(void) case Scroll_Ceiling: for (s=-1; (s = P_FindSectorFromTag (l->args[0],s)) >= 0;) + { new DScroller (DScroller::sc_ceiling, -dx, dy, control, s, accel); + } + for(unsigned j = 0;j < copyscrollers.Size(); j++) + { + line_t *line = &lines[copyscrollers[j]]; + + if (line->args[0] == l->args[0] && (line->args[1] & 1)) + { + new DScroller (DScroller::sc_ceiling, -dx, dy, control, int(line->frontsector-sectors), accel); + } + } break; case Scroll_Floor: if (l->args[2] != 1) { // scroll the floor texture for (s=-1; (s = P_FindSectorFromTag (l->args[0],s)) >= 0;) + { new DScroller (DScroller::sc_floor, -dx, dy, control, s, accel); + } + for(unsigned j = 0;j < copyscrollers.Size(); j++) + { + line_t *line = &lines[copyscrollers[j]]; + + if (line->args[0] == l->args[0] && (line->args[1] & 2)) + { + new DScroller (DScroller::sc_floor, -dx, dy, control, int(line->frontsector-sectors), accel); + } + } } if (l->args[2] > 0) { // carry objects on the floor for (s=-1; (s = P_FindSectorFromTag (l->args[0],s)) >= 0;) + { new DScroller (DScroller::sc_carry, dx, dy, control, s, accel); + } + for(unsigned j = 0;j < copyscrollers.Size(); j++) + { + line_t *line = &lines[copyscrollers[j]]; + + if (line->args[0] == l->args[0] && (line->args[1] & 4)) + { + new DScroller (DScroller::sc_carry, dx, dy, control, int(line->frontsector-sectors), accel); + } + } } break; diff --git a/src/statnums.h b/src/statnums.h index f699b9c39..344a328c8 100644 --- a/src/statnums.h +++ b/src/statnums.h @@ -35,7 +35,7 @@ ** lists for different types of thinkers is taken from Build. Every thinker ** is ticked by statnum, so a thinker with a low statnum will always tick ** before a thinker with a high statnum. If a thinker is not explicitly -** created with a statnum, it will be given MAX_STATNUM. +** created with a statnum, it will be given STAT_DEFAULT */ enum @@ -59,10 +59,10 @@ enum STAT_EARTHQUAKE, // Earthquake actors STAT_MAPMARKER, // Map marker actors - STAT_DEFAULT = 100, + STAT_DEFAULT = 100, // Thinkers go here unless specified otherwise. STAT_SECTOREFFECT, // All sector effects that cause floor and ceiling movement STAT_ACTORMOVER, // actor movers - STAT_SCRIPTS, // The ACS thinker. This is to ensure that it can't tick before all actors calles PostBeginPlay + STAT_SCRIPTS, // The ACS thinker. This is to ensure that it can't tick before all actors called PostBeginPlay }; #endif \ No newline at end of file diff --git a/wadsrc/static/compatibility.txt b/wadsrc/static/compatibility.txt index 685fda086..09f38a80b 100644 --- a/wadsrc/static/compatibility.txt +++ b/wadsrc/static/compatibility.txt @@ -58,7 +58,7 @@ F84AB4557464A383E93F37CD3A82AC48 // MM2 map03 9D50EBE17CEC78938C7A668DB0768611 // Strain map07: Make the exit accessible { - spechitoverflow + clearlineflags 1021 1 } 71C2E6D9CFA3D8750C6A9599FB2453BD // Hacx map03: There are some switches behind @@ -128,3 +128,9 @@ CA267398C9B3A8F79349D3394F8B2106 // map20 { spritesort } + +DCE862393CAAA6FF1294FB7056B53057 // UAC Ultra map07: Contains a scroller depending on Boom side effects +{ + setlinespecial 391 Sector_CopyScroller 99 6 0 0 0 +} + diff --git a/wadsrc/static/xlat/base.txt b/wadsrc/static/xlat/base.txt index a7aa69f1c..45b23e52f 100644 --- a/wadsrc/static/xlat/base.txt +++ b/wadsrc/static/xlat/base.txt @@ -321,6 +321,10 @@ include "xlat/defines.i" 350 = 0, Transfer_Heights (tag, 2) // Just fake the floor 351 = 0, Transfer_Heights (tag, 6) // Just fake the floor and clip it too +352 = 0, Sector_CopyScroller(tag, 1) // copy ceiling scroller +353 = 0, Sector_CopyScroller(tag, 2) // copy floor scroller +354 = 0, Sector_CopyScroller(tag, 6) // copy carrying floor scroller + /****** EDGE linetypes ******/ 400 = 0, ExtraFloor_LightOnly (tag, 0) // thick