ref: 7c47cdf16112ed6b15e8a918377156035a166f1e
parent: bf8974e63b988ae1b5d2fdb0492dfe0bb3613680
author: Simon Howard <[email protected]>
date: Tue Jan 26 14:18:18 EST 2010
Fix glass hack windows where a linedef is flagged as two sided but has only one side. Fixes WADs such as OTTAWAU.WAD (thanks Never_Again). Subversion-branch: /trunk/chocolate-doom Subversion-revision: 1826
--- a/NEWS
+++ b/NEWS
@@ -50,6 +50,8 @@
instead of the red colormaps normally used when taking damage
or using the berserk pack. This matches Vanilla chex.exe
behavior (thanks Fuzztooth).
+ * Impassible glass now displays and works the same as in Vanilla,
+ fixing wads such as OTTAWAU.WAD (thanks Never_Again).
Bugs fixed:
* Memory-mapped WAD I/O is disabled by default, as it caused
--- a/src/p_map.c
+++ b/src/p_map.c
@@ -885,7 +885,17 @@
dist = FixedMul (attackrange, in->frac);
- if (li->frontsector->floorheight != li->backsector->floorheight)
+ // Return false if there is no back sector. This should never
+ // be the case if the line is two-sided; however, some WADs
+ // (eg. ottawau.wad) use this as an "impassible glass" trick
+ // and rely on Vanilla Doom's (unintentional) support for this.
+
+ if (li->backsector == NULL)
+ {
+ return false;
+ }
+
+ if (li->frontsector->floorheight != li->backsector->floorheight)
{
slope = FixedDiv (openbottom - shootz , dist);
if (slope > bottomslope)
@@ -973,7 +983,14 @@
dist = FixedMul (attackrange, in->frac);
- if (li->frontsector->floorheight != li->backsector->floorheight)
+ // Check if backsector is NULL. See comment in PTR_AimTraverse.
+
+ if (li->backsector == NULL)
+ {
+ goto hitline;
+ }
+
+ if (li->frontsector->floorheight != li->backsector->floorheight)
{
slope = FixedDiv (openbottom - shootz , dist);
if (slope > aimslope)
--- a/src/p_setup.c
+++ b/src/p_setup.c
@@ -167,6 +167,7 @@
line_t* ldef;
int linedef;
int side;
+ int sidenum;
numsegs = W_LumpLength (lump) / sizeof(mapseg_t);
segs = Z_Malloc (numsegs*sizeof(seg_t),PU_LEVEL,0);
@@ -179,7 +180,7 @@
{
li->v1 = &vertexes[SHORT(ml->v1)];
li->v2 = &vertexes[SHORT(ml->v2)];
-
+
li->angle = (SHORT(ml->angle))<<16;
li->offset = (SHORT(ml->offset))<<16;
linedef = SHORT(ml->linedef);
@@ -188,10 +189,28 @@
side = SHORT(ml->side);
li->sidedef = &sides[ldef->sidenum[side]];
li->frontsector = sides[ldef->sidenum[side]].sector;
- if (ldef-> flags & ML_TWOSIDED)
- li->backsector = sides[ldef->sidenum[side^1]].sector;
- else
+
+ if (ldef-> flags & ML_TWOSIDED)
+ {
+ sidenum = ldef->sidenum[side ^ 1];
+
+ // If the sidenum is out of range, this may be a "glass hack"
+ // impassible window. Point at side #0 (this may not be
+ // the correct Vanilla behavior; however, it seems to work for
+ // OTTAWAU.WAD, which is the one place I've seen this trick
+ // used).
+
+ if (sidenum < 0 || sidenum >= numsides)
+ {
+ sidenum = 0;
+ }
+
+ li->backsector = sides[sidenum].sector;
+ }
+ else
+ {
li->backsector = 0;
+ }
}
W_ReleaseLumpNum(lump);
--- a/src/p_sight.c
+++ b/src/p_sight.c
@@ -173,7 +173,7 @@
continue;
line->validcount = validcount;
-
+
v1 = line->v1;
v2 = line->v2;
s1 = P_DivlineSide (v1->x,v1->y, &strace);
@@ -193,6 +193,14 @@
// line isn't crossed?
if (s1 == s2)
continue;
+
+ // Backsector may be NULL if this is an "impassible
+ // glass" hack line.
+
+ if (line->backsector == NULL)
+ {
+ return false;
+ }
// stop because it is not two sided anyway
// might do this after updating validcount?