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