- added a Boom (strict) compatibility mode.

- Restored some original Doom behavior that received complaints from users:
* reactivated the old sliding against diagonal walls code and compatibility optioned it with COMPATF_WALLRUN.
* re-added the original hitscan checking code using a cross-section of the actor instead of the bounding box, compatibility optioned with COMPATF_HITSCAN.


SVN r2340 (trunk)
This commit is contained in:
Christoph Oelckers 2010-05-28 11:15:05 +00:00
parent 9dfdf2ecdd
commit 8f881be0fb
6 changed files with 171 additions and 100 deletions

View file

@ -116,6 +116,7 @@ static FCompatOption Options[] =
{ "corpsegibs", COMPATF_CORPSEGIBS, 0 }, { "corpsegibs", COMPATF_CORPSEGIBS, 0 },
{ "noblockfriends", COMPATF_NOBLOCKFRIENDS, 0 }, { "noblockfriends", COMPATF_NOBLOCKFRIENDS, 0 },
{ "spritesort", COMPATF_SPRITESORT, 0 }, { "spritesort", COMPATF_SPRITESORT, 0 },
{ "hitscan", COMPATF_HITSCAN, 0 },
{ NULL, 0, 0 } { NULL, 0, 0 }
}; };

View file

@ -500,7 +500,8 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL)
case 2: // same as 1 but stricter (NO_PASSMOBJ and INVISIBILITY are also set) 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| v = COMPATF_SHORTTEX|COMPATF_STAIRINDEX|COMPATF_USEBLOCKING|COMPATF_NODOORLIGHT|COMPATF_SPRITESORT|
COMPATF_TRACE|COMPATF_MISSILECLIP|COMPATF_SOUNDTARGET|COMPATF_NO_PASSMOBJ|COMPATF_LIMITPAIN| COMPATF_TRACE|COMPATF_MISSILECLIP|COMPATF_SOUNDTARGET|COMPATF_NO_PASSMOBJ|COMPATF_LIMITPAIN|
COMPATF_DEHHEALTH|COMPATF_INVISIBILITY|COMPATF_CROSSDROPOFF|COMPATF_CORPSEGIBS; COMPATF_DEHHEALTH|COMPATF_INVISIBILITY|COMPATF_CROSSDROPOFF|COMPATF_CORPSEGIBS|COMPATF_HITSCAN|
COMPATF_WALLRUN|COMPATF_NOTOSSDROPS;
break; break;
case 3: // Boom compat mode case 3: // Boom compat mode
@ -516,6 +517,11 @@ CUSTOM_CVAR(Int, compatmode, 0, CVAR_ARCHIVE|CVAR_NOINITCALL)
COMPATF_MBFMONSTERMOVE|COMPATF_NOBLOCKFRIENDS; COMPATF_MBFMONSTERMOVE|COMPATF_NOBLOCKFRIENDS;
break; break;
case 6: // Boom with some added settings to reenable spme 'broken' behavior
v = COMPATF_TRACE|COMPATF_SOUNDTARGET|COMPATF_BOOMSCROLL|COMPATF_MISSILECLIP|COMPATF_NO_PASSMOBJ|
COMPATF_INVISIBILITY|COMPATF_CORPSEGIBS|COMPATF_HITSCAN|COMPATF_WALLRUN|COMPATF_NOTOSSDROPS;
break;
} }
compatflags = v; compatflags = v;
} }
@ -548,6 +554,7 @@ CVAR (Flag, compat_mbfmonstermove,compatflags, COMPATF_MBFMONSTERMOVE);
CVAR (Flag, compat_corpsegibs, compatflags, COMPATF_CORPSEGIBS); CVAR (Flag, compat_corpsegibs, compatflags, COMPATF_CORPSEGIBS);
CVAR (Flag, compat_noblockfriends,compatflags,COMPATF_NOBLOCKFRIENDS); CVAR (Flag, compat_noblockfriends,compatflags,COMPATF_NOBLOCKFRIENDS);
CVAR (Flag, compat_spritesort, compatflags,COMPATF_SPRITESORT); CVAR (Flag, compat_spritesort, compatflags,COMPATF_SPRITESORT);
CVAR (Flag, compat_hitscan, compatflags,COMPATF_HITSCAN);
//========================================================================== //==========================================================================
// //

View file

@ -325,6 +325,7 @@ enum
COMPATF_CORPSEGIBS = 1 << 25, // Crushed monsters are turned into gibs, rather than replaced by gibs. COMPATF_CORPSEGIBS = 1 << 25, // Crushed monsters are turned into gibs, rather than replaced by gibs.
COMPATF_NOBLOCKFRIENDS = 1 << 26, // Friendly monsters aren't blocked by monster-blocking lines. 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_SPRITESORT = 1 << 27, // Invert sprite sorting order for sprites of equal distance
COMPATF_HITSCAN = 1 << 28, // Hitscans use original blockmap anf hit check code.
}; };
// Emulate old bugs for select maps. These are not exposed by a cvar // Emulate old bugs for select maps. These are not exposed by a cvar

View file

@ -149,13 +149,14 @@ value_t OffOn[2] = {
{ 1.0, "Off" } { 1.0, "Off" }
}; };
value_t CompatModes[6] = { value_t CompatModes[] = {
{ 0.0, "Default" }, { 0.0, "Default" },
{ 1.0, "Doom" }, { 1.0, "Doom" },
{ 2.0, "Doom (strict)" }, { 2.0, "Doom (strict)" },
{ 3.0, "Boom" }, { 3.0, "Boom" },
{ 4.0, "ZDoom 2.0.63" }, { 6.0, "Boom (strict)" },
{ 5.0, "MBF" }, { 5.0, "MBF" },
{ 4.0, "ZDoom 2.0.63" },
}; };
menu_t *CurrentMenu; menu_t *CurrentMenu;
@ -1092,7 +1093,7 @@ static menu_t DMFlagsMenu =
*=======================================*/ *=======================================*/
static menuitem_t CompatibilityItems[] = { static menuitem_t CompatibilityItems[] = {
{ discrete, "Compatibility mode", {&compatmode}, {6.0}, {1.0}, {0.0}, {CompatModes} }, { discrete, "Compatibility mode", {&compatmode}, {7.0}, {1.0}, {0.0}, {CompatModes} },
{ redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} }, { redtext, " ", {NULL}, {0.0}, {0.0}, {0.0}, {NULL} },
{ bitflag, "Find shortest textures like Doom", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_SHORTTEX} }, { 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, "Use buggier stair building", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_STAIRINDEX} },
@ -1122,6 +1123,7 @@ static menuitem_t CompatibilityItems[] = {
{ bitflag, "Crushed monsters can be resurrected", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_CORPSEGIBS} }, { bitflag, "Crushed monsters can be resurrected", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_CORPSEGIBS} },
{ bitflag, "Friendly monsters aren't blocked", {&compatflags}, {0}, {0}, {0}, {(value_t *)COMPATF_NOBLOCKFRIENDS} }, { 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, "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} },
{ discrete, "Interpolate monster movement", {&nomonsterinterpolation}, {2.0}, {0.0}, {0.0}, {NoYes} }, { discrete, "Interpolate monster movement", {&nomonsterinterpolation}, {2.0}, {0.0}, {0.0}, {NoYes} },
}; };

View file

@ -2183,7 +2183,10 @@ void FSlide::HitSlideLine (line_t* ld)
} // ^ } // ^
else // | else // |
{ // phares { // phares
#if 0 // Doom's original algorithm here does not work well due to imprecisions of the sine table.
// However, keep it active if the wallrunning compatibility flag is on
if (i_compatflags & COMPATF_WALLRUN)
{
fixed_t newlen; fixed_t newlen;
if (deltaangle > ANG180) if (deltaangle > ANG180)
@ -2197,7 +2200,9 @@ void FSlide::HitSlideLine (line_t* ld)
tmxmove = FixedMul (newlen, finecosine[lineangle]); tmxmove = FixedMul (newlen, finecosine[lineangle]);
tmymove = FixedMul (newlen, finesine[lineangle]); tmymove = FixedMul (newlen, finesine[lineangle]);
#else }
else
{
divline_t dll, dlv; divline_t dll, dlv;
fixed_t inter1, inter2, inter3; fixed_t inter1, inter2, inter3;
@ -2224,7 +2229,7 @@ void FSlide::HitSlideLine (line_t* ld)
{ {
tmxmove = tmymove = 0; tmxmove = tmymove = 0;
} }
#endif }
} // phares } // phares
} }

View file

@ -970,8 +970,11 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it
divline_t line; divline_t line;
int i; int i;
if (!(i_compatflags & COMPATF_HITSCAN))
{
// [RH] Don't check a corner to corner crossection for hit. // [RH] Don't check a corner to corner crossection for hit.
// Instead, check against the actual bounding box. // Instead, check against the actual bounding box (but not if compatibility optioned.)
// There's probably a smarter way to determine which two sides // There's probably a smarter way to determine which two sides
// of the thing face the trace than by trying all four sides... // of the thing face the trace than by trying all four sides...
@ -1046,6 +1049,58 @@ void FPathTraverse::AddThingIntercepts (int bx, int by, FBlockThingsIterator &it
intercepts.Push (newintercept); intercepts.Push (newintercept);
} }
} }
else
{
// Old code for compatibility purposes
fixed_t x1, y1, x2, y2;
int s1, s2;
divline_t dl;
fixed_t frac;
bool tracepositive = (trace.dx ^ trace.dy)>0;
// check a corner to corner crossection for hit
if (tracepositive)
{
x1 = thing->x - thing->radius;
y1 = thing->y + thing->radius;
x2 = thing->x + thing->radius;
y2 = thing->y - thing->radius;
}
else
{
x1 = thing->x - thing->radius;
y1 = thing->y - thing->radius;
x2 = thing->x + thing->radius;
y2 = thing->y + thing->radius;
}
s1 = P_PointOnDivlineSide (x1, y1, &trace);
s2 = P_PointOnDivlineSide (x2, y2, &trace);
if (s1 != s2)
{
dl.x = x1;
dl.y = y1;
dl.dx = x2-x1;
dl.dy = y2-y1;
frac = P_InterceptVector (&trace, &dl);
if (frac >= 0)
{
intercept_t newintercept;
newintercept.frac = frac;
newintercept.isaline = false;
newintercept.done = false;
newintercept.d.thing = thing;
intercepts.Push (newintercept);
}
}
}
}
} }