diff --git a/src/compatibility.cpp b/src/compatibility.cpp index 75729ff61..b93cb68f2 100644 --- a/src/compatibility.cpp +++ b/src/compatibility.cpp @@ -117,6 +117,7 @@ static FCompatOption Options[] = { "noblockfriends", COMPATF_NOBLOCKFRIENDS, 0 }, { "spritesort", COMPATF_SPRITESORT, 0 }, { "hitscan", COMPATF_HITSCAN, 0 }, + { "lightlevel", COMPATF_LIGHT, 0 }, { NULL, 0, 0 } }; @@ -255,10 +256,12 @@ void CheckCompatibility(MapData *map) FMD5Holder md5; FCompatValues *flags; - // When playing Doom IWAD levels force COMPAT_SHORTTEX. + // When playing Doom IWAD levels force COMPAT_SHORTTEX and COMPATF_LIGHT. + // I'm not sure if the IWAD maps actually need COMPATF_LIGHT but it certainly does not hurt. + // TNT's MAP31 also needs COMPATF_STAIRINDEX but that only gets activated for TNT.WAD. if (Wads.GetLumpFile(map->lumpnum) == 1 && (gameinfo.flags & GI_COMPATSHORTTEX) && !(level.flags & LEVEL_HEXENFORMAT)) { - ii_compatflags = COMPATF_SHORTTEX; + ii_compatflags = COMPATF_SHORTTEX|COMPATF_LIGHT; if (gameinfo.flags & GI_COMPATSTAIRS) ii_compatflags |= COMPATF_STAIRINDEX; ib_compatflags = 0; ii_compatparams = -1; diff --git a/src/d_main.cpp b/src/d_main.cpp index ceba6cfff..3b4341b28 100644 --- a/src/d_main.cpp +++ b/src/d_main.cpp @@ -494,14 +494,15 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL) case 1: // Doom2.exe compatible with a few relaxed settings v = COMPATF_SHORTTEX|COMPATF_STAIRINDEX|COMPATF_USEBLOCKING|COMPATF_NODOORLIGHT|COMPATF_SPRITESORT| - COMPATF_TRACE|COMPATF_MISSILECLIP|COMPATF_SOUNDTARGET|COMPATF_DEHHEALTH|COMPATF_CROSSDROPOFF; + COMPATF_TRACE|COMPATF_MISSILECLIP|COMPATF_SOUNDTARGET|COMPATF_DEHHEALTH|COMPATF_CROSSDROPOFF| + COMPATF_LIGHT; break; case 2: // same as 1 but stricter (NO_PASSMOBJ and INVISIBILITY are also set) v = COMPATF_SHORTTEX|COMPATF_STAIRINDEX|COMPATF_USEBLOCKING|COMPATF_NODOORLIGHT|COMPATF_SPRITESORT| COMPATF_TRACE|COMPATF_MISSILECLIP|COMPATF_SOUNDTARGET|COMPATF_NO_PASSMOBJ|COMPATF_LIMITPAIN| COMPATF_DEHHEALTH|COMPATF_INVISIBILITY|COMPATF_CROSSDROPOFF|COMPATF_CORPSEGIBS|COMPATF_HITSCAN| - COMPATF_WALLRUN|COMPATF_NOTOSSDROPS; + COMPATF_WALLRUN|COMPATF_NOTOSSDROPS|COMPATF_LIGHT; break; case 3: // Boom compat mode @@ -509,7 +510,7 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL) break; case 4: // Old ZDoom compat mode - v = COMPATF_SOUNDTARGET; + v = COMPATF_SOUNDTARGET|COMPATF_LIGHT; break; case 5: // MBF compat mode @@ -555,6 +556,7 @@ CVAR (Flag, compat_corpsegibs, compatflags, COMPATF_CORPSEGIBS); CVAR (Flag, compat_noblockfriends,compatflags,COMPATF_NOBLOCKFRIENDS); CVAR (Flag, compat_spritesort, compatflags,COMPATF_SPRITESORT); CVAR (Flag, compat_hitscan, compatflags,COMPATF_HITSCAN); +CVAR (Flag, compat_light, compatflags,COMPATF_LIGHT); //========================================================================== // diff --git a/src/doomdef.h b/src/doomdef.h index bfba79a2d..061e2b2c4 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -326,6 +326,7 @@ enum COMPATF_NOBLOCKFRIENDS = 1 << 26, // Friendly monsters aren't blocked by monster-blocking lines. COMPATF_SPRITESORT = 1 << 27, // Invert sprite sorting order for sprites of equal distance COMPATF_HITSCAN = 1 << 28, // Hitscans use original blockmap anf hit check code. + COMPATF_LIGHT = 1 << 29, // Find neighboring light level like Doom }; // Emulate old bugs for select maps. These are not exposed by a cvar diff --git a/src/g_mapinfo.cpp b/src/g_mapinfo.cpp index 1014d1770..53cd9ee5c 100644 --- a/src/g_mapinfo.cpp +++ b/src/g_mapinfo.cpp @@ -1400,6 +1400,7 @@ MapFlagHandlers[] = { "compat_corpsegibs", MITYPE_COMPATFLAG, COMPATF_CORPSEGIBS}, { "compat_noblockfriends", MITYPE_COMPATFLAG, COMPATF_NOBLOCKFRIENDS}, { "compat_spritesort", MITYPE_COMPATFLAG, COMPATF_SPRITESORT}, + { "compat_light", MITYPE_COMPATFLAG, COMPATF_LIGHT}, { "cd_start_track", MITYPE_EATNEXT, 0, 0 }, { "cd_end1_track", MITYPE_EATNEXT, 0, 0 }, { "cd_end2_track", MITYPE_EATNEXT, 0, 0 }, diff --git a/src/m_options.cpp b/src/m_options.cpp index a71b58025..db09257aa 100644 --- a/src/m_options.cpp +++ b/src/m_options.cpp @@ -1097,10 +1097,10 @@ static menuitem_t CompatibilityItems[] = { { redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} }, { bitflag, "Find shortest textures like Doom", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_SHORTTEX} }, { bitflag, "Use buggier stair building", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_STAIRINDEX} }, + { bitflag, "Find neighboring light like Doom", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_LIGHT} }, { bitflag, "Limit Pain Elementals' Lost Souls", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_LIMITPAIN} }, { bitflag, "Don't let others hear your pickups", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_SILENTPICKUP} }, { bitflag, "Actors are infinitely tall", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_NO_PASSMOBJ} }, - { bitflag, "Cripple sound for silent BFG trick", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_MAGICSILENCE} }, { bitflag, "Enable wall running", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_WALLRUN} }, { bitflag, "Spawn item drops on the floor", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_NOTOSSDROPS} }, { bitflag, "All special lines can block ", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_USEBLOCKING} }, @@ -1124,6 +1124,7 @@ static menuitem_t CompatibilityItems[] = { { bitflag, "Friendly monsters aren't blocked", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_NOBLOCKFRIENDS} }, { bitflag, "Invert sprite sorting", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_SPRITESORT} }, { bitflag, "Use Doom code for hitscan checks", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_HITSCAN} }, + { bitflag, "Cripple sound for silent BFG trick", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_MAGICSILENCE} }, { discrete, "Interpolate monster movement", {&nomonsterinterpolation}, {2.0}, {0.0}, {0.0}, {NoYes} }, }; diff --git a/src/p_lights.cpp b/src/p_lights.cpp index c33e27466..f437f4c7b 100644 --- a/src/p_lights.cpp +++ b/src/p_lights.cpp @@ -39,6 +39,12 @@ static FRandom pr_lightflash ("LightFlash"); static FRandom pr_strobeflash ("StrobeFlash"); static FRandom pr_fireflicker ("FireFlicker"); +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + IMPLEMENT_CLASS (DLighting) DLighting::DLighting () @@ -51,9 +57,11 @@ DLighting::DLighting (sector_t *sector) ChangeStatNum (STAT_LIGHT); } +//----------------------------------------------------------------------------- // // FIRELIGHT FLICKER // +//----------------------------------------------------------------------------- IMPLEMENT_CLASS (DFireFlicker) @@ -68,9 +76,12 @@ void DFireFlicker::Serialize (FArchive &arc) } +//----------------------------------------------------------------------------- // // T_FireFlicker // +//----------------------------------------------------------------------------- + void DFireFlicker::Tick () { int amount; @@ -89,9 +100,12 @@ void DFireFlicker::Tick () } } +//----------------------------------------------------------------------------- // // P_SpawnFireFlicker // +//----------------------------------------------------------------------------- + DFireFlicker::DFireFlicker (sector_t *sector) : DLighting (sector) { @@ -108,9 +122,12 @@ DFireFlicker::DFireFlicker (sector_t *sector, int upper, int lower) m_Count = 4; } +//----------------------------------------------------------------------------- // // [RH] flickering light like Hexen's // +//----------------------------------------------------------------------------- + IMPLEMENT_CLASS (DFlicker) DFlicker::DFlicker () @@ -123,6 +140,11 @@ void DFlicker::Serialize (FArchive &arc) arc << m_Count << m_MaxLight << m_MinLight; } +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- void DFlicker::Tick () { @@ -142,6 +164,12 @@ void DFlicker::Tick () } } +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + DFlicker::DFlicker (sector_t *sector, int upper, int lower) : DLighting (sector) { @@ -151,6 +179,12 @@ DFlicker::DFlicker (sector_t *sector, int upper, int lower) m_Count = (pr_flicker()&64)+1; } +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + void EV_StartLightFlickering (int tag, int upper, int lower) { int secnum; @@ -163,9 +197,11 @@ void EV_StartLightFlickering (int tag, int upper, int lower) } +//----------------------------------------------------------------------------- // // BROKEN LIGHT FLASHING // +//----------------------------------------------------------------------------- IMPLEMENT_CLASS (DLightFlash) @@ -179,10 +215,13 @@ void DLightFlash::Serialize (FArchive &arc) arc << m_Count << m_MaxLight << m_MaxTime << m_MinLight << m_MinTime; } +//----------------------------------------------------------------------------- // // T_LightFlash // Do flashing lights. // +//----------------------------------------------------------------------------- + void DLightFlash::Tick () { if (--m_Count == 0) @@ -200,9 +239,12 @@ void DLightFlash::Tick () } } +//----------------------------------------------------------------------------- // // P_SpawnLightFlash // +//----------------------------------------------------------------------------- + DLightFlash::DLightFlash (sector_t *sector) : DLighting (sector) { @@ -226,9 +268,11 @@ DLightFlash::DLightFlash (sector_t *sector, int min, int max) } +//----------------------------------------------------------------------------- // // STROBE LIGHT FLASHING // +//----------------------------------------------------------------------------- IMPLEMENT_CLASS (DStrobe) @@ -242,9 +286,12 @@ void DStrobe::Serialize (FArchive &arc) arc << m_Count << m_MaxLight << m_MinLight << m_DarkTime << m_BrightTime; } +//----------------------------------------------------------------------------- // // T_StrobeFlash // +//----------------------------------------------------------------------------- + void DStrobe::Tick () { if (--m_Count == 0) @@ -262,9 +309,12 @@ void DStrobe::Tick () } } +//----------------------------------------------------------------------------- // // Hexen-style constructor // +//----------------------------------------------------------------------------- + DStrobe::DStrobe (sector_t *sector, int upper, int lower, int utics, int ltics) : DLighting (sector) { @@ -275,9 +325,12 @@ DStrobe::DStrobe (sector_t *sector, int upper, int lower, int utics, int ltics) m_Count = 1; // Hexen-style is always in sync } +//----------------------------------------------------------------------------- // // Doom-style constructor // +//----------------------------------------------------------------------------- + DStrobe::DStrobe (sector_t *sector, int utics, int ltics, bool inSync) : DLighting (sector) { @@ -295,10 +348,13 @@ DStrobe::DStrobe (sector_t *sector, int utics, int ltics, bool inSync) +//----------------------------------------------------------------------------- // // Start strobing lights (usually from a trigger) // [RH] Made it more configurable. // +//----------------------------------------------------------------------------- + void EV_StartLightStrobing (int tag, int upper, int lower, int utics, int ltics) { int secnum; @@ -330,10 +386,13 @@ void EV_StartLightStrobing (int tag, int utics, int ltics) } +//----------------------------------------------------------------------------- // // TURN LINE'S TAG LIGHTS OFF // [RH] Takes a tag instead of a line // +//----------------------------------------------------------------------------- + void EV_TurnTagLightsOff (int tag) { int i; @@ -358,10 +417,13 @@ void EV_TurnTagLightsOff (int tag) } +//----------------------------------------------------------------------------- // // TURN LINE'S TAG LIGHTS ON // [RH] Takes a tag instead of a line // +//----------------------------------------------------------------------------- + void EV_LightTurnOn (int tag, int bright) { int secnum = -1; @@ -370,6 +432,7 @@ void EV_LightTurnOn (int tag, int bright) while ((secnum = P_FindSectorFromTag (tag, secnum)) >= 0) { sector_t *sector = sectors + secnum; + int tbright = bright; //jff 5/17/98 search for maximum PER sector // bright = -1 means to search ([RH] Not 0) // for highest light level @@ -378,7 +441,6 @@ void EV_LightTurnOn (int tag, int bright) { int j; - bright = 0; for (j = 0; j < sector->linecount; j++) { sector_t *temp = getNextSector (sector->lines[j], sector); @@ -386,14 +448,23 @@ void EV_LightTurnOn (int tag, int bright) if (!temp) continue; - if (temp->lightlevel > bright) - bright = temp->lightlevel; + if (temp->lightlevel > tbright) + tbright = temp->lightlevel; } } - sector->SetLightLevel(bright); + sector->SetLightLevel(tbright); + + //jff 5/17/98 unless compatibility optioned + //then maximum near ANY tagged sector + if (i_compatflags & COMPATF_LIGHT) + { + bright = tbright; + } } } +//----------------------------------------------------------------------------- +// // killough 10/98 // // EV_LightTurnOnPartway @@ -404,7 +475,7 @@ void EV_LightTurnOn (int tag, int bright) // Sets the light to min on 0, max on 1, and interpolates in-between. // Used for doors with gradual lighting effects. // -// Returns true +//----------------------------------------------------------------------------- void EV_LightTurnOnPartway (int tag, fixed_t frac) { @@ -438,11 +509,14 @@ void EV_LightTurnOnPartway (int tag, fixed_t frac) } +//----------------------------------------------------------------------------- // // [RH] New function to adjust tagged sectors' light levels // by a relative amount. Light levels are clipped to // within the range 0-255 inclusive. // +//----------------------------------------------------------------------------- + void EV_LightChange (int tag, int value) { int secnum = -1; @@ -455,9 +529,12 @@ void EV_LightChange (int tag, int value) } +//----------------------------------------------------------------------------- // // Spawn glowing light // +//----------------------------------------------------------------------------- + IMPLEMENT_CLASS (DGlow) DGlow::DGlow () @@ -470,6 +547,12 @@ void DGlow::Serialize (FArchive &arc) arc << m_Direction << m_MaxLight << m_MinLight; } +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + void DGlow::Tick () { int newlight = m_Sector->lightlevel; @@ -499,6 +582,11 @@ void DGlow::Tick () m_Sector->SetLightLevel(newlight); } +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- DGlow::DGlow (sector_t *sector) : DLighting (sector) @@ -508,9 +596,11 @@ DGlow::DGlow (sector_t *sector) m_Direction = -1; } +//----------------------------------------------------------------------------- // // [RH] More glowing light, this time appropriate for Hexen-ish uses. // +//----------------------------------------------------------------------------- IMPLEMENT_CLASS (DGlow2) @@ -524,6 +614,12 @@ void DGlow2::Serialize (FArchive &arc) arc << m_End << m_MaxTics << m_OneShot << m_Start << m_Tics; } +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + void DGlow2::Tick () { if (m_Tics++ >= m_MaxTics) @@ -546,6 +642,12 @@ void DGlow2::Tick () m_Sector->SetLightLevel(((m_End - m_Start) * m_Tics) / m_MaxTics + m_Start); } +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + DGlow2::DGlow2 (sector_t *sector, int start, int end, int tics, bool oneshot) : DLighting (sector) { @@ -556,6 +658,12 @@ DGlow2::DGlow2 (sector_t *sector, int start, int end, int tics, bool oneshot) m_OneShot = oneshot; } +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + void EV_StartLightGlowing (int tag, int upper, int lower, int tics) { int secnum; @@ -584,6 +692,12 @@ void EV_StartLightGlowing (int tag, int upper, int lower, int tics) } } +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + void EV_StartLightFading (int tag, int value, int tics) { int secnum; @@ -611,8 +725,12 @@ void EV_StartLightFading (int tag, int value, int tics) } +//----------------------------------------------------------------------------- +// // [RH] Phased lighting ala Hexen, but implemented without the help of the Hexen source // The effect is a little different, but close enough, I feel. +// +//----------------------------------------------------------------------------- IMPLEMENT_CLASS (DPhased) @@ -626,6 +744,12 @@ void DPhased::Serialize (FArchive &arc) arc << m_BaseLevel << m_Phase; } +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + void DPhased::Tick () { const int steps = 12; @@ -644,6 +768,12 @@ void DPhased::Tick () m_Phase--; } +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + int DPhased::PhaseHelper (sector_t *sector, int index, int light, sector_t *prev) { if (!sector) @@ -675,6 +805,12 @@ int DPhased::PhaseHelper (sector_t *sector, int index, int light, sector_t *prev } } +//----------------------------------------------------------------------------- +// +// +// +//----------------------------------------------------------------------------- + DPhased::DPhased (sector_t *sector, int baselevel) : DLighting (sector) {